summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeLists.txt9
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CPack/WiX/cmCPackWIXGenerator.cxx13
-rw-r--r--Source/CPack/cmCPackGeneratorFactory.cxx5
-rw-r--r--Source/CPack/cmCPackPackageMakerGenerator.cxx577
-rw-r--r--Source/CPack/cmCPackPackageMakerGenerator.h50
-rw-r--r--Source/CPack/cpack.cxx223
-rw-r--r--Source/CTest/cmCTestCoverageHandler.cxx6
-rw-r--r--Source/CTest/cmCTestMemCheckHandler.cxx3
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.cxx2
-rw-r--r--Source/CTest/cmCTestResourceSpec.cxx53
-rw-r--r--Source/CTest/cmCTestRunTest.cxx11
-rw-r--r--Source/CTest/cmCTestTestHandler.cxx97
-rw-r--r--Source/CTest/cmCTestTestHandler.h11
-rw-r--r--Source/CTest/cmCTestTypes.h16
-rw-r--r--Source/CursesDialog/cmCursesLongMessageForm.cxx4
-rw-r--r--Source/CursesDialog/form/frm_driver.c2
-rw-r--r--Source/LexerParser/cmCommandArgumentParser.cxx210
-rw-r--r--Source/LexerParser/cmCommandArgumentParser.y5
-rw-r--r--Source/LexerParser/cmCommandArgumentParserTokens.h6
-rw-r--r--Source/LexerParser/cmDependsJavaParser.cxx1545
-rw-r--r--Source/LexerParser/cmDependsJavaParser.y5
-rw-r--r--Source/LexerParser/cmDependsJavaParserTokens.h6
-rw-r--r--Source/LexerParser/cmExprParser.cxx208
-rw-r--r--Source/LexerParser/cmExprParser.y3
-rw-r--r--Source/LexerParser/cmExprParserTokens.h6
-rw-r--r--Source/LexerParser/cmFortranParser.cxx235
-rw-r--r--Source/LexerParser/cmFortranParser.y5
-rw-r--r--Source/LexerParser/cmFortranParserTokens.h8
-rw-r--r--Source/QtDialog/CMakeSetupDialog.cxx3
-rw-r--r--Source/QtDialog/cmake-gui.desktop2
-rw-r--r--Source/cmAddExecutableCommand.cxx4
-rw-r--r--Source/cmAddLibraryCommand.cxx4
-rw-r--r--Source/cmArchiveWrite.cxx59
-rw-r--r--Source/cmCMakeHostSystemInformationCommand.cxx100
-rw-r--r--Source/cmCMakeLanguageCommand.cxx3
-rw-r--r--Source/cmCMakePresetsGraph.cxx12
-rw-r--r--Source/cmCMakePresetsGraph.h4
-rw-r--r--Source/cmCMakePresetsGraphReadJSON.cxx102
-rw-r--r--Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx7
-rw-r--r--Source/cmCMakePresetsGraphReadJSONConfigurePresets.cxx24
-rw-r--r--Source/cmCMakePresetsGraphReadJSONTestPresets.cxx101
-rw-r--r--Source/cmCPluginAPI.cxx2
-rw-r--r--Source/cmCTest.cxx12
-rw-r--r--Source/cmCommandLineArgument.h50
-rw-r--r--Source/cmCommonTargetGenerator.cxx30
-rw-r--r--Source/cmCommonTargetGenerator.h4
-rw-r--r--Source/cmComputeLinkDepends.cxx643
-rw-r--r--Source/cmComputeLinkDepends.h51
-rw-r--r--Source/cmComputeLinkInformation.cxx711
-rw-r--r--Source/cmComputeLinkInformation.h122
-rw-r--r--Source/cmComputeTargetDepends.cxx4
-rw-r--r--Source/cmComputeTargetDepends.h2
-rw-r--r--Source/cmConstStack.h39
-rw-r--r--Source/cmConstStack.tcc62
-rw-r--r--Source/cmCoreTryCompile.cxx223
-rw-r--r--Source/cmCreateTestSourceList.cxx2
-rw-r--r--Source/cmEnableTestingCommand.h4
-rw-r--r--Source/cmExportBuildAndroidMKGenerator.cxx6
-rw-r--r--Source/cmExportBuildAndroidMKGenerator.h6
-rw-r--r--Source/cmExportBuildFileGenerator.cxx45
-rw-r--r--Source/cmExportBuildFileGenerator.h8
-rw-r--r--Source/cmExportFileGenerator.cxx196
-rw-r--r--Source/cmExportFileGenerator.h49
-rw-r--r--Source/cmExportInstallAndroidMKGenerator.cxx5
-rw-r--r--Source/cmExportInstallAndroidMKGenerator.h7
-rw-r--r--Source/cmExportInstallFileGenerator.cxx59
-rw-r--r--Source/cmExportInstallFileGenerator.h9
-rw-r--r--Source/cmExportTryCompileFileGenerator.cxx2
-rw-r--r--Source/cmExportTryCompileFileGenerator.h6
-rw-r--r--Source/cmFLTKWrapUICommand.cxx2
-rw-r--r--Source/cmFileAPICodemodel.cxx2
-rw-r--r--Source/cmFileCommand.cxx42
-rw-r--r--Source/cmFileSet.cxx9
-rw-r--r--Source/cmFindBase.cxx74
-rw-r--r--Source/cmFindCommon.cxx20
-rw-r--r--Source/cmFindCommon.h3
-rw-r--r--Source/cmFindPackageCommand.cxx185
-rw-r--r--Source/cmFindPackageCommand.h5
-rw-r--r--Source/cmFindProgramCommand.cxx14
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.cxx4
-rw-r--r--Source/cmGeneratorExpressionNode.cxx193
-rw-r--r--Source/cmGeneratorTarget.cxx494
-rw-r--r--Source/cmGeneratorTarget.h41
-rw-r--r--Source/cmGhsMultiTargetGenerator.cxx134
-rw-r--r--Source/cmGhsMultiTargetGenerator.h6
-rw-r--r--Source/cmGlobalGenerator.cxx100
-rw-r--r--Source/cmGlobalGenerator.h20
-rw-r--r--Source/cmGlobalGhsMultiGenerator.cxx351
-rw-r--r--Source/cmGlobalGhsMultiGenerator.h14
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx12
-rw-r--r--Source/cmGlobalVisualStudio10Generator.cxx8
-rw-r--r--Source/cmGlobalVisualStudio10Generator.h2
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx20
-rw-r--r--Source/cmGlobalVisualStudio7Generator.h2
-rw-r--r--Source/cmGlobalVisualStudio8Generator.cxx2
-rw-r--r--Source/cmGlobalVisualStudioGenerator.cxx6
-rw-r--r--Source/cmGlobalVisualStudioGenerator.h3
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx217
-rw-r--r--Source/cmGlobalXCodeGenerator.h11
-rw-r--r--Source/cmIfCommand.cxx12
-rw-r--r--Source/cmInstallCommand.cxx6
-rw-r--r--Source/cmInstallDirectoryGenerator.cxx1
-rw-r--r--Source/cmInstallDirectoryGenerator.h2
-rw-r--r--Source/cmInstallExportGenerator.cxx93
-rw-r--r--Source/cmInstallExportGenerator.h6
-rw-r--r--Source/cmInstallFileSetGenerator.cxx1
-rw-r--r--Source/cmInstallFileSetGenerator.h2
-rw-r--r--Source/cmInstallFilesGenerator.cxx1
-rw-r--r--Source/cmInstallFilesGenerator.h2
-rw-r--r--Source/cmInstallGenerator.cxx54
-rw-r--r--Source/cmInstallGenerator.h3
-rw-r--r--Source/cmInstallGetRuntimeDependenciesGenerator.cxx1
-rw-r--r--Source/cmInstallGetRuntimeDependenciesGenerator.h2
-rw-r--r--Source/cmInstallRuntimeDependencySetGenerator.h2
-rw-r--r--Source/cmInstallSubdirectoryGenerator.cxx1
-rw-r--r--Source/cmInstallSubdirectoryGenerator.h2
-rw-r--r--Source/cmJSONHelpers.h494
-rw-r--r--Source/cmLinkItem.h6
-rw-r--r--Source/cmLinkItemGraphVisitor.cxx4
-rw-r--r--Source/cmLinkLibrariesCommand.cxx2
-rw-r--r--Source/cmLinkLineComputer.cxx10
-rw-r--r--Source/cmLinkLineDeviceComputer.cxx11
-rw-r--r--Source/cmListFileCache.cxx72
-rw-r--r--Source/cmListFileCache.h62
-rw-r--r--Source/cmLocalGenerator.cxx69
-rw-r--r--Source/cmLocalGenerator.h2
-rw-r--r--Source/cmLocalNinjaGenerator.h2
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx21
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx4
-rw-r--r--Source/cmLocalVisualStudioGenerator.cxx2
-rw-r--r--Source/cmLocalXCodeGenerator.cxx20
-rw-r--r--Source/cmLocalXCodeGenerator.h2
-rw-r--r--Source/cmMacroCommand.cxx2
-rw-r--r--Source/cmMakefile.cxx64
-rw-r--r--Source/cmMakefile.h51
-rw-r--r--Source/cmMakefileTargetGenerator.cxx14
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx10
-rw-r--r--Source/cmNinjaTargetGenerator.cxx83
-rw-r--r--Source/cmOutputConverter.cxx57
-rw-r--r--Source/cmOutputConverter.h13
-rw-r--r--Source/cmPlaceholderExpander.cxx54
-rw-r--r--Source/cmPlaceholderExpander.h19
-rw-r--r--Source/cmPolicies.h29
-rw-r--r--Source/cmQtAutoGen.cxx7
-rw-r--r--Source/cmQtAutoGen.h5
-rw-r--r--Source/cmQtAutoGenInitializer.cxx6
-rw-r--r--Source/cmQtAutoMocUic.cxx51
-rw-r--r--Source/cmRulePlaceholderExpander.cxx245
-rw-r--r--Source/cmRulePlaceholderExpander.h14
-rw-r--r--Source/cmScriptGenerator.cxx6
-rw-r--r--Source/cmSearchPath.cxx30
-rw-r--r--Source/cmState.h6
-rw-r--r--Source/cmStateDirectory.cxx1
-rw-r--r--Source/cmStateDirectory.h5
-rw-r--r--Source/cmStringCommand.cxx9
-rw-r--r--Source/cmSystemTools.cxx41
-rw-r--r--Source/cmSystemTools.h13
-rw-r--r--Source/cmTarget.cxx776
-rw-r--r--Source/cmTarget.h5
-rw-r--r--Source/cmTargetLinkLibrariesCommand.cxx3
-rw-r--r--Source/cmTryCompileCommand.cxx2
-rw-r--r--Source/cmTryRunCommand.cxx20
-rw-r--r--Source/cmVSSetupHelper.cxx182
-rw-r--r--Source/cmVSSetupHelper.h3
-rw-r--r--Source/cmVariableWatchCommand.cxx2
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx348
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h10
-rw-r--r--Source/cmVisualStudioGeneratorOptions.cxx3
-rw-r--r--Source/cmVsProjectType.h3
-rw-r--r--Source/cmWhileCommand.cxx33
-rw-r--r--Source/cmWindowsRegistry.cxx770
-rw-r--r--Source/cmWindowsRegistry.h85
-rw-r--r--Source/cmake.cxx45
-rw-r--r--Source/cmake.h1
-rw-r--r--Source/cmakemain.cxx89
-rw-r--r--Source/cmcmd.cxx36
-rw-r--r--Source/ctest.cxx3
-rw-r--r--Source/kwsys/ProcessUNIX.c2
-rw-r--r--Source/kwsys/ProcessWin32.c2
180 files changed, 8114 insertions, 4224 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index ddcdd7e..2deaaaa 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -182,6 +182,8 @@ set(SRCS
cmComputeTargetDepends.cxx
cmConsoleBuf.h
cmConsoleBuf.cxx
+ cmConstStack.h
+ cmConstStack.tcc
cmCPackPropertiesGenerator.h
cmCPackPropertiesGenerator.cxx
cmCryptoHash.cxx
@@ -358,6 +360,8 @@ set(SRCS
cmLocalCommonGenerator.h
cmLocalGenerator.cxx
cmLocalGenerator.h
+ cmPlaceholderExpander.cxx
+ cmPlaceholderExpander.h
cmRulePlaceholderExpander.cxx
cmRulePlaceholderExpander.h
cmLocalUnixMakefileGenerator3.cxx
@@ -456,6 +460,8 @@ set(SRCS
cmVariableWatch.h
cmVersion.cxx
cmVersion.h
+ cmWindowsRegistry.cxx
+ cmWindowsRegistry.h
cmWorkerPool.cxx
cmWorkerPool.h
cmWorkingDirectory.cxx
@@ -728,7 +734,7 @@ set(SRCS
bindexplib.cxx
)
-SET_PROPERTY(SOURCE cmProcessOutput.cxx APPEND PROPERTY COMPILE_DEFINITIONS
+SET_PROPERTY(SOURCE cmProcessOutput.cxx cmWindowsRegistry.cxx APPEND PROPERTY COMPILE_DEFINITIONS
KWSYS_ENCODING_DEFAULT_CODEPAGE=${KWSYS_ENCODING_DEFAULT_CODEPAGE})
# Xcode only works on Apple
@@ -1115,7 +1121,6 @@ if(APPLE)
CPack/cmCPackBundleGenerator.cxx
CPack/cmCPackDragNDropGenerator.cxx
CPack/cmCPackPKGGenerator.cxx
- CPack/cmCPackPackageMakerGenerator.cxx
CPack/cmCPackProductBuildGenerator.cxx
)
endif()
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 19359d8..e650f7f 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 23)
-set(CMake_VERSION_PATCH 1)
+set(CMake_VERSION_PATCH 20220518)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
index 6a0095b..594f408 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
@@ -89,10 +89,21 @@ bool cmCPackWIXGenerator::RunCandleCommand(std::string const& sourceFile,
return false;
}
+ std::string arch;
+ if (cmValue archOpt = GetOption("CPACK_WIX_ARCHITECTURE")) {
+ arch = *archOpt;
+ } else {
+ arch = GetArchitecture();
+ cmCPackLogger(
+ cmCPackLog::LOG_VERBOSE,
+ "CPACK_WIX_ARCHITECTURE was not set. Invoking WiX with architecture "
+ << arch << " . " << std::endl);
+ }
+
std::ostringstream command;
command << QuotePath(executable);
command << " -nologo";
- command << " -arch " << GetArchitecture();
+ command << " -arch " << arch;
command << " -out " << QuotePath(objectFile);
for (std::string const& ext : CandleExtensions) {
diff --git a/Source/CPack/cmCPackGeneratorFactory.cxx b/Source/CPack/cmCPackGeneratorFactory.cxx
index 0b2acca..725ea8a 100644
--- a/Source/CPack/cmCPackGeneratorFactory.cxx
+++ b/Source/CPack/cmCPackGeneratorFactory.cxx
@@ -21,7 +21,6 @@
#ifdef __APPLE__
# include "cmCPackBundleGenerator.h"
# include "cmCPackDragNDropGenerator.h"
-# include "cmCPackPackageMakerGenerator.h"
# include "cmCPackProductBuildGenerator.h"
#endif
@@ -108,10 +107,6 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory()
this->RegisterGenerator("Bundle", "Mac OSX bundle",
cmCPackBundleGenerator::CreateGenerator);
}
- if (cmCPackPackageMakerGenerator::CanGenerate()) {
- this->RegisterGenerator("PackageMaker", "Mac OSX Package Maker installer",
- cmCPackPackageMakerGenerator::CreateGenerator);
- }
if (cmCPackProductBuildGenerator::CanGenerate()) {
this->RegisterGenerator("productbuild", "Mac OSX pkg",
cmCPackProductBuildGenerator::CreateGenerator);
diff --git a/Source/CPack/cmCPackPackageMakerGenerator.cxx b/Source/CPack/cmCPackPackageMakerGenerator.cxx
deleted file mode 100644
index a8cf1fa..0000000
--- a/Source/CPack/cmCPackPackageMakerGenerator.cxx
+++ /dev/null
@@ -1,577 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmCPackPackageMakerGenerator.h"
-
-#include <cassert>
-#include <cstdio>
-#include <cstdlib>
-#include <map>
-#include <sstream>
-#include <string>
-
-#include "cmsys/FStream.hxx"
-#include "cmsys/RegularExpression.hxx"
-
-#include "cmCPackComponentGroup.h"
-#include "cmCPackLog.h"
-#include "cmDuration.h"
-#include "cmGeneratedFileStream.h"
-#include "cmStringAlgorithms.h"
-#include "cmSystemTools.h"
-#include "cmValue.h"
-#include "cmXMLWriter.h"
-
-static inline unsigned int getVersion(unsigned int major, unsigned int minor)
-{
- assert(major < 256 && minor < 256);
- return ((major & 0xFF) << 16 | minor);
-}
-
-cmCPackPackageMakerGenerator::cmCPackPackageMakerGenerator()
-{
- this->PackageMakerVersion = 0.0;
- this->PackageCompatibilityVersion = getVersion(10, 4);
-}
-
-cmCPackPackageMakerGenerator::~cmCPackPackageMakerGenerator() = default;
-
-bool cmCPackPackageMakerGenerator::SupportsComponentInstallation() const
-{
- return this->PackageCompatibilityVersion >= getVersion(10, 4);
-}
-
-int cmCPackPackageMakerGenerator::PackageFiles()
-{
- // TODO: Use toplevel
- // It is used! Is this an obsolete comment?
-
- std::string resDir; // Where this package's resources will go.
- std::string packageDirFileName =
- this->GetOption("CPACK_TEMPORARY_DIRECTORY");
- if (this->Components.empty()) {
- packageDirFileName += ".pkg";
- resDir =
- cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/Resources");
- } else {
- packageDirFileName += ".mpkg";
- if (!cmsys::SystemTools::MakeDirectory(packageDirFileName.c_str())) {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "unable to create package directory " << packageDirFileName
- << std::endl);
- return 0;
- }
-
- resDir = cmStrCat(packageDirFileName, "/Contents");
- if (!cmsys::SystemTools::MakeDirectory(resDir.c_str())) {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "unable to create package subdirectory " << resDir
- << std::endl);
- return 0;
- }
-
- resDir += "/Resources";
- if (!cmsys::SystemTools::MakeDirectory(resDir.c_str())) {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "unable to create package subdirectory " << resDir
- << std::endl);
- return 0;
- }
-
- resDir += "/en.lproj";
- }
-
- cmValue preflight = this->GetOption("CPACK_PREFLIGHT_SCRIPT");
- cmValue postflight = this->GetOption("CPACK_POSTFLIGHT_SCRIPT");
- cmValue postupgrade = this->GetOption("CPACK_POSTUPGRADE_SCRIPT");
-
- if (this->Components.empty()) {
- // Create directory structure
- std::string preflightDirName = resDir + "/PreFlight";
- std::string postflightDirName = resDir + "/PostFlight";
- // if preflight or postflight scripts not there create directories
- // of the same name, I think this makes it work
- if (!preflight) {
- if (!cmsys::SystemTools::MakeDirectory(preflightDirName.c_str())) {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Problem creating installer directory: "
- << preflightDirName << std::endl);
- return 0;
- }
- }
- if (!postflight) {
- if (!cmsys::SystemTools::MakeDirectory(postflightDirName.c_str())) {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Problem creating installer directory: "
- << postflightDirName << std::endl);
- return 0;
- }
- }
- // if preflight, postflight, or postupgrade are set
- // then copy them into the resource directory and make
- // them executable
- if (preflight) {
- this->CopyInstallScript(resDir, preflight, "preflight");
- }
- if (postflight) {
- this->CopyInstallScript(resDir, postflight, "postflight");
- }
- if (postupgrade) {
- this->CopyInstallScript(resDir, postupgrade, "postupgrade");
- }
- } else if (postflight) {
- // create a postflight component to house the script
- this->PostFlightComponent.Name = "PostFlight";
- this->PostFlightComponent.DisplayName = "PostFlight";
- this->PostFlightComponent.Description = "PostFlight";
- this->PostFlightComponent.IsHidden = true;
-
- // empty directory for pkg contents
- std::string packageDir = toplevel + "/" + PostFlightComponent.Name;
- if (!cmsys::SystemTools::MakeDirectory(packageDir.c_str())) {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Problem creating component packages directory: "
- << packageDir << std::endl);
- return 0;
- }
-
- // create package
- std::string packageFileDir = packageDirFileName + "/Contents/Packages/";
- if (!cmsys::SystemTools::MakeDirectory(packageFileDir.c_str())) {
- cmCPackLogger(
- cmCPackLog::LOG_ERROR,
- "Problem creating component PostFlight Packages directory: "
- << packageFileDir << std::endl);
- return 0;
- }
- std::string packageFile =
- packageFileDir + this->GetPackageName(PostFlightComponent);
- if (!this->GenerateComponentPackage(
- packageFile.c_str(), packageDir.c_str(), PostFlightComponent)) {
- return 0;
- }
-
- // copy postflight script into resource directory of .pkg
- std::string resourceDir = packageFile + "/Contents/Resources";
- this->CopyInstallScript(resourceDir, postflight, "postflight");
- }
-
- if (!this->Components.empty()) {
- // Create the directory where component packages will be built.
- std::string basePackageDir =
- cmStrCat(packageDirFileName, "/Contents/Packages");
- if (!cmsys::SystemTools::MakeDirectory(basePackageDir.c_str())) {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Problem creating component packages directory: "
- << basePackageDir << std::endl);
- return 0;
- }
-
- // Create the directory where downloaded component packages will
- // be placed.
- cmValue userUploadDirectory = this->GetOption("CPACK_UPLOAD_DIRECTORY");
- std::string uploadDirectory;
- if (userUploadDirectory && !userUploadDirectory->empty()) {
- uploadDirectory = userUploadDirectory;
- } else {
- uploadDirectory =
- cmStrCat(this->GetOption("CPACK_PACKAGE_DIRECTORY"), "/CPackUploads");
- }
-
- // Create packages for each component
- bool warnedAboutDownloadCompatibility = false;
-
- std::map<std::string, cmCPackComponent>::iterator compIt;
- for (compIt = this->Components.begin(); compIt != this->Components.end();
- ++compIt) {
- std::string packageFile;
- if (compIt->second.IsDownloaded) {
- if (this->PackageCompatibilityVersion >= getVersion(10, 5) &&
- this->PackageMakerVersion >= 3.0) {
- // Build this package within the upload directory.
- packageFile = uploadDirectory;
-
- if (!cmSystemTools::FileExists(uploadDirectory.c_str())) {
- if (!cmSystemTools::MakeDirectory(uploadDirectory.c_str())) {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Unable to create package upload directory "
- << uploadDirectory << std::endl);
- return 0;
- }
- }
- } else if (!warnedAboutDownloadCompatibility) {
- if (this->PackageCompatibilityVersion < getVersion(10, 5)) {
- cmCPackLogger(
- cmCPackLog::LOG_WARNING,
- "CPack warning: please set CPACK_OSX_PACKAGE_VERSION to 10.5 "
- "or greater enable downloaded packages. CPack will build a "
- "non-downloaded package."
- << std::endl);
- }
-
- if (this->PackageMakerVersion < 3) {
- cmCPackLogger(cmCPackLog::LOG_WARNING,
- "CPack warning: unable to build downloaded "
- "packages with PackageMaker versions prior "
- "to 3.0. CPack will build a non-downloaded package."
- << std::endl);
- }
-
- warnedAboutDownloadCompatibility = true;
- }
- }
-
- if (packageFile.empty()) {
- // Build this package within the overall distribution
- // metapackage.
- packageFile = basePackageDir;
-
- // We're not downloading this component, even if the user
- // requested it.
- compIt->second.IsDownloaded = false;
- }
-
- packageFile += '/';
- packageFile += GetPackageName(compIt->second);
-
- std::string packageDir = cmStrCat(toplevel, '/', compIt->first);
- if (!this->GenerateComponentPackage(
- packageFile.c_str(), packageDir.c_str(), compIt->second)) {
- return 0;
- }
- }
- }
- this->SetOption("CPACK_MODULE_VERSION_SUFFIX", "");
-
- // Copy or create all of the resource files we need.
- if (!this->CopyCreateResourceFile("License", resDir) ||
- !this->CopyCreateResourceFile("ReadMe", resDir) ||
- !this->CopyCreateResourceFile("Welcome", resDir) ||
- !this->CopyResourcePlistFile("Info.plist") ||
- !this->CopyResourcePlistFile("Description.plist")) {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Problem copying the resource files" << std::endl);
- return 0;
- }
-
- if (this->Components.empty()) {
- // Use PackageMaker to build the package.
- std::ostringstream pkgCmd;
- pkgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM")
- << "\" -build -p \"" << packageDirFileName << "\"";
- if (this->Components.empty()) {
- pkgCmd << " -f \"" << this->GetOption("CPACK_TEMPORARY_DIRECTORY");
- } else {
- pkgCmd << " -mi \"" << this->GetOption("CPACK_TEMPORARY_DIRECTORY")
- << "/packages/";
- }
- pkgCmd << "\" -r \"" << this->GetOption("CPACK_TOPLEVEL_DIRECTORY")
- << "/Resources\" -i \""
- << this->GetOption("CPACK_TOPLEVEL_DIRECTORY")
- << "/Info.plist\" -d \""
- << this->GetOption("CPACK_TOPLEVEL_DIRECTORY")
- << "/Description.plist\"";
- if (this->PackageMakerVersion > 2.0) {
- pkgCmd << " -v";
- }
- if (!RunPackageMaker(pkgCmd.str().c_str(), packageDirFileName.c_str())) {
- return 0;
- }
- } else {
- // We have built the package in place. Generate the
- // distribution.dist file to describe it for the installer.
- WriteDistributionFile(packageDirFileName.c_str(), "PACKAGEMAKER");
- }
-
- std::string tmpFile = cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"),
- "/hdiutilOutput.log");
- std::ostringstream dmgCmd;
- dmgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM_DISK_IMAGE")
- << "\" create -ov -fs HFS+ -format UDZO -srcfolder \""
- << packageDirFileName << "\" \"" << packageFileNames[0] << "\"";
- std::string output;
- int retVal = 1;
- int numTries = 10;
- bool res = false;
- while (numTries > 0) {
- res = cmSystemTools::RunSingleCommand(
- dmgCmd.str(), &output, &output, &retVal, nullptr, this->GeneratorVerbose,
- cmDuration::zero());
- if (res && !retVal) {
- numTries = -1;
- break;
- }
- cmSystemTools::Delay(500);
- numTries--;
- }
- if (!res || retVal) {
- cmGeneratedFileStream ofs(tmpFile);
- ofs << "# Run command: " << dmgCmd.str() << std::endl
- << "# Output:" << std::endl
- << output << std::endl;
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Problem running hdiutil command: "
- << dmgCmd.str() << std::endl
- << "Please check " << tmpFile << " for errors"
- << std::endl);
- return 0;
- }
-
- return 1;
-}
-
-int cmCPackPackageMakerGenerator::InitializeInternal()
-{
- cmCPackLogger(cmCPackLog::LOG_WARNING,
- "The PackageMaker generator is deprecated "
- "and will be removed in a future version.\n");
- this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/usr");
-
- // Starting with Xcode 4.3, PackageMaker is a separate app, and you
- // can put it anywhere you want. So... use a variable for its location.
- // People who put it in unexpected places can use the variable to tell
- // us where it is.
- //
- // Use the following locations, in "most recent installation" order,
- // to search for the PackageMaker app. Assume people who copy it into
- // the new Xcode 4.3 app in "/Applications" will copy it into the nested
- // Applications folder inside the Xcode bundle itself. Or directly in
- // the "/Applications" directory.
- //
- // If found, save result in the CPACK_INSTALLER_PROGRAM variable.
-
- std::vector<std::string> paths;
- paths.emplace_back("/Applications/Xcode.app/Contents/Applications"
- "/PackageMaker.app/Contents/MacOS");
- paths.emplace_back("/Applications/Utilities"
- "/PackageMaker.app/Contents/MacOS");
- paths.emplace_back("/Applications"
- "/PackageMaker.app/Contents/MacOS");
- paths.emplace_back("/Developer/Applications/Utilities"
- "/PackageMaker.app/Contents/MacOS");
- paths.emplace_back("/Developer/Applications"
- "/PackageMaker.app/Contents/MacOS");
-
- std::string pkgPath;
- cmValue inst_program = this->GetOption("CPACK_INSTALLER_PROGRAM");
- if (inst_program && !inst_program->empty()) {
- pkgPath = inst_program;
- } else {
- pkgPath = cmSystemTools::FindProgram("PackageMaker", paths, false);
- if (pkgPath.empty()) {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Cannot find PackageMaker compiler" << std::endl);
- return 0;
- }
- this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM", pkgPath);
- }
-
- // Get path to the real PackageMaker, not a symlink:
- pkgPath = cmSystemTools::GetRealPath(pkgPath);
- // Up from there to find the version.plist file in the "Contents" dir:
- std::string contents_dir;
- contents_dir = cmSystemTools::GetFilenamePath(pkgPath);
- contents_dir = cmSystemTools::GetFilenamePath(contents_dir);
-
- std::string versionFile = contents_dir + "/version.plist";
-
- if (!cmSystemTools::FileExists(versionFile.c_str())) {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Cannot find PackageMaker compiler version file: "
- << versionFile << std::endl);
- return 0;
- }
-
- cmsys::ifstream ifs(versionFile.c_str());
- if (!ifs) {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Cannot open PackageMaker compiler version file"
- << std::endl);
- return 0;
- }
-
- // Check the PackageMaker version
- cmsys::RegularExpression rexKey("<key>CFBundleShortVersionString</key>");
- cmsys::RegularExpression rexVersion("<string>([0-9]+.[0-9.]+)</string>");
- std::string line;
- bool foundKey = false;
- while (cmSystemTools::GetLineFromStream(ifs, line)) {
- if (rexKey.find(line)) {
- foundKey = true;
- break;
- }
- }
- if (!foundKey) {
- cmCPackLogger(
- cmCPackLog::LOG_ERROR,
- "Cannot find CFBundleShortVersionString in the PackageMaker compiler "
- "version file"
- << std::endl);
- return 0;
- }
- if (!cmSystemTools::GetLineFromStream(ifs, line) || !rexVersion.find(line)) {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Problem reading the PackageMaker compiler version file: "
- << versionFile << std::endl);
- return 0;
- }
- this->PackageMakerVersion = atof(rexVersion.match(1).c_str());
- if (this->PackageMakerVersion < 1.0) {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Require PackageMaker 1.0 or higher" << std::endl);
- return 0;
- }
- cmCPackLogger(cmCPackLog::LOG_DEBUG,
- "PackageMaker version is: " << this->PackageMakerVersion
- << std::endl);
-
- // Determine the package compatibility version. If it wasn't
- // specified by the user, we define it based on which features the
- // user requested.
- cmValue packageCompat = this->GetOption("CPACK_OSX_PACKAGE_VERSION");
- if (packageCompat && !packageCompat->empty()) {
- unsigned int majorVersion = 10;
- unsigned int minorVersion = 5;
- int res =
- sscanf(packageCompat->c_str(), "%u.%u", &majorVersion, &minorVersion);
- if (res == 2) {
- this->PackageCompatibilityVersion =
- getVersion(majorVersion, minorVersion);
- }
- } else if (this->GetOption("CPACK_DOWNLOAD_SITE")) {
- this->SetOption("CPACK_OSX_PACKAGE_VERSION", "10.5");
- this->PackageCompatibilityVersion = getVersion(10, 5);
- } else if (this->GetOption("CPACK_COMPONENTS_ALL")) {
- this->SetOption("CPACK_OSX_PACKAGE_VERSION", "10.4");
- this->PackageCompatibilityVersion = getVersion(10, 4);
- } else {
- this->SetOption("CPACK_OSX_PACKAGE_VERSION", "10.3");
- this->PackageCompatibilityVersion = getVersion(10, 3);
- }
-
- std::vector<std::string> no_paths;
- pkgPath = cmSystemTools::FindProgram("hdiutil", no_paths, false);
- if (pkgPath.empty()) {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Cannot find hdiutil compiler" << std::endl);
- return 0;
- }
- this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM_DISK_IMAGE", pkgPath);
-
- return this->Superclass::InitializeInternal();
-}
-
-bool cmCPackPackageMakerGenerator::RunPackageMaker(const char* command,
- const char* packageFile)
-{
- std::string tmpFile = cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"),
- "/PackageMakerOutput.log");
-
- cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << command << std::endl);
- std::string output;
- int retVal = 1;
- bool res = cmSystemTools::RunSingleCommand(
- command, &output, &output, &retVal, nullptr, this->GeneratorVerbose,
- cmDuration::zero());
- cmCPackLogger(cmCPackLog::LOG_VERBOSE,
- "Done running package maker" << std::endl);
- if (!res || retVal) {
- cmGeneratedFileStream ofs(tmpFile);
- ofs << "# Run command: " << command << std::endl
- << "# Output:" << std::endl
- << output << std::endl;
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Problem running PackageMaker command: "
- << command << std::endl
- << "Please check " << tmpFile << " for errors"
- << std::endl);
- return false;
- }
- // sometimes the command finishes but the directory is not yet
- // created, so try 10 times to see if it shows up
- int tries = 10;
- while (tries > 0 && !cmSystemTools::FileExists(packageFile)) {
- cmSystemTools::Delay(500);
- tries--;
- }
- if (!cmSystemTools::FileExists(packageFile)) {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Problem running PackageMaker command: "
- << command << std::endl
- << "Package not created: " << packageFile << std::endl);
- return false;
- }
-
- return true;
-}
-
-bool cmCPackPackageMakerGenerator::GenerateComponentPackage(
- const char* packageFile, const char* packageDir,
- const cmCPackComponent& component)
-{
- cmCPackLogger(cmCPackLog::LOG_OUTPUT,
- "- Building component package: " << packageFile
- << std::endl);
-
- // The command that will be used to run PackageMaker
- std::ostringstream pkgCmd;
-
- if (this->PackageCompatibilityVersion < getVersion(10, 5) ||
- this->PackageMakerVersion < 3.0) {
- // Create Description.plist and Info.plist files for normal Mac OS
- // X packages, which work on Mac OS X 10.3 and newer.
- std::string descriptionFile =
- cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), '/',
- component.Name, "-Description.plist");
- cmsys::ofstream out(descriptionFile.c_str());
- cmXMLWriter xout(out);
- xout.StartDocument();
- xout.Doctype("plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\""
- "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"");
- xout.StartElement("plist");
- xout.Attribute("version", "1.4");
- xout.StartElement("dict");
- xout.Element("key", "IFPkgDescriptionTitle");
- xout.Element("string", component.DisplayName);
- xout.Element("key", "IFPkgDescriptionVersion");
- xout.Element("string", this->GetOption("CPACK_PACKAGE_VERSION"));
- xout.Element("key", "IFPkgDescriptionDescription");
- xout.Element("string", component.Description);
- xout.EndElement(); // dict
- xout.EndElement(); // plist
- xout.EndDocument();
- out.close();
-
- // Create the Info.plist file for this component
- std::string moduleVersionSuffix = cmStrCat('.', component.Name);
- this->SetOption("CPACK_MODULE_VERSION_SUFFIX", moduleVersionSuffix);
- std::string infoFileName = cmStrCat(component.Name, "-Info.plist");
- if (!this->CopyResourcePlistFile("Info.plist", infoFileName.c_str())) {
- return false;
- }
-
- pkgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM")
- << "\" -build -p \"" << packageFile << "\""
- << " -f \"" << packageDir << "\""
- << " -i \"" << this->GetOption("CPACK_TOPLEVEL_DIRECTORY") << "/"
- << infoFileName << "\""
- << " -d \"" << descriptionFile << "\"";
- } else {
- // Create a "flat" package on Mac OS X 10.5 and newer. Flat
- // packages are stored in a single file, rather than a directory
- // like normal packages, and can be downloaded by the installer
- // on-the-fly in Mac OS X 10.5 or newer. Thus, we need to create
- // flat packages when the packages will be downloaded on the fly.
- std::string pkgId =
- cmStrCat("com.", this->GetOption("CPACK_PACKAGE_VENDOR"), '.',
- this->GetOption("CPACK_PACKAGE_NAME"), '.', component.Name);
-
- pkgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM")
- << "\" --root \"" << packageDir << "\""
- << " --id " << pkgId << " --target "
- << this->GetOption("CPACK_OSX_PACKAGE_VERSION") << " --out \""
- << packageFile << "\"";
- }
-
- // Run PackageMaker
- return RunPackageMaker(pkgCmd.str().c_str(), packageFile);
-}
diff --git a/Source/CPack/cmCPackPackageMakerGenerator.h b/Source/CPack/cmCPackPackageMakerGenerator.h
deleted file mode 100644
index cda9277..0000000
--- a/Source/CPack/cmCPackPackageMakerGenerator.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#pragma once
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include "cmCPackGenerator.h"
-#include "cmCPackPKGGenerator.h"
-
-class cmCPackComponent;
-
-/** \class cmCPackPackageMakerGenerator
- * \brief A generator for PackageMaker files
- *
- * http://developer.apple.com/documentation/Darwin
- * /Reference/ManPages/man1/packagemaker.1.html
- */
-class cmCPackPackageMakerGenerator : public cmCPackPKGGenerator
-{
-public:
- cmCPackTypeMacro(cmCPackPackageMakerGenerator, cmCPackPKGGenerator);
-
- /**
- * Construct generator
- */
- cmCPackPackageMakerGenerator();
- ~cmCPackPackageMakerGenerator() override;
- bool SupportsComponentInstallation() const override;
-
-protected:
- int InitializeInternal() override;
- int PackageFiles() override;
- const char* GetOutputExtension() override { return ".dmg"; }
-
- // Run PackageMaker with the given command line, which will (if
- // successful) produce the given package file. Returns true if
- // PackageMaker succeeds, false otherwise.
- bool RunPackageMaker(const char* command, const char* packageFile);
-
- // Generate a package in the file packageFile for the given
- // component. All of the files within this component are stored in
- // the directory packageDir. Returns true if successful, false
- // otherwise.
- bool GenerateComponentPackage(const char* packageFile,
- const char* packageDir,
- const cmCPackComponent& component);
-
- double PackageMakerVersion;
- unsigned int PackageCompatibilityVersion;
-};
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index f43642f..6c6d0ca 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include <cstddef>
+#include <functional>
#include <iostream>
#include <map>
#include <memory>
@@ -10,12 +11,14 @@
#include <utility>
#include <vector>
-#include "cmsys/CommandLineArguments.hxx"
+#include <cmext/algorithm>
+
#include "cmsys/Encoding.hxx"
#include "cmCPackGenerator.h"
#include "cmCPackGeneratorFactory.h"
#include "cmCPackLog.h"
+#include "cmCommandLineArgument.h"
#include "cmConsoleBuf.h"
#include "cmDocumentation.h"
#include "cmDocumentationEntry.h"
@@ -58,39 +61,6 @@ const char* cmDocumentationOptions[][2] = {
{ nullptr, nullptr }
};
-int cpackUnknownArgument(const char* /*unused*/, void* /*unused*/)
-{
- return 1;
-}
-
-struct cpackDefinitions
-{
- using MapType = std::map<std::string, std::string>;
- MapType Map;
- cmCPackLog* Log{};
-};
-
-int cpackDefinitionArgument(const char* argument, const char* cValue,
- void* call_data)
-{
- (void)argument;
- cpackDefinitions* def = static_cast<cpackDefinitions*>(call_data);
- std::string value = cValue;
- size_t pos = value.find_first_of('=');
- if (pos == std::string::npos) {
- cmCPack_Log(def->Log, cmCPackLog::LOG_ERROR,
- "Please specify CPack definitions as: KEY=VALUE" << std::endl);
- return 0;
- }
- std::string key = value.substr(0, pos);
- value.erase(0, pos + 1);
- def->Map[key] = value;
- cmCPack_Log(def->Log, cmCPackLog::LOG_DEBUG,
- "Set CPack variable: " << key << " to \"" << value << "\""
- << std::endl);
- return 1;
-}
-
void cpackProgressCallback(const std::string& message, float /*unused*/)
{
std::cout << "-- " << message << std::endl;
@@ -111,6 +81,10 @@ int main(int argc, char const* const* argv)
argc = args.argc();
argv = args.argv();
+ std::vector<std::string> inputArgs;
+ inputArgs.reserve(argc - 1);
+ cm::append(inputArgs, argv + 1, argv + argc);
+
cmSystemTools::InitializeLibUV();
cmSystemTools::FindCMakeResources(argv[0]);
cmCPackLog log;
@@ -130,10 +104,6 @@ int main(int argc, char const* const* argv)
std::string generator;
bool help = false;
bool helpVersion = false;
- bool verbose = false;
- bool trace = false;
- bool traceExpand = false;
- bool debug = false;
std::string helpFull;
std::string helpMAN;
std::string helpHTML;
@@ -146,64 +116,93 @@ int main(int argc, char const* const* argv)
std::string cpackProjectVendor;
std::string cpackConfigFile;
- cpackDefinitions definitions;
- definitions.Log = &log;
-
- cpackConfigFile.clear();
-
- cmsys::CommandLineArguments arg;
- arg.Initialize(argc, argv);
- using argT = cmsys::CommandLineArguments;
- // Help arguments
- arg.AddArgument("--help", argT::NO_ARGUMENT, &help, "CPack help");
- arg.AddArgument("--help-full", argT::SPACE_ARGUMENT, &helpFull,
- "CPack help");
- arg.AddArgument("--help-html", argT::SPACE_ARGUMENT, &helpHTML,
- "CPack help");
- arg.AddArgument("--help-man", argT::SPACE_ARGUMENT, &helpMAN, "CPack help");
- arg.AddArgument("--version", argT::NO_ARGUMENT, &helpVersion, "CPack help");
-
- arg.AddArgument("-V", argT::NO_ARGUMENT, &verbose, "CPack verbose");
- arg.AddArgument("--verbose", argT::NO_ARGUMENT, &verbose, "-V");
- arg.AddArgument("--debug", argT::NO_ARGUMENT, &debug, "-V");
- arg.AddArgument("--config", argT::SPACE_ARGUMENT, &cpackConfigFile,
- "CPack configuration file");
- arg.AddArgument("--trace", argT::NO_ARGUMENT, &trace,
- "Put underlying cmake scripts in trace mode.");
- arg.AddArgument("--trace-expand", argT::NO_ARGUMENT, &traceExpand,
- "Put underlying cmake scripts in expanded trace mode.");
- arg.AddArgument("-C", argT::SPACE_ARGUMENT, &cpackBuildConfig,
- "CPack build configuration");
- arg.AddArgument("-G", argT::SPACE_ARGUMENT, &generator, "CPack generator");
- arg.AddArgument("-P", argT::SPACE_ARGUMENT, &cpackProjectName,
- "CPack project name");
- arg.AddArgument("-R", argT::SPACE_ARGUMENT, &cpackProjectVersion,
- "CPack project version");
- arg.AddArgument("-B", argT::SPACE_ARGUMENT, &cpackProjectDirectory,
- "CPack project directory");
- arg.AddArgument("--patch", argT::SPACE_ARGUMENT, &cpackProjectPatch,
- "CPack project patch");
- arg.AddArgument("--vendor", argT::SPACE_ARGUMENT, &cpackProjectVendor,
- "CPack project vendor");
- arg.AddCallback("-D", argT::SPACE_ARGUMENT, cpackDefinitionArgument,
- &definitions, "CPack Definitions");
- arg.SetUnknownArgumentCallback(cpackUnknownArgument);
-
- // Parse command line
- int parsed = arg.Parse();
-
- // Setup logging
- if (verbose) {
- log.SetVerbose(verbose);
+ std::map<std::string, std::string> definitions;
+
+ auto const verboseLambda = [&log](const std::string&, cmake*,
+ cmMakefile*) -> bool {
+ log.SetVerbose(true);
cmCPack_Log(&log, cmCPackLog::LOG_OUTPUT, "Enable Verbose" << std::endl);
- }
- if (debug) {
- log.SetDebug(debug);
- cmCPack_Log(&log, cmCPackLog::LOG_OUTPUT, "Enable Debug" << std::endl);
- }
+ return true;
+ };
- cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE,
- "Read CPack config file: " << cpackConfigFile << std::endl);
+ auto const debugLambda = [&log](const std::string&, cmake*,
+ cmMakefile*) -> bool {
+ log.SetDebug(true);
+ cmCPack_Log(&log, cmCPackLog::LOG_OUTPUT, "Enable Debug" << std::endl);
+ return true;
+ };
+
+ auto const traceLambda = [](const std::string&, cmake* state,
+ cmMakefile*) -> bool {
+ state->SetTrace(true);
+ return true;
+ };
+
+ auto const traceExpandLambda = [](const std::string&, cmake* state,
+ cmMakefile*) -> bool {
+ state->SetTrace(true);
+ state->SetTraceExpand(true);
+ return true;
+ };
+
+ using CommandArgument =
+ cmCommandLineArgument<bool(std::string const&, cmake*, cmMakefile*)>;
+
+ std::vector<CommandArgument> arguments = {
+ CommandArgument{ "--help", CommandArgument::Values::Zero,
+ CommandArgument::setToTrue(help) },
+ CommandArgument{ "--help-full", CommandArgument::Values::Zero,
+ CommandArgument::setToValue(helpFull) },
+ CommandArgument{ "--help-html", CommandArgument::Values::Zero,
+ CommandArgument::setToValue(helpHTML) },
+ CommandArgument{ "--help-man", CommandArgument::Values::Zero,
+ CommandArgument::setToValue(helpMAN) },
+ CommandArgument{ "--version", CommandArgument::Values::Zero,
+ CommandArgument::setToTrue(helpVersion) },
+ CommandArgument{ "-V", CommandArgument::Values::Zero, verboseLambda },
+ CommandArgument{ "--verbose", CommandArgument::Values::Zero,
+ verboseLambda },
+ CommandArgument{ "--debug", CommandArgument::Values::Zero, debugLambda },
+ CommandArgument{ "--config", CommandArgument::Values::One,
+ CommandArgument::setToValue(cpackConfigFile) },
+ CommandArgument{ "--trace", CommandArgument::Values::One, traceLambda },
+ CommandArgument{ "--trace-expand", CommandArgument::Values::One,
+ traceExpandLambda },
+ CommandArgument{ "-C", CommandArgument::Values::One,
+ CommandArgument::setToValue(cpackBuildConfig) },
+ CommandArgument{ "-G", CommandArgument::Values::One,
+ CommandArgument::setToValue(generator) },
+ CommandArgument{ "-P", CommandArgument::Values::One,
+ CommandArgument::setToValue(cpackProjectName) },
+ CommandArgument{ "-R", CommandArgument::Values::One,
+ CommandArgument::setToValue(cpackProjectVersion) },
+ CommandArgument{ "-B", CommandArgument::Values::One,
+ CommandArgument::setToValue(cpackProjectDirectory) },
+ CommandArgument{ "--patch", CommandArgument::Values::One,
+ CommandArgument::setToValue(cpackProjectPatch) },
+ CommandArgument{ "--vendor", CommandArgument::Values::One,
+ CommandArgument::setToValue(cpackProjectVendor) },
+ CommandArgument{
+ "-D", CommandArgument::Values::One,
+ [&log, &definitions](const std::string& arg, cmake*,
+ cmMakefile*) -> bool {
+ std::string value = arg;
+ size_t pos = value.find_first_of('=');
+ if (pos == std::string::npos) {
+ cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
+ "Please specify CPack definitions as: KEY=VALUE"
+ << std::endl);
+ return false;
+ }
+ std::string key = value.substr(0, pos);
+ value.erase(0, pos + 1);
+ definitions[key] = value;
+ cmCPack_Log(&log, cmCPackLog::LOG_DEBUG,
+ "Set CPack variable: " << key << " to \"" << value << "\""
+ << std::endl);
+ return true;
+ } },
+ };
cmake cminst(cmake::RoleScript, cmState::CPack);
cminst.SetHomeDirectory("");
@@ -216,14 +215,22 @@ int main(int argc, char const* const* argv)
globalMF.AddDefinition("CMAKE_LEGACY_CYGWIN_WIN32", "0");
#endif
- if (trace) {
- cminst.SetTrace(true);
- }
- if (traceExpand) {
- cminst.SetTrace(true);
- cminst.SetTraceExpand(true);
+ bool parsed = true;
+ for (std::size_t i = 0; i < inputArgs.size(); i++) {
+ auto const& arg = inputArgs[i];
+ for (auto const& m : arguments) {
+ if (m.matches(arg)) {
+ if (!m.parse(arg, i, inputArgs, &cminst, &globalMF)) {
+ parsed = false;
+ }
+ break;
+ }
+ }
}
+ cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE,
+ "Read CPack config file: " << cpackConfigFile << std::endl);
+
bool cpackConfigFileSpecified = true;
if (cpackConfigFile.empty()) {
cpackConfigFile = cmStrCat(cmSystemTools::GetCurrentWorkingDirectory(),
@@ -315,7 +322,7 @@ int main(int argc, char const* const* argv)
cpackProjectDirectory);
}
}
- for (auto const& cd : definitions.Map) {
+ for (auto const& cd : definitions) {
globalMF.AddDefinition(cd.first, cd.second);
}
@@ -344,7 +351,7 @@ int main(int argc, char const* const* argv)
if (!mf->GetDefinition("CPACK_PACKAGE_NAME")) {
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
"CPack project name not specified" << std::endl);
- parsed = 0;
+ parsed = false;
}
if (parsed &&
!(mf->GetDefinition("CPACK_PACKAGE_VERSION") ||
@@ -359,14 +366,14 @@ int main(int argc, char const* const* argv)
"CPACK_PACKAGE_VERSION_MINOR, and "
"CPACK_PACKAGE_VERSION_PATCH."
<< std::endl);
- parsed = 0;
+ parsed = false;
}
if (parsed) {
std::unique_ptr<cmCPackGenerator> cpackGenerator =
generators.NewGenerator(gen);
if (cpackGenerator) {
- cpackGenerator->SetTrace(trace);
- cpackGenerator->SetTraceExpand(traceExpand);
+ cpackGenerator->SetTrace(cminst.GetTrace());
+ cpackGenerator->SetTraceExpand(cminst.GetTraceExpand());
} else {
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
"Could not create CPack generator: " << gen
@@ -384,14 +391,14 @@ int main(int argc, char const* const* argv)
std::cerr << "\n";
generatorDocs.PrintDocumentation(cmDocumentation::ListGenerators,
std::cerr);
- parsed = 0;
+ parsed = false;
}
if (parsed && !cpackGenerator->Initialize(gen, mf)) {
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
"Cannot initialize the generator " << gen
<< std::endl);
- parsed = 0;
+ parsed = false;
}
if (!mf->GetDefinition("CPACK_INSTALL_COMMANDS") &&
@@ -405,7 +412,7 @@ int main(int argc, char const* const* argv)
"CPACK_INSTALL_COMMANDS, CPACK_INSTALL_SCRIPT, or "
"CPACK_INSTALLED_DIRECTORIES."
<< std::endl);
- parsed = 0;
+ parsed = false;
}
if (parsed) {
cmValue projName = mf->GetDefinition("CPACK_PACKAGE_NAME");
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
index 1b2f769..aef58c5 100644
--- a/Source/CTest/cmCTestCoverageHandler.cxx
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -1218,11 +1218,8 @@ int cmCTestCoverageHandler::HandleGCovCoverage(
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Cannot open file: " << gcovFile << std::endl);
} else {
- long cnt = -1;
std::string nl;
while (cmSystemTools::GetLineFromStream(ifile, nl)) {
- cnt++;
-
// Skip empty lines
if (nl.empty()) {
continue;
@@ -1528,7 +1525,6 @@ int cmCTestCoverageHandler::HandleLCovCoverage(
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Cannot open file: " << lcovFile << std::endl);
} else {
- long cnt = -1;
std::string nl;
// Skip the first line
@@ -1537,8 +1533,6 @@ int cmCTestCoverageHandler::HandleLCovCoverage(
"File is ready, start reading." << std::endl,
this->Quiet);
while (cmSystemTools::GetLineFromStream(ifile, nl)) {
- cnt++;
-
// Skip empty lines
if (nl.empty()) {
continue;
diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx
index 6bb8e79..2d8276a 100644
--- a/Source/CTest/cmCTestMemCheckHandler.cxx
+++ b/Source/CTest/cmCTestMemCheckHandler.cxx
@@ -371,7 +371,8 @@ void cmCTestMemCheckHandler::GenerateCTestXML(cmXMLWriter& xml)
}
this->CleanTestOutput(
memcheckstr,
- static_cast<size_t>(this->CustomMaximumFailedTestOutputSize));
+ static_cast<size_t>(this->CustomMaximumFailedTestOutputSize),
+ this->TestOutputTruncation);
this->WriteTestResultHeader(xml, result);
xml.StartElement("Results");
int memoryErrors = 0;
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx
index d90c4a6..abd1aa6 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.cxx
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -1284,10 +1284,8 @@ void cmCTestMultiProcessHandler::PrintTestList()
}
this->TestHandler->SetMaxIndex(this->FindMaxIndex());
- int count = 0;
for (auto& it : this->Properties) {
- count++;
cmCTestTestHandler::cmCTestTestProperties& p = *it.second;
// Don't worry if this fails, we are only showing the test list, not
diff --git a/Source/CTest/cmCTestResourceSpec.cxx b/Source/CTest/cmCTestResourceSpec.cxx
index 101dc2c..142b07d 100644
--- a/Source/CTest/cmCTestResourceSpec.cxx
+++ b/Source/CTest/cmCTestResourceSpec.cxx
@@ -19,6 +19,8 @@
#include "cmJSONHelpers.h"
namespace {
+using JSONHelperBuilder =
+ cmJSONHelperBuilder<cmCTestResourceSpec::ReadFileResult>;
const cmsys::RegularExpression IdentifierRegex{ "^[a-z_][a-z0-9_]*$" };
const cmsys::RegularExpression IdRegex{ "^[a-z0-9_]+$" };
@@ -34,21 +36,19 @@ struct TopVersion
};
auto const VersionFieldHelper =
- cmJSONIntHelper<cmCTestResourceSpec::ReadFileResult>(
- cmCTestResourceSpec::ReadFileResult::READ_OK,
- cmCTestResourceSpec::ReadFileResult::INVALID_VERSION);
+ JSONHelperBuilder::Int(cmCTestResourceSpec::ReadFileResult::READ_OK,
+ cmCTestResourceSpec::ReadFileResult::INVALID_VERSION);
-auto const VersionHelper =
- cmJSONRequiredHelper<Version, cmCTestResourceSpec::ReadFileResult>(
- cmCTestResourceSpec::ReadFileResult::NO_VERSION,
- cmJSONObjectHelper<Version, cmCTestResourceSpec::ReadFileResult>(
- cmCTestResourceSpec::ReadFileResult::READ_OK,
- cmCTestResourceSpec::ReadFileResult::INVALID_VERSION)
- .Bind("major"_s, &Version::Major, VersionFieldHelper)
- .Bind("minor"_s, &Version::Minor, VersionFieldHelper));
+auto const VersionHelper = JSONHelperBuilder::Required<Version>(
+ cmCTestResourceSpec::ReadFileResult::NO_VERSION,
+ JSONHelperBuilder::Object<Version>(
+ cmCTestResourceSpec::ReadFileResult::READ_OK,
+ cmCTestResourceSpec::ReadFileResult::INVALID_VERSION)
+ .Bind("major"_s, &Version::Major, VersionFieldHelper)
+ .Bind("minor"_s, &Version::Minor, VersionFieldHelper));
auto const RootVersionHelper =
- cmJSONObjectHelper<TopVersion, cmCTestResourceSpec::ReadFileResult>(
+ JSONHelperBuilder::Object<TopVersion>(
cmCTestResourceSpec::ReadFileResult::READ_OK,
cmCTestResourceSpec::ReadFileResult::INVALID_ROOT)
.Bind("version"_s, &TopVersion::Version, VersionHelper, false);
@@ -56,7 +56,7 @@ auto const RootVersionHelper =
cmCTestResourceSpec::ReadFileResult ResourceIdHelper(std::string& out,
const Json::Value* value)
{
- auto result = cmJSONStringHelper(
+ auto result = JSONHelperBuilder::String(
cmCTestResourceSpec::ReadFileResult::READ_OK,
cmCTestResourceSpec::ReadFileResult::INVALID_RESOURCE)(out, value);
if (result != cmCTestResourceSpec::ReadFileResult::READ_OK) {
@@ -70,27 +70,24 @@ cmCTestResourceSpec::ReadFileResult ResourceIdHelper(std::string& out,
}
auto const ResourceHelper =
- cmJSONObjectHelper<cmCTestResourceSpec::Resource,
- cmCTestResourceSpec::ReadFileResult>(
+ JSONHelperBuilder::Object<cmCTestResourceSpec::Resource>(
cmCTestResourceSpec::ReadFileResult::READ_OK,
cmCTestResourceSpec::ReadFileResult::INVALID_RESOURCE)
.Bind("id"_s, &cmCTestResourceSpec::Resource::Id, ResourceIdHelper)
.Bind("slots"_s, &cmCTestResourceSpec::Resource::Capacity,
- cmJSONUIntHelper(
+ JSONHelperBuilder::UInt(
cmCTestResourceSpec::ReadFileResult::READ_OK,
cmCTestResourceSpec::ReadFileResult::INVALID_RESOURCE, 1),
false);
auto const ResourceListHelper =
- cmJSONVectorHelper<cmCTestResourceSpec::Resource,
- cmCTestResourceSpec::ReadFileResult>(
+ JSONHelperBuilder::Vector<cmCTestResourceSpec::Resource>(
cmCTestResourceSpec::ReadFileResult::READ_OK,
cmCTestResourceSpec::ReadFileResult::INVALID_RESOURCE_TYPE,
ResourceHelper);
auto const ResourceMapHelper =
- cmJSONMapFilterHelper<std::vector<cmCTestResourceSpec::Resource>,
- cmCTestResourceSpec::ReadFileResult>(
+ JSONHelperBuilder::MapFilter<std::vector<cmCTestResourceSpec::Resource>>(
cmCTestResourceSpec::ReadFileResult::READ_OK,
cmCTestResourceSpec::ReadFileResult::INVALID_SOCKET_SPEC,
ResourceListHelper, [](const std::string& key) -> bool {
@@ -98,7 +95,7 @@ auto const ResourceMapHelper =
return IdentifierRegex.find(key.c_str(), match);
});
-auto const SocketSetHelper = cmJSONVectorHelper<
+auto const SocketSetHelper = JSONHelperBuilder::Vector<
std::map<std::string, std::vector<cmCTestResourceSpec::Resource>>>(
cmCTestResourceSpec::ReadFileResult::READ_OK,
cmCTestResourceSpec::ReadFileResult::INVALID_SOCKET_SPEC, ResourceMapHelper);
@@ -125,16 +122,14 @@ cmCTestResourceSpec::ReadFileResult SocketHelper(
}
auto const LocalRequiredHelper =
- cmJSONRequiredHelper<cmCTestResourceSpec::Socket,
- cmCTestResourceSpec::ReadFileResult>(
+ JSONHelperBuilder::Required<cmCTestResourceSpec::Socket>(
cmCTestResourceSpec::ReadFileResult::INVALID_SOCKET_SPEC, SocketHelper);
-auto const RootHelper =
- cmJSONObjectHelper<cmCTestResourceSpec, cmCTestResourceSpec::ReadFileResult>(
- cmCTestResourceSpec::ReadFileResult::READ_OK,
- cmCTestResourceSpec::ReadFileResult::INVALID_ROOT)
- .Bind("local", &cmCTestResourceSpec::LocalSocket, LocalRequiredHelper,
- false);
+auto const RootHelper = JSONHelperBuilder::Object<cmCTestResourceSpec>(
+ cmCTestResourceSpec::ReadFileResult::READ_OK,
+ cmCTestResourceSpec::ReadFileResult::INVALID_ROOT)
+ .Bind("local", &cmCTestResourceSpec::LocalSocket,
+ LocalRequiredHelper, false);
}
cmCTestResourceSpec::ReadFileResult cmCTestResourceSpec::ReadFromJSONFile(
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index 6cd3b09..2a2cb1c 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -277,7 +277,8 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
static_cast<size_t>(
this->TestResult.Status == cmCTestTestHandler::COMPLETED
? this->TestHandler->CustomMaximumPassedTestOutputSize
- : this->TestHandler->CustomMaximumFailedTestOutputSize));
+ : this->TestHandler->CustomMaximumFailedTestOutputSize),
+ this->TestHandler->TestOutputTruncation);
}
this->TestResult.Reason = reason;
if (this->TestHandler->LogFile) {
@@ -694,6 +695,14 @@ void cmCTestRunTest::ComputeArguments()
<< " command: " << testCommand << std::endl);
// Print any test-specific env vars in verbose mode
+ if (!this->TestProperties->Directory.empty()) {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ this->Index << ": "
+ << "Working Directory: "
+ << this->TestProperties->Directory << std::endl);
+ }
+
+ // Print any test-specific env vars in verbose mode
if (!this->TestProperties->Environment.empty()) {
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
this->Index << ": "
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index 5a3a8d0..696a5ea 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -281,6 +281,7 @@ cmCTestTestHandler::cmCTestTestHandler()
this->CustomMaximumPassedTestOutputSize = 1 * 1024;
this->CustomMaximumFailedTestOutputSize = 300 * 1024;
+ this->TestOutputTruncation = cmCTestTypes::TruncationMode::Tail;
this->MemCheck = false;
@@ -325,6 +326,7 @@ void cmCTestTestHandler::Initialize()
this->CustomPostTest.clear();
this->CustomMaximumPassedTestOutputSize = 1 * 1024;
this->CustomMaximumFailedTestOutputSize = 300 * 1024;
+ this->TestOutputTruncation = cmCTestTypes::TruncationMode::Tail;
this->TestsToRun.clear();
@@ -358,6 +360,11 @@ void cmCTestTestHandler::PopulateCustomVectors(cmMakefile* mf)
this->CTest->PopulateCustomInteger(
mf, "CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE",
this->CustomMaximumFailedTestOutputSize);
+
+ cmValue dval = mf->GetDefinition("CTEST_CUSTOM_TEST_OUTPUT_TRUNCATION");
+ if (dval) {
+ this->SetTestOutputTruncation(dval);
+ }
}
int cmCTestTestHandler::PreProcessHandler()
@@ -2076,6 +2083,20 @@ void cmCTestTestHandler::SetExcludeRegExp(const std::string& arg)
this->ExcludeRegExp = arg;
}
+bool cmCTestTestHandler::SetTestOutputTruncation(const std::string& mode)
+{
+ if (mode == "tail") {
+ this->TestOutputTruncation = cmCTestTypes::TruncationMode::Tail;
+ } else if (mode == "middle") {
+ this->TestOutputTruncation = cmCTestTypes::TruncationMode::Middle;
+ } else if (mode == "head") {
+ this->TestOutputTruncation = cmCTestTypes::TruncationMode::Head;
+ } else {
+ return false;
+ }
+ return true;
+}
+
void cmCTestTestHandler::SetTestsToRunInformation(cmValue in)
{
if (!in) {
@@ -2094,41 +2115,58 @@ void cmCTestTestHandler::SetTestsToRunInformation(cmValue in)
}
}
-void cmCTestTestHandler::CleanTestOutput(std::string& output, size_t length)
+void cmCTestTestHandler::CleanTestOutput(std::string& output, size_t length,
+ cmCTestTypes::TruncationMode truncate)
{
if (!length || length >= output.size() ||
output.find("CTEST_FULL_OUTPUT") != std::string::npos) {
return;
}
- // Truncate at given length but do not break in the middle of a multi-byte
- // UTF-8 encoding.
- char const* const begin = output.c_str();
- char const* const end = begin + output.size();
- char const* const truncate = begin + length;
- char const* current = begin;
- while (current < truncate) {
- unsigned int ch;
- if (const char* next = cm_utf8_decode_character(current, end, &ch)) {
- if (next > truncate) {
- break;
+ // Advance n bytes in string delimited by begin/end but do not break in the
+ // middle of a multi-byte UTF-8 encoding.
+ auto utf8_advance = [](char const* const begin, char const* const end,
+ size_t n) -> const char* {
+ char const* const stop = begin + n;
+ char const* current = begin;
+ while (current < stop) {
+ unsigned int ch;
+ if (const char* next = cm_utf8_decode_character(current, end, &ch)) {
+ if (next > stop) {
+ break;
+ }
+ current = next;
+ } else // Bad byte will be handled by cmXMLWriter.
+ {
+ ++current;
}
- current = next;
- } else // Bad byte will be handled by cmXMLWriter.
- {
- ++current;
}
- }
- output.erase(current - begin);
+ return current;
+ };
- // Append truncation message.
- std::ostringstream msg;
- msg << "...\n"
- "The rest of the test output was removed since it exceeds the "
- "threshold "
- "of "
- << length << " bytes.\n";
- output += msg.str();
+ // Truncation message.
+ const std::string msg =
+ "\n[This part of the test output was removed since it "
+ "exceeds the threshold of " +
+ std::to_string(length) + " bytes.]\n";
+
+ char const* const begin = output.c_str();
+ char const* const end = begin + output.size();
+
+ // Erase head, middle or tail of output.
+ if (truncate == cmCTestTypes::TruncationMode::Head) {
+ char const* current = utf8_advance(begin, end, output.size() - length);
+ output.erase(0, current - begin);
+ output.insert(0, msg + "...");
+ } else if (truncate == cmCTestTypes::TruncationMode::Middle) {
+ char const* current = utf8_advance(begin, end, length / 2);
+ output.erase(current - begin, output.size() - length);
+ output.insert(current - begin, "..." + msg + "...");
+ } else { // default or "tail"
+ char const* current = utf8_advance(begin, end, length);
+ output.erase(current - begin);
+ output += ("..." + msg);
+ }
}
bool cmCTestTestHandler::SetTestsProperties(
@@ -2448,22 +2486,19 @@ bool cmCTestTestHandler::WriteJUnitXML()
// Iterate over the test results to get the number of tests that
// passed, failed, etc.
auto num_tests = 0;
- auto num_passed = 0;
auto num_failed = 0;
auto num_notrun = 0;
auto num_disabled = 0;
SetOfTests resultsSet(this->TestResults.begin(), this->TestResults.end());
for (cmCTestTestResult const& result : resultsSet) {
num_tests++;
- if (result.Status == cmCTestTestHandler::COMPLETED) {
- num_passed++;
- } else if (result.Status == cmCTestTestHandler::NOT_RUN) {
+ if (result.Status == cmCTestTestHandler::NOT_RUN) {
if (result.CompletionStatus == "Disabled") {
num_disabled++;
} else {
num_notrun++;
}
- } else {
+ } else if (result.Status != cmCTestTestHandler::COMPLETED) {
num_failed++;
}
}
diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h
index 135e764..d0049da 100644
--- a/Source/CTest/cmCTestTestHandler.h
+++ b/Source/CTest/cmCTestTestHandler.h
@@ -19,6 +19,7 @@
#include "cmCTest.h"
#include "cmCTestGenericHandler.h"
#include "cmCTestResourceSpec.h"
+#include "cmCTestTypes.h"
#include "cmDuration.h"
#include "cmListFileCache.h"
#include "cmValue.h"
@@ -32,6 +33,7 @@ class cmXMLWriter;
*/
class cmCTestTestHandler : public cmCTestGenericHandler
{
+ friend class cmCTest;
friend class cmCTestRunTest;
friend class cmCTestMultiProcessHandler;
@@ -80,6 +82,9 @@ public:
this->CustomMaximumFailedTestOutputSize = n;
}
+ //! Set test output truncation mode. Return false if unknown mode.
+ bool SetTestOutputTruncation(const std::string& mode);
+
//! pass the -I argument down
void SetTestsToRunInformation(cmValue);
@@ -242,8 +247,9 @@ protected:
void AttachFile(cmXMLWriter& xml, std::string const& file,
std::string const& name);
- //! Clean test output to specified length
- void CleanTestOutput(std::string& output, size_t length);
+ //! Clean test output to specified length and truncation mode
+ void CleanTestOutput(std::string& output, size_t length,
+ cmCTestTypes::TruncationMode truncate);
cmDuration ElapsedTestingTime;
@@ -258,6 +264,7 @@ protected:
bool MemCheck;
int CustomMaximumPassedTestOutputSize;
int CustomMaximumFailedTestOutputSize;
+ cmCTestTypes::TruncationMode TestOutputTruncation;
int MaxIndex;
public:
diff --git a/Source/CTest/cmCTestTypes.h b/Source/CTest/cmCTestTypes.h
new file mode 100644
index 0000000..843d27a
--- /dev/null
+++ b/Source/CTest/cmCTestTypes.h
@@ -0,0 +1,16 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#pragma once
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+namespace cmCTestTypes {
+
+enum class TruncationMode
+{ // Test output truncation mode
+ Tail,
+ Middle,
+ Head
+};
+}
diff --git a/Source/CursesDialog/cmCursesLongMessageForm.cxx b/Source/CursesDialog/cmCursesLongMessageForm.cxx
index 9b3a649..8a7bb86 100644
--- a/Source/CursesDialog/cmCursesLongMessageForm.cxx
+++ b/Source/CursesDialog/cmCursesLongMessageForm.cxx
@@ -191,9 +191,9 @@ void cmCursesLongMessageForm::HandleInput()
if (key == 'o' || key == 'e') {
break;
}
- if (key == KEY_DOWN || key == ctrl('n')) {
+ if (key == KEY_DOWN || key == ctrl('n') || key == 'j') {
form_driver(this->Form, REQ_SCR_FLINE);
- } else if (key == KEY_UP || key == ctrl('p')) {
+ } else if (key == KEY_UP || key == ctrl('p') || key == 'k') {
form_driver(this->Form, REQ_SCR_BLINE);
} else if (key == KEY_NPAGE || key == ctrl('d')) {
form_driver(this->Form, REQ_SCR_FPAGE);
diff --git a/Source/CursesDialog/form/frm_driver.c b/Source/CursesDialog/form/frm_driver.c
index 112ab08..9cbb12f 100644
--- a/Source/CursesDialog/form/frm_driver.c
+++ b/Source/CursesDialog/form/frm_driver.c
@@ -1456,7 +1456,7 @@ static int IFN_Beginning_Of_Field(FORM * form)
|
| Description : Place the cursor after the last non-pad character in
| the field. If the field occupies the last position in
-| the buffer, the cursos is positioned on the last
+| the buffer, the cursor is positioned on the last
| character.
|
| Return Values : E_OK - success
diff --git a/Source/LexerParser/cmCommandArgumentParser.cxx b/Source/LexerParser/cmCommandArgumentParser.cxx
index 5727992..4c49e0f 100644
--- a/Source/LexerParser/cmCommandArgumentParser.cxx
+++ b/Source/LexerParser/cmCommandArgumentParser.cxx
@@ -1,4 +1,4 @@
-/* A Bison parser, made by GNU Bison 3.7.5. */
+/* A Bison parser, made by GNU Bison 3.8.2. */
/* Bison implementation for Yacc-like parsers in C
@@ -16,7 +16,7 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@@ -46,10 +46,10 @@
USER NAME SPACE" below. */
/* Identify Bison output, and Bison version. */
-#define YYBISON 30705
+#define YYBISON 30802
/* Bison version string. */
-#define YYBISON_VERSION "3.7.5"
+#define YYBISON_VERSION "3.8.2"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -131,8 +131,13 @@ static void cmCommandArgument_yyerror(yyscan_t yyscanner, const char* message);
# pragma GCC diagnostic ignored "-Wconversion"
# pragma GCC diagnostic ignored "-Wfree-nonheap-object"
#endif
+#if defined(__clang__) && defined(__has_warning)
+# if __has_warning("-Wunused-but-set-variable")
+# pragma clang diagnostic ignored "-Wunused-but-set-variable"
+# endif
+#endif
-#line 136 "cmCommandArgumentParser.cxx"
+#line 141 "cmCommandArgumentParser.cxx"
# ifndef YY_CAST
# ifdef __cplusplus
@@ -342,12 +347,18 @@ typedef int yy_state_fast_t;
# define YY_USE(E) /* empty */
#endif
-#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
/* Suppress an incorrect diagnostic about yylval being uninitialized. */
-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+#if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__
+# if __GNUC__ * 100 + __GNUC_MINOR__ < 407
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")
+# else
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
_Pragma ("GCC diagnostic push") \
_Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \
_Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# endif
# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
_Pragma ("GCC diagnostic pop")
#else
@@ -562,12 +573,12 @@ static const yytype_int8 yytranslate[] =
};
#if YYDEBUG
- /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
+/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_uint8 yyrline[] =
{
- 0, 97, 97, 103, 106, 111, 114, 119, 122, 127,
- 130, 133, 136, 139, 142, 147, 150, 153, 156, 161,
- 164, 169, 172, 177, 180
+ 0, 102, 102, 108, 111, 116, 119, 124, 127, 132,
+ 135, 138, 141, 144, 147, 152, 155, 158, 161, 166,
+ 169, 174, 177, 182, 185
};
#endif
@@ -597,16 +608,6 @@ yysymbol_name (yysymbol_kind_t yysymbol)
}
#endif
-#ifdef YYPRINT
-/* YYTOKNUM[NUM] -- (External) token number corresponding to the
- (internal) symbol number NUM (which must be that of a token). */
-static const yytype_int16 yytoknum[] =
-{
- 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
- 265, 266, 267, 268, 269
-};
-#endif
-
#define YYPACT_NINF (-3)
#define yypact_value_is_default(Yyn) \
@@ -617,8 +618,8 @@ static const yytype_int16 yytoknum[] =
#define yytable_value_is_error(Yyn) \
0
- /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
- STATE-NUM. */
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
static const yytype_int8 yypact[] =
{
0, 14, 26, 26, -3, -3, -3, -3, -3, -3,
@@ -627,9 +628,9 @@ static const yytype_int8 yypact[] =
-3, -3, -3
};
- /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
- Performed when YYTABLE does not specify something else to do. Zero
- means the default is an error. */
+/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+ Performed when YYTABLE does not specify something else to do. Zero
+ means the default is an error. */
static const yytype_int8 yydefact[] =
{
5, 21, 21, 21, 11, 12, 13, 9, 14, 10,
@@ -638,21 +639,21 @@ static const yytype_int8 yydefact[] =
22, 16, 17
};
- /* YYPGOTO[NTERM-NUM]. */
+/* YYPGOTO[NTERM-NUM]. */
static const yytype_int8 yypgoto[] =
{
-3, -3, -3, 8, -3, -3, 2, 9, -2, -3
};
- /* YYDEFGOTO[NTERM-NUM]. */
+/* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int8 yydefgoto[] =
{
0, 11, 12, 13, 14, 15, 19, 20, 21, 22
};
- /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
- positive, shift that token. If negative, reduce the rule whose
- number is the opposite. If YYTABLE_NINF, syntax error. */
+/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule whose
+ number is the opposite. If YYTABLE_NINF, syntax error. */
static const yytype_int8 yytable[] =
{
23, 24, 16, 1, 2, 3, 4, 5, 6, 7,
@@ -671,8 +672,8 @@ static const yytype_int8 yycheck[] =
14
};
- /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
- symbol of state STATE-NUM. */
+/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of
+ state STATE-NUM. */
static const yytype_int8 yystos[] =
{
0, 3, 4, 5, 6, 7, 8, 9, 11, 12,
@@ -681,7 +682,7 @@ static const yytype_int8 yystos[] =
23, 8, 8
};
- /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */
static const yytype_int8 yyr1[] =
{
0, 15, 16, 17, 17, 18, 18, 19, 19, 20,
@@ -689,7 +690,7 @@ static const yytype_int8 yyr1[] =
22, 23, 23, 24, 24
};
- /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
+/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */
static const yytype_int8 yyr2[] =
{
0, 2, 1, 1, 2, 0, 2, 1, 1, 1,
@@ -706,6 +707,7 @@ enum { YYENOMEM = -2 };
#define YYACCEPT goto yyacceptlab
#define YYABORT goto yyabortlab
#define YYERROR goto yyerrorlab
+#define YYNOMEM goto yyexhaustedlab
#define YYRECOVERING() (!!yyerrstatus)
@@ -746,10 +748,7 @@ do { \
YYFPRINTF Args; \
} while (0)
-/* This macro is provided for backward compatibility. */
-# ifndef YY_LOCATION_PRINT
-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-# endif
+
# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \
@@ -777,10 +776,6 @@ yy_symbol_value_print (FILE *yyo,
YY_USE (yyscanner);
if (!yyvaluep)
return;
-# ifdef YYPRINT
- if (yykind < YYNTOKENS)
- YYPRINT (yyo, yytoknum[yykind], *yyvaluep);
-# endif
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
YY_USE (yykind);
YY_IGNORE_MAYBE_UNINITIALIZED_END
@@ -1242,6 +1237,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
YYDPRINTF ((stderr, "Starting parse\n"));
yychar = YYEMPTY; /* Cause a token to be read. */
+
goto yysetstate;
@@ -1267,7 +1263,7 @@ yysetstate:
if (yyss + yystacksize - 1 <= yyssp)
#if !defined yyoverflow && !defined YYSTACK_RELOCATE
- goto yyexhaustedlab;
+ YYNOMEM;
#else
{
/* Get the current used size of the three stacks, in elements. */
@@ -1295,7 +1291,7 @@ yysetstate:
# else /* defined YYSTACK_RELOCATE */
/* Extend the stack our own way. */
if (YYMAXDEPTH <= yystacksize)
- goto yyexhaustedlab;
+ YYNOMEM;
yystacksize *= 2;
if (YYMAXDEPTH < yystacksize)
yystacksize = YYMAXDEPTH;
@@ -1306,7 +1302,7 @@ yysetstate:
YY_CAST (union yyalloc *,
YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize))));
if (! yyptr)
- goto yyexhaustedlab;
+ YYNOMEM;
YYSTACK_RELOCATE (yyss_alloc, yyss);
YYSTACK_RELOCATE (yyvs_alloc, yyvs);
# undef YYSTACK_RELOCATE
@@ -1328,6 +1324,7 @@ yysetstate:
}
#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
+
if (yystate == YYFINAL)
YYACCEPT;
@@ -1440,192 +1437,192 @@ yyreduce:
switch (yyn)
{
case 2: /* Start: GoalWithOptionalBackSlash */
-#line 97 "cmCommandArgumentParser.y"
+#line 102 "cmCommandArgumentParser.y"
{
(yyval.str) = 0;
yyGetParser->SetResult((yyvsp[0].str));
}
-#line 1449 "cmCommandArgumentParser.cxx"
+#line 1446 "cmCommandArgumentParser.cxx"
break;
case 3: /* GoalWithOptionalBackSlash: Goal */
-#line 103 "cmCommandArgumentParser.y"
+#line 108 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1457 "cmCommandArgumentParser.cxx"
+#line 1454 "cmCommandArgumentParser.cxx"
break;
case 4: /* GoalWithOptionalBackSlash: Goal "\\" */
-#line 106 "cmCommandArgumentParser.y"
+#line 111 "cmCommandArgumentParser.y"
{
(yyval.str) = yyGetParser->CombineUnions((yyvsp[-1].str), (yyvsp[0].str));
}
-#line 1465 "cmCommandArgumentParser.cxx"
+#line 1462 "cmCommandArgumentParser.cxx"
break;
case 5: /* Goal: %empty */
-#line 111 "cmCommandArgumentParser.y"
+#line 116 "cmCommandArgumentParser.y"
{
(yyval.str) = 0;
}
-#line 1473 "cmCommandArgumentParser.cxx"
+#line 1470 "cmCommandArgumentParser.cxx"
break;
case 6: /* Goal: String Goal */
-#line 114 "cmCommandArgumentParser.y"
+#line 119 "cmCommandArgumentParser.y"
{
(yyval.str) = yyGetParser->CombineUnions((yyvsp[-1].str), (yyvsp[0].str));
}
-#line 1481 "cmCommandArgumentParser.cxx"
+#line 1478 "cmCommandArgumentParser.cxx"
break;
case 7: /* String: OuterText */
-#line 119 "cmCommandArgumentParser.y"
+#line 124 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1489 "cmCommandArgumentParser.cxx"
+#line 1486 "cmCommandArgumentParser.cxx"
break;
case 8: /* String: Variable */
-#line 122 "cmCommandArgumentParser.y"
+#line 127 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1497 "cmCommandArgumentParser.cxx"
+#line 1494 "cmCommandArgumentParser.cxx"
break;
case 9: /* OuterText: cal_NAME */
-#line 127 "cmCommandArgumentParser.y"
+#line 132 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1505 "cmCommandArgumentParser.cxx"
+#line 1502 "cmCommandArgumentParser.cxx"
break;
case 10: /* OuterText: "@" */
-#line 130 "cmCommandArgumentParser.y"
+#line 135 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1513 "cmCommandArgumentParser.cxx"
+#line 1510 "cmCommandArgumentParser.cxx"
break;
case 11: /* OuterText: "$" */
-#line 133 "cmCommandArgumentParser.y"
+#line 138 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1521 "cmCommandArgumentParser.cxx"
+#line 1518 "cmCommandArgumentParser.cxx"
break;
case 12: /* OuterText: "{" */
-#line 136 "cmCommandArgumentParser.y"
+#line 141 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1529 "cmCommandArgumentParser.cxx"
+#line 1526 "cmCommandArgumentParser.cxx"
break;
case 13: /* OuterText: "}" */
-#line 139 "cmCommandArgumentParser.y"
+#line 144 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1537 "cmCommandArgumentParser.cxx"
+#line 1534 "cmCommandArgumentParser.cxx"
break;
case 14: /* OuterText: cal_SYMBOL */
-#line 142 "cmCommandArgumentParser.y"
+#line 147 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1545 "cmCommandArgumentParser.cxx"
+#line 1542 "cmCommandArgumentParser.cxx"
break;
case 15: /* Variable: cal_ENVCURLY EnvVarName "}" */
-#line 147 "cmCommandArgumentParser.y"
+#line 152 "cmCommandArgumentParser.y"
{
(yyval.str) = yyGetParser->ExpandSpecialVariable((yyvsp[-2].str), (yyvsp[-1].str));
}
-#line 1553 "cmCommandArgumentParser.cxx"
+#line 1550 "cmCommandArgumentParser.cxx"
break;
case 16: /* Variable: cal_NCURLY MultipleIds "}" */
-#line 150 "cmCommandArgumentParser.y"
+#line 155 "cmCommandArgumentParser.y"
{
(yyval.str) = yyGetParser->ExpandSpecialVariable((yyvsp[-2].str), (yyvsp[-1].str));
}
-#line 1561 "cmCommandArgumentParser.cxx"
+#line 1558 "cmCommandArgumentParser.cxx"
break;
case 17: /* Variable: cal_DCURLY MultipleIds "}" */
-#line 153 "cmCommandArgumentParser.y"
+#line 158 "cmCommandArgumentParser.y"
{
(yyval.str) = yyGetParser->ExpandVariable((yyvsp[-1].str));
}
-#line 1569 "cmCommandArgumentParser.cxx"
+#line 1566 "cmCommandArgumentParser.cxx"
break;
case 18: /* Variable: cal_ATNAME */
-#line 156 "cmCommandArgumentParser.y"
+#line 161 "cmCommandArgumentParser.y"
{
(yyval.str) = yyGetParser->ExpandVariableForAt((yyvsp[0].str));
}
-#line 1577 "cmCommandArgumentParser.cxx"
+#line 1574 "cmCommandArgumentParser.cxx"
break;
case 19: /* EnvVarName: MultipleIds */
-#line 161 "cmCommandArgumentParser.y"
+#line 166 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1585 "cmCommandArgumentParser.cxx"
+#line 1582 "cmCommandArgumentParser.cxx"
break;
case 20: /* EnvVarName: cal_SYMBOL EnvVarName */
-#line 164 "cmCommandArgumentParser.y"
+#line 169 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[-1].str);
}
-#line 1593 "cmCommandArgumentParser.cxx"
+#line 1590 "cmCommandArgumentParser.cxx"
break;
case 21: /* MultipleIds: %empty */
-#line 169 "cmCommandArgumentParser.y"
+#line 174 "cmCommandArgumentParser.y"
{
(yyval.str) = 0;
}
-#line 1601 "cmCommandArgumentParser.cxx"
+#line 1598 "cmCommandArgumentParser.cxx"
break;
case 22: /* MultipleIds: ID MultipleIds */
-#line 172 "cmCommandArgumentParser.y"
+#line 177 "cmCommandArgumentParser.y"
{
(yyval.str) = yyGetParser->CombineUnions((yyvsp[-1].str), (yyvsp[0].str));
}
-#line 1609 "cmCommandArgumentParser.cxx"
+#line 1606 "cmCommandArgumentParser.cxx"
break;
case 23: /* ID: cal_NAME */
-#line 177 "cmCommandArgumentParser.y"
+#line 182 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1617 "cmCommandArgumentParser.cxx"
+#line 1614 "cmCommandArgumentParser.cxx"
break;
case 24: /* ID: Variable */
-#line 180 "cmCommandArgumentParser.y"
+#line 185 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1625 "cmCommandArgumentParser.cxx"
+#line 1622 "cmCommandArgumentParser.cxx"
break;
-#line 1629 "cmCommandArgumentParser.cxx"
+#line 1626 "cmCommandArgumentParser.cxx"
default: break;
}
@@ -1701,7 +1698,7 @@ yyerrlab:
}
yyerror (yyscanner, yymsgp);
if (yysyntax_error_status == YYENOMEM)
- goto yyexhaustedlab;
+ YYNOMEM;
}
}
@@ -1737,6 +1734,7 @@ yyerrorlab:
label yyerrorlab therefore never appears in user code. */
if (0)
YYERROR;
+ ++yynerrs;
/* Do not reclaim the symbols of the rule whose action triggered
this YYERROR. */
@@ -1797,7 +1795,7 @@ yyerrlab1:
`-------------------------------------*/
yyacceptlab:
yyresult = 0;
- goto yyreturn;
+ goto yyreturnlab;
/*-----------------------------------.
@@ -1805,24 +1803,22 @@ yyacceptlab:
`-----------------------------------*/
yyabortlab:
yyresult = 1;
- goto yyreturn;
+ goto yyreturnlab;
-#if 1
-/*-------------------------------------------------.
-| yyexhaustedlab -- memory exhaustion comes here. |
-`-------------------------------------------------*/
+/*-----------------------------------------------------------.
+| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. |
+`-----------------------------------------------------------*/
yyexhaustedlab:
yyerror (yyscanner, YY_("memory exhausted"));
yyresult = 2;
- goto yyreturn;
-#endif
+ goto yyreturnlab;
-/*-------------------------------------------------------.
-| yyreturn -- parsing is finished, clean up and return. |
-`-------------------------------------------------------*/
-yyreturn:
+/*----------------------------------------------------------.
+| yyreturnlab -- parsing is finished, clean up and return. |
+`----------------------------------------------------------*/
+yyreturnlab:
if (yychar != YYEMPTY)
{
/* Make sure we have latest lookahead translation. See comments at
@@ -1850,7 +1846,7 @@ yyreturn:
return yyresult;
}
-#line 185 "cmCommandArgumentParser.y"
+#line 190 "cmCommandArgumentParser.y"
/* End of grammar */
diff --git a/Source/LexerParser/cmCommandArgumentParser.y b/Source/LexerParser/cmCommandArgumentParser.y
index 2689415..602e1c3 100644
--- a/Source/LexerParser/cmCommandArgumentParser.y
+++ b/Source/LexerParser/cmCommandArgumentParser.y
@@ -56,6 +56,11 @@ static void cmCommandArgument_yyerror(yyscan_t yyscanner, const char* message);
# pragma GCC diagnostic ignored "-Wconversion"
# pragma GCC diagnostic ignored "-Wfree-nonheap-object"
#endif
+#if defined(__clang__) && defined(__has_warning)
+# if __has_warning("-Wunused-but-set-variable")
+# pragma clang diagnostic ignored "-Wunused-but-set-variable"
+# endif
+#endif
%}
/* Generate a reentrant parser object. */
diff --git a/Source/LexerParser/cmCommandArgumentParserTokens.h b/Source/LexerParser/cmCommandArgumentParserTokens.h
index 414c6dd..6365d5b 100644
--- a/Source/LexerParser/cmCommandArgumentParserTokens.h
+++ b/Source/LexerParser/cmCommandArgumentParserTokens.h
@@ -1,4 +1,4 @@
-/* A Bison parser, made by GNU Bison 3.7.5. */
+/* A Bison parser, made by GNU Bison 3.8.2. */
/* Bison interface for Yacc-like parsers in C
@@ -16,7 +16,7 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@@ -74,6 +74,8 @@ extern int cmCommandArgument_yydebug;
+
int cmCommandArgument_yyparse (yyscan_t yyscanner);
+
#endif /* !YY_CMCOMMANDARGUMENT_YY_CMCOMMANDARGUMENTPARSERTOKENS_H_INCLUDED */
diff --git a/Source/LexerParser/cmDependsJavaParser.cxx b/Source/LexerParser/cmDependsJavaParser.cxx
index e6b3a7e..59cf1be 100644
--- a/Source/LexerParser/cmDependsJavaParser.cxx
+++ b/Source/LexerParser/cmDependsJavaParser.cxx
@@ -1,4 +1,4 @@
-/* A Bison parser, made by GNU Bison 3.7.5. */
+/* A Bison parser, made by GNU Bison 3.8.2. */
/* Bison implementation for Yacc-like parsers in C
@@ -16,7 +16,7 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@@ -46,10 +46,10 @@
USER NAME SPACE" below. */
/* Identify Bison output, and Bison version. */
-#define YYBISON 30705
+#define YYBISON 30802
/* Bison version string. */
-#define YYBISON_VERSION "3.7.5"
+#define YYBISON_VERSION "3.8.2"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -120,8 +120,13 @@ static void cmDependsJava_yyerror(yyscan_t yyscanner, const char* message);
# pragma GCC diagnostic ignored "-Wconversion"
# pragma GCC diagnostic ignored "-Wfree-nonheap-object"
#endif
+#if defined(__clang__) && defined(__has_warning)
+# if __has_warning("-Wunused-but-set-variable")
+# pragma clang diagnostic ignored "-Wunused-but-set-variable"
+# endif
+#endif
-#line 125 "cmDependsJavaParser.cxx"
+#line 130 "cmDependsJavaParser.cxx"
# ifndef YY_CAST
# ifdef __cplusplus
@@ -570,12 +575,18 @@ typedef int yy_state_fast_t;
# define YY_USE(E) /* empty */
#endif
-#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
/* Suppress an incorrect diagnostic about yylval being uninitialized. */
-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+#if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__
+# if __GNUC__ * 100 + __GNUC_MINOR__ < 407
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")
+# else
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
_Pragma ("GCC diagnostic push") \
_Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \
_Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# endif
# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
_Pragma ("GCC diagnostic pop")
#else
@@ -800,45 +811,45 @@ static const yytype_int8 yytranslate[] =
};
#if YYDEBUG
- /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
+/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_int16 yyrline[] =
{
- 0, 180, 180, 189, 197, 205, 213, 221, 229, 238,
- 246, 255, 263, 272, 277, 282, 287, 292, 297, 302,
- 307, 313, 321, 330, 340, 349, 358, 366, 376, 382,
- 389, 396, 402, 409, 418, 428, 438, 447, 455, 464,
- 473, 479, 488, 494, 503, 509, 518, 530, 538, 547,
- 559, 572, 580, 588, 597, 605, 614, 614, 614, 615,
- 616, 616, 616, 616, 616, 616, 617, 620, 630, 639,
- 648, 657, 667, 673, 682, 691, 700, 708, 717, 726,
- 732, 741, 749, 757, 765, 774, 782, 791, 797, 805,
- 814, 822, 831, 840, 849, 857, 866, 874, 882, 891,
- 900, 910, 917, 927, 937, 944, 951, 954, 960, 970,
- 980, 990, 996, 1006, 1016, 1026, 1035, 1045, 1056, 1066,
- 1073, 1083, 1092, 1102, 1111, 1121, 1127, 1137, 1146, 1156,
- 1166, 1173, 1182, 1191, 1200, 1209, 1217, 1226, 1235, 1245,
- 1255, 1264, 1274, 1284, 1291, 1300, 1310, 1319, 1329, 1338,
- 1345, 1355, 1364, 1374, 1383, 1392, 1402, 1412, 1421, 1431,
- 1440, 1449, 1458, 1467, 1476, 1486, 1495, 1504, 1513, 1522,
- 1532, 1541, 1550, 1559, 1568, 1577, 1586, 1595, 1604, 1613,
- 1622, 1631, 1641, 1651, 1662, 1672, 1682, 1691, 1700, 1709,
- 1718, 1727, 1736, 1746, 1756, 1766, 1776, 1783, 1790, 1797,
- 1807, 1814, 1824, 1834, 1843, 1853, 1862, 1872, 1879, 1886,
- 1893, 1901, 1908, 1918, 1925, 1935, 1945, 1952, 1962, 1971,
- 1981, 1991, 2000, 2010, 2019, 2029, 2040, 2047, 2054, 2065,
- 2075, 2085, 2095, 2104, 2114, 2121, 2131, 2140, 2150, 2157,
- 2167, 2176, 2186, 2195, 2201, 2210, 2219, 2228, 2237, 2247,
- 2257, 2264, 2274, 2281, 2291, 2300, 2310, 2319, 2328, 2337,
- 2347, 2354, 2364, 2373, 2383, 2393, 2399, 2406, 2416, 2426,
- 2436, 2447, 2457, 2468, 2478, 2489, 2499, 2509, 2518, 2527,
- 2536, 2545, 2555, 2565, 2575, 2584, 2593, 2602, 2611, 2621,
- 2631, 2641, 2650, 2659, 2668, 2678, 2687, 2696, 2703, 2712,
- 2721, 2730, 2740, 2749, 2758, 2768, 2777, 2786, 2795, 2805,
- 2814, 2823, 2832, 2841, 2850, 2860, 2869, 2878, 2888, 2897,
- 2907, 2916, 2926, 2935, 2945, 2954, 2964, 2973, 2983, 2992,
- 3002, 3011, 3021, 3031, 3041, 3050, 3060, 3069, 3078, 3087,
- 3096, 3105, 3114, 3123, 3132, 3141, 3150, 3159, 3169, 3179,
- 3189, 3198
+ 0, 185, 185, 194, 202, 210, 218, 226, 234, 243,
+ 251, 260, 268, 277, 282, 287, 292, 297, 302, 307,
+ 312, 318, 326, 335, 345, 354, 363, 371, 381, 387,
+ 394, 401, 407, 414, 423, 433, 443, 452, 460, 469,
+ 478, 484, 493, 499, 508, 514, 523, 535, 543, 552,
+ 564, 577, 585, 593, 602, 610, 619, 619, 619, 620,
+ 621, 621, 621, 621, 621, 621, 622, 625, 635, 644,
+ 653, 662, 672, 678, 687, 696, 705, 713, 722, 731,
+ 737, 746, 754, 762, 770, 779, 787, 796, 802, 810,
+ 819, 827, 836, 845, 854, 862, 871, 879, 887, 896,
+ 905, 915, 922, 932, 942, 949, 956, 959, 965, 975,
+ 985, 995, 1001, 1011, 1021, 1031, 1040, 1050, 1061, 1071,
+ 1078, 1088, 1097, 1107, 1116, 1126, 1132, 1142, 1151, 1161,
+ 1171, 1178, 1187, 1196, 1205, 1214, 1222, 1231, 1240, 1250,
+ 1260, 1269, 1279, 1289, 1296, 1305, 1315, 1324, 1334, 1343,
+ 1350, 1360, 1369, 1379, 1388, 1397, 1407, 1417, 1426, 1436,
+ 1445, 1454, 1463, 1472, 1481, 1491, 1500, 1509, 1518, 1527,
+ 1537, 1546, 1555, 1564, 1573, 1582, 1591, 1600, 1609, 1618,
+ 1627, 1636, 1646, 1656, 1667, 1677, 1687, 1696, 1705, 1714,
+ 1723, 1732, 1741, 1751, 1761, 1771, 1781, 1788, 1795, 1802,
+ 1812, 1819, 1829, 1839, 1848, 1858, 1867, 1877, 1884, 1891,
+ 1898, 1906, 1913, 1923, 1930, 1940, 1950, 1957, 1967, 1976,
+ 1986, 1996, 2005, 2015, 2024, 2034, 2045, 2052, 2059, 2070,
+ 2080, 2090, 2100, 2109, 2119, 2126, 2136, 2145, 2155, 2162,
+ 2172, 2181, 2191, 2200, 2206, 2215, 2224, 2233, 2242, 2252,
+ 2262, 2269, 2279, 2286, 2296, 2305, 2315, 2324, 2333, 2342,
+ 2352, 2359, 2369, 2378, 2388, 2398, 2404, 2411, 2421, 2431,
+ 2441, 2452, 2462, 2473, 2483, 2494, 2504, 2514, 2523, 2532,
+ 2541, 2550, 2560, 2570, 2580, 2589, 2598, 2607, 2616, 2626,
+ 2636, 2646, 2655, 2664, 2673, 2683, 2692, 2701, 2708, 2717,
+ 2726, 2735, 2745, 2754, 2763, 2773, 2782, 2791, 2800, 2810,
+ 2819, 2828, 2837, 2846, 2855, 2865, 2874, 2883, 2893, 2902,
+ 2912, 2921, 2931, 2940, 2950, 2959, 2969, 2978, 2988, 2997,
+ 3007, 3016, 3026, 3036, 3046, 3055, 3065, 3074, 3083, 3092,
+ 3101, 3110, 3119, 3128, 3137, 3146, 3155, 3164, 3174, 3184,
+ 3194, 3203
};
#endif
@@ -938,25 +949,6 @@ yysymbol_name (yysymbol_kind_t yysymbol)
}
#endif
-#ifdef YYPRINT
-/* YYTOKNUM[NUM] -- (External) token number corresponding to the
- (internal) symbol number NUM (which must be that of a token). */
-static const yytype_int16 yytoknum[] =
-{
- 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
- 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
- 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
- 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
- 295, 296, 297, 298, 299, 300, 301, 302, 303, 304,
- 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
- 315, 316, 317, 318, 319, 320, 321, 322, 323, 324,
- 325, 326, 327, 328, 329, 330, 331, 332, 333, 334,
- 335, 336, 337, 338, 339, 340, 341, 342, 343, 344,
- 345, 346, 347, 348, 349, 350, 351, 352, 353, 354,
- 355, 356, 357, 358, 359, 360
-};
-#endif
-
#define YYPACT_NINF (-503)
#define yypact_value_is_default(Yyn) \
@@ -967,8 +959,8 @@ static const yytype_int16 yytoknum[] =
#define yytable_value_is_error(Yyn) \
0
- /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
- STATE-NUM. */
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
static const yytype_int16 yypact[] =
{
159, 1039, 236, -503, -503, -503, -503, -503, -503, -503,
@@ -1031,9 +1023,9 @@ static const yytype_int16 yypact[] =
1699, 432, -503, 1699, -503
};
- /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
- Performed when YYTABLE does not specify something else to do. Zero
- means the default is an error. */
+/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+ Performed when YYTABLE does not specify something else to do. Zero
+ means the default is an error. */
static const yytype_int16 yydefact[] =
{
40, 0, 0, 2, 42, 41, 20, 13, 17, 19,
@@ -1096,7 +1088,7 @@ static const yytype_int16 yydefact[] =
0, 0, 195, 0, 215
};
- /* YYPGOTO[NTERM-NUM]. */
+/* YYPGOTO[NTERM-NUM]. */
static const yytype_int16 yypgoto[] =
{
-503, -503, -503, -503, -85, 2, 181, -41, -198, -45,
@@ -1117,7 +1109,7 @@ static const yytype_int16 yypgoto[] =
95, 274, 350, -503, -503, 660, -503, -503
};
- /* YYDEFGOTO[NTERM-NUM]. */
+/* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int16 yydefgoto[] =
{
0, 2, 156, 157, 158, 229, 112, 113, 75, 78,
@@ -1138,9 +1130,9 @@ static const yytype_int16 yydefgoto[] =
252, 253, 254, 203, 306, 386, 557, 204
};
- /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
- positive, shift that token. If negative, reduce the rule whose
- number is the opposite. If YYTABLE_NINF, syntax error. */
+/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule whose
+ number is the opposite. If YYTABLE_NINF, syntax error. */
static const yytype_int16 yytable[] =
{
18, 82, 83, 17, 287, 61, 309, 56, 114, 364,
@@ -1593,8 +1585,8 @@ static const yytype_int16 yycheck[] =
-1, -1, -1, -1, -1, 104
};
- /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
- symbol of state STATE-NUM. */
+/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of
+ state STATE-NUM. */
static const yytype_int16 yystos[] =
{
0, 31, 107, 122, 123, 126, 5, 7, 10, 15,
@@ -1657,7 +1649,7 @@ static const yytype_int16 yystos[] =
16, 205, 184, 90, 184
};
- /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */
static const yytype_int16 yyr1[] =
{
0, 106, 107, 108, 108, 108, 108, 108, 108, 109,
@@ -1698,7 +1690,7 @@ static const yytype_int16 yyr1[] =
263, 263
};
- /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
+/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */
static const yytype_int8 yyr2[] =
{
0, 2, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -1748,6 +1740,7 @@ enum { YYENOMEM = -2 };
#define YYACCEPT goto yyacceptlab
#define YYABORT goto yyabortlab
#define YYERROR goto yyerrorlab
+#define YYNOMEM goto yyexhaustedlab
#define YYRECOVERING() (!!yyerrstatus)
@@ -1788,10 +1781,7 @@ do { \
YYFPRINTF Args; \
} while (0)
-/* This macro is provided for backward compatibility. */
-# ifndef YY_LOCATION_PRINT
-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-# endif
+
# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \
@@ -1819,10 +1809,6 @@ yy_symbol_value_print (FILE *yyo,
YY_USE (yyscanner);
if (!yyvaluep)
return;
-# ifdef YYPRINT
- if (yykind < YYNTOKENS)
- YYPRINT (yyo, yytoknum[yykind], *yyvaluep);
-# endif
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
YY_USE (yykind);
YY_IGNORE_MAYBE_UNINITIALIZED_END
@@ -2284,6 +2270,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
YYDPRINTF ((stderr, "Starting parse\n"));
yychar = YYEMPTY; /* Cause a token to be read. */
+
goto yysetstate;
@@ -2309,7 +2296,7 @@ yysetstate:
if (yyss + yystacksize - 1 <= yyssp)
#if !defined yyoverflow && !defined YYSTACK_RELOCATE
- goto yyexhaustedlab;
+ YYNOMEM;
#else
{
/* Get the current used size of the three stacks, in elements. */
@@ -2337,7 +2324,7 @@ yysetstate:
# else /* defined YYSTACK_RELOCATE */
/* Extend the stack our own way. */
if (YYMAXDEPTH <= yystacksize)
- goto yyexhaustedlab;
+ YYNOMEM;
yystacksize *= 2;
if (YYMAXDEPTH < yystacksize)
yystacksize = YYMAXDEPTH;
@@ -2348,7 +2335,7 @@ yysetstate:
YY_CAST (union yyalloc *,
YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize))));
if (! yyptr)
- goto yyexhaustedlab;
+ YYNOMEM;
YYSTACK_RELOCATE (yyss_alloc, yyss);
YYSTACK_RELOCATE (yyvs_alloc, yyvs);
# undef YYSTACK_RELOCATE
@@ -2370,6 +2357,7 @@ yysetstate:
}
#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
+
if (yystate == YYFINAL)
YYACCEPT;
@@ -2482,214 +2470,214 @@ yyreduce:
switch (yyn)
{
case 2: /* Goal: CompilationUnit */
-#line 181 "cmDependsJavaParser.y"
+#line 186 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2493 "cmDependsJavaParser.cxx"
+#line 2481 "cmDependsJavaParser.cxx"
break;
case 3: /* Literal: IntegerLiteral */
-#line 190 "cmDependsJavaParser.y"
+#line 195 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2504 "cmDependsJavaParser.cxx"
+#line 2492 "cmDependsJavaParser.cxx"
break;
case 4: /* Literal: jp_FLOATINGPOINTLITERAL */
-#line 198 "cmDependsJavaParser.y"
+#line 203 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2515 "cmDependsJavaParser.cxx"
+#line 2503 "cmDependsJavaParser.cxx"
break;
case 5: /* Literal: jp_BOOLEANLITERAL */
-#line 206 "cmDependsJavaParser.y"
+#line 211 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2526 "cmDependsJavaParser.cxx"
+#line 2514 "cmDependsJavaParser.cxx"
break;
case 6: /* Literal: jp_CHARACTERLITERAL */
-#line 214 "cmDependsJavaParser.y"
+#line 219 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2537 "cmDependsJavaParser.cxx"
+#line 2525 "cmDependsJavaParser.cxx"
break;
case 7: /* Literal: jp_STRINGLITERAL */
-#line 222 "cmDependsJavaParser.y"
+#line 227 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2548 "cmDependsJavaParser.cxx"
+#line 2536 "cmDependsJavaParser.cxx"
break;
case 8: /* Literal: jp_NULLLITERAL */
-#line 230 "cmDependsJavaParser.y"
+#line 235 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2559 "cmDependsJavaParser.cxx"
+#line 2547 "cmDependsJavaParser.cxx"
break;
case 9: /* IntegerLiteral: jp_DECIMALINTEGERLITERAL */
-#line 239 "cmDependsJavaParser.y"
+#line 244 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2570 "cmDependsJavaParser.cxx"
+#line 2558 "cmDependsJavaParser.cxx"
break;
case 10: /* IntegerLiteral: jp_HEXINTEGERLITERAL */
-#line 247 "cmDependsJavaParser.y"
+#line 252 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2581 "cmDependsJavaParser.cxx"
+#line 2569 "cmDependsJavaParser.cxx"
break;
case 11: /* Type: PrimitiveType */
-#line 256 "cmDependsJavaParser.y"
+#line 261 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2592 "cmDependsJavaParser.cxx"
+#line 2580 "cmDependsJavaParser.cxx"
break;
case 12: /* Type: ReferenceType */
-#line 264 "cmDependsJavaParser.y"
+#line 269 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2603 "cmDependsJavaParser.cxx"
+#line 2591 "cmDependsJavaParser.cxx"
break;
case 13: /* PrimitiveType: jp_BYTE_TYPE */
-#line 273 "cmDependsJavaParser.y"
+#line 278 "cmDependsJavaParser.y"
{
jpElementStart(0);
}
-#line 2611 "cmDependsJavaParser.cxx"
+#line 2599 "cmDependsJavaParser.cxx"
break;
case 14: /* PrimitiveType: jp_SHORT_TYPE */
-#line 278 "cmDependsJavaParser.y"
+#line 283 "cmDependsJavaParser.y"
{
jpElementStart(0);
}
-#line 2619 "cmDependsJavaParser.cxx"
+#line 2607 "cmDependsJavaParser.cxx"
break;
case 15: /* PrimitiveType: jp_INT_TYPE */
-#line 283 "cmDependsJavaParser.y"
+#line 288 "cmDependsJavaParser.y"
{
jpElementStart(0);
}
-#line 2627 "cmDependsJavaParser.cxx"
+#line 2615 "cmDependsJavaParser.cxx"
break;
case 16: /* PrimitiveType: jp_LONG_TYPE */
-#line 288 "cmDependsJavaParser.y"
+#line 293 "cmDependsJavaParser.y"
{
jpElementStart(0);
}
-#line 2635 "cmDependsJavaParser.cxx"
+#line 2623 "cmDependsJavaParser.cxx"
break;
case 17: /* PrimitiveType: jp_CHAR_TYPE */
-#line 293 "cmDependsJavaParser.y"
+#line 298 "cmDependsJavaParser.y"
{
jpElementStart(0);
}
-#line 2643 "cmDependsJavaParser.cxx"
+#line 2631 "cmDependsJavaParser.cxx"
break;
case 18: /* PrimitiveType: jp_FLOAT_TYPE */
-#line 298 "cmDependsJavaParser.y"
+#line 303 "cmDependsJavaParser.y"
{
jpElementStart(0);
}
-#line 2651 "cmDependsJavaParser.cxx"
+#line 2639 "cmDependsJavaParser.cxx"
break;
case 19: /* PrimitiveType: jp_DOUBLE_TYPE */
-#line 303 "cmDependsJavaParser.y"
+#line 308 "cmDependsJavaParser.y"
{
jpElementStart(0);
}
-#line 2659 "cmDependsJavaParser.cxx"
+#line 2647 "cmDependsJavaParser.cxx"
break;
case 20: /* PrimitiveType: jp_BOOLEAN_TYPE */
-#line 308 "cmDependsJavaParser.y"
+#line 313 "cmDependsJavaParser.y"
{
jpElementStart(0);
}
-#line 2667 "cmDependsJavaParser.cxx"
+#line 2655 "cmDependsJavaParser.cxx"
break;
case 21: /* ReferenceType: ClassOrInterfaceType */
-#line 314 "cmDependsJavaParser.y"
+#line 319 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2678 "cmDependsJavaParser.cxx"
+#line 2666 "cmDependsJavaParser.cxx"
break;
case 22: /* ReferenceType: ArrayType */
-#line 322 "cmDependsJavaParser.y"
+#line 327 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2689 "cmDependsJavaParser.cxx"
+#line 2677 "cmDependsJavaParser.cxx"
break;
case 23: /* ClassOrInterfaceType: Name */
-#line 331 "cmDependsJavaParser.y"
+#line 336 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpStoreClass((yyvsp[0].str));
@@ -2697,44 +2685,44 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2701 "cmDependsJavaParser.cxx"
+#line 2689 "cmDependsJavaParser.cxx"
break;
case 24: /* ClassType: ClassOrInterfaceType */
-#line 341 "cmDependsJavaParser.y"
+#line 346 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2712 "cmDependsJavaParser.cxx"
+#line 2700 "cmDependsJavaParser.cxx"
break;
case 25: /* InterfaceType: ClassOrInterfaceType */
-#line 350 "cmDependsJavaParser.y"
+#line 355 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2723 "cmDependsJavaParser.cxx"
+#line 2711 "cmDependsJavaParser.cxx"
break;
case 26: /* ArrayType: PrimitiveType Dims */
-#line 359 "cmDependsJavaParser.y"
+#line 364 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2734 "cmDependsJavaParser.cxx"
+#line 2722 "cmDependsJavaParser.cxx"
break;
case 27: /* ArrayType: Name Dims */
-#line 367 "cmDependsJavaParser.y"
+#line 372 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpStoreClass((yyvsp[-1].str));
@@ -2742,56 +2730,56 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2746 "cmDependsJavaParser.cxx"
+#line 2734 "cmDependsJavaParser.cxx"
break;
case 28: /* Name: SimpleName */
-#line 377 "cmDependsJavaParser.y"
+#line 382 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = (yyvsp[0].str);
}
-#line 2755 "cmDependsJavaParser.cxx"
+#line 2743 "cmDependsJavaParser.cxx"
break;
case 29: /* Name: QualifiedName */
-#line 383 "cmDependsJavaParser.y"
+#line 388 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = (yyvsp[0].str);
}
-#line 2764 "cmDependsJavaParser.cxx"
+#line 2752 "cmDependsJavaParser.cxx"
break;
case 30: /* SimpleName: Identifier */
-#line 390 "cmDependsJavaParser.y"
+#line 395 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = (yyvsp[0].str);
}
-#line 2773 "cmDependsJavaParser.cxx"
+#line 2761 "cmDependsJavaParser.cxx"
break;
case 31: /* Identifier: jp_NAME */
-#line 397 "cmDependsJavaParser.y"
+#line 402 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = (yyvsp[0].str);
}
-#line 2782 "cmDependsJavaParser.cxx"
+#line 2770 "cmDependsJavaParser.cxx"
break;
case 32: /* Identifier: jp_DOLLAR jp_NAME */
-#line 403 "cmDependsJavaParser.y"
+#line 408 "cmDependsJavaParser.y"
{
jpElementStart(2);
(yyval.str) = (yyvsp[0].str);
}
-#line 2791 "cmDependsJavaParser.cxx"
+#line 2779 "cmDependsJavaParser.cxx"
break;
case 33: /* QualifiedName: Name jp_DOT Identifier */
-#line 410 "cmDependsJavaParser.y"
+#line 415 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->AddClassFound((yyvsp[-2].str));
@@ -2799,11 +2787,11 @@ yyreduce:
yyGetParser->DeallocateParserType(&((yyvsp[-2].str)));
(yyval.str) = const_cast<char*>(yyGetParser->GetCurrentCombine());
}
-#line 2803 "cmDependsJavaParser.cxx"
+#line 2791 "cmDependsJavaParser.cxx"
break;
case 34: /* QualifiedName: Name jp_DOT jp_CLASS */
-#line 419 "cmDependsJavaParser.y"
+#line 424 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpStoreClass((yyvsp[-2].str));
@@ -2812,11 +2800,11 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2816 "cmDependsJavaParser.cxx"
+#line 2804 "cmDependsJavaParser.cxx"
break;
case 35: /* QualifiedName: Name jp_DOT jp_THIS */
-#line 429 "cmDependsJavaParser.y"
+#line 434 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpStoreClass((yyvsp[-2].str));
@@ -2825,118 +2813,118 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2829 "cmDependsJavaParser.cxx"
+#line 2817 "cmDependsJavaParser.cxx"
break;
case 36: /* QualifiedName: SimpleType jp_DOT jp_CLASS */
-#line 439 "cmDependsJavaParser.y"
+#line 444 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2840 "cmDependsJavaParser.cxx"
+#line 2828 "cmDependsJavaParser.cxx"
break;
case 37: /* SimpleType: PrimitiveType */
-#line 448 "cmDependsJavaParser.y"
+#line 453 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2851 "cmDependsJavaParser.cxx"
+#line 2839 "cmDependsJavaParser.cxx"
break;
case 38: /* SimpleType: jp_VOID */
-#line 456 "cmDependsJavaParser.y"
+#line 461 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2862 "cmDependsJavaParser.cxx"
+#line 2850 "cmDependsJavaParser.cxx"
break;
case 39: /* CompilationUnit: PackageDeclarationopt ImportDeclarations TypeDeclarations */
-#line 465 "cmDependsJavaParser.y"
+#line 470 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2873 "cmDependsJavaParser.cxx"
+#line 2861 "cmDependsJavaParser.cxx"
break;
case 40: /* PackageDeclarationopt: %empty */
-#line 473 "cmDependsJavaParser.y"
+#line 478 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2883 "cmDependsJavaParser.cxx"
+#line 2871 "cmDependsJavaParser.cxx"
break;
case 41: /* PackageDeclarationopt: PackageDeclaration */
-#line 480 "cmDependsJavaParser.y"
+#line 485 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2894 "cmDependsJavaParser.cxx"
+#line 2882 "cmDependsJavaParser.cxx"
break;
case 42: /* ImportDeclarations: %empty */
-#line 488 "cmDependsJavaParser.y"
+#line 493 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2904 "cmDependsJavaParser.cxx"
+#line 2892 "cmDependsJavaParser.cxx"
break;
case 43: /* ImportDeclarations: ImportDeclarations ImportDeclaration */
-#line 495 "cmDependsJavaParser.y"
+#line 500 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2915 "cmDependsJavaParser.cxx"
+#line 2903 "cmDependsJavaParser.cxx"
break;
case 44: /* TypeDeclarations: %empty */
-#line 503 "cmDependsJavaParser.y"
+#line 508 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2925 "cmDependsJavaParser.cxx"
+#line 2913 "cmDependsJavaParser.cxx"
break;
case 45: /* TypeDeclarations: TypeDeclarations TypeDeclaration */
-#line 510 "cmDependsJavaParser.y"
+#line 515 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2936 "cmDependsJavaParser.cxx"
+#line 2924 "cmDependsJavaParser.cxx"
break;
case 46: /* PackageDeclaration: jp_PACKAGE Name jp_SEMICOL */
-#line 519 "cmDependsJavaParser.y"
+#line 524 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->SetCurrentPackage((yyvsp[-1].str));
@@ -2946,33 +2934,33 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2950 "cmDependsJavaParser.cxx"
+#line 2938 "cmDependsJavaParser.cxx"
break;
case 47: /* ImportDeclaration: SingleTypeImportDeclaration */
-#line 531 "cmDependsJavaParser.y"
+#line 536 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2961 "cmDependsJavaParser.cxx"
+#line 2949 "cmDependsJavaParser.cxx"
break;
case 48: /* ImportDeclaration: TypeImportOnDemandDeclaration */
-#line 539 "cmDependsJavaParser.y"
+#line 544 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2972 "cmDependsJavaParser.cxx"
+#line 2960 "cmDependsJavaParser.cxx"
break;
case 49: /* SingleTypeImportDeclaration: jp_IMPORT Name jp_SEMICOL */
-#line 548 "cmDependsJavaParser.y"
+#line 553 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->AddPackagesImport((yyvsp[-1].str));
@@ -2982,11 +2970,11 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2986 "cmDependsJavaParser.cxx"
+#line 2974 "cmDependsJavaParser.cxx"
break;
case 50: /* TypeImportOnDemandDeclaration: jp_IMPORT Name jp_DOT jp_TIMES jp_SEMICOL */
-#line 560 "cmDependsJavaParser.y"
+#line 565 "cmDependsJavaParser.y"
{
jpElementStart(5);
std::string str = (yyvsp[-3].str);
@@ -2997,77 +2985,77 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3001 "cmDependsJavaParser.cxx"
+#line 2989 "cmDependsJavaParser.cxx"
break;
case 51: /* TypeDeclaration: ClassDeclaration */
-#line 573 "cmDependsJavaParser.y"
+#line 578 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3012 "cmDependsJavaParser.cxx"
+#line 3000 "cmDependsJavaParser.cxx"
break;
case 52: /* TypeDeclaration: InterfaceDeclaration */
-#line 581 "cmDependsJavaParser.y"
+#line 586 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3023 "cmDependsJavaParser.cxx"
+#line 3011 "cmDependsJavaParser.cxx"
break;
case 53: /* TypeDeclaration: jp_SEMICOL */
-#line 589 "cmDependsJavaParser.y"
+#line 594 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3034 "cmDependsJavaParser.cxx"
+#line 3022 "cmDependsJavaParser.cxx"
break;
case 54: /* Modifiers: Modifier */
-#line 598 "cmDependsJavaParser.y"
+#line 603 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3045 "cmDependsJavaParser.cxx"
+#line 3033 "cmDependsJavaParser.cxx"
break;
case 55: /* Modifiers: Modifiers Modifier */
-#line 606 "cmDependsJavaParser.y"
+#line 611 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3056 "cmDependsJavaParser.cxx"
+#line 3044 "cmDependsJavaParser.cxx"
break;
case 67: /* ClassHeader: Modifiersopt jp_CLASS Identifier */
-#line 621 "cmDependsJavaParser.y"
+#line 626 "cmDependsJavaParser.y"
{
yyGetParser->StartClass((yyvsp[0].str));
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
jpCheckEmpty(3);
}
-#line 3067 "cmDependsJavaParser.cxx"
+#line 3055 "cmDependsJavaParser.cxx"
break;
case 68: /* ClassDeclaration: ClassHeader ClassBody */
-#line 631 "cmDependsJavaParser.y"
+#line 636 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3075,11 +3063,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
yyGetParser->EndClass();
}
-#line 3079 "cmDependsJavaParser.cxx"
+#line 3067 "cmDependsJavaParser.cxx"
break;
case 69: /* ClassDeclaration: ClassHeader Interfaces ClassBody */
-#line 640 "cmDependsJavaParser.y"
+#line 645 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(2);
@@ -3087,11 +3075,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
yyGetParser->EndClass();
}
-#line 3091 "cmDependsJavaParser.cxx"
+#line 3079 "cmDependsJavaParser.cxx"
break;
case 70: /* ClassDeclaration: ClassHeader Super ClassBody */
-#line 649 "cmDependsJavaParser.y"
+#line 654 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3099,11 +3087,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
yyGetParser->EndClass();
}
-#line 3103 "cmDependsJavaParser.cxx"
+#line 3091 "cmDependsJavaParser.cxx"
break;
case 71: /* ClassDeclaration: ClassHeader Super Interfaces ClassBody */
-#line 658 "cmDependsJavaParser.y"
+#line 663 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -3111,226 +3099,226 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
yyGetParser->EndClass();
}
-#line 3115 "cmDependsJavaParser.cxx"
+#line 3103 "cmDependsJavaParser.cxx"
break;
case 72: /* Modifiersopt: %empty */
-#line 667 "cmDependsJavaParser.y"
+#line 672 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3125 "cmDependsJavaParser.cxx"
+#line 3113 "cmDependsJavaParser.cxx"
break;
case 73: /* Modifiersopt: Modifiers */
-#line 674 "cmDependsJavaParser.y"
+#line 679 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3136 "cmDependsJavaParser.cxx"
+#line 3124 "cmDependsJavaParser.cxx"
break;
case 74: /* Super: jp_EXTENDS ClassType */
-#line 683 "cmDependsJavaParser.y"
+#line 688 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3147 "cmDependsJavaParser.cxx"
+#line 3135 "cmDependsJavaParser.cxx"
break;
case 75: /* Interfaces: jp_IMPLEMENTS InterfaceTypeList */
-#line 692 "cmDependsJavaParser.y"
+#line 697 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3158 "cmDependsJavaParser.cxx"
+#line 3146 "cmDependsJavaParser.cxx"
break;
case 76: /* InterfaceTypeList: InterfaceType */
-#line 701 "cmDependsJavaParser.y"
+#line 706 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3169 "cmDependsJavaParser.cxx"
+#line 3157 "cmDependsJavaParser.cxx"
break;
case 77: /* InterfaceTypeList: InterfaceTypeList jp_COMMA InterfaceType */
-#line 709 "cmDependsJavaParser.y"
+#line 714 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3180 "cmDependsJavaParser.cxx"
+#line 3168 "cmDependsJavaParser.cxx"
break;
case 78: /* ClassBody: jp_CURLYSTART ClassBodyDeclarations jp_CURLYEND */
-#line 718 "cmDependsJavaParser.y"
+#line 723 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3191 "cmDependsJavaParser.cxx"
+#line 3179 "cmDependsJavaParser.cxx"
break;
case 79: /* ClassBodyDeclarations: %empty */
-#line 726 "cmDependsJavaParser.y"
+#line 731 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3201 "cmDependsJavaParser.cxx"
+#line 3189 "cmDependsJavaParser.cxx"
break;
case 80: /* ClassBodyDeclarations: ClassBodyDeclarations ClassBodyDeclaration */
-#line 733 "cmDependsJavaParser.y"
+#line 738 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3212 "cmDependsJavaParser.cxx"
+#line 3200 "cmDependsJavaParser.cxx"
break;
case 81: /* ClassBodyDeclaration: ClassMemberDeclaration */
-#line 742 "cmDependsJavaParser.y"
+#line 747 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3223 "cmDependsJavaParser.cxx"
+#line 3211 "cmDependsJavaParser.cxx"
break;
case 82: /* ClassBodyDeclaration: StaticInitializer */
-#line 750 "cmDependsJavaParser.y"
+#line 755 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3234 "cmDependsJavaParser.cxx"
+#line 3222 "cmDependsJavaParser.cxx"
break;
case 83: /* ClassBodyDeclaration: ConstructorDeclaration */
-#line 758 "cmDependsJavaParser.y"
+#line 763 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3245 "cmDependsJavaParser.cxx"
+#line 3233 "cmDependsJavaParser.cxx"
break;
case 84: /* ClassBodyDeclaration: TypeDeclaration */
-#line 766 "cmDependsJavaParser.y"
+#line 771 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3256 "cmDependsJavaParser.cxx"
+#line 3244 "cmDependsJavaParser.cxx"
break;
case 85: /* ClassMemberDeclaration: FieldDeclaration */
-#line 775 "cmDependsJavaParser.y"
+#line 780 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3267 "cmDependsJavaParser.cxx"
+#line 3255 "cmDependsJavaParser.cxx"
break;
case 86: /* ClassMemberDeclaration: MethodDeclaration */
-#line 783 "cmDependsJavaParser.y"
+#line 788 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3278 "cmDependsJavaParser.cxx"
+#line 3266 "cmDependsJavaParser.cxx"
break;
case 87: /* FieldDeclaration: Modifiersopt Type VariableDeclarators jp_SEMICOL */
-#line 792 "cmDependsJavaParser.y"
+#line 797 "cmDependsJavaParser.y"
{
jpElementStart(4);
}
-#line 3286 "cmDependsJavaParser.cxx"
+#line 3274 "cmDependsJavaParser.cxx"
break;
case 88: /* VariableDeclarators: VariableDeclarator */
-#line 798 "cmDependsJavaParser.y"
+#line 803 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3297 "cmDependsJavaParser.cxx"
+#line 3285 "cmDependsJavaParser.cxx"
break;
case 89: /* VariableDeclarators: VariableDeclarators jp_COMMA VariableDeclarator */
-#line 806 "cmDependsJavaParser.y"
+#line 811 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3308 "cmDependsJavaParser.cxx"
+#line 3296 "cmDependsJavaParser.cxx"
break;
case 90: /* VariableDeclarator: VariableDeclaratorId */
-#line 815 "cmDependsJavaParser.y"
+#line 820 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3319 "cmDependsJavaParser.cxx"
+#line 3307 "cmDependsJavaParser.cxx"
break;
case 91: /* VariableDeclarator: VariableDeclaratorId jp_EQUALS VariableInitializer */
-#line 823 "cmDependsJavaParser.y"
+#line 828 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3330 "cmDependsJavaParser.cxx"
+#line 3318 "cmDependsJavaParser.cxx"
break;
case 92: /* VariableDeclaratorId: Identifier */
-#line 832 "cmDependsJavaParser.y"
+#line 837 "cmDependsJavaParser.y"
{
jpElementStart(1);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -3338,77 +3326,77 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3342 "cmDependsJavaParser.cxx"
+#line 3330 "cmDependsJavaParser.cxx"
break;
case 93: /* VariableDeclaratorId: VariableDeclaratorId jp_BRACKETSTART jp_BRACKETEND */
-#line 841 "cmDependsJavaParser.y"
+#line 846 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3353 "cmDependsJavaParser.cxx"
+#line 3341 "cmDependsJavaParser.cxx"
break;
case 94: /* VariableInitializer: Expression */
-#line 850 "cmDependsJavaParser.y"
+#line 855 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3364 "cmDependsJavaParser.cxx"
+#line 3352 "cmDependsJavaParser.cxx"
break;
case 95: /* VariableInitializer: ArrayInitializer */
-#line 858 "cmDependsJavaParser.y"
+#line 863 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3375 "cmDependsJavaParser.cxx"
+#line 3363 "cmDependsJavaParser.cxx"
break;
case 96: /* MethodDeclaration: MethodHeader jp_SEMICOL */
-#line 867 "cmDependsJavaParser.y"
+#line 872 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3386 "cmDependsJavaParser.cxx"
+#line 3374 "cmDependsJavaParser.cxx"
break;
case 97: /* MethodDeclaration: MethodHeader MethodBody */
-#line 875 "cmDependsJavaParser.y"
+#line 880 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3397 "cmDependsJavaParser.cxx"
+#line 3385 "cmDependsJavaParser.cxx"
break;
case 98: /* MethodDeclaration: MethodHeader MethodBody jp_SEMICOL */
-#line 883 "cmDependsJavaParser.y"
+#line 888 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3408 "cmDependsJavaParser.cxx"
+#line 3396 "cmDependsJavaParser.cxx"
break;
case 99: /* MethodHeader: Modifiersopt Type MethodDeclarator Throwsopt */
-#line 892 "cmDependsJavaParser.y"
+#line 897 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -3416,11 +3404,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3420 "cmDependsJavaParser.cxx"
+#line 3408 "cmDependsJavaParser.cxx"
break;
case 100: /* MethodHeader: Modifiersopt jp_VOID MethodDeclarator Throwsopt */
-#line 901 "cmDependsJavaParser.y"
+#line 906 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -3428,22 +3416,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3432 "cmDependsJavaParser.cxx"
+#line 3420 "cmDependsJavaParser.cxx"
break;
case 101: /* Throwsopt: %empty */
-#line 910 "cmDependsJavaParser.y"
+#line 915 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3443 "cmDependsJavaParser.cxx"
+#line 3431 "cmDependsJavaParser.cxx"
break;
case 102: /* Throwsopt: Throws */
-#line 918 "cmDependsJavaParser.y"
+#line 923 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3451,11 +3439,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3455 "cmDependsJavaParser.cxx"
+#line 3443 "cmDependsJavaParser.cxx"
break;
case 103: /* MethodDeclarator: Identifier jp_PARESTART FormalParameterListopt jp_PAREEND */
-#line 928 "cmDependsJavaParser.y"
+#line 933 "cmDependsJavaParser.y"
{
jpElementStart(4);
yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -3464,40 +3452,40 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3468 "cmDependsJavaParser.cxx"
+#line 3456 "cmDependsJavaParser.cxx"
break;
case 104: /* MethodDeclarator: MethodDeclarator jp_BRACKETSTART jp_BRACKETEND */
-#line 938 "cmDependsJavaParser.y"
+#line 943 "cmDependsJavaParser.y"
{
jpElementStart(3);
}
-#line 3477 "cmDependsJavaParser.cxx"
+#line 3465 "cmDependsJavaParser.cxx"
break;
case 105: /* FormalParameterListopt: %empty */
-#line 944 "cmDependsJavaParser.y"
+#line 949 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3488 "cmDependsJavaParser.cxx"
+#line 3476 "cmDependsJavaParser.cxx"
break;
case 107: /* FormalParameterList: FormalParameter */
-#line 955 "cmDependsJavaParser.y"
+#line 960 "cmDependsJavaParser.y"
{
jpElementStart(1);
}
-#line 3497 "cmDependsJavaParser.cxx"
+#line 3485 "cmDependsJavaParser.cxx"
break;
case 108: /* FormalParameterList: FormalParameterList jp_COMMA FormalParameter */
-#line 961 "cmDependsJavaParser.y"
+#line 966 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3505,11 +3493,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3509 "cmDependsJavaParser.cxx"
+#line 3497 "cmDependsJavaParser.cxx"
break;
case 109: /* FormalParameter: Modifiersopt Type VariableDeclaratorId */
-#line 971 "cmDependsJavaParser.y"
+#line 976 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3517,11 +3505,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3521 "cmDependsJavaParser.cxx"
+#line 3509 "cmDependsJavaParser.cxx"
break;
case 110: /* Throws: jp_THROWS ClassTypeList */
-#line 981 "cmDependsJavaParser.y"
+#line 986 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3529,20 +3517,20 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3533 "cmDependsJavaParser.cxx"
+#line 3521 "cmDependsJavaParser.cxx"
break;
case 111: /* ClassTypeList: ClassType */
-#line 991 "cmDependsJavaParser.y"
+#line 996 "cmDependsJavaParser.y"
{
jpElementStart(1);
}
-#line 3542 "cmDependsJavaParser.cxx"
+#line 3530 "cmDependsJavaParser.cxx"
break;
case 112: /* ClassTypeList: ClassTypeList jp_COMMA ClassType */
-#line 997 "cmDependsJavaParser.y"
+#line 1002 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3550,11 +3538,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3554 "cmDependsJavaParser.cxx"
+#line 3542 "cmDependsJavaParser.cxx"
break;
case 113: /* MethodBody: Block */
-#line 1007 "cmDependsJavaParser.y"
+#line 1012 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3562,11 +3550,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3566 "cmDependsJavaParser.cxx"
+#line 3554 "cmDependsJavaParser.cxx"
break;
case 114: /* StaticInitializer: jp_STATIC Block */
-#line 1017 "cmDependsJavaParser.y"
+#line 1022 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3574,11 +3562,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3578 "cmDependsJavaParser.cxx"
+#line 3566 "cmDependsJavaParser.cxx"
break;
case 115: /* ConstructorDeclaration: Modifiersopt ConstructorDeclarator Throwsopt ConstructorBody */
-#line 1027 "cmDependsJavaParser.y"
+#line 1032 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -3586,11 +3574,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3590 "cmDependsJavaParser.cxx"
+#line 3578 "cmDependsJavaParser.cxx"
break;
case 116: /* ConstructorDeclaration: Modifiersopt ConstructorDeclarator Throwsopt ConstructorBody jp_SEMICOL */
-#line 1036 "cmDependsJavaParser.y"
+#line 1041 "cmDependsJavaParser.y"
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -3598,11 +3586,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3602 "cmDependsJavaParser.cxx"
+#line 3590 "cmDependsJavaParser.cxx"
break;
case 117: /* ConstructorDeclarator: SimpleName jp_PARESTART FormalParameterListopt jp_PAREEND */
-#line 1046 "cmDependsJavaParser.y"
+#line 1051 "cmDependsJavaParser.y"
{
jpElementStart(4);
yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -3611,11 +3599,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3615 "cmDependsJavaParser.cxx"
+#line 3603 "cmDependsJavaParser.cxx"
break;
case 118: /* ConstructorBody: jp_CURLYSTART ExplicitConstructorInvocationopt BlockStatementsopt jp_CURLYEND */
-#line 1057 "cmDependsJavaParser.y"
+#line 1062 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -3623,22 +3611,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3627 "cmDependsJavaParser.cxx"
+#line 3615 "cmDependsJavaParser.cxx"
break;
case 119: /* ExplicitConstructorInvocationopt: %empty */
-#line 1066 "cmDependsJavaParser.y"
+#line 1071 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3638 "cmDependsJavaParser.cxx"
+#line 3626 "cmDependsJavaParser.cxx"
break;
case 120: /* ExplicitConstructorInvocationopt: ExplicitConstructorInvocationopt ExplicitConstructorInvocation */
-#line 1074 "cmDependsJavaParser.y"
+#line 1079 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3646,11 +3634,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3650 "cmDependsJavaParser.cxx"
+#line 3638 "cmDependsJavaParser.cxx"
break;
case 121: /* ExplicitConstructorInvocation: jp_THIS jp_PARESTART ArgumentListopt jp_PAREEND jp_SEMICOL */
-#line 1084 "cmDependsJavaParser.y"
+#line 1089 "cmDependsJavaParser.y"
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -3658,11 +3646,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3662 "cmDependsJavaParser.cxx"
+#line 3650 "cmDependsJavaParser.cxx"
break;
case 122: /* ExplicitConstructorInvocation: jp_SUPER jp_PARESTART ArgumentListopt jp_PAREEND jp_SEMICOL */
-#line 1093 "cmDependsJavaParser.y"
+#line 1098 "cmDependsJavaParser.y"
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -3670,22 +3658,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3674 "cmDependsJavaParser.cxx"
+#line 3662 "cmDependsJavaParser.cxx"
break;
case 123: /* InterfaceHeader: Modifiersopt jp_INTERFACE Identifier */
-#line 1103 "cmDependsJavaParser.y"
+#line 1108 "cmDependsJavaParser.y"
{
yyGetParser->StartClass((yyvsp[0].str));
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
jpCheckEmpty(3);
}
-#line 3685 "cmDependsJavaParser.cxx"
+#line 3673 "cmDependsJavaParser.cxx"
break;
case 124: /* InterfaceDeclaration: InterfaceHeader ExtendsInterfacesopt InterfaceBody */
-#line 1112 "cmDependsJavaParser.y"
+#line 1117 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3693,21 +3681,21 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
yyGetParser->EndClass();
}
-#line 3697 "cmDependsJavaParser.cxx"
+#line 3685 "cmDependsJavaParser.cxx"
break;
case 125: /* ExtendsInterfacesopt: %empty */
-#line 1121 "cmDependsJavaParser.y"
+#line 1126 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3707 "cmDependsJavaParser.cxx"
+#line 3695 "cmDependsJavaParser.cxx"
break;
case 126: /* ExtendsInterfacesopt: ExtendsInterfaces */
-#line 1128 "cmDependsJavaParser.y"
+#line 1133 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3715,11 +3703,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3719 "cmDependsJavaParser.cxx"
+#line 3707 "cmDependsJavaParser.cxx"
break;
case 127: /* ExtendsInterfaces: jp_EXTENDS InterfaceType */
-#line 1138 "cmDependsJavaParser.y"
+#line 1143 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3727,11 +3715,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3731 "cmDependsJavaParser.cxx"
+#line 3719 "cmDependsJavaParser.cxx"
break;
case 128: /* ExtendsInterfaces: ExtendsInterfaces jp_COMMA InterfaceType */
-#line 1147 "cmDependsJavaParser.y"
+#line 1152 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3739,11 +3727,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3743 "cmDependsJavaParser.cxx"
+#line 3731 "cmDependsJavaParser.cxx"
break;
case 129: /* InterfaceBody: jp_CURLYSTART InterfaceMemberDeclarations jp_CURLYEND */
-#line 1157 "cmDependsJavaParser.y"
+#line 1162 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3751,33 +3739,33 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3755 "cmDependsJavaParser.cxx"
+#line 3743 "cmDependsJavaParser.cxx"
break;
case 130: /* InterfaceMemberDeclarations: %empty */
-#line 1166 "cmDependsJavaParser.y"
+#line 1171 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3766 "cmDependsJavaParser.cxx"
+#line 3754 "cmDependsJavaParser.cxx"
break;
case 131: /* InterfaceMemberDeclarations: InterfaceMemberDeclarations InterfaceMemberDeclaration */
-#line 1174 "cmDependsJavaParser.y"
+#line 1179 "cmDependsJavaParser.y"
{
jpElementStart(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3777 "cmDependsJavaParser.cxx"
+#line 3765 "cmDependsJavaParser.cxx"
break;
case 132: /* InterfaceMemberDeclaration: ConstantDeclaration */
-#line 1183 "cmDependsJavaParser.y"
+#line 1188 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3785,11 +3773,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3789 "cmDependsJavaParser.cxx"
+#line 3777 "cmDependsJavaParser.cxx"
break;
case 133: /* InterfaceMemberDeclaration: AbstractMethodDeclaration */
-#line 1192 "cmDependsJavaParser.y"
+#line 1197 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3797,11 +3785,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3801 "cmDependsJavaParser.cxx"
+#line 3789 "cmDependsJavaParser.cxx"
break;
case 134: /* InterfaceMemberDeclaration: ClassDeclaration */
-#line 1201 "cmDependsJavaParser.y"
+#line 1206 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3809,22 +3797,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3813 "cmDependsJavaParser.cxx"
+#line 3801 "cmDependsJavaParser.cxx"
break;
case 135: /* InterfaceMemberDeclaration: ClassDeclaration jp_SEMICOL */
-#line 1210 "cmDependsJavaParser.y"
+#line 1215 "cmDependsJavaParser.y"
{
jpElementStart(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3824 "cmDependsJavaParser.cxx"
+#line 3812 "cmDependsJavaParser.cxx"
break;
case 136: /* InterfaceMemberDeclaration: InterfaceDeclaration */
-#line 1218 "cmDependsJavaParser.y"
+#line 1223 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3832,22 +3820,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3836 "cmDependsJavaParser.cxx"
+#line 3824 "cmDependsJavaParser.cxx"
break;
case 137: /* InterfaceMemberDeclaration: InterfaceDeclaration jp_SEMICOL */
-#line 1227 "cmDependsJavaParser.y"
+#line 1232 "cmDependsJavaParser.y"
{
jpElementStart(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3847 "cmDependsJavaParser.cxx"
+#line 3835 "cmDependsJavaParser.cxx"
break;
case 138: /* ConstantDeclaration: FieldDeclaration */
-#line 1236 "cmDependsJavaParser.y"
+#line 1241 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3855,11 +3843,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3859 "cmDependsJavaParser.cxx"
+#line 3847 "cmDependsJavaParser.cxx"
break;
case 139: /* AbstractMethodDeclaration: MethodHeader Semicols */
-#line 1246 "cmDependsJavaParser.y"
+#line 1251 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3867,11 +3855,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3871 "cmDependsJavaParser.cxx"
+#line 3859 "cmDependsJavaParser.cxx"
break;
case 140: /* Semicols: jp_SEMICOL */
-#line 1256 "cmDependsJavaParser.y"
+#line 1261 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3879,11 +3867,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3883 "cmDependsJavaParser.cxx"
+#line 3871 "cmDependsJavaParser.cxx"
break;
case 141: /* Semicols: Semicols jp_SEMICOL */
-#line 1265 "cmDependsJavaParser.y"
+#line 1270 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3891,11 +3879,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3895 "cmDependsJavaParser.cxx"
+#line 3883 "cmDependsJavaParser.cxx"
break;
case 142: /* ArrayInitializer: jp_CURLYSTART VariableInitializersOptional jp_CURLYEND */
-#line 1275 "cmDependsJavaParser.y"
+#line 1280 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3903,22 +3891,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3907 "cmDependsJavaParser.cxx"
+#line 3895 "cmDependsJavaParser.cxx"
break;
case 143: /* VariableInitializersOptional: %empty */
-#line 1284 "cmDependsJavaParser.y"
+#line 1289 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3918 "cmDependsJavaParser.cxx"
+#line 3906 "cmDependsJavaParser.cxx"
break;
case 144: /* VariableInitializersOptional: VariableInitializers */
-#line 1292 "cmDependsJavaParser.y"
+#line 1297 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3926,11 +3914,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3930 "cmDependsJavaParser.cxx"
+#line 3918 "cmDependsJavaParser.cxx"
break;
case 145: /* VariableInitializersOptional: VariableInitializers jp_COMMA */
-#line 1301 "cmDependsJavaParser.y"
+#line 1306 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3938,11 +3926,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3942 "cmDependsJavaParser.cxx"
+#line 3930 "cmDependsJavaParser.cxx"
break;
case 146: /* VariableInitializers: VariableInitializer */
-#line 1311 "cmDependsJavaParser.y"
+#line 1316 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3950,11 +3938,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3954 "cmDependsJavaParser.cxx"
+#line 3942 "cmDependsJavaParser.cxx"
break;
case 147: /* VariableInitializers: VariableInitializers jp_COMMA VariableInitializer */
-#line 1320 "cmDependsJavaParser.y"
+#line 1325 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3962,33 +3950,33 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3966 "cmDependsJavaParser.cxx"
+#line 3954 "cmDependsJavaParser.cxx"
break;
case 148: /* Block: jp_CURLYSTART BlockStatementsopt jp_CURLYEND */
-#line 1330 "cmDependsJavaParser.y"
+#line 1335 "cmDependsJavaParser.y"
{
jpElementStart(4);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3977 "cmDependsJavaParser.cxx"
+#line 3965 "cmDependsJavaParser.cxx"
break;
case 149: /* BlockStatementsopt: %empty */
-#line 1338 "cmDependsJavaParser.y"
+#line 1343 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3988 "cmDependsJavaParser.cxx"
+#line 3976 "cmDependsJavaParser.cxx"
break;
case 150: /* BlockStatementsopt: BlockStatements */
-#line 1346 "cmDependsJavaParser.y"
+#line 1351 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3996,11 +3984,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4000 "cmDependsJavaParser.cxx"
+#line 3988 "cmDependsJavaParser.cxx"
break;
case 151: /* BlockStatements: BlockStatement */
-#line 1356 "cmDependsJavaParser.y"
+#line 1361 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4008,11 +3996,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4012 "cmDependsJavaParser.cxx"
+#line 4000 "cmDependsJavaParser.cxx"
break;
case 152: /* BlockStatements: BlockStatements BlockStatement */
-#line 1365 "cmDependsJavaParser.y"
+#line 1370 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(2);
@@ -4020,11 +4008,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4024 "cmDependsJavaParser.cxx"
+#line 4012 "cmDependsJavaParser.cxx"
break;
case 153: /* BlockStatement: LocalVariableDeclarationStatement */
-#line 1375 "cmDependsJavaParser.y"
+#line 1380 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4032,11 +4020,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4036 "cmDependsJavaParser.cxx"
+#line 4024 "cmDependsJavaParser.cxx"
break;
case 154: /* BlockStatement: Statement */
-#line 1384 "cmDependsJavaParser.y"
+#line 1389 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4044,11 +4032,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4048 "cmDependsJavaParser.cxx"
+#line 4036 "cmDependsJavaParser.cxx"
break;
case 155: /* BlockStatement: ClassDeclaration */
-#line 1393 "cmDependsJavaParser.y"
+#line 1398 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4056,11 +4044,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4060 "cmDependsJavaParser.cxx"
+#line 4048 "cmDependsJavaParser.cxx"
break;
case 156: /* LocalVariableDeclarationStatement: LocalVariableDeclaration jp_SEMICOL */
-#line 1403 "cmDependsJavaParser.y"
+#line 1408 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(2);
@@ -4068,11 +4056,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4072 "cmDependsJavaParser.cxx"
+#line 4060 "cmDependsJavaParser.cxx"
break;
case 157: /* LocalVariableDeclaration: Modifiers Type VariableDeclarators */
-#line 1413 "cmDependsJavaParser.y"
+#line 1418 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(3);
@@ -4080,11 +4068,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4084 "cmDependsJavaParser.cxx"
+#line 4072 "cmDependsJavaParser.cxx"
break;
case 158: /* LocalVariableDeclaration: Type VariableDeclarators */
-#line 1422 "cmDependsJavaParser.y"
+#line 1427 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(2);
@@ -4092,11 +4080,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4096 "cmDependsJavaParser.cxx"
+#line 4084 "cmDependsJavaParser.cxx"
break;
case 159: /* Statement: StatementWithoutTrailingSubstatement */
-#line 1432 "cmDependsJavaParser.y"
+#line 1437 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4104,11 +4092,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4108 "cmDependsJavaParser.cxx"
+#line 4096 "cmDependsJavaParser.cxx"
break;
case 160: /* Statement: LabeledStatement */
-#line 1441 "cmDependsJavaParser.y"
+#line 1446 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4116,11 +4104,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4120 "cmDependsJavaParser.cxx"
+#line 4108 "cmDependsJavaParser.cxx"
break;
case 161: /* Statement: IfThenStatement */
-#line 1450 "cmDependsJavaParser.y"
+#line 1455 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4128,11 +4116,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4132 "cmDependsJavaParser.cxx"
+#line 4120 "cmDependsJavaParser.cxx"
break;
case 162: /* Statement: IfThenElseStatement */
-#line 1459 "cmDependsJavaParser.y"
+#line 1464 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4140,11 +4128,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4144 "cmDependsJavaParser.cxx"
+#line 4132 "cmDependsJavaParser.cxx"
break;
case 163: /* Statement: WhileStatement */
-#line 1468 "cmDependsJavaParser.y"
+#line 1473 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4152,11 +4140,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4156 "cmDependsJavaParser.cxx"
+#line 4144 "cmDependsJavaParser.cxx"
break;
case 164: /* Statement: ForStatement */
-#line 1477 "cmDependsJavaParser.y"
+#line 1482 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4164,11 +4152,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4168 "cmDependsJavaParser.cxx"
+#line 4156 "cmDependsJavaParser.cxx"
break;
case 165: /* StatementNoShortIf: StatementWithoutTrailingSubstatement */
-#line 1487 "cmDependsJavaParser.y"
+#line 1492 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4176,11 +4164,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4180 "cmDependsJavaParser.cxx"
+#line 4168 "cmDependsJavaParser.cxx"
break;
case 166: /* StatementNoShortIf: LabeledStatementNoShortIf */
-#line 1496 "cmDependsJavaParser.y"
+#line 1501 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4188,11 +4176,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4192 "cmDependsJavaParser.cxx"
+#line 4180 "cmDependsJavaParser.cxx"
break;
case 167: /* StatementNoShortIf: IfThenElseStatementNoShortIf */
-#line 1505 "cmDependsJavaParser.y"
+#line 1510 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4200,11 +4188,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4204 "cmDependsJavaParser.cxx"
+#line 4192 "cmDependsJavaParser.cxx"
break;
case 168: /* StatementNoShortIf: WhileStatementNoShortIf */
-#line 1514 "cmDependsJavaParser.y"
+#line 1519 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4212,11 +4200,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4216 "cmDependsJavaParser.cxx"
+#line 4204 "cmDependsJavaParser.cxx"
break;
case 169: /* StatementNoShortIf: ForStatementNoShortIf */
-#line 1523 "cmDependsJavaParser.y"
+#line 1528 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4224,11 +4212,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4228 "cmDependsJavaParser.cxx"
+#line 4216 "cmDependsJavaParser.cxx"
break;
case 170: /* StatementWithoutTrailingSubstatement: Block */
-#line 1533 "cmDependsJavaParser.y"
+#line 1538 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4236,11 +4224,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4240 "cmDependsJavaParser.cxx"
+#line 4228 "cmDependsJavaParser.cxx"
break;
case 171: /* StatementWithoutTrailingSubstatement: EmptyStatement */
-#line 1542 "cmDependsJavaParser.y"
+#line 1547 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4248,11 +4236,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4252 "cmDependsJavaParser.cxx"
+#line 4240 "cmDependsJavaParser.cxx"
break;
case 172: /* StatementWithoutTrailingSubstatement: ExpressionStatement */
-#line 1551 "cmDependsJavaParser.y"
+#line 1556 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4260,11 +4248,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4264 "cmDependsJavaParser.cxx"
+#line 4252 "cmDependsJavaParser.cxx"
break;
case 173: /* StatementWithoutTrailingSubstatement: SwitchStatement */
-#line 1560 "cmDependsJavaParser.y"
+#line 1565 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4272,11 +4260,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4276 "cmDependsJavaParser.cxx"
+#line 4264 "cmDependsJavaParser.cxx"
break;
case 174: /* StatementWithoutTrailingSubstatement: DoStatement */
-#line 1569 "cmDependsJavaParser.y"
+#line 1574 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4284,11 +4272,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4288 "cmDependsJavaParser.cxx"
+#line 4276 "cmDependsJavaParser.cxx"
break;
case 175: /* StatementWithoutTrailingSubstatement: BreakStatement */
-#line 1578 "cmDependsJavaParser.y"
+#line 1583 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4296,11 +4284,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4300 "cmDependsJavaParser.cxx"
+#line 4288 "cmDependsJavaParser.cxx"
break;
case 176: /* StatementWithoutTrailingSubstatement: ContinueStatement */
-#line 1587 "cmDependsJavaParser.y"
+#line 1592 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4308,11 +4296,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4312 "cmDependsJavaParser.cxx"
+#line 4300 "cmDependsJavaParser.cxx"
break;
case 177: /* StatementWithoutTrailingSubstatement: ReturnStatement */
-#line 1596 "cmDependsJavaParser.y"
+#line 1601 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4320,11 +4308,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4324 "cmDependsJavaParser.cxx"
+#line 4312 "cmDependsJavaParser.cxx"
break;
case 178: /* StatementWithoutTrailingSubstatement: SynchronizedStatement */
-#line 1605 "cmDependsJavaParser.y"
+#line 1610 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4332,11 +4320,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4336 "cmDependsJavaParser.cxx"
+#line 4324 "cmDependsJavaParser.cxx"
break;
case 179: /* StatementWithoutTrailingSubstatement: ThrowStatement */
-#line 1614 "cmDependsJavaParser.y"
+#line 1619 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4344,11 +4332,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4348 "cmDependsJavaParser.cxx"
+#line 4336 "cmDependsJavaParser.cxx"
break;
case 180: /* StatementWithoutTrailingSubstatement: TryStatement */
-#line 1623 "cmDependsJavaParser.y"
+#line 1628 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4356,11 +4344,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4360 "cmDependsJavaParser.cxx"
+#line 4348 "cmDependsJavaParser.cxx"
break;
case 181: /* StatementWithoutTrailingSubstatement: AssertStatement */
-#line 1632 "cmDependsJavaParser.y"
+#line 1637 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4368,11 +4356,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4372 "cmDependsJavaParser.cxx"
+#line 4360 "cmDependsJavaParser.cxx"
break;
case 182: /* EmptyStatement: jp_SEMICOL */
-#line 1642 "cmDependsJavaParser.y"
+#line 1647 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4380,11 +4368,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4384 "cmDependsJavaParser.cxx"
+#line 4372 "cmDependsJavaParser.cxx"
break;
case 183: /* LabeledStatement: Identifier jp_COLON Statement */
-#line 1652 "cmDependsJavaParser.y"
+#line 1657 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[-2].str)));
@@ -4393,11 +4381,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4397 "cmDependsJavaParser.cxx"
+#line 4385 "cmDependsJavaParser.cxx"
break;
case 184: /* LabeledStatementNoShortIf: Identifier jp_COLON StatementNoShortIf */
-#line 1663 "cmDependsJavaParser.y"
+#line 1668 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4405,11 +4393,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4409 "cmDependsJavaParser.cxx"
+#line 4397 "cmDependsJavaParser.cxx"
break;
case 185: /* ExpressionStatement: StatementExpression jp_SEMICOL */
-#line 1673 "cmDependsJavaParser.y"
+#line 1678 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -4417,11 +4405,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4421 "cmDependsJavaParser.cxx"
+#line 4409 "cmDependsJavaParser.cxx"
break;
case 186: /* StatementExpression: Assignment */
-#line 1683 "cmDependsJavaParser.y"
+#line 1688 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4429,11 +4417,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4433 "cmDependsJavaParser.cxx"
+#line 4421 "cmDependsJavaParser.cxx"
break;
case 187: /* StatementExpression: PreIncrementExpression */
-#line 1692 "cmDependsJavaParser.y"
+#line 1697 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4441,11 +4429,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4445 "cmDependsJavaParser.cxx"
+#line 4433 "cmDependsJavaParser.cxx"
break;
case 188: /* StatementExpression: PreDecrementExpression */
-#line 1701 "cmDependsJavaParser.y"
+#line 1706 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4453,11 +4441,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4457 "cmDependsJavaParser.cxx"
+#line 4445 "cmDependsJavaParser.cxx"
break;
case 189: /* StatementExpression: PostIncrementExpression */
-#line 1710 "cmDependsJavaParser.y"
+#line 1715 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4465,11 +4453,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4469 "cmDependsJavaParser.cxx"
+#line 4457 "cmDependsJavaParser.cxx"
break;
case 190: /* StatementExpression: PostDecrementExpression */
-#line 1719 "cmDependsJavaParser.y"
+#line 1724 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4477,11 +4465,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4481 "cmDependsJavaParser.cxx"
+#line 4469 "cmDependsJavaParser.cxx"
break;
case 191: /* StatementExpression: MethodInvocation */
-#line 1728 "cmDependsJavaParser.y"
+#line 1733 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4489,11 +4477,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4493 "cmDependsJavaParser.cxx"
+#line 4481 "cmDependsJavaParser.cxx"
break;
case 192: /* StatementExpression: ClassInstanceCreationExpression */
-#line 1737 "cmDependsJavaParser.y"
+#line 1742 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4501,11 +4489,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4505 "cmDependsJavaParser.cxx"
+#line 4493 "cmDependsJavaParser.cxx"
break;
case 193: /* IfThenStatement: jp_IF jp_PARESTART Expression jp_PAREEND Statement */
-#line 1747 "cmDependsJavaParser.y"
+#line 1752 "cmDependsJavaParser.y"
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -4513,11 +4501,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4517 "cmDependsJavaParser.cxx"
+#line 4505 "cmDependsJavaParser.cxx"
break;
case 194: /* IfThenElseStatement: jp_IF jp_PARESTART Expression jp_PAREEND StatementNoShortIf jp_ELSE Statement */
-#line 1757 "cmDependsJavaParser.y"
+#line 1762 "cmDependsJavaParser.y"
{
jpElementStart(7);
jpCheckEmpty(7);
@@ -4525,11 +4513,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4529 "cmDependsJavaParser.cxx"
+#line 4517 "cmDependsJavaParser.cxx"
break;
case 195: /* IfThenElseStatementNoShortIf: jp_IF jp_PARESTART Expression jp_PAREEND StatementNoShortIf jp_ELSE StatementNoShortIf */
-#line 1767 "cmDependsJavaParser.y"
+#line 1772 "cmDependsJavaParser.y"
{
jpElementStart(7);
jpCheckEmpty(7);
@@ -4537,40 +4525,40 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4541 "cmDependsJavaParser.cxx"
+#line 4529 "cmDependsJavaParser.cxx"
break;
case 196: /* SwitchStatement: jp_SWITCH jp_PARESTART Expression jp_PAREEND SwitchBlock */
-#line 1777 "cmDependsJavaParser.y"
+#line 1782 "cmDependsJavaParser.y"
{
jpElementStart(5);
}
-#line 4550 "cmDependsJavaParser.cxx"
+#line 4538 "cmDependsJavaParser.cxx"
break;
case 197: /* SwitchBlock: jp_CURLYSTART SwitchBlockStatementGroups SwitchLabelsopt jp_CURLYEND */
-#line 1784 "cmDependsJavaParser.y"
+#line 1789 "cmDependsJavaParser.y"
{
jpElementStart(4);
}
-#line 4559 "cmDependsJavaParser.cxx"
+#line 4547 "cmDependsJavaParser.cxx"
break;
case 198: /* SwitchLabelsopt: %empty */
-#line 1790 "cmDependsJavaParser.y"
+#line 1795 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4570 "cmDependsJavaParser.cxx"
+#line 4558 "cmDependsJavaParser.cxx"
break;
case 199: /* SwitchLabelsopt: SwitchLabels */
-#line 1798 "cmDependsJavaParser.y"
+#line 1803 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4578,22 +4566,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4582 "cmDependsJavaParser.cxx"
+#line 4570 "cmDependsJavaParser.cxx"
break;
case 200: /* SwitchBlockStatementGroups: %empty */
-#line 1807 "cmDependsJavaParser.y"
+#line 1812 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4593 "cmDependsJavaParser.cxx"
+#line 4581 "cmDependsJavaParser.cxx"
break;
case 201: /* SwitchBlockStatementGroups: SwitchBlockStatementGroups SwitchBlockStatementGroup */
-#line 1815 "cmDependsJavaParser.y"
+#line 1820 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -4601,11 +4589,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4605 "cmDependsJavaParser.cxx"
+#line 4593 "cmDependsJavaParser.cxx"
break;
case 202: /* SwitchBlockStatementGroup: SwitchLabels BlockStatements */
-#line 1825 "cmDependsJavaParser.y"
+#line 1830 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -4613,11 +4601,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4617 "cmDependsJavaParser.cxx"
+#line 4605 "cmDependsJavaParser.cxx"
break;
case 203: /* SwitchLabels: SwitchLabel */
-#line 1835 "cmDependsJavaParser.y"
+#line 1840 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4625,11 +4613,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4629 "cmDependsJavaParser.cxx"
+#line 4617 "cmDependsJavaParser.cxx"
break;
case 204: /* SwitchLabels: SwitchLabels SwitchLabel */
-#line 1844 "cmDependsJavaParser.y"
+#line 1849 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -4637,11 +4625,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4641 "cmDependsJavaParser.cxx"
+#line 4629 "cmDependsJavaParser.cxx"
break;
case 205: /* SwitchLabel: jp_CASE ConstantExpression jp_COLON */
-#line 1854 "cmDependsJavaParser.y"
+#line 1859 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4649,11 +4637,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4653 "cmDependsJavaParser.cxx"
+#line 4641 "cmDependsJavaParser.cxx"
break;
case 206: /* SwitchLabel: jp_DEFAULT jp_COLON */
-#line 1863 "cmDependsJavaParser.y"
+#line 1868 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -4661,58 +4649,58 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4665 "cmDependsJavaParser.cxx"
+#line 4653 "cmDependsJavaParser.cxx"
break;
case 207: /* WhileStatement: jp_WHILE jp_PARESTART Expression jp_PAREEND Statement */
-#line 1873 "cmDependsJavaParser.y"
+#line 1878 "cmDependsJavaParser.y"
{
jpElementStart(5);
}
-#line 4674 "cmDependsJavaParser.cxx"
+#line 4662 "cmDependsJavaParser.cxx"
break;
case 208: /* WhileStatementNoShortIf: jp_WHILE jp_PARESTART Expression jp_PAREEND StatementNoShortIf */
-#line 1880 "cmDependsJavaParser.y"
+#line 1885 "cmDependsJavaParser.y"
{
jpElementStart(5);
}
-#line 4683 "cmDependsJavaParser.cxx"
+#line 4671 "cmDependsJavaParser.cxx"
break;
case 209: /* DoStatement: jp_DO Statement jp_WHILE jp_PARESTART Expression jp_PAREEND jp_SEMICOL */
-#line 1887 "cmDependsJavaParser.y"
+#line 1892 "cmDependsJavaParser.y"
{
jpElementStart(7);
}
-#line 4692 "cmDependsJavaParser.cxx"
+#line 4680 "cmDependsJavaParser.cxx"
break;
case 210: /* ForStatement: jp_FOR jp_PARESTART ForInitopt jp_SEMICOL Expressionopt jp_SEMICOL ForUpdateopt jp_PAREEND Statement */
-#line 1895 "cmDependsJavaParser.y"
+#line 1900 "cmDependsJavaParser.y"
{
jpElementStart(9);
}
-#line 4701 "cmDependsJavaParser.cxx"
+#line 4689 "cmDependsJavaParser.cxx"
break;
case 211: /* ForUpdateopt: %empty */
-#line 1901 "cmDependsJavaParser.y"
+#line 1906 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4712 "cmDependsJavaParser.cxx"
+#line 4700 "cmDependsJavaParser.cxx"
break;
case 212: /* ForUpdateopt: ForUpdate */
-#line 1909 "cmDependsJavaParser.y"
+#line 1914 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4720,22 +4708,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4724 "cmDependsJavaParser.cxx"
+#line 4712 "cmDependsJavaParser.cxx"
break;
case 213: /* ForInitopt: %empty */
-#line 1918 "cmDependsJavaParser.y"
+#line 1923 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4735 "cmDependsJavaParser.cxx"
+#line 4723 "cmDependsJavaParser.cxx"
break;
case 214: /* ForInitopt: ForInit */
-#line 1926 "cmDependsJavaParser.y"
+#line 1931 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4743,33 +4731,33 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4747 "cmDependsJavaParser.cxx"
+#line 4735 "cmDependsJavaParser.cxx"
break;
case 215: /* ForStatementNoShortIf: jp_FOR jp_PARESTART ForInitopt jp_SEMICOL Expressionopt jp_SEMICOL ForUpdateopt jp_PAREEND StatementNoShortIf */
-#line 1937 "cmDependsJavaParser.y"
+#line 1942 "cmDependsJavaParser.y"
{
jpElementStart(9);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4758 "cmDependsJavaParser.cxx"
+#line 4746 "cmDependsJavaParser.cxx"
break;
case 216: /* Expressionopt: %empty */
-#line 1945 "cmDependsJavaParser.y"
+#line 1950 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4769 "cmDependsJavaParser.cxx"
+#line 4757 "cmDependsJavaParser.cxx"
break;
case 217: /* Expressionopt: Expression */
-#line 1953 "cmDependsJavaParser.y"
+#line 1958 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4777,11 +4765,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4781 "cmDependsJavaParser.cxx"
+#line 4769 "cmDependsJavaParser.cxx"
break;
case 218: /* ForInit: StatementExpressionList */
-#line 1963 "cmDependsJavaParser.y"
+#line 1968 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4789,11 +4777,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4793 "cmDependsJavaParser.cxx"
+#line 4781 "cmDependsJavaParser.cxx"
break;
case 219: /* ForInit: LocalVariableDeclaration */
-#line 1972 "cmDependsJavaParser.y"
+#line 1977 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4801,11 +4789,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4805 "cmDependsJavaParser.cxx"
+#line 4793 "cmDependsJavaParser.cxx"
break;
case 220: /* ForUpdate: StatementExpressionList */
-#line 1982 "cmDependsJavaParser.y"
+#line 1987 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4813,11 +4801,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4817 "cmDependsJavaParser.cxx"
+#line 4805 "cmDependsJavaParser.cxx"
break;
case 221: /* StatementExpressionList: StatementExpression */
-#line 1992 "cmDependsJavaParser.y"
+#line 1997 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4825,11 +4813,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4829 "cmDependsJavaParser.cxx"
+#line 4817 "cmDependsJavaParser.cxx"
break;
case 222: /* StatementExpressionList: StatementExpressionList jp_COMMA StatementExpression */
-#line 2001 "cmDependsJavaParser.y"
+#line 2006 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4837,11 +4825,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4841 "cmDependsJavaParser.cxx"
+#line 4829 "cmDependsJavaParser.cxx"
break;
case 223: /* AssertStatement: jp_ASSERT Expression jp_SEMICOL */
-#line 2011 "cmDependsJavaParser.y"
+#line 2016 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4849,11 +4837,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4853 "cmDependsJavaParser.cxx"
+#line 4841 "cmDependsJavaParser.cxx"
break;
case 224: /* AssertStatement: jp_ASSERT Expression jp_COLON Expression jp_SEMICOL */
-#line 2020 "cmDependsJavaParser.y"
+#line 2025 "cmDependsJavaParser.y"
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -4861,11 +4849,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4865 "cmDependsJavaParser.cxx"
+#line 4853 "cmDependsJavaParser.cxx"
break;
case 225: /* BreakStatement: jp_BREAK Identifieropt jp_SEMICOL */
-#line 2030 "cmDependsJavaParser.y"
+#line 2035 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[-1].str)));
@@ -4874,31 +4862,31 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4878 "cmDependsJavaParser.cxx"
+#line 4866 "cmDependsJavaParser.cxx"
break;
case 226: /* Identifieropt: %empty */
-#line 2040 "cmDependsJavaParser.y"
+#line 2045 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4889 "cmDependsJavaParser.cxx"
+#line 4877 "cmDependsJavaParser.cxx"
break;
case 227: /* Identifieropt: Identifier */
-#line 2048 "cmDependsJavaParser.y"
+#line 2053 "cmDependsJavaParser.y"
{
jpElementStart(1);
}
-#line 4898 "cmDependsJavaParser.cxx"
+#line 4886 "cmDependsJavaParser.cxx"
break;
case 228: /* ContinueStatement: jp_CONTINUE Identifieropt jp_SEMICOL */
-#line 2055 "cmDependsJavaParser.y"
+#line 2060 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[-1].str)));
@@ -4907,11 +4895,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4911 "cmDependsJavaParser.cxx"
+#line 4899 "cmDependsJavaParser.cxx"
break;
case 229: /* ReturnStatement: jp_RETURN Expressionopt jp_SEMICOL */
-#line 2066 "cmDependsJavaParser.y"
+#line 2071 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4919,11 +4907,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4923 "cmDependsJavaParser.cxx"
+#line 4911 "cmDependsJavaParser.cxx"
break;
case 230: /* ThrowStatement: jp_THROW Expression jp_SEMICOL */
-#line 2076 "cmDependsJavaParser.y"
+#line 2081 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4931,11 +4919,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4935 "cmDependsJavaParser.cxx"
+#line 4923 "cmDependsJavaParser.cxx"
break;
case 231: /* SynchronizedStatement: jp_SYNCHRONIZED jp_PARESTART Expression jp_PAREEND Block */
-#line 2086 "cmDependsJavaParser.y"
+#line 2091 "cmDependsJavaParser.y"
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -4943,11 +4931,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4947 "cmDependsJavaParser.cxx"
+#line 4935 "cmDependsJavaParser.cxx"
break;
case 232: /* TryStatement: jp_TRY Block Catches */
-#line 2096 "cmDependsJavaParser.y"
+#line 2101 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4955,11 +4943,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4959 "cmDependsJavaParser.cxx"
+#line 4947 "cmDependsJavaParser.cxx"
break;
case 233: /* TryStatement: jp_TRY Block Catchesopt Finally */
-#line 2105 "cmDependsJavaParser.y"
+#line 2110 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -4967,22 +4955,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4971 "cmDependsJavaParser.cxx"
+#line 4959 "cmDependsJavaParser.cxx"
break;
case 234: /* Catchesopt: %empty */
-#line 2114 "cmDependsJavaParser.y"
+#line 2119 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4982 "cmDependsJavaParser.cxx"
+#line 4970 "cmDependsJavaParser.cxx"
break;
case 235: /* Catchesopt: Catches */
-#line 2122 "cmDependsJavaParser.y"
+#line 2127 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4990,11 +4978,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4994 "cmDependsJavaParser.cxx"
+#line 4982 "cmDependsJavaParser.cxx"
break;
case 236: /* Catches: CatchClause */
-#line 2132 "cmDependsJavaParser.y"
+#line 2137 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5002,11 +4990,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5006 "cmDependsJavaParser.cxx"
+#line 4994 "cmDependsJavaParser.cxx"
break;
case 237: /* Catches: Catches CatchClause */
-#line 2141 "cmDependsJavaParser.y"
+#line 2146 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5014,20 +5002,20 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5018 "cmDependsJavaParser.cxx"
+#line 5006 "cmDependsJavaParser.cxx"
break;
case 238: /* CatchClause: jp_CATCH jp_PARESTART FormalParameter jp_PAREEND Block */
-#line 2151 "cmDependsJavaParser.y"
+#line 2156 "cmDependsJavaParser.y"
{
jpElementStart(5);
}
-#line 5027 "cmDependsJavaParser.cxx"
+#line 5015 "cmDependsJavaParser.cxx"
break;
case 239: /* Finally: jp_FINALLY Block */
-#line 2158 "cmDependsJavaParser.y"
+#line 2163 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5035,11 +5023,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5039 "cmDependsJavaParser.cxx"
+#line 5027 "cmDependsJavaParser.cxx"
break;
case 240: /* Primary: PrimaryNoNewArray */
-#line 2168 "cmDependsJavaParser.y"
+#line 2173 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5047,11 +5035,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5051 "cmDependsJavaParser.cxx"
+#line 5039 "cmDependsJavaParser.cxx"
break;
case 241: /* Primary: ArrayCreationExpression */
-#line 2177 "cmDependsJavaParser.y"
+#line 2182 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5059,11 +5047,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5063 "cmDependsJavaParser.cxx"
+#line 5051 "cmDependsJavaParser.cxx"
break;
case 242: /* PrimaryNoNewArray: Literal */
-#line 2187 "cmDependsJavaParser.y"
+#line 2192 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5071,20 +5059,20 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5075 "cmDependsJavaParser.cxx"
+#line 5063 "cmDependsJavaParser.cxx"
break;
case 243: /* PrimaryNoNewArray: jp_THIS */
-#line 2196 "cmDependsJavaParser.y"
+#line 2201 "cmDependsJavaParser.y"
{
jpElementStart(1);
}
-#line 5084 "cmDependsJavaParser.cxx"
+#line 5072 "cmDependsJavaParser.cxx"
break;
case 244: /* PrimaryNoNewArray: jp_PARESTART Expression jp_PAREEND */
-#line 2202 "cmDependsJavaParser.y"
+#line 2207 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5092,11 +5080,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5096 "cmDependsJavaParser.cxx"
+#line 5084 "cmDependsJavaParser.cxx"
break;
case 245: /* PrimaryNoNewArray: ClassInstanceCreationExpression */
-#line 2211 "cmDependsJavaParser.y"
+#line 2216 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5104,11 +5092,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5108 "cmDependsJavaParser.cxx"
+#line 5096 "cmDependsJavaParser.cxx"
break;
case 246: /* PrimaryNoNewArray: FieldAccess */
-#line 2220 "cmDependsJavaParser.y"
+#line 2225 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5116,11 +5104,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5120 "cmDependsJavaParser.cxx"
+#line 5108 "cmDependsJavaParser.cxx"
break;
case 247: /* PrimaryNoNewArray: MethodInvocation */
-#line 2229 "cmDependsJavaParser.y"
+#line 2234 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5128,11 +5116,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5132 "cmDependsJavaParser.cxx"
+#line 5120 "cmDependsJavaParser.cxx"
break;
case 248: /* PrimaryNoNewArray: ArrayAccess */
-#line 2238 "cmDependsJavaParser.y"
+#line 2243 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5140,11 +5128,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5144 "cmDependsJavaParser.cxx"
+#line 5132 "cmDependsJavaParser.cxx"
break;
case 249: /* ClassInstanceCreationExpression: New ClassType jp_PARESTART ArgumentListopt jp_PAREEND ClassBodyOpt */
-#line 2248 "cmDependsJavaParser.y"
+#line 2253 "cmDependsJavaParser.y"
{
jpElementStart(6);
jpCheckEmpty(6);
@@ -5152,22 +5140,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5156 "cmDependsJavaParser.cxx"
+#line 5144 "cmDependsJavaParser.cxx"
break;
case 250: /* ClassBodyOpt: %empty */
-#line 2257 "cmDependsJavaParser.y"
+#line 2262 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 5167 "cmDependsJavaParser.cxx"
+#line 5155 "cmDependsJavaParser.cxx"
break;
case 251: /* ClassBodyOpt: ClassBody */
-#line 2265 "cmDependsJavaParser.y"
+#line 2270 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5175,22 +5163,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5179 "cmDependsJavaParser.cxx"
+#line 5167 "cmDependsJavaParser.cxx"
break;
case 252: /* ArgumentListopt: %empty */
-#line 2274 "cmDependsJavaParser.y"
+#line 2279 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 5190 "cmDependsJavaParser.cxx"
+#line 5178 "cmDependsJavaParser.cxx"
break;
case 253: /* ArgumentListopt: ArgumentList */
-#line 2282 "cmDependsJavaParser.y"
+#line 2287 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5198,11 +5186,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5202 "cmDependsJavaParser.cxx"
+#line 5190 "cmDependsJavaParser.cxx"
break;
case 254: /* ArgumentList: Expression */
-#line 2292 "cmDependsJavaParser.y"
+#line 2297 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5210,11 +5198,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5214 "cmDependsJavaParser.cxx"
+#line 5202 "cmDependsJavaParser.cxx"
break;
case 255: /* ArgumentList: ArgumentList jp_COMMA Expression */
-#line 2301 "cmDependsJavaParser.y"
+#line 2306 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5222,11 +5210,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5226 "cmDependsJavaParser.cxx"
+#line 5214 "cmDependsJavaParser.cxx"
break;
case 256: /* ArrayCreationExpression: New PrimitiveType DimExprs Dimsopt */
-#line 2311 "cmDependsJavaParser.y"
+#line 2316 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -5234,11 +5222,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5238 "cmDependsJavaParser.cxx"
+#line 5226 "cmDependsJavaParser.cxx"
break;
case 257: /* ArrayCreationExpression: New ClassOrInterfaceType DimExprs Dimsopt */
-#line 2320 "cmDependsJavaParser.y"
+#line 2325 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -5246,11 +5234,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5250 "cmDependsJavaParser.cxx"
+#line 5238 "cmDependsJavaParser.cxx"
break;
case 258: /* ArrayCreationExpression: New PrimitiveType Dims ArrayInitializer */
-#line 2329 "cmDependsJavaParser.y"
+#line 2334 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -5258,11 +5246,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5262 "cmDependsJavaParser.cxx"
+#line 5250 "cmDependsJavaParser.cxx"
break;
case 259: /* ArrayCreationExpression: New ClassOrInterfaceType Dims ArrayInitializer */
-#line 2338 "cmDependsJavaParser.y"
+#line 2343 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -5270,22 +5258,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5274 "cmDependsJavaParser.cxx"
+#line 5262 "cmDependsJavaParser.cxx"
break;
case 260: /* Dimsopt: %empty */
-#line 2347 "cmDependsJavaParser.y"
+#line 2352 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 5285 "cmDependsJavaParser.cxx"
+#line 5273 "cmDependsJavaParser.cxx"
break;
case 261: /* Dimsopt: Dims */
-#line 2355 "cmDependsJavaParser.y"
+#line 2360 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5293,11 +5281,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5297 "cmDependsJavaParser.cxx"
+#line 5285 "cmDependsJavaParser.cxx"
break;
case 262: /* DimExprs: DimExpr */
-#line 2365 "cmDependsJavaParser.y"
+#line 2370 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5305,11 +5293,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5309 "cmDependsJavaParser.cxx"
+#line 5297 "cmDependsJavaParser.cxx"
break;
case 263: /* DimExprs: DimExprs DimExpr */
-#line 2374 "cmDependsJavaParser.y"
+#line 2379 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5317,11 +5305,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5321 "cmDependsJavaParser.cxx"
+#line 5309 "cmDependsJavaParser.cxx"
break;
case 264: /* DimExpr: jp_BRACKETSTART Expression jp_BRACKETEND */
-#line 2384 "cmDependsJavaParser.y"
+#line 2389 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5329,29 +5317,29 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5333 "cmDependsJavaParser.cxx"
+#line 5321 "cmDependsJavaParser.cxx"
break;
case 265: /* Dims: jp_BRACKETSTART jp_BRACKETEND */
-#line 2394 "cmDependsJavaParser.y"
+#line 2399 "cmDependsJavaParser.y"
{
jpElementStart(2);
}
-#line 5342 "cmDependsJavaParser.cxx"
+#line 5330 "cmDependsJavaParser.cxx"
break;
case 266: /* Dims: Dims jp_BRACKETSTART jp_BRACKETEND */
-#line 2400 "cmDependsJavaParser.y"
+#line 2405 "cmDependsJavaParser.y"
{
jpElementStart(3);
}
-#line 5351 "cmDependsJavaParser.cxx"
+#line 5339 "cmDependsJavaParser.cxx"
break;
case 267: /* FieldAccess: Primary jp_DOT Identifier */
-#line 2407 "cmDependsJavaParser.y"
+#line 2412 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5360,11 +5348,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5364 "cmDependsJavaParser.cxx"
+#line 5352 "cmDependsJavaParser.cxx"
break;
case 268: /* FieldAccess: jp_SUPER jp_DOT Identifier */
-#line 2417 "cmDependsJavaParser.y"
+#line 2422 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5373,11 +5361,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5377 "cmDependsJavaParser.cxx"
+#line 5365 "cmDependsJavaParser.cxx"
break;
case 269: /* FieldAccess: jp_THIS jp_DOT Identifier */
-#line 2427 "cmDependsJavaParser.y"
+#line 2432 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5386,11 +5374,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5390 "cmDependsJavaParser.cxx"
+#line 5378 "cmDependsJavaParser.cxx"
break;
case 270: /* FieldAccess: Primary jp_DOT jp_THIS */
-#line 2437 "cmDependsJavaParser.y"
+#line 2442 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5399,11 +5387,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5403 "cmDependsJavaParser.cxx"
+#line 5391 "cmDependsJavaParser.cxx"
break;
case 271: /* MethodInvocation: Name jp_PARESTART ArgumentListopt jp_PAREEND */
-#line 2448 "cmDependsJavaParser.y"
+#line 2453 "cmDependsJavaParser.y"
{
jpElementStart(4);
yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -5412,11 +5400,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5416 "cmDependsJavaParser.cxx"
+#line 5404 "cmDependsJavaParser.cxx"
break;
case 272: /* MethodInvocation: Primary jp_DOT Identifier jp_PARESTART ArgumentListopt jp_PAREEND */
-#line 2458 "cmDependsJavaParser.y"
+#line 2463 "cmDependsJavaParser.y"
{
jpElementStart(6);
yyGetParser->DeallocateParserType(&((yyvsp[-5].str)));
@@ -5426,11 +5414,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5430 "cmDependsJavaParser.cxx"
+#line 5418 "cmDependsJavaParser.cxx"
break;
case 273: /* MethodInvocation: jp_SUPER jp_DOT Identifier jp_PARESTART ArgumentListopt jp_PAREEND */
-#line 2469 "cmDependsJavaParser.y"
+#line 2474 "cmDependsJavaParser.y"
{
jpElementStart(6);
yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -5439,11 +5427,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5443 "cmDependsJavaParser.cxx"
+#line 5431 "cmDependsJavaParser.cxx"
break;
case 274: /* MethodInvocation: jp_THIS jp_DOT Identifier jp_PARESTART ArgumentListopt jp_PAREEND */
-#line 2479 "cmDependsJavaParser.y"
+#line 2484 "cmDependsJavaParser.y"
{
jpElementStart(6);
yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -5452,11 +5440,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5456 "cmDependsJavaParser.cxx"
+#line 5444 "cmDependsJavaParser.cxx"
break;
case 275: /* ArrayAccess: Name jp_BRACKETSTART Expression jp_BRACKETEND */
-#line 2490 "cmDependsJavaParser.y"
+#line 2495 "cmDependsJavaParser.y"
{
jpElementStart(4);
yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -5465,11 +5453,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5469 "cmDependsJavaParser.cxx"
+#line 5457 "cmDependsJavaParser.cxx"
break;
case 276: /* ArrayAccess: PrimaryNoNewArray jp_BRACKETSTART Expression jp_BRACKETEND */
-#line 2500 "cmDependsJavaParser.y"
+#line 2505 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -5477,11 +5465,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5481 "cmDependsJavaParser.cxx"
+#line 5469 "cmDependsJavaParser.cxx"
break;
case 277: /* PostfixExpression: Primary */
-#line 2510 "cmDependsJavaParser.y"
+#line 2515 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5489,11 +5477,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5493 "cmDependsJavaParser.cxx"
+#line 5481 "cmDependsJavaParser.cxx"
break;
case 278: /* PostfixExpression: Name */
-#line 2519 "cmDependsJavaParser.y"
+#line 2524 "cmDependsJavaParser.y"
{
jpElementStart(1);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5501,11 +5489,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5505 "cmDependsJavaParser.cxx"
+#line 5493 "cmDependsJavaParser.cxx"
break;
case 279: /* PostfixExpression: ArrayType jp_DOT jp_CLASS */
-#line 2528 "cmDependsJavaParser.y"
+#line 2533 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5513,11 +5501,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5517 "cmDependsJavaParser.cxx"
+#line 5505 "cmDependsJavaParser.cxx"
break;
case 280: /* PostfixExpression: PostIncrementExpression */
-#line 2537 "cmDependsJavaParser.y"
+#line 2542 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5525,11 +5513,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5529 "cmDependsJavaParser.cxx"
+#line 5517 "cmDependsJavaParser.cxx"
break;
case 281: /* PostfixExpression: PostDecrementExpression */
-#line 2546 "cmDependsJavaParser.y"
+#line 2551 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5537,11 +5525,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5541 "cmDependsJavaParser.cxx"
+#line 5529 "cmDependsJavaParser.cxx"
break;
case 282: /* PostIncrementExpression: PostfixExpression jp_PLUSPLUS */
-#line 2556 "cmDependsJavaParser.y"
+#line 2561 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5549,11 +5537,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5553 "cmDependsJavaParser.cxx"
+#line 5541 "cmDependsJavaParser.cxx"
break;
case 283: /* PostDecrementExpression: PostfixExpression jp_MINUSMINUS */
-#line 2566 "cmDependsJavaParser.y"
+#line 2571 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5561,11 +5549,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5565 "cmDependsJavaParser.cxx"
+#line 5553 "cmDependsJavaParser.cxx"
break;
case 284: /* UnaryExpression: PreIncrementExpression */
-#line 2576 "cmDependsJavaParser.y"
+#line 2581 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5573,11 +5561,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5577 "cmDependsJavaParser.cxx"
+#line 5565 "cmDependsJavaParser.cxx"
break;
case 285: /* UnaryExpression: PreDecrementExpression */
-#line 2585 "cmDependsJavaParser.y"
+#line 2590 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5585,11 +5573,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5589 "cmDependsJavaParser.cxx"
+#line 5577 "cmDependsJavaParser.cxx"
break;
case 286: /* UnaryExpression: jp_PLUS UnaryExpression */
-#line 2594 "cmDependsJavaParser.y"
+#line 2599 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5597,11 +5585,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5601 "cmDependsJavaParser.cxx"
+#line 5589 "cmDependsJavaParser.cxx"
break;
case 287: /* UnaryExpression: jp_MINUS UnaryExpression */
-#line 2603 "cmDependsJavaParser.y"
+#line 2608 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5609,11 +5597,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5613 "cmDependsJavaParser.cxx"
+#line 5601 "cmDependsJavaParser.cxx"
break;
case 288: /* UnaryExpression: UnaryExpressionNotPlusMinus */
-#line 2612 "cmDependsJavaParser.y"
+#line 2617 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5621,11 +5609,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5625 "cmDependsJavaParser.cxx"
+#line 5613 "cmDependsJavaParser.cxx"
break;
case 289: /* PreIncrementExpression: jp_PLUSPLUS UnaryExpression */
-#line 2622 "cmDependsJavaParser.y"
+#line 2627 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5633,11 +5621,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5637 "cmDependsJavaParser.cxx"
+#line 5625 "cmDependsJavaParser.cxx"
break;
case 290: /* PreDecrementExpression: jp_MINUSMINUS UnaryExpression */
-#line 2632 "cmDependsJavaParser.y"
+#line 2637 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5645,11 +5633,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5649 "cmDependsJavaParser.cxx"
+#line 5637 "cmDependsJavaParser.cxx"
break;
case 291: /* UnaryExpressionNotPlusMinus: PostfixExpression */
-#line 2642 "cmDependsJavaParser.y"
+#line 2647 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5657,11 +5645,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5661 "cmDependsJavaParser.cxx"
+#line 5649 "cmDependsJavaParser.cxx"
break;
case 292: /* UnaryExpressionNotPlusMinus: jp_TILDE UnaryExpression */
-#line 2651 "cmDependsJavaParser.y"
+#line 2656 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5669,11 +5657,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5673 "cmDependsJavaParser.cxx"
+#line 5661 "cmDependsJavaParser.cxx"
break;
case 293: /* UnaryExpressionNotPlusMinus: jp_EXCLAMATION UnaryExpression */
-#line 2660 "cmDependsJavaParser.y"
+#line 2665 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5681,11 +5669,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5685 "cmDependsJavaParser.cxx"
+#line 5673 "cmDependsJavaParser.cxx"
break;
case 294: /* UnaryExpressionNotPlusMinus: CastExpression */
-#line 2669 "cmDependsJavaParser.y"
+#line 2674 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5693,11 +5681,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5697 "cmDependsJavaParser.cxx"
+#line 5685 "cmDependsJavaParser.cxx"
break;
case 295: /* CastExpression: jp_PARESTART PrimitiveType Dimsopt jp_PAREEND UnaryExpression */
-#line 2679 "cmDependsJavaParser.y"
+#line 2684 "cmDependsJavaParser.y"
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -5705,11 +5693,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5709 "cmDependsJavaParser.cxx"
+#line 5697 "cmDependsJavaParser.cxx"
break;
case 296: /* CastExpression: jp_PARESTART Expression jp_PAREEND UnaryExpressionNotPlusMinus */
-#line 2688 "cmDependsJavaParser.y"
+#line 2693 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -5717,20 +5705,20 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5721 "cmDependsJavaParser.cxx"
+#line 5709 "cmDependsJavaParser.cxx"
break;
case 297: /* CastExpression: jp_PARESTART Name Dims jp_PAREEND UnaryExpressionNotPlusMinus */
-#line 2697 "cmDependsJavaParser.y"
+#line 2702 "cmDependsJavaParser.y"
{
jpElementStart(5);
}
-#line 5730 "cmDependsJavaParser.cxx"
+#line 5718 "cmDependsJavaParser.cxx"
break;
case 298: /* MultiplicativeExpression: UnaryExpression */
-#line 2704 "cmDependsJavaParser.y"
+#line 2709 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5738,11 +5726,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5742 "cmDependsJavaParser.cxx"
+#line 5730 "cmDependsJavaParser.cxx"
break;
case 299: /* MultiplicativeExpression: MultiplicativeExpression jp_TIMES UnaryExpression */
-#line 2713 "cmDependsJavaParser.y"
+#line 2718 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5750,11 +5738,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5754 "cmDependsJavaParser.cxx"
+#line 5742 "cmDependsJavaParser.cxx"
break;
case 300: /* MultiplicativeExpression: MultiplicativeExpression jp_DIVIDE UnaryExpression */
-#line 2722 "cmDependsJavaParser.y"
+#line 2727 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5762,11 +5750,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5766 "cmDependsJavaParser.cxx"
+#line 5754 "cmDependsJavaParser.cxx"
break;
case 301: /* MultiplicativeExpression: MultiplicativeExpression jp_PERCENT UnaryExpression */
-#line 2731 "cmDependsJavaParser.y"
+#line 2736 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5774,11 +5762,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5778 "cmDependsJavaParser.cxx"
+#line 5766 "cmDependsJavaParser.cxx"
break;
case 302: /* AdditiveExpression: MultiplicativeExpression */
-#line 2741 "cmDependsJavaParser.y"
+#line 2746 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5786,11 +5774,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5790 "cmDependsJavaParser.cxx"
+#line 5778 "cmDependsJavaParser.cxx"
break;
case 303: /* AdditiveExpression: AdditiveExpression jp_PLUS MultiplicativeExpression */
-#line 2750 "cmDependsJavaParser.y"
+#line 2755 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5798,11 +5786,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5802 "cmDependsJavaParser.cxx"
+#line 5790 "cmDependsJavaParser.cxx"
break;
case 304: /* AdditiveExpression: AdditiveExpression jp_MINUS MultiplicativeExpression */
-#line 2759 "cmDependsJavaParser.y"
+#line 2764 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5810,11 +5798,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5814 "cmDependsJavaParser.cxx"
+#line 5802 "cmDependsJavaParser.cxx"
break;
case 305: /* ShiftExpression: AdditiveExpression */
-#line 2769 "cmDependsJavaParser.y"
+#line 2774 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5822,11 +5810,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5826 "cmDependsJavaParser.cxx"
+#line 5814 "cmDependsJavaParser.cxx"
break;
case 306: /* ShiftExpression: ShiftExpression jp_LTLT AdditiveExpression */
-#line 2778 "cmDependsJavaParser.y"
+#line 2783 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5834,11 +5822,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5838 "cmDependsJavaParser.cxx"
+#line 5826 "cmDependsJavaParser.cxx"
break;
case 307: /* ShiftExpression: ShiftExpression jp_GTGT AdditiveExpression */
-#line 2787 "cmDependsJavaParser.y"
+#line 2792 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5846,11 +5834,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5850 "cmDependsJavaParser.cxx"
+#line 5838 "cmDependsJavaParser.cxx"
break;
case 308: /* ShiftExpression: ShiftExpression jp_GTGTGT AdditiveExpression */
-#line 2796 "cmDependsJavaParser.y"
+#line 2801 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5858,11 +5846,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5862 "cmDependsJavaParser.cxx"
+#line 5850 "cmDependsJavaParser.cxx"
break;
case 309: /* RelationalExpression: ShiftExpression */
-#line 2806 "cmDependsJavaParser.y"
+#line 2811 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5870,11 +5858,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5874 "cmDependsJavaParser.cxx"
+#line 5862 "cmDependsJavaParser.cxx"
break;
case 310: /* RelationalExpression: RelationalExpression jp_LESSTHAN ShiftExpression */
-#line 2815 "cmDependsJavaParser.y"
+#line 2820 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5882,11 +5870,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5886 "cmDependsJavaParser.cxx"
+#line 5874 "cmDependsJavaParser.cxx"
break;
case 311: /* RelationalExpression: RelationalExpression jp_GREATER ShiftExpression */
-#line 2824 "cmDependsJavaParser.y"
+#line 2829 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5894,11 +5882,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5898 "cmDependsJavaParser.cxx"
+#line 5886 "cmDependsJavaParser.cxx"
break;
case 312: /* RelationalExpression: RelationalExpression jp_LTEQUALS ShiftExpression */
-#line 2833 "cmDependsJavaParser.y"
+#line 2838 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5906,11 +5894,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5910 "cmDependsJavaParser.cxx"
+#line 5898 "cmDependsJavaParser.cxx"
break;
case 313: /* RelationalExpression: RelationalExpression jp_GTEQUALS ShiftExpression */
-#line 2842 "cmDependsJavaParser.y"
+#line 2847 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5918,11 +5906,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5922 "cmDependsJavaParser.cxx"
+#line 5910 "cmDependsJavaParser.cxx"
break;
case 314: /* RelationalExpression: RelationalExpression jp_INSTANCEOF ReferenceType */
-#line 2851 "cmDependsJavaParser.y"
+#line 2856 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5930,11 +5918,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5934 "cmDependsJavaParser.cxx"
+#line 5922 "cmDependsJavaParser.cxx"
break;
case 315: /* EqualityExpression: RelationalExpression */
-#line 2861 "cmDependsJavaParser.y"
+#line 2866 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5942,11 +5930,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5946 "cmDependsJavaParser.cxx"
+#line 5934 "cmDependsJavaParser.cxx"
break;
case 316: /* EqualityExpression: EqualityExpression jp_EQUALSEQUALS RelationalExpression */
-#line 2870 "cmDependsJavaParser.y"
+#line 2875 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5954,11 +5942,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5958 "cmDependsJavaParser.cxx"
+#line 5946 "cmDependsJavaParser.cxx"
break;
case 317: /* EqualityExpression: EqualityExpression jp_EXCLAMATIONEQUALS RelationalExpression */
-#line 2879 "cmDependsJavaParser.y"
+#line 2884 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5966,11 +5954,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5970 "cmDependsJavaParser.cxx"
+#line 5958 "cmDependsJavaParser.cxx"
break;
case 318: /* AndExpression: EqualityExpression */
-#line 2889 "cmDependsJavaParser.y"
+#line 2894 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5978,11 +5966,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5982 "cmDependsJavaParser.cxx"
+#line 5970 "cmDependsJavaParser.cxx"
break;
case 319: /* AndExpression: AndExpression jp_AND EqualityExpression */
-#line 2898 "cmDependsJavaParser.y"
+#line 2903 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5990,11 +5978,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5994 "cmDependsJavaParser.cxx"
+#line 5982 "cmDependsJavaParser.cxx"
break;
case 320: /* ExclusiveOrExpression: AndExpression */
-#line 2908 "cmDependsJavaParser.y"
+#line 2913 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6002,11 +5990,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6006 "cmDependsJavaParser.cxx"
+#line 5994 "cmDependsJavaParser.cxx"
break;
case 321: /* ExclusiveOrExpression: ExclusiveOrExpression jp_CARROT AndExpression */
-#line 2917 "cmDependsJavaParser.y"
+#line 2922 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -6014,11 +6002,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6018 "cmDependsJavaParser.cxx"
+#line 6006 "cmDependsJavaParser.cxx"
break;
case 322: /* InclusiveOrExpression: ExclusiveOrExpression */
-#line 2927 "cmDependsJavaParser.y"
+#line 2932 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6026,11 +6014,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6030 "cmDependsJavaParser.cxx"
+#line 6018 "cmDependsJavaParser.cxx"
break;
case 323: /* InclusiveOrExpression: InclusiveOrExpression jp_PIPE ExclusiveOrExpression */
-#line 2936 "cmDependsJavaParser.y"
+#line 2941 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -6038,11 +6026,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6042 "cmDependsJavaParser.cxx"
+#line 6030 "cmDependsJavaParser.cxx"
break;
case 324: /* ConditionalAndExpression: InclusiveOrExpression */
-#line 2946 "cmDependsJavaParser.y"
+#line 2951 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6050,11 +6038,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6054 "cmDependsJavaParser.cxx"
+#line 6042 "cmDependsJavaParser.cxx"
break;
case 325: /* ConditionalAndExpression: ConditionalAndExpression jp_ANDAND InclusiveOrExpression */
-#line 2955 "cmDependsJavaParser.y"
+#line 2960 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -6062,11 +6050,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6066 "cmDependsJavaParser.cxx"
+#line 6054 "cmDependsJavaParser.cxx"
break;
case 326: /* ConditionalOrExpression: ConditionalAndExpression */
-#line 2965 "cmDependsJavaParser.y"
+#line 2970 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6074,11 +6062,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6078 "cmDependsJavaParser.cxx"
+#line 6066 "cmDependsJavaParser.cxx"
break;
case 327: /* ConditionalOrExpression: ConditionalOrExpression jp_PIPEPIPE ConditionalAndExpression */
-#line 2974 "cmDependsJavaParser.y"
+#line 2979 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -6086,11 +6074,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6090 "cmDependsJavaParser.cxx"
+#line 6078 "cmDependsJavaParser.cxx"
break;
case 328: /* ConditionalExpression: ConditionalOrExpression */
-#line 2984 "cmDependsJavaParser.y"
+#line 2989 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6098,11 +6086,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6102 "cmDependsJavaParser.cxx"
+#line 6090 "cmDependsJavaParser.cxx"
break;
case 329: /* ConditionalExpression: ConditionalOrExpression jp_QUESTION Expression jp_COLON ConditionalExpression */
-#line 2993 "cmDependsJavaParser.y"
+#line 2998 "cmDependsJavaParser.y"
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -6110,11 +6098,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6114 "cmDependsJavaParser.cxx"
+#line 6102 "cmDependsJavaParser.cxx"
break;
case 330: /* AssignmentExpression: ConditionalExpression */
-#line 3003 "cmDependsJavaParser.y"
+#line 3008 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6122,11 +6110,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6126 "cmDependsJavaParser.cxx"
+#line 6114 "cmDependsJavaParser.cxx"
break;
case 331: /* AssignmentExpression: Assignment */
-#line 3012 "cmDependsJavaParser.y"
+#line 3017 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6134,11 +6122,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6138 "cmDependsJavaParser.cxx"
+#line 6126 "cmDependsJavaParser.cxx"
break;
case 332: /* Assignment: LeftHandSide AssignmentOperator AssignmentExpression */
-#line 3022 "cmDependsJavaParser.y"
+#line 3027 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -6146,11 +6134,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6150 "cmDependsJavaParser.cxx"
+#line 6138 "cmDependsJavaParser.cxx"
break;
case 333: /* LeftHandSide: Name */
-#line 3032 "cmDependsJavaParser.y"
+#line 3037 "cmDependsJavaParser.y"
{
jpElementStart(1);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -6159,11 +6147,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6163 "cmDependsJavaParser.cxx"
+#line 6151 "cmDependsJavaParser.cxx"
break;
case 334: /* LeftHandSide: FieldAccess */
-#line 3042 "cmDependsJavaParser.y"
+#line 3047 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6171,11 +6159,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6175 "cmDependsJavaParser.cxx"
+#line 6163 "cmDependsJavaParser.cxx"
break;
case 335: /* LeftHandSide: ArrayAccess */
-#line 3051 "cmDependsJavaParser.y"
+#line 3056 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6183,11 +6171,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6187 "cmDependsJavaParser.cxx"
+#line 6175 "cmDependsJavaParser.cxx"
break;
case 336: /* AssignmentOperator: jp_EQUALS */
-#line 3061 "cmDependsJavaParser.y"
+#line 3066 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6195,11 +6183,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6199 "cmDependsJavaParser.cxx"
+#line 6187 "cmDependsJavaParser.cxx"
break;
case 337: /* AssignmentOperator: jp_TIMESEQUALS */
-#line 3070 "cmDependsJavaParser.y"
+#line 3075 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6207,11 +6195,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6211 "cmDependsJavaParser.cxx"
+#line 6199 "cmDependsJavaParser.cxx"
break;
case 338: /* AssignmentOperator: jp_DIVIDEEQUALS */
-#line 3079 "cmDependsJavaParser.y"
+#line 3084 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6219,11 +6207,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6223 "cmDependsJavaParser.cxx"
+#line 6211 "cmDependsJavaParser.cxx"
break;
case 339: /* AssignmentOperator: jp_PERCENTEQUALS */
-#line 3088 "cmDependsJavaParser.y"
+#line 3093 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6231,11 +6219,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6235 "cmDependsJavaParser.cxx"
+#line 6223 "cmDependsJavaParser.cxx"
break;
case 340: /* AssignmentOperator: jp_PLUSEQUALS */
-#line 3097 "cmDependsJavaParser.y"
+#line 3102 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6243,11 +6231,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6247 "cmDependsJavaParser.cxx"
+#line 6235 "cmDependsJavaParser.cxx"
break;
case 341: /* AssignmentOperator: jp_MINUSEQUALS */
-#line 3106 "cmDependsJavaParser.y"
+#line 3111 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6255,11 +6243,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6259 "cmDependsJavaParser.cxx"
+#line 6247 "cmDependsJavaParser.cxx"
break;
case 342: /* AssignmentOperator: jp_LESLESEQUALS */
-#line 3115 "cmDependsJavaParser.y"
+#line 3120 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6267,11 +6255,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6271 "cmDependsJavaParser.cxx"
+#line 6259 "cmDependsJavaParser.cxx"
break;
case 343: /* AssignmentOperator: jp_GTGTEQUALS */
-#line 3124 "cmDependsJavaParser.y"
+#line 3129 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6279,11 +6267,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6283 "cmDependsJavaParser.cxx"
+#line 6271 "cmDependsJavaParser.cxx"
break;
case 344: /* AssignmentOperator: jp_GTGTGTEQUALS */
-#line 3133 "cmDependsJavaParser.y"
+#line 3138 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6291,11 +6279,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6295 "cmDependsJavaParser.cxx"
+#line 6283 "cmDependsJavaParser.cxx"
break;
case 345: /* AssignmentOperator: jp_ANDEQUALS */
-#line 3142 "cmDependsJavaParser.y"
+#line 3147 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6303,11 +6291,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6307 "cmDependsJavaParser.cxx"
+#line 6295 "cmDependsJavaParser.cxx"
break;
case 346: /* AssignmentOperator: jp_CARROTEQUALS */
-#line 3151 "cmDependsJavaParser.y"
+#line 3156 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6315,11 +6303,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6319 "cmDependsJavaParser.cxx"
+#line 6307 "cmDependsJavaParser.cxx"
break;
case 347: /* AssignmentOperator: jp_PIPEEQUALS */
-#line 3160 "cmDependsJavaParser.y"
+#line 3165 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6327,11 +6315,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6331 "cmDependsJavaParser.cxx"
+#line 6319 "cmDependsJavaParser.cxx"
break;
case 348: /* Expression: AssignmentExpression */
-#line 3170 "cmDependsJavaParser.y"
+#line 3175 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6339,11 +6327,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6343 "cmDependsJavaParser.cxx"
+#line 6331 "cmDependsJavaParser.cxx"
break;
case 349: /* ConstantExpression: Expression */
-#line 3180 "cmDependsJavaParser.y"
+#line 3185 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6351,11 +6339,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6355 "cmDependsJavaParser.cxx"
+#line 6343 "cmDependsJavaParser.cxx"
break;
case 350: /* New: jp_NEW */
-#line 3190 "cmDependsJavaParser.y"
+#line 3195 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6363,11 +6351,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6367 "cmDependsJavaParser.cxx"
+#line 6355 "cmDependsJavaParser.cxx"
break;
case 351: /* New: Name jp_DOT jp_NEW */
-#line 3199 "cmDependsJavaParser.y"
+#line 3204 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpStoreClass((yyvsp[-2].str));
@@ -6376,11 +6364,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6380 "cmDependsJavaParser.cxx"
+#line 6368 "cmDependsJavaParser.cxx"
break;
-#line 6384 "cmDependsJavaParser.cxx"
+#line 6372 "cmDependsJavaParser.cxx"
default: break;
}
@@ -6456,7 +6444,7 @@ yyerrlab:
}
yyerror (yyscanner, yymsgp);
if (yysyntax_error_status == YYENOMEM)
- goto yyexhaustedlab;
+ YYNOMEM;
}
}
@@ -6492,6 +6480,7 @@ yyerrorlab:
label yyerrorlab therefore never appears in user code. */
if (0)
YYERROR;
+ ++yynerrs;
/* Do not reclaim the symbols of the rule whose action triggered
this YYERROR. */
@@ -6552,7 +6541,7 @@ yyerrlab1:
`-------------------------------------*/
yyacceptlab:
yyresult = 0;
- goto yyreturn;
+ goto yyreturnlab;
/*-----------------------------------.
@@ -6560,24 +6549,22 @@ yyacceptlab:
`-----------------------------------*/
yyabortlab:
yyresult = 1;
- goto yyreturn;
+ goto yyreturnlab;
-#if 1
-/*-------------------------------------------------.
-| yyexhaustedlab -- memory exhaustion comes here. |
-`-------------------------------------------------*/
+/*-----------------------------------------------------------.
+| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. |
+`-----------------------------------------------------------*/
yyexhaustedlab:
yyerror (yyscanner, YY_("memory exhausted"));
yyresult = 2;
- goto yyreturn;
-#endif
+ goto yyreturnlab;
-/*-------------------------------------------------------.
-| yyreturn -- parsing is finished, clean up and return. |
-`-------------------------------------------------------*/
-yyreturn:
+/*----------------------------------------------------------.
+| yyreturnlab -- parsing is finished, clean up and return. |
+`----------------------------------------------------------*/
+yyreturnlab:
if (yychar != YYEMPTY)
{
/* Make sure we have latest lookahead translation. See comments at
@@ -6605,7 +6592,7 @@ yyreturn:
return yyresult;
}
-#line 3208 "cmDependsJavaParser.y"
+#line 3213 "cmDependsJavaParser.y"
/* End of grammar */
diff --git a/Source/LexerParser/cmDependsJavaParser.y b/Source/LexerParser/cmDependsJavaParser.y
index a76ec50..ff37af2 100644
--- a/Source/LexerParser/cmDependsJavaParser.y
+++ b/Source/LexerParser/cmDependsJavaParser.y
@@ -45,6 +45,11 @@ static void cmDependsJava_yyerror(yyscan_t yyscanner, const char* message);
# pragma GCC diagnostic ignored "-Wconversion"
# pragma GCC diagnostic ignored "-Wfree-nonheap-object"
#endif
+#if defined(__clang__) && defined(__has_warning)
+# if __has_warning("-Wunused-but-set-variable")
+# pragma clang diagnostic ignored "-Wunused-but-set-variable"
+# endif
+#endif
%}
/* Generate a reentrant parser object. */
diff --git a/Source/LexerParser/cmDependsJavaParserTokens.h b/Source/LexerParser/cmDependsJavaParserTokens.h
index 885cc66..02f40aa 100644
--- a/Source/LexerParser/cmDependsJavaParserTokens.h
+++ b/Source/LexerParser/cmDependsJavaParserTokens.h
@@ -1,4 +1,4 @@
-/* A Bison parser, made by GNU Bison 3.7.5. */
+/* A Bison parser, made by GNU Bison 3.8.2. */
/* Bison interface for Yacc-like parsers in C
@@ -16,7 +16,7 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@@ -165,6 +165,8 @@ extern int cmDependsJava_yydebug;
+
int cmDependsJava_yyparse (yyscan_t yyscanner);
+
#endif /* !YY_CMDEPENDSJAVA_YY_CMDEPENDSJAVAPARSERTOKENS_H_INCLUDED */
diff --git a/Source/LexerParser/cmExprParser.cxx b/Source/LexerParser/cmExprParser.cxx
index d9b0ae3..cb5e498 100644
--- a/Source/LexerParser/cmExprParser.cxx
+++ b/Source/LexerParser/cmExprParser.cxx
@@ -1,4 +1,4 @@
-/* A Bison parser, made by GNU Bison 3.7.5. */
+/* A Bison parser, made by GNU Bison 3.8.2. */
/* Bison implementation for Yacc-like parsers in C
@@ -16,7 +16,7 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@@ -46,10 +46,10 @@
USER NAME SPACE" below. */
/* Identify Bison output, and Bison version. */
-#define YYBISON 30705
+#define YYBISON 30802
/* Bison version string. */
-#define YYBISON_VERSION "3.7.5"
+#define YYBISON_VERSION "3.8.2"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -115,6 +115,9 @@ static void cmExpr_yyerror(yyscan_t yyscanner, const char* message);
# pragma GCC diagnostic ignored "-Wfree-nonheap-object"
#endif
#if defined(__clang__) && defined(__has_warning)
+# if __has_warning("-Wunused-but-set-variable")
+# pragma clang diagnostic ignored "-Wunused-but-set-variable"
+# endif
# if __has_warning("-Wused-but-marked-unused")
# pragma clang diagnostic ignored "-Wused-but-marked-unused"
# endif
@@ -124,7 +127,7 @@ static void cmExpr_yyerror(yyscan_t yyscanner, const char* message);
# pragma diag_suppress 550 /* variable set but never used */
#endif
-#line 128 "cmExprParser.cxx"
+#line 131 "cmExprParser.cxx"
# ifndef YY_CAST
# ifdef __cplusplus
@@ -336,12 +339,18 @@ typedef int yy_state_fast_t;
# define YY_USE(E) /* empty */
#endif
-#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
/* Suppress an incorrect diagnostic about yylval being uninitialized. */
-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+#if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__
+# if __GNUC__ * 100 + __GNUC_MINOR__ < 407
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")
+# else
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
_Pragma ("GCC diagnostic push") \
_Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \
_Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# endif
# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
_Pragma ("GCC diagnostic pop")
#else
@@ -557,12 +566,12 @@ static const yytype_int8 yytranslate[] =
};
#if YYDEBUG
- /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
+/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_uint8 yyrline[] =
{
- 0, 85, 85, 90, 93, 98, 101, 106, 109, 114,
- 117, 120, 125, 128, 131, 136, 139, 142, 148, 153,
- 156, 159, 162, 167, 170
+ 0, 88, 88, 93, 96, 101, 104, 109, 112, 117,
+ 120, 123, 128, 131, 134, 139, 142, 145, 151, 156,
+ 159, 162, 165, 170, 173
};
#endif
@@ -593,16 +602,6 @@ yysymbol_name (yysymbol_kind_t yysymbol)
}
#endif
-#ifdef YYPRINT
-/* YYTOKNUM[NUM] -- (External) token number corresponding to the
- (internal) symbol number NUM (which must be that of a token). */
-static const yytype_int16 yytoknum[] =
-{
- 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
- 265, 266, 267, 268, 269, 270, 271
-};
-#endif
-
#define YYPACT_NINF (-11)
#define yypact_value_is_default(Yyn) \
@@ -613,8 +612,8 @@ static const yytype_int16 yytoknum[] =
#define yytable_value_is_error(Yyn) \
0
- /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
- STATE-NUM. */
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
static const yytype_int8 yypact[] =
{
1, 1, 1, 1, 1, -11, 6, -10, -4, 9,
@@ -624,9 +623,9 @@ static const yytype_int8 yypact[] =
-11
};
- /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
- Performed when YYTABLE does not specify something else to do. Zero
- means the default is an error. */
+/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+ Performed when YYTABLE does not specify something else to do. Zero
+ means the default is an error. */
static const yytype_int8 yydefact[] =
{
0, 0, 0, 0, 0, 23, 0, 2, 3, 5,
@@ -636,21 +635,21 @@ static const yytype_int8 yydefact[] =
18
};
- /* YYPGOTO[NTERM-NUM]. */
+/* YYPGOTO[NTERM-NUM]. */
static const yytype_int8 yypgoto[] =
{
-11, -11, 22, 10, 8, 12, -3, -2, -1, -11
};
- /* YYDEFGOTO[NTERM-NUM]. */
+/* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int8 yydefgoto[] =
{
0, 6, 7, 8, 9, 10, 11, 12, 13, 14
};
- /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
- positive, shift that token. If negative, reduce the rule whose
- number is the opposite. If YYTABLE_NINF, syntax error. */
+/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule whose
+ number is the opposite. If YYTABLE_NINF, syntax error. */
static const yytype_int8 yytable[] =
{
15, 16, 20, 18, 1, 2, 19, 27, 28, 29,
@@ -667,8 +666,8 @@ static const yytype_int8 yycheck[] =
20, -1, -1, -1, 22
};
- /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
- symbol of state STATE-NUM. */
+/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of
+ state STATE-NUM. */
static const yytype_int8 yystos[] =
{
0, 3, 4, 10, 15, 16, 18, 19, 20, 21,
@@ -678,7 +677,7 @@ static const yytype_int8 yystos[] =
25
};
- /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */
static const yytype_int8 yyr1[] =
{
0, 17, 18, 19, 19, 20, 20, 21, 21, 22,
@@ -686,7 +685,7 @@ static const yytype_int8 yyr1[] =
25, 25, 25, 26, 26
};
- /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
+/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */
static const yytype_int8 yyr2[] =
{
0, 2, 1, 1, 3, 1, 3, 1, 3, 1,
@@ -703,6 +702,7 @@ enum { YYENOMEM = -2 };
#define YYACCEPT goto yyacceptlab
#define YYABORT goto yyabortlab
#define YYERROR goto yyerrorlab
+#define YYNOMEM goto yyexhaustedlab
#define YYRECOVERING() (!!yyerrstatus)
@@ -743,10 +743,7 @@ do { \
YYFPRINTF Args; \
} while (0)
-/* This macro is provided for backward compatibility. */
-# ifndef YY_LOCATION_PRINT
-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-# endif
+
# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \
@@ -774,10 +771,6 @@ yy_symbol_value_print (FILE *yyo,
YY_USE (yyscanner);
if (!yyvaluep)
return;
-# ifdef YYPRINT
- if (yykind < YYNTOKENS)
- YYPRINT (yyo, yytoknum[yykind], *yyvaluep);
-# endif
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
YY_USE (yykind);
YY_IGNORE_MAYBE_UNINITIALIZED_END
@@ -1239,6 +1232,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
YYDPRINTF ((stderr, "Starting parse\n"));
yychar = YYEMPTY; /* Cause a token to be read. */
+
goto yysetstate;
@@ -1264,7 +1258,7 @@ yysetstate:
if (yyss + yystacksize - 1 <= yyssp)
#if !defined yyoverflow && !defined YYSTACK_RELOCATE
- goto yyexhaustedlab;
+ YYNOMEM;
#else
{
/* Get the current used size of the three stacks, in elements. */
@@ -1292,7 +1286,7 @@ yysetstate:
# else /* defined YYSTACK_RELOCATE */
/* Extend the stack our own way. */
if (YYMAXDEPTH <= yystacksize)
- goto yyexhaustedlab;
+ YYNOMEM;
yystacksize *= 2;
if (YYMAXDEPTH < yystacksize)
yystacksize = YYMAXDEPTH;
@@ -1303,7 +1297,7 @@ yysetstate:
YY_CAST (union yyalloc *,
YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize))));
if (! yyptr)
- goto yyexhaustedlab;
+ YYNOMEM;
YYSTACK_RELOCATE (yyss_alloc, yyss);
YYSTACK_RELOCATE (yyvs_alloc, yyvs);
# undef YYSTACK_RELOCATE
@@ -1325,6 +1319,7 @@ yysetstate:
}
#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
+
if (yystate == YYFINAL)
YYACCEPT;
@@ -1437,194 +1432,194 @@ yyreduce:
switch (yyn)
{
case 2: /* start: exp */
-#line 85 "cmExprParser.y"
+#line 88 "cmExprParser.y"
{
cmExpr_yyget_extra(yyscanner)->SetResult((yyvsp[0].Number));
}
-#line 1445 "cmExprParser.cxx"
+#line 1440 "cmExprParser.cxx"
break;
case 3: /* exp: bitwiseor */
-#line 90 "cmExprParser.y"
+#line 93 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1453 "cmExprParser.cxx"
+#line 1448 "cmExprParser.cxx"
break;
case 4: /* exp: exp exp_OR bitwiseor */
-#line 93 "cmExprParser.y"
+#line 96 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) | (yyvsp[0].Number);
}
-#line 1461 "cmExprParser.cxx"
+#line 1456 "cmExprParser.cxx"
break;
case 5: /* bitwiseor: bitwisexor */
-#line 98 "cmExprParser.y"
+#line 101 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1469 "cmExprParser.cxx"
+#line 1464 "cmExprParser.cxx"
break;
case 6: /* bitwiseor: bitwiseor exp_XOR bitwisexor */
-#line 101 "cmExprParser.y"
+#line 104 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) ^ (yyvsp[0].Number);
}
-#line 1477 "cmExprParser.cxx"
+#line 1472 "cmExprParser.cxx"
break;
case 7: /* bitwisexor: bitwiseand */
-#line 106 "cmExprParser.y"
+#line 109 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1485 "cmExprParser.cxx"
+#line 1480 "cmExprParser.cxx"
break;
case 8: /* bitwisexor: bitwisexor exp_AND bitwiseand */
-#line 109 "cmExprParser.y"
+#line 112 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) & (yyvsp[0].Number);
}
-#line 1493 "cmExprParser.cxx"
+#line 1488 "cmExprParser.cxx"
break;
case 9: /* bitwiseand: shift */
-#line 114 "cmExprParser.y"
+#line 117 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1501 "cmExprParser.cxx"
+#line 1496 "cmExprParser.cxx"
break;
case 10: /* bitwiseand: bitwiseand exp_SHIFTLEFT shift */
-#line 117 "cmExprParser.y"
+#line 120 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) << (yyvsp[0].Number);
}
-#line 1509 "cmExprParser.cxx"
+#line 1504 "cmExprParser.cxx"
break;
case 11: /* bitwiseand: bitwiseand exp_SHIFTRIGHT shift */
-#line 120 "cmExprParser.y"
+#line 123 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) >> (yyvsp[0].Number);
}
-#line 1517 "cmExprParser.cxx"
+#line 1512 "cmExprParser.cxx"
break;
case 12: /* shift: term */
-#line 125 "cmExprParser.y"
+#line 128 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1525 "cmExprParser.cxx"
+#line 1520 "cmExprParser.cxx"
break;
case 13: /* shift: shift exp_PLUS term */
-#line 128 "cmExprParser.y"
+#line 131 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) + (yyvsp[0].Number);
}
-#line 1533 "cmExprParser.cxx"
+#line 1528 "cmExprParser.cxx"
break;
case 14: /* shift: shift exp_MINUS term */
-#line 131 "cmExprParser.y"
+#line 134 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) - (yyvsp[0].Number);
}
-#line 1541 "cmExprParser.cxx"
+#line 1536 "cmExprParser.cxx"
break;
case 15: /* term: unary */
-#line 136 "cmExprParser.y"
+#line 139 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1549 "cmExprParser.cxx"
+#line 1544 "cmExprParser.cxx"
break;
case 16: /* term: term exp_TIMES unary */
-#line 139 "cmExprParser.y"
+#line 142 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) * (yyvsp[0].Number);
}
-#line 1557 "cmExprParser.cxx"
+#line 1552 "cmExprParser.cxx"
break;
case 17: /* term: term exp_DIVIDE unary */
-#line 142 "cmExprParser.y"
+#line 145 "cmExprParser.y"
{
if (yyvsp[0].Number == 0) {
throw std::overflow_error("divide by zero");
}
(yyval.Number) = (yyvsp[-2].Number) / (yyvsp[0].Number);
}
-#line 1568 "cmExprParser.cxx"
+#line 1563 "cmExprParser.cxx"
break;
case 18: /* term: term exp_MOD unary */
-#line 148 "cmExprParser.y"
+#line 151 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) % (yyvsp[0].Number);
}
-#line 1576 "cmExprParser.cxx"
+#line 1571 "cmExprParser.cxx"
break;
case 19: /* unary: factor */
-#line 153 "cmExprParser.y"
+#line 156 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1584 "cmExprParser.cxx"
+#line 1579 "cmExprParser.cxx"
break;
case 20: /* unary: exp_PLUS unary */
-#line 156 "cmExprParser.y"
+#line 159 "cmExprParser.y"
{
(yyval.Number) = + (yyvsp[0].Number);
}
-#line 1592 "cmExprParser.cxx"
+#line 1587 "cmExprParser.cxx"
break;
case 21: /* unary: exp_MINUS unary */
-#line 159 "cmExprParser.y"
+#line 162 "cmExprParser.y"
{
(yyval.Number) = - (yyvsp[0].Number);
}
-#line 1600 "cmExprParser.cxx"
+#line 1595 "cmExprParser.cxx"
break;
case 22: /* unary: exp_NOT unary */
-#line 162 "cmExprParser.y"
+#line 165 "cmExprParser.y"
{
(yyval.Number) = ~ (yyvsp[0].Number);
}
-#line 1608 "cmExprParser.cxx"
+#line 1603 "cmExprParser.cxx"
break;
case 23: /* factor: exp_NUMBER */
-#line 167 "cmExprParser.y"
+#line 170 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1616 "cmExprParser.cxx"
+#line 1611 "cmExprParser.cxx"
break;
case 24: /* factor: exp_OPENPARENT exp exp_CLOSEPARENT */
-#line 170 "cmExprParser.y"
+#line 173 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-1].Number);
}
-#line 1624 "cmExprParser.cxx"
+#line 1619 "cmExprParser.cxx"
break;
-#line 1628 "cmExprParser.cxx"
+#line 1623 "cmExprParser.cxx"
default: break;
}
@@ -1700,7 +1695,7 @@ yyerrlab:
}
yyerror (yyscanner, yymsgp);
if (yysyntax_error_status == YYENOMEM)
- goto yyexhaustedlab;
+ YYNOMEM;
}
}
@@ -1736,6 +1731,7 @@ yyerrorlab:
label yyerrorlab therefore never appears in user code. */
if (0)
YYERROR;
+ ++yynerrs;
/* Do not reclaim the symbols of the rule whose action triggered
this YYERROR. */
@@ -1796,7 +1792,7 @@ yyerrlab1:
`-------------------------------------*/
yyacceptlab:
yyresult = 0;
- goto yyreturn;
+ goto yyreturnlab;
/*-----------------------------------.
@@ -1804,24 +1800,22 @@ yyacceptlab:
`-----------------------------------*/
yyabortlab:
yyresult = 1;
- goto yyreturn;
+ goto yyreturnlab;
-#if 1
-/*-------------------------------------------------.
-| yyexhaustedlab -- memory exhaustion comes here. |
-`-------------------------------------------------*/
+/*-----------------------------------------------------------.
+| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. |
+`-----------------------------------------------------------*/
yyexhaustedlab:
yyerror (yyscanner, YY_("memory exhausted"));
yyresult = 2;
- goto yyreturn;
-#endif
+ goto yyreturnlab;
-/*-------------------------------------------------------.
-| yyreturn -- parsing is finished, clean up and return. |
-`-------------------------------------------------------*/
-yyreturn:
+/*----------------------------------------------------------.
+| yyreturnlab -- parsing is finished, clean up and return. |
+`----------------------------------------------------------*/
+yyreturnlab:
if (yychar != YYEMPTY)
{
/* Make sure we have latest lookahead translation. See comments at
@@ -1849,7 +1843,7 @@ yyreturn:
return yyresult;
}
-#line 175 "cmExprParser.y"
+#line 178 "cmExprParser.y"
/* End of grammar */
diff --git a/Source/LexerParser/cmExprParser.y b/Source/LexerParser/cmExprParser.y
index fda2395..1c959f6 100644
--- a/Source/LexerParser/cmExprParser.y
+++ b/Source/LexerParser/cmExprParser.y
@@ -40,6 +40,9 @@ static void cmExpr_yyerror(yyscan_t yyscanner, const char* message);
# pragma GCC diagnostic ignored "-Wfree-nonheap-object"
#endif
#if defined(__clang__) && defined(__has_warning)
+# if __has_warning("-Wunused-but-set-variable")
+# pragma clang diagnostic ignored "-Wunused-but-set-variable"
+# endif
# if __has_warning("-Wused-but-marked-unused")
# pragma clang diagnostic ignored "-Wused-but-marked-unused"
# endif
diff --git a/Source/LexerParser/cmExprParserTokens.h b/Source/LexerParser/cmExprParserTokens.h
index 67b03de..e552fbe 100644
--- a/Source/LexerParser/cmExprParserTokens.h
+++ b/Source/LexerParser/cmExprParserTokens.h
@@ -1,4 +1,4 @@
-/* A Bison parser, made by GNU Bison 3.7.5. */
+/* A Bison parser, made by GNU Bison 3.8.2. */
/* Bison interface for Yacc-like parsers in C
@@ -16,7 +16,7 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@@ -76,6 +76,8 @@ extern int cmExpr_yydebug;
+
int cmExpr_yyparse (yyscan_t yyscanner);
+
#endif /* !YY_CMEXPR_YY_CMEXPRPARSERTOKENS_H_INCLUDED */
diff --git a/Source/LexerParser/cmFortranParser.cxx b/Source/LexerParser/cmFortranParser.cxx
index 50e9752..b177296 100644
--- a/Source/LexerParser/cmFortranParser.cxx
+++ b/Source/LexerParser/cmFortranParser.cxx
@@ -1,4 +1,4 @@
-/* A Bison parser, made by GNU Bison 3.7.5. */
+/* A Bison parser, made by GNU Bison 3.8.2. */
/* Bison implementation for Yacc-like parsers in C
@@ -16,7 +16,7 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@@ -46,10 +46,10 @@
USER NAME SPACE" below. */
/* Identify Bison output, and Bison version. */
-#define YYBISON 30705
+#define YYBISON 30802
/* Bison version string. */
-#define YYBISON_VERSION "3.7.5"
+#define YYBISON_VERSION "3.8.2"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -132,8 +132,13 @@ static void cmFortran_yyerror(yyscan_t yyscanner, const char* message)
# pragma GCC diagnostic ignored "-Wconversion"
# pragma GCC diagnostic ignored "-Wfree-nonheap-object"
#endif
+#if defined(__clang__) && defined(__has_warning)
+# if __has_warning("-Wunused-but-set-variable")
+# pragma clang diagnostic ignored "-Wunused-but-set-variable"
+# endif
+#endif
-#line 137 "cmFortranParser.cxx"
+#line 142 "cmFortranParser.cxx"
# ifndef YY_CAST
# ifdef __cplusplus
@@ -373,12 +378,18 @@ typedef int yy_state_fast_t;
# define YY_USE(E) /* empty */
#endif
-#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
/* Suppress an incorrect diagnostic about yylval being uninitialized. */
-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+#if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__
+# if __GNUC__ * 100 + __GNUC_MINOR__ < 407
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")
+# else
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
_Pragma ("GCC diagnostic push") \
_Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \
_Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# endif
# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
_Pragma ("GCC diagnostic pop")
#else
@@ -596,16 +607,16 @@ static const yytype_int8 yytranslate[] =
};
#if YYDEBUG
- /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
-static const yytype_uint8 yyrline[] =
+/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
+static const yytype_int16 yyrline[] =
{
- 0, 101, 101, 101, 104, 108, 113, 122, 128, 135,
- 140, 144, 149, 161, 166, 171, 176, 181, 186, 191,
- 196, 201, 205, 209, 213, 217, 218, 223, 223, 223,
- 224, 224, 225, 225, 226, 226, 227, 227, 228, 228,
- 229, 229, 230, 230, 231, 231, 232, 232, 235, 236,
- 237, 238, 239, 240, 241, 242, 243, 244, 245, 246,
- 247, 248, 249, 250, 251
+ 0, 106, 106, 106, 109, 113, 118, 127, 133, 140,
+ 145, 149, 154, 166, 171, 176, 181, 186, 191, 196,
+ 201, 206, 210, 214, 218, 222, 223, 228, 228, 228,
+ 229, 229, 230, 230, 231, 231, 232, 232, 233, 233,
+ 234, 234, 235, 235, 236, 236, 237, 237, 240, 241,
+ 242, 243, 244, 245, 246, 247, 248, 249, 250, 251,
+ 252, 253, 254, 255, 256
};
#endif
@@ -641,19 +652,6 @@ yysymbol_name (yysymbol_kind_t yysymbol)
}
#endif
-#ifdef YYPRINT
-/* YYTOKNUM[NUM] -- (External) token number corresponding to the
- (internal) symbol number NUM (which must be that of a token). */
-static const yytype_int16 yytoknum[] =
-{
- 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
- 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
- 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
- 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
- 295
-};
-#endif
-
#define YYPACT_NINF (-39)
#define yypact_value_is_default(Yyn) \
@@ -664,8 +662,8 @@ static const yytype_int16 yytoknum[] =
#define yytable_value_is_error(Yyn) \
0
- /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
- STATE-NUM. */
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
static const yytype_int16 yypact[] =
{
-39, 21, -39, 1, -39, -20, -39, -39, -39, -39,
@@ -683,9 +681,9 @@ static const yytype_int16 yypact[] =
501, 539, -39, -39, -39, 554, -39
};
- /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
- Performed when YYTABLE does not specify something else to do. Zero
- means the default is an error. */
+/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+ Performed when YYTABLE does not specify something else to do. Zero
+ means the default is an error. */
static const yytype_int8 yydefact[] =
{
2, 0, 1, 0, 25, 0, 27, 28, 29, 31,
@@ -703,23 +701,23 @@ static const yytype_int8 yydefact[] =
0, 0, 46, 7, 12, 0, 8
};
- /* YYPGOTO[NTERM-NUM]. */
+/* YYPGOTO[NTERM-NUM]. */
static const yytype_int8 yypgoto[] =
{
-39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
-39, -39, -38, -39
};
- /* YYDEFGOTO[NTERM-NUM]. */
+/* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int8 yydefgoto[] =
{
0, 1, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 44, 82
};
- /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
- positive, shift that token. If negative, reduce the rule whose
- number is the opposite. If YYTABLE_NINF, syntax error. */
+/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule whose
+ number is the opposite. If YYTABLE_NINF, syntax error. */
static const yytype_int8 yytable[] =
{
59, 60, 61, 62, 42, 63, 105, 83, 84, 106,
@@ -848,8 +846,8 @@ static const yytype_int8 yycheck[] =
36, 37, 38, 39, 40
};
- /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
- symbol of state STATE-NUM. */
+/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of
+ state STATE-NUM. */
static const yytype_int8 yystos[] =
{
0, 42, 0, 1, 3, 6, 7, 8, 9, 10,
@@ -867,7 +865,7 @@ static const yytype_int8 yystos[] =
53, 53, 33, 3, 3, 53, 3
};
- /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */
static const yytype_int8 yyr1[] =
{
0, 41, 42, 42, 43, 43, 43, 43, 43, 43,
@@ -879,7 +877,7 @@ static const yytype_int8 yyr1[] =
54, 54, 54, 54, 54
};
- /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
+/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */
static const yytype_int8 yyr2[] =
{
0, 2, 0, 2, 2, 4, 4, 7, 9, 4,
@@ -900,6 +898,7 @@ enum { YYENOMEM = -2 };
#define YYACCEPT goto yyacceptlab
#define YYABORT goto yyabortlab
#define YYERROR goto yyerrorlab
+#define YYNOMEM goto yyexhaustedlab
#define YYRECOVERING() (!!yyerrstatus)
@@ -940,10 +939,7 @@ do { \
YYFPRINTF Args; \
} while (0)
-/* This macro is provided for backward compatibility. */
-# ifndef YY_LOCATION_PRINT
-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-# endif
+
# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \
@@ -971,10 +967,6 @@ yy_symbol_value_print (FILE *yyo,
YY_USE (yyscanner);
if (!yyvaluep)
return;
-# ifdef YYPRINT
- if (yykind < YYNTOKENS)
- YYPRINT (yyo, yytoknum[yykind], *yyvaluep);
-# endif
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
YY_USE (yykind);
YY_IGNORE_MAYBE_UNINITIALIZED_END
@@ -1367,21 +1359,21 @@ yydestruct (const char *yymsg,
switch (yykind)
{
case YYSYMBOL_STRING: /* STRING */
-#line 95 "cmFortranParser.y"
+#line 100 "cmFortranParser.y"
{ free(((*yyvaluep).string)); }
-#line 1373 "cmFortranParser.cxx"
+#line 1365 "cmFortranParser.cxx"
break;
case YYSYMBOL_WORD: /* WORD */
-#line 95 "cmFortranParser.y"
+#line 100 "cmFortranParser.y"
{ free(((*yyvaluep).string)); }
-#line 1379 "cmFortranParser.cxx"
+#line 1371 "cmFortranParser.cxx"
break;
case YYSYMBOL_CPP_INCLUDE_ANGLE: /* CPP_INCLUDE_ANGLE */
-#line 95 "cmFortranParser.y"
+#line 100 "cmFortranParser.y"
{ free(((*yyvaluep).string)); }
-#line 1385 "cmFortranParser.cxx"
+#line 1377 "cmFortranParser.cxx"
break;
default:
@@ -1458,6 +1450,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
YYDPRINTF ((stderr, "Starting parse\n"));
yychar = YYEMPTY; /* Cause a token to be read. */
+
goto yysetstate;
@@ -1483,7 +1476,7 @@ yysetstate:
if (yyss + yystacksize - 1 <= yyssp)
#if !defined yyoverflow && !defined YYSTACK_RELOCATE
- goto yyexhaustedlab;
+ YYNOMEM;
#else
{
/* Get the current used size of the three stacks, in elements. */
@@ -1511,7 +1504,7 @@ yysetstate:
# else /* defined YYSTACK_RELOCATE */
/* Extend the stack our own way. */
if (YYMAXDEPTH <= yystacksize)
- goto yyexhaustedlab;
+ YYNOMEM;
yystacksize *= 2;
if (YYMAXDEPTH < yystacksize)
yystacksize = YYMAXDEPTH;
@@ -1522,7 +1515,7 @@ yysetstate:
YY_CAST (union yyalloc *,
YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize))));
if (! yyptr)
- goto yyexhaustedlab;
+ YYNOMEM;
YYSTACK_RELOCATE (yyss_alloc, yyss);
YYSTACK_RELOCATE (yyvs_alloc, yyvs);
# undef YYSTACK_RELOCATE
@@ -1544,6 +1537,7 @@ yysetstate:
}
#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
+
if (yystate == YYFINAL)
YYACCEPT;
@@ -1656,26 +1650,26 @@ yyreduce:
switch (yyn)
{
case 4: /* stmt: INTERFACE EOSTMT */
-#line 104 "cmFortranParser.y"
+#line 109 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_SetInInterface(parser, true);
}
-#line 1665 "cmFortranParser.cxx"
+#line 1659 "cmFortranParser.cxx"
break;
case 5: /* stmt: USE WORD other EOSTMT */
-#line 108 "cmFortranParser.y"
+#line 113 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleUse(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1675 "cmFortranParser.cxx"
+#line 1669 "cmFortranParser.cxx"
break;
case 6: /* stmt: MODULE WORD other EOSTMT */
-#line 113 "cmFortranParser.y"
+#line 118 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
if (cmsysString_strcasecmp((yyvsp[-2].string), "function") != 0 &&
@@ -1685,22 +1679,22 @@ yyreduce:
}
free((yyvsp[-2].string));
}
-#line 1689 "cmFortranParser.cxx"
+#line 1683 "cmFortranParser.cxx"
break;
case 7: /* stmt: SUBMODULE LPAREN WORD RPAREN WORD other EOSTMT */
-#line 122 "cmFortranParser.y"
+#line 127 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleSubmodule(parser, (yyvsp[-4].string), (yyvsp[-2].string));
free((yyvsp[-4].string));
free((yyvsp[-2].string));
}
-#line 1700 "cmFortranParser.cxx"
+#line 1694 "cmFortranParser.cxx"
break;
case 8: /* stmt: SUBMODULE LPAREN WORD COLON WORD RPAREN WORD other EOSTMT */
-#line 128 "cmFortranParser.y"
+#line 133 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleSubmoduleNested(parser, (yyvsp[-6].string), (yyvsp[-4].string), (yyvsp[-2].string));
@@ -1708,40 +1702,40 @@ yyreduce:
free((yyvsp[-4].string));
free((yyvsp[-2].string));
}
-#line 1712 "cmFortranParser.cxx"
+#line 1706 "cmFortranParser.cxx"
break;
case 9: /* stmt: INTERFACE WORD other EOSTMT */
-#line 135 "cmFortranParser.y"
+#line 140 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_SetInInterface(parser, true);
free((yyvsp[-2].string));
}
-#line 1722 "cmFortranParser.cxx"
+#line 1716 "cmFortranParser.cxx"
break;
case 10: /* stmt: END INTERFACE other EOSTMT */
-#line 140 "cmFortranParser.y"
+#line 145 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_SetInInterface(parser, false);
}
-#line 1731 "cmFortranParser.cxx"
+#line 1725 "cmFortranParser.cxx"
break;
case 11: /* stmt: USE DCOLON WORD other EOSTMT */
-#line 144 "cmFortranParser.y"
+#line 149 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleUse(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1741 "cmFortranParser.cxx"
+#line 1735 "cmFortranParser.cxx"
break;
case 12: /* stmt: USE COMMA WORD DCOLON WORD other EOSTMT */
-#line 149 "cmFortranParser.y"
+#line 154 "cmFortranParser.y"
{
if (cmsysString_strcasecmp((yyvsp[-4].string), "non_intrinsic") == 0) {
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
@@ -1754,139 +1748,139 @@ yyreduce:
free((yyvsp[-4].string));
free((yyvsp[-2].string));
}
-#line 1758 "cmFortranParser.cxx"
+#line 1752 "cmFortranParser.cxx"
break;
case 13: /* stmt: INCLUDE STRING other EOSTMT */
-#line 161 "cmFortranParser.y"
+#line 166 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1768 "cmFortranParser.cxx"
+#line 1762 "cmFortranParser.cxx"
break;
case 14: /* stmt: CPP_LINE_DIRECTIVE STRING other EOSTMT */
-#line 166 "cmFortranParser.y"
+#line 171 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleLineDirective(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1778 "cmFortranParser.cxx"
+#line 1772 "cmFortranParser.cxx"
break;
case 15: /* stmt: CPP_INCLUDE_ANGLE other EOSTMT */
-#line 171 "cmFortranParser.y"
+#line 176 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1788 "cmFortranParser.cxx"
+#line 1782 "cmFortranParser.cxx"
break;
case 16: /* stmt: include STRING other EOSTMT */
-#line 176 "cmFortranParser.y"
+#line 181 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1798 "cmFortranParser.cxx"
+#line 1792 "cmFortranParser.cxx"
break;
case 17: /* stmt: define WORD other EOSTMT */
-#line 181 "cmFortranParser.y"
+#line 186 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleDefine(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1808 "cmFortranParser.cxx"
+#line 1802 "cmFortranParser.cxx"
break;
case 18: /* stmt: undef WORD other EOSTMT */
-#line 186 "cmFortranParser.y"
+#line 191 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleUndef(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1818 "cmFortranParser.cxx"
+#line 1812 "cmFortranParser.cxx"
break;
case 19: /* stmt: ifdef WORD other EOSTMT */
-#line 191 "cmFortranParser.y"
+#line 196 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleIfdef(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1828 "cmFortranParser.cxx"
+#line 1822 "cmFortranParser.cxx"
break;
case 20: /* stmt: ifndef WORD other EOSTMT */
-#line 196 "cmFortranParser.y"
+#line 201 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleIfndef(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1838 "cmFortranParser.cxx"
+#line 1832 "cmFortranParser.cxx"
break;
case 21: /* stmt: if other EOSTMT */
-#line 201 "cmFortranParser.y"
+#line 206 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleIf(parser);
}
-#line 1847 "cmFortranParser.cxx"
+#line 1841 "cmFortranParser.cxx"
break;
case 22: /* stmt: elif other EOSTMT */
-#line 205 "cmFortranParser.y"
+#line 210 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleElif(parser);
}
-#line 1856 "cmFortranParser.cxx"
+#line 1850 "cmFortranParser.cxx"
break;
case 23: /* stmt: else other EOSTMT */
-#line 209 "cmFortranParser.y"
+#line 214 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleElse(parser);
}
-#line 1865 "cmFortranParser.cxx"
+#line 1859 "cmFortranParser.cxx"
break;
case 24: /* stmt: endif other EOSTMT */
-#line 213 "cmFortranParser.y"
+#line 218 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleEndif(parser);
}
-#line 1874 "cmFortranParser.cxx"
+#line 1868 "cmFortranParser.cxx"
break;
case 48: /* misc_code: WORD */
-#line 235 "cmFortranParser.y"
+#line 240 "cmFortranParser.y"
{ free ((yyvsp[0].string)); }
-#line 1880 "cmFortranParser.cxx"
+#line 1874 "cmFortranParser.cxx"
break;
case 55: /* misc_code: STRING */
-#line 242 "cmFortranParser.y"
+#line 247 "cmFortranParser.y"
{ free ((yyvsp[0].string)); }
-#line 1886 "cmFortranParser.cxx"
+#line 1880 "cmFortranParser.cxx"
break;
-#line 1890 "cmFortranParser.cxx"
+#line 1884 "cmFortranParser.cxx"
default: break;
}
@@ -1962,7 +1956,7 @@ yyerrlab:
}
yyerror (yyscanner, yymsgp);
if (yysyntax_error_status == YYENOMEM)
- goto yyexhaustedlab;
+ YYNOMEM;
}
}
@@ -1998,6 +1992,7 @@ yyerrorlab:
label yyerrorlab therefore never appears in user code. */
if (0)
YYERROR;
+ ++yynerrs;
/* Do not reclaim the symbols of the rule whose action triggered
this YYERROR. */
@@ -2058,7 +2053,7 @@ yyerrlab1:
`-------------------------------------*/
yyacceptlab:
yyresult = 0;
- goto yyreturn;
+ goto yyreturnlab;
/*-----------------------------------.
@@ -2066,24 +2061,22 @@ yyacceptlab:
`-----------------------------------*/
yyabortlab:
yyresult = 1;
- goto yyreturn;
+ goto yyreturnlab;
-#if 1
-/*-------------------------------------------------.
-| yyexhaustedlab -- memory exhaustion comes here. |
-`-------------------------------------------------*/
+/*-----------------------------------------------------------.
+| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. |
+`-----------------------------------------------------------*/
yyexhaustedlab:
yyerror (yyscanner, YY_("memory exhausted"));
yyresult = 2;
- goto yyreturn;
-#endif
+ goto yyreturnlab;
-/*-------------------------------------------------------.
-| yyreturn -- parsing is finished, clean up and return. |
-`-------------------------------------------------------*/
-yyreturn:
+/*----------------------------------------------------------.
+| yyreturnlab -- parsing is finished, clean up and return. |
+`----------------------------------------------------------*/
+yyreturnlab:
if (yychar != YYEMPTY)
{
/* Make sure we have latest lookahead translation. See comments at
@@ -2111,6 +2104,6 @@ yyreturn:
return yyresult;
}
-#line 254 "cmFortranParser.y"
+#line 259 "cmFortranParser.y"
/* End of grammar */
diff --git a/Source/LexerParser/cmFortranParser.y b/Source/LexerParser/cmFortranParser.y
index 8ef1903..07ca630 100644
--- a/Source/LexerParser/cmFortranParser.y
+++ b/Source/LexerParser/cmFortranParser.y
@@ -57,6 +57,11 @@ static void cmFortran_yyerror(yyscan_t yyscanner, const char* message)
# pragma GCC diagnostic ignored "-Wconversion"
# pragma GCC diagnostic ignored "-Wfree-nonheap-object"
#endif
+#if defined(__clang__) && defined(__has_warning)
+# if __has_warning("-Wunused-but-set-variable")
+# pragma clang diagnostic ignored "-Wunused-but-set-variable"
+# endif
+#endif
%}
/* Generate a reentrant parser object. */
diff --git a/Source/LexerParser/cmFortranParserTokens.h b/Source/LexerParser/cmFortranParserTokens.h
index 3a19cfb..cb2b999 100644
--- a/Source/LexerParser/cmFortranParserTokens.h
+++ b/Source/LexerParser/cmFortranParserTokens.h
@@ -1,4 +1,4 @@
-/* A Bison parser, made by GNU Bison 3.7.5. */
+/* A Bison parser, made by GNU Bison 3.8.2. */
/* Bison interface for Yacc-like parsers in C
@@ -16,7 +16,7 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@@ -100,7 +100,7 @@ extern int cmFortran_yydebug;
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
union YYSTYPE
{
-#line 71 "cmFortranParser.y"
+#line 76 "cmFortranParser.y"
char* string;
@@ -114,6 +114,8 @@ typedef union YYSTYPE YYSTYPE;
+
int cmFortran_yyparse (yyscan_t yyscanner);
+
#endif /* !YY_CMFORTRAN_YY_CMFORTRANPARSERTOKENS_H_INCLUDED */
diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx
index f90b781..3c41fce 100644
--- a/Source/QtDialog/CMakeSetupDialog.cxx
+++ b/Source/QtDialog/CMakeSetupDialog.cxx
@@ -226,7 +226,8 @@ CMakeSetupDialog::CMakeSetupDialog()
this->SourceDirectory->setCompleter(new QCMakeFileCompleter(this, true));
// fixed pitch font in output window
- QFont outputFont("Courier");
+ QFont outputFont("Courier New");
+ outputFont.setStyleHint(QFont::Monospace);
this->Output->setFont(outputFont);
this->ErrorFormat.setForeground(QBrush(Qt::red));
diff --git a/Source/QtDialog/cmake-gui.desktop b/Source/QtDialog/cmake-gui.desktop
index 842091f..0299c9d 100644
--- a/Source/QtDialog/cmake-gui.desktop
+++ b/Source/QtDialog/cmake-gui.desktop
@@ -7,6 +7,6 @@ Icon=CMakeSetup
Terminal=false
X-MultipleArgs=false
Type=Application
-Categories=Development;
+Categories=Development;Building;
StartupNotify=true
MimeType=application/x-cmakecache;
diff --git a/Source/cmAddExecutableCommand.cxx b/Source/cmAddExecutableCommand.cxx
index 9dd8a19..16a8965 100644
--- a/Source/cmAddExecutableCommand.cxx
+++ b/Source/cmAddExecutableCommand.cxx
@@ -54,6 +54,10 @@ bool cmAddExecutableCommand(std::vector<std::string> const& args,
}
}
+ if (importTarget && !importGlobal) {
+ importGlobal = mf.IsImportedTargetGlobalScope();
+ }
+
bool nameOk = cmGeneratorExpression::IsValidTargetName(exename) &&
!cmGlobalGenerator::IsReservedTarget(exename);
diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx
index a5d1f6a..29fc09b 100644
--- a/Source/cmAddLibraryCommand.cxx
+++ b/Source/cmAddLibraryCommand.cxx
@@ -131,6 +131,10 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
}
}
+ if (importTarget && !importGlobal) {
+ importGlobal = mf.IsImportedTargetGlobalScope();
+ }
+
if (type == cmStateEnums::INTERFACE_LIBRARY) {
if (importGlobal && !importTarget) {
status.SetError(
diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx
index 9e0d80c..cfde37c 100644
--- a/Source/cmArchiveWrite.cxx
+++ b/Source/cmArchiveWrite.cxx
@@ -95,6 +95,19 @@ cmArchiveWrite::cmArchiveWrite(std::ostream& os, Compress c,
, Verbose(false)
, Format(format)
{
+ // Upstream fixed an issue with their integer parsing in 3.4.0
+ // which would cause spurious errors to be raised from `strtoull`.
+
+ if (numThreads < 1) {
+ int upperLimit = (numThreads == 0) ? std::numeric_limits<int>::max()
+ : std::abs(numThreads);
+
+ numThreads =
+ cm::clamp<int>(std::thread::hardware_concurrency(), 1, upperLimit);
+ }
+
+ std::string sNumThreads = std::to_string(numThreads);
+
switch (c) {
case CompressNone:
if (archive_write_add_filter_none(this->Archive) != ARCHIVE_OK) {
@@ -150,36 +163,23 @@ cmArchiveWrite::cmArchiveWrite(std::ostream& os, Compress c,
return;
}
- {
#if ARCHIVE_VERSION_NUMBER >= 3004000
- // Upstream fixed an issue with their integer parsing in 3.4.0
- // which would cause spurious errors to be raised from `strtoull`.
-
- if (numThreads < 1) {
- int upperLimit = (numThreads == 0) ? std::numeric_limits<int>::max()
- : std::abs(numThreads);
-
- numThreads =
- cm::clamp<int>(std::thread::hardware_concurrency(), 1, upperLimit);
- }
# ifdef _AIX
- // FIXME: Using more than 2 threads creates an empty archive.
- // Enforce this limit pending further investigation.
- numThreads = std::min(numThreads, 2);
+ // FIXME: Using more than 2 threads creates an empty archive.
+ // Enforce this limit pending further investigation.
+ if (numThreads > 2) {
+ numThreads = 2;
+ sNumThreads = std::to_string(numThreads);
+ }
# endif
-
- std::string sNumThreads = std::to_string(numThreads);
-
- if (archive_write_set_filter_option(this->Archive, "xz", "threads",
- sNumThreads.c_str()) !=
- ARCHIVE_OK) {
- this->Error = cmStrCat("archive_compressor_xz_options: ",
- cm_archive_error_string(this->Archive));
- return;
- }
-#endif
+ if (archive_write_set_filter_option(this->Archive, "xz", "threads",
+ sNumThreads.c_str()) != ARCHIVE_OK) {
+ this->Error = cmStrCat("archive_compressor_xz_options: ",
+ cm_archive_error_string(this->Archive));
+ return;
}
+#endif
break;
case CompressZstd:
@@ -188,6 +188,15 @@ cmArchiveWrite::cmArchiveWrite(std::ostream& os, Compress c,
cm_archive_error_string(this->Archive));
return;
}
+
+#if ARCHIVE_VERSION_NUMBER >= 3006000
+ if (archive_write_set_filter_option(this->Archive, "zstd", "threads",
+ sNumThreads.c_str()) != ARCHIVE_OK) {
+ this->Error = cmStrCat("archive_compressor_zstd_options: ",
+ cm_archive_error_string(this->Archive));
+ return;
+ }
+#endif
break;
}
diff --git a/Source/cmCMakeHostSystemInformationCommand.cxx b/Source/cmCMakeHostSystemInformationCommand.cxx
index 3922c56..2a019b1 100644
--- a/Source/cmCMakeHostSystemInformationCommand.cxx
+++ b/Source/cmCMakeHostSystemInformationCommand.cxx
@@ -19,10 +19,13 @@
#include "cmsys/Glob.hxx"
#include "cmsys/SystemInformation.hxx"
+#include "cmArgumentParser.h"
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
+#include "cmRange.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmWindowsRegistry.h"
#ifdef _WIN32
# include "cmAlgorithms.h"
@@ -459,6 +462,98 @@ cm::optional<std::string> GetValueChained(GetterFn current, Next... chain)
}
return GetValueChained(chain...);
}
+
+template <typename Range>
+bool QueryWindowsRegistry(Range args, cmExecutionStatus& status,
+ std::string const& variable)
+{
+ using View = cmWindowsRegistry::View;
+ if (args.empty()) {
+ status.SetError("missing <key> specification.");
+ return false;
+ }
+ std::string const& key = *args.begin();
+
+ struct Arguments
+ {
+ std::string ValueName;
+ bool ValueNames = false;
+ bool SubKeys = false;
+ std::string View;
+ std::string Separator;
+ std::string ErrorVariable;
+ };
+ cmArgumentParser<Arguments> parser;
+ parser.Bind("VALUE"_s, &Arguments::ValueName)
+ .Bind("VALUE_NAMES"_s, &Arguments::ValueNames)
+ .Bind("SUBKEYS"_s, &Arguments::SubKeys)
+ .Bind("VIEW"_s, &Arguments::View)
+ .Bind("SEPARATOR"_s, &Arguments::Separator)
+ .Bind("ERROR_VARIABLE"_s, &Arguments::ErrorVariable);
+ std::vector<std::string> invalidArgs;
+ std::vector<std::string> keywordsMissingValue;
+
+ Arguments const arguments =
+ parser.Parse(args.advance(1), &invalidArgs, &keywordsMissingValue);
+ if (!invalidArgs.empty()) {
+ status.SetError(cmStrCat("given invalid argument(s) \"",
+ cmJoin(invalidArgs, ", "_s), "\"."));
+ return false;
+ }
+ if (!keywordsMissingValue.empty()) {
+ status.SetError(cmStrCat("missing expected value for argument(s) \"",
+ cmJoin(keywordsMissingValue, ", "_s), "\"."));
+ return false;
+ }
+ if ((!arguments.ValueName.empty() &&
+ (arguments.ValueNames || arguments.SubKeys)) ||
+ (arguments.ValueName.empty() && arguments.ValueNames &&
+ arguments.SubKeys)) {
+ status.SetError("given mutually exclusive sub-options \"VALUE\", "
+ "\"VALUE_NAMES\" or \"SUBKEYS\".");
+ return false;
+ }
+
+ if (!arguments.View.empty() && !cmWindowsRegistry::ToView(arguments.View)) {
+ status.SetError(
+ cmStrCat("given invalid value for \"VIEW\": ", arguments.View, '.'));
+ return false;
+ }
+
+ auto& makefile = status.GetMakefile();
+
+ makefile.AddDefinition(variable, ""_s);
+
+ auto view = arguments.View.empty()
+ ? View::Both
+ : *cmWindowsRegistry::ToView(arguments.View);
+ cmWindowsRegistry registry(makefile);
+ if (arguments.ValueNames) {
+ auto result = registry.GetValueNames(key, view);
+ if (result) {
+ makefile.AddDefinition(variable, cmJoin(*result, ";"_s));
+ }
+ } else if (arguments.SubKeys) {
+ auto result = registry.GetSubKeys(key, view);
+ if (result) {
+ makefile.AddDefinition(variable, cmJoin(*result, ";"_s));
+ }
+ } else {
+ auto result =
+ registry.ReadValue(key, arguments.ValueName, view, arguments.Separator);
+ if (result) {
+ makefile.AddDefinition(variable, *result);
+ }
+ }
+
+ // return error message if requested
+ if (!arguments.ErrorVariable.empty()) {
+ makefile.AddDefinition(arguments.ErrorVariable, registry.GetLastError());
+ }
+
+ return true;
+}
+
// END Private functions
} // anonymous namespace
@@ -481,6 +576,11 @@ bool cmCMakeHostSystemInformationCommand(std::vector<std::string> const& args,
return false;
}
+ if (args[current_index + 1] == "WINDOWS_REGISTRY"_s) {
+ return QueryWindowsRegistry(cmMakeRange(args).advance(current_index + 2),
+ status, variable);
+ }
+
static cmsys::SystemInformation info;
static auto initialized = false;
if (!initialized) {
diff --git a/Source/cmCMakeLanguageCommand.cxx b/Source/cmCMakeLanguageCommand.cxx
index 789c78d..27d8cb8 100644
--- a/Source/cmCMakeLanguageCommand.cxx
+++ b/Source/cmCMakeLanguageCommand.cxx
@@ -84,7 +84,8 @@ bool cmCMakeLanguageCommandCALL(std::vector<cmListFileArgument> const& args,
for (size_t i = startArg; i < args.size(); ++i) {
funcArgs.emplace_back(args[i].Value, args[i].Delim, context.Line);
}
- cmListFileFunction func{ callCommand, context.Line, std::move(funcArgs) };
+ cmListFileFunction func{ callCommand, context.Line, context.Line,
+ std::move(funcArgs) };
if (defer) {
if (defer->Id.empty()) {
diff --git a/Source/cmCMakePresetsGraph.cxx b/Source/cmCMakePresetsGraph.cxx
index dc14831..b737c1f 100644
--- a/Source/cmCMakePresetsGraph.cxx
+++ b/Source/cmCMakePresetsGraph.cxx
@@ -361,6 +361,13 @@ bool ExpandMacros(const cmCMakePresetsGraph& graph, const T& preset,
cmSystemTools::GetParentDirectory(preset.OriginFile->Filename);
return ExpandMacroResult::Ok;
}
+ if (macroName == "pathListSep") {
+ if (version < 5) {
+ return ExpandMacroResult::Error;
+ }
+ macroOut += cmSystemTools::GetSystemPathlistSeparator();
+ return ExpandMacroResult::Ok;
+ }
}
return ExpandMacroResult::Ignore;
@@ -781,6 +788,8 @@ cmCMakePresetsGraph::TestPreset::VisitPresetInherit(
parentOutput.MaxPassedTestOutputSize);
InheritOptionalValue(output.MaxFailedTestOutputSize,
parentOutput.MaxFailedTestOutputSize);
+ InheritOptionalValue(output.TestOutputTruncation,
+ parentOutput.TestOutputTruncation);
InheritOptionalValue(output.MaxTestNameWidth,
parentOutput.MaxTestNameWidth);
} else {
@@ -1035,6 +1044,9 @@ const char* cmCMakePresetsGraph::ResultToString(ReadFileResult result)
"support.";
case ReadFileResult::CYCLIC_INCLUDE:
return "Cyclic include among preset files";
+ case ReadFileResult::TEST_OUTPUT_TRUNCATION_UNSUPPORTED:
+ return "File version must be 5 or higher for testOutputTruncation "
+ "preset support.";
}
return "Unknown error";
diff --git a/Source/cmCMakePresetsGraph.h b/Source/cmCMakePresetsGraph.h
index 9d6c61a..f1f8662 100644
--- a/Source/cmCMakePresetsGraph.h
+++ b/Source/cmCMakePresetsGraph.h
@@ -14,6 +14,8 @@
#include <cm/optional>
+#include "CTest/cmCTestTypes.h"
+
enum class PackageResolveMode;
class cmCMakePresetsGraph
@@ -47,6 +49,7 @@ public:
CONDITION_UNSUPPORTED,
TOOLCHAIN_FILE_UNSUPPORTED,
CYCLIC_INCLUDE,
+ TEST_OUTPUT_TRUNCATION_UNSUPPORTED,
};
enum class ArchToolsetStrategy
@@ -226,6 +229,7 @@ public:
cm::optional<bool> SubprojectSummary;
cm::optional<int> MaxPassedTestOutputSize;
cm::optional<int> MaxFailedTestOutputSize;
+ cm::optional<cmCTestTypes::TruncationMode> TestOutputTruncation;
cm::optional<int> MaxTestNameWidth;
};
diff --git a/Source/cmCMakePresetsGraphReadJSON.cxx b/Source/cmCMakePresetsGraphReadJSON.cxx
index 85cf5be..d11e839 100644
--- a/Source/cmCMakePresetsGraphReadJSON.cxx
+++ b/Source/cmCMakePresetsGraphReadJSON.cxx
@@ -31,9 +31,10 @@ using ConfigurePreset = cmCMakePresetsGraph::ConfigurePreset;
using BuildPreset = cmCMakePresetsGraph::BuildPreset;
using TestPreset = cmCMakePresetsGraph::TestPreset;
using ArchToolsetStrategy = cmCMakePresetsGraph::ArchToolsetStrategy;
+using JSONHelperBuilder = cmJSONHelperBuilder<ReadFileResult>;
constexpr int MIN_VERSION = 1;
-constexpr int MAX_VERSION = 4;
+constexpr int MAX_VERSION = 5;
struct CMakeVersion
{
@@ -59,29 +60,26 @@ std::unique_ptr<cmCMakePresetsGraphInternal::NotCondition> InvertCondition(
return retval;
}
-auto const ConditionStringHelper = cmJSONStringHelper<ReadFileResult>(
+auto const ConditionStringHelper = JSONHelperBuilder::String(
ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION);
-auto const ConditionBoolHelper = cmJSONBoolHelper<ReadFileResult>(
+auto const ConditionBoolHelper = JSONHelperBuilder::Bool(
ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION);
-auto const ConditionStringListHelper =
- cmJSONVectorHelper<std::string, ReadFileResult>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION,
- ConditionStringHelper);
+auto const ConditionStringListHelper = JSONHelperBuilder::Vector<std::string>(
+ ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION,
+ ConditionStringHelper);
auto const ConstConditionHelper =
- cmJSONObjectHelper<cmCMakePresetsGraphInternal::ConstCondition,
- ReadFileResult>(ReadFileResult::READ_OK,
- ReadFileResult::INVALID_CONDITION, false)
+ JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::ConstCondition>(
+ ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false)
.Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
.Bind("value"_s, &cmCMakePresetsGraphInternal::ConstCondition::Value,
ConditionBoolHelper, true);
auto const EqualsConditionHelper =
- cmJSONObjectHelper<cmCMakePresetsGraphInternal::EqualsCondition,
- ReadFileResult>(ReadFileResult::READ_OK,
- ReadFileResult::INVALID_CONDITION, false)
+ JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::EqualsCondition>(
+ ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false)
.Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
.Bind("lhs"_s, &cmCMakePresetsGraphInternal::EqualsCondition::Lhs,
ConditionStringHelper, true)
@@ -89,9 +87,8 @@ auto const EqualsConditionHelper =
ConditionStringHelper, true);
auto const InListConditionHelper =
- cmJSONObjectHelper<cmCMakePresetsGraphInternal::InListCondition,
- ReadFileResult>(ReadFileResult::READ_OK,
- ReadFileResult::INVALID_CONDITION, false)
+ JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::InListCondition>(
+ ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false)
.Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
.Bind("string"_s, &cmCMakePresetsGraphInternal::InListCondition::String,
ConditionStringHelper, true)
@@ -99,9 +96,8 @@ auto const InListConditionHelper =
ConditionStringListHelper, true);
auto const MatchesConditionHelper =
- cmJSONObjectHelper<cmCMakePresetsGraphInternal::MatchesCondition,
- ReadFileResult>(ReadFileResult::READ_OK,
- ReadFileResult::INVALID_CONDITION, false)
+ JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::MatchesCondition>(
+ ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false)
.Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
.Bind("string"_s, &cmCMakePresetsGraphInternal::MatchesCondition::String,
ConditionStringHelper, true)
@@ -113,23 +109,20 @@ ReadFileResult SubConditionHelper(
const Json::Value* value);
auto const ListConditionVectorHelper =
- cmJSONVectorHelper<std::unique_ptr<cmCMakePresetsGraph::Condition>,
- ReadFileResult>(ReadFileResult::READ_OK,
- ReadFileResult::INVALID_CONDITION,
- SubConditionHelper);
+ JSONHelperBuilder::Vector<std::unique_ptr<cmCMakePresetsGraph::Condition>>(
+ ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION,
+ SubConditionHelper);
auto const AnyAllOfConditionHelper =
- cmJSONObjectHelper<cmCMakePresetsGraphInternal::AnyAllOfCondition,
- ReadFileResult>(ReadFileResult::READ_OK,
- ReadFileResult::INVALID_CONDITION, false)
+ JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::AnyAllOfCondition>(
+ ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false)
.Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
.Bind("conditions"_s,
&cmCMakePresetsGraphInternal::AnyAllOfCondition::Conditions,
ListConditionVectorHelper);
auto const NotConditionHelper =
- cmJSONObjectHelper<cmCMakePresetsGraphInternal::NotCondition,
- ReadFileResult>(ReadFileResult::READ_OK,
- ReadFileResult::INVALID_CONDITION, false)
+ JSONHelperBuilder::Object<cmCMakePresetsGraphInternal::NotCondition>(
+ ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false)
.Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
.Bind("condition"_s,
&cmCMakePresetsGraphInternal::NotCondition::SubCondition,
@@ -251,37 +244,36 @@ ReadFileResult EnvironmentHelper(cm::optional<std::string>& out,
return ReadFileResult::INVALID_PRESET;
}
-auto const VersionIntHelper = cmJSONIntHelper<ReadFileResult>(
+auto const VersionIntHelper = JSONHelperBuilder::Int(
ReadFileResult::READ_OK, ReadFileResult::INVALID_VERSION);
-auto const VersionHelper = cmJSONRequiredHelper<int, ReadFileResult>(
+auto const VersionHelper = JSONHelperBuilder::Required<int>(
ReadFileResult::NO_VERSION, VersionIntHelper);
auto const RootVersionHelper =
- cmJSONObjectHelper<int, ReadFileResult>(ReadFileResult::READ_OK,
- ReadFileResult::INVALID_ROOT)
+ JSONHelperBuilder::Object<int>(ReadFileResult::READ_OK,
+ ReadFileResult::INVALID_ROOT)
.Bind("version"_s, VersionHelper, false);
-auto const CMakeVersionUIntHelper = cmJSONUIntHelper<ReadFileResult>(
+auto const CMakeVersionUIntHelper = JSONHelperBuilder::UInt(
ReadFileResult::READ_OK, ReadFileResult::INVALID_VERSION);
auto const CMakeVersionHelper =
- cmJSONObjectHelper<CMakeVersion, ReadFileResult>(
+ JSONHelperBuilder::Object<CMakeVersion>(
ReadFileResult::READ_OK, ReadFileResult::INVALID_CMAKE_VERSION, false)
.Bind("major"_s, &CMakeVersion::Major, CMakeVersionUIntHelper, false)
.Bind("minor"_s, &CMakeVersion::Minor, CMakeVersionUIntHelper, false)
.Bind("patch"_s, &CMakeVersion::Patch, CMakeVersionUIntHelper, false);
-auto const IncludeHelper = cmJSONStringHelper<ReadFileResult>(
+auto const IncludeHelper = JSONHelperBuilder::String(
ReadFileResult::READ_OK, ReadFileResult::INVALID_INCLUDE);
-auto const IncludeVectorHelper =
- cmJSONVectorHelper<std::string, ReadFileResult>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_INCLUDE, IncludeHelper);
+auto const IncludeVectorHelper = JSONHelperBuilder::Vector<std::string>(
+ ReadFileResult::READ_OK, ReadFileResult::INVALID_INCLUDE, IncludeHelper);
auto const RootPresetsHelper =
- cmJSONObjectHelper<RootPresets, ReadFileResult>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_ROOT, false)
+ JSONHelperBuilder::Object<RootPresets>(ReadFileResult::READ_OK,
+ ReadFileResult::INVALID_ROOT, false)
.Bind<int>("version"_s, nullptr, VersionHelper)
.Bind("configurePresets"_s, &RootPresets::ConfigurePresets,
cmCMakePresetsGraphInternal::ConfigurePresetsHelper, false)
@@ -302,7 +294,7 @@ namespace cmCMakePresetsGraphInternal {
cmCMakePresetsGraph::ReadFileResult PresetStringHelper(
std::string& out, const Json::Value* value)
{
- static auto const helper = cmJSONStringHelper<ReadFileResult>(
+ static auto const helper = JSONHelperBuilder::String(
ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET);
return helper(out, value);
@@ -311,7 +303,7 @@ cmCMakePresetsGraph::ReadFileResult PresetStringHelper(
cmCMakePresetsGraph::ReadFileResult PresetVectorStringHelper(
std::vector<std::string>& out, const Json::Value* value)
{
- static auto const helper = cmJSONVectorHelper<std::string, ReadFileResult>(
+ static auto const helper = JSONHelperBuilder::Vector<std::string>(
ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET,
cmCMakePresetsGraphInternal::PresetStringHelper);
@@ -321,7 +313,7 @@ cmCMakePresetsGraph::ReadFileResult PresetVectorStringHelper(
cmCMakePresetsGraph::ReadFileResult PresetBoolHelper(bool& out,
const Json::Value* value)
{
- static auto const helper = cmJSONBoolHelper<ReadFileResult>(
+ static auto const helper = JSONHelperBuilder::Bool(
ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET);
return helper(out, value);
@@ -330,7 +322,7 @@ cmCMakePresetsGraph::ReadFileResult PresetBoolHelper(bool& out,
cmCMakePresetsGraph::ReadFileResult PresetOptionalBoolHelper(
cm::optional<bool>& out, const Json::Value* value)
{
- static auto const helper = cmJSONOptionalHelper<bool, ReadFileResult>(
+ static auto const helper = JSONHelperBuilder::Optional<bool>(
ReadFileResult::READ_OK, PresetBoolHelper);
return helper(out, value);
@@ -339,7 +331,7 @@ cmCMakePresetsGraph::ReadFileResult PresetOptionalBoolHelper(
cmCMakePresetsGraph::ReadFileResult PresetIntHelper(int& out,
const Json::Value* value)
{
- static auto const helper = cmJSONIntHelper<ReadFileResult>(
+ static auto const helper = JSONHelperBuilder::Int(
ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET);
return helper(out, value);
@@ -348,8 +340,8 @@ cmCMakePresetsGraph::ReadFileResult PresetIntHelper(int& out,
cmCMakePresetsGraph::ReadFileResult PresetOptionalIntHelper(
cm::optional<int>& out, const Json::Value* value)
{
- static auto const helper = cmJSONOptionalHelper<int, ReadFileResult>(
- ReadFileResult::READ_OK, PresetIntHelper);
+ static auto const helper =
+ JSONHelperBuilder::Optional<int>(ReadFileResult::READ_OK, PresetIntHelper);
return helper(out, value);
}
@@ -357,7 +349,7 @@ cmCMakePresetsGraph::ReadFileResult PresetOptionalIntHelper(
cmCMakePresetsGraph::ReadFileResult PresetVectorIntHelper(
std::vector<int>& out, const Json::Value* value)
{
- static auto const helper = cmJSONVectorHelper<int, ReadFileResult>(
+ static auto const helper = JSONHelperBuilder::Vector<int>(
ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, PresetIntHelper);
return helper(out, value);
@@ -409,10 +401,9 @@ cmCMakePresetsGraph::ReadFileResult EnvironmentMapHelper(
std::map<std::string, cm::optional<std::string>>& out,
const Json::Value* value)
{
- static auto const helper =
- cmJSONMapHelper<cm::optional<std::string>, ReadFileResult>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET,
- EnvironmentHelper);
+ static auto const helper = JSONHelperBuilder::Map<cm::optional<std::string>>(
+ ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET,
+ EnvironmentHelper);
return helper(out, value);
}
@@ -568,6 +559,11 @@ cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile(
return ReadFileResult::CONDITION_UNSUPPORTED;
}
+ // Support for TestOutputTruncation added in version 5.
+ if (v < 5 && preset.Output && preset.Output->TestOutputTruncation) {
+ return ReadFileResult::TEST_OUTPUT_TRUNCATION_UNSUPPORTED;
+ }
+
this->TestPresetOrder.push_back(preset.Name);
}
diff --git a/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx b/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx
index eefe2fe..430d7ee 100644
--- a/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx
+++ b/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx
@@ -20,6 +20,7 @@
namespace {
using ReadFileResult = cmCMakePresetsGraph::ReadFileResult;
using BuildPreset = cmCMakePresetsGraph::BuildPreset;
+using JSONHelperBuilder = cmJSONHelperBuilder<ReadFileResult>;
ReadFileResult PackageResolveModeHelper(cm::optional<PackageResolveMode>& out,
const Json::Value* value)
@@ -53,8 +54,8 @@ std::function<ReadFileResult(BuildPreset&, const Json::Value*)> const
};
auto const BuildPresetHelper =
- cmJSONObjectHelper<BuildPreset, ReadFileResult>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
+ JSONHelperBuilder::Object<BuildPreset>(ReadFileResult::READ_OK,
+ ReadFileResult::INVALID_PRESET, false)
.Bind("name"_s, &BuildPreset::Name,
cmCMakePresetsGraphInternal::PresetStringHelper)
.Bind("inherits"_s, &BuildPreset::Inherits,
@@ -99,7 +100,7 @@ namespace cmCMakePresetsGraphInternal {
ReadFileResult BuildPresetsHelper(std::vector<BuildPreset>& out,
const Json::Value* value)
{
- static auto const helper = cmJSONVectorHelper<BuildPreset, ReadFileResult>(
+ static auto const helper = JSONHelperBuilder::Vector<BuildPreset>(
ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS,
BuildPresetHelper);
diff --git a/Source/cmCMakePresetsGraphReadJSONConfigurePresets.cxx b/Source/cmCMakePresetsGraphReadJSONConfigurePresets.cxx
index 0f44546..7cff55a 100644
--- a/Source/cmCMakePresetsGraphReadJSONConfigurePresets.cxx
+++ b/Source/cmCMakePresetsGraphReadJSONConfigurePresets.cxx
@@ -21,6 +21,7 @@ using ReadFileResult = cmCMakePresetsGraph::ReadFileResult;
using CacheVariable = cmCMakePresetsGraph::CacheVariable;
using ConfigurePreset = cmCMakePresetsGraph::ConfigurePreset;
using ArchToolsetStrategy = cmCMakePresetsGraph::ArchToolsetStrategy;
+using JSONHelperBuilder = cmJSONHelperBuilder<ReadFileResult>;
ReadFileResult ArchToolsetStrategyHelper(
cm::optional<ArchToolsetStrategy>& out, const Json::Value* value)
@@ -53,7 +54,7 @@ ArchToolsetHelper(
cm::optional<ArchToolsetStrategy> ConfigurePreset::*strategyField)
{
auto const objectHelper =
- cmJSONObjectHelper<ConfigurePreset, ReadFileResult>(
+ JSONHelperBuilder::Object<ConfigurePreset>(
ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
.Bind("value", valueField,
cmCMakePresetsGraphInternal::PresetStringHelper, false)
@@ -85,7 +86,7 @@ auto const ArchitectureHelper = ArchToolsetHelper(
auto const ToolsetHelper = ArchToolsetHelper(
&ConfigurePreset::Toolset, &ConfigurePreset::ToolsetStrategy);
-auto const VariableStringHelper = cmJSONStringHelper<ReadFileResult>(
+auto const VariableStringHelper = JSONHelperBuilder::String(
ReadFileResult::READ_OK, ReadFileResult::INVALID_VARIABLE);
ReadFileResult VariableValueHelper(std::string& out, const Json::Value* value)
@@ -104,7 +105,7 @@ ReadFileResult VariableValueHelper(std::string& out, const Json::Value* value)
}
auto const VariableObjectHelper =
- cmJSONObjectHelper<CacheVariable, ReadFileResult>(
+ JSONHelperBuilder::Object<CacheVariable>(
ReadFileResult::READ_OK, ReadFileResult::INVALID_VARIABLE, false)
.Bind("type"_s, &CacheVariable::Type, VariableStringHelper, false)
.Bind("value"_s, &CacheVariable::Value, VariableValueHelper);
@@ -138,11 +139,11 @@ ReadFileResult VariableHelper(cm::optional<CacheVariable>& out,
}
auto const VariablesHelper =
- cmJSONMapHelper<cm::optional<CacheVariable>, ReadFileResult>(
+ JSONHelperBuilder::Map<cm::optional<CacheVariable>>(
ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, VariableHelper);
auto const PresetWarningsHelper =
- cmJSONObjectHelper<ConfigurePreset, ReadFileResult>(
+ JSONHelperBuilder::Object<ConfigurePreset>(
ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
.Bind("dev"_s, &ConfigurePreset::WarnDev,
cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false)
@@ -156,7 +157,7 @@ auto const PresetWarningsHelper =
cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false);
auto const PresetErrorsHelper =
- cmJSONObjectHelper<ConfigurePreset, ReadFileResult>(
+ JSONHelperBuilder::Object<ConfigurePreset>(
ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
.Bind("dev"_s, &ConfigurePreset::ErrorDev,
cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false)
@@ -164,7 +165,7 @@ auto const PresetErrorsHelper =
cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false);
auto const PresetDebugHelper =
- cmJSONObjectHelper<ConfigurePreset, ReadFileResult>(
+ JSONHelperBuilder::Object<ConfigurePreset>(
ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
.Bind("output"_s, &ConfigurePreset::DebugOutput,
cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false)
@@ -174,7 +175,7 @@ auto const PresetDebugHelper =
cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false);
auto const ConfigurePresetHelper =
- cmJSONObjectHelper<ConfigurePreset, ReadFileResult>(
+ JSONHelperBuilder::Object<ConfigurePreset>(
ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
.Bind("name"_s, &ConfigurePreset::Name,
cmCMakePresetsGraphInternal::PresetStringHelper)
@@ -218,10 +219,9 @@ namespace cmCMakePresetsGraphInternal {
ReadFileResult ConfigurePresetsHelper(std::vector<ConfigurePreset>& out,
const Json::Value* value)
{
- static auto const helper =
- cmJSONVectorHelper<ConfigurePreset, ReadFileResult>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS,
- ConfigurePresetHelper);
+ static auto const helper = JSONHelperBuilder::Vector<ConfigurePreset>(
+ ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS,
+ ConfigurePresetHelper);
return helper(out, value);
}
diff --git a/Source/cmCMakePresetsGraphReadJSONTestPresets.cxx b/Source/cmCMakePresetsGraphReadJSONTestPresets.cxx
index 4d6474a..c07d380 100644
--- a/Source/cmCMakePresetsGraphReadJSONTestPresets.cxx
+++ b/Source/cmCMakePresetsGraphReadJSONTestPresets.cxx
@@ -16,9 +16,12 @@
#include "cmCMakePresetsGraphInternal.h"
#include "cmJSONHelpers.h"
+#include "CTest/cmCTestTypes.h"
+
namespace {
using ReadFileResult = cmCMakePresetsGraph::ReadFileResult;
using TestPreset = cmCMakePresetsGraph::TestPreset;
+using JSONHelperBuilder = cmJSONHelperBuilder<ReadFileResult>;
ReadFileResult TestPresetOutputVerbosityHelper(
TestPreset::OutputOptions::VerbosityEnum& out, const Json::Value* value)
@@ -51,14 +54,43 @@ ReadFileResult TestPresetOutputVerbosityHelper(
}
auto const TestPresetOptionalOutputVerbosityHelper =
- cmJSONOptionalHelper<TestPreset::OutputOptions::VerbosityEnum,
- ReadFileResult>(ReadFileResult::READ_OK,
- TestPresetOutputVerbosityHelper);
+ JSONHelperBuilder::Optional<TestPreset::OutputOptions::VerbosityEnum>(
+ ReadFileResult::READ_OK, TestPresetOutputVerbosityHelper);
+
+ReadFileResult TestPresetOutputTruncationHelper(
+ cm::optional<cmCTestTypes::TruncationMode>& out, const Json::Value* value)
+{
+ if (!value) {
+ out = cm::nullopt;
+ return ReadFileResult::READ_OK;
+ }
+
+ if (!value->isString()) {
+ return ReadFileResult::INVALID_PRESET;
+ }
+
+ if (value->asString() == "tail") {
+ out = cmCTestTypes::TruncationMode::Tail;
+ return ReadFileResult::READ_OK;
+ }
+
+ if (value->asString() == "middle") {
+ out = cmCTestTypes::TruncationMode::Middle;
+ return ReadFileResult::READ_OK;
+ }
+
+ if (value->asString() == "head") {
+ out = cmCTestTypes::TruncationMode::Head;
+ return ReadFileResult::READ_OK;
+ }
+
+ return ReadFileResult::INVALID_PRESET;
+}
auto const TestPresetOptionalOutputHelper =
- cmJSONOptionalHelper<TestPreset::OutputOptions, ReadFileResult>(
+ JSONHelperBuilder::Optional<TestPreset::OutputOptions>(
ReadFileResult::READ_OK,
- cmJSONObjectHelper<TestPreset::OutputOptions, ReadFileResult>(
+ JSONHelperBuilder::Object<TestPreset::OutputOptions>(
ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
.Bind("shortProgress"_s, &TestPreset::OutputOptions::ShortProgress,
cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false)
@@ -83,16 +115,17 @@ auto const TestPresetOptionalOutputHelper =
.Bind("maxFailedTestOutputSize"_s,
&TestPreset::OutputOptions::MaxFailedTestOutputSize,
cmCMakePresetsGraphInternal::PresetOptionalIntHelper, false)
+ .Bind("testOutputTruncation"_s,
+ &TestPreset::OutputOptions::TestOutputTruncation,
+ TestPresetOutputTruncationHelper, false)
.Bind("maxTestNameWidth"_s, &TestPreset::OutputOptions::MaxTestNameWidth,
cmCMakePresetsGraphInternal::PresetOptionalIntHelper, false));
auto const TestPresetOptionalFilterIncludeIndexObjectHelper =
- cmJSONOptionalHelper<TestPreset::IncludeOptions::IndexOptions,
- ReadFileResult>(
+ JSONHelperBuilder::Optional<TestPreset::IncludeOptions::IndexOptions>(
ReadFileResult::READ_OK,
- cmJSONObjectHelper<TestPreset::IncludeOptions::IndexOptions,
- ReadFileResult>(ReadFileResult::READ_OK,
- ReadFileResult::INVALID_PRESET)
+ JSONHelperBuilder::Object<TestPreset::IncludeOptions::IndexOptions>(
+ ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET)
.Bind("start"_s, &TestPreset::IncludeOptions::IndexOptions::Start,
cmCMakePresetsGraphInternal::PresetOptionalIntHelper, false)
.Bind("end"_s, &TestPreset::IncludeOptions::IndexOptions::End,
@@ -126,9 +159,9 @@ ReadFileResult TestPresetOptionalFilterIncludeIndexHelper(
}
auto const TestPresetOptionalFilterIncludeHelper =
- cmJSONOptionalHelper<TestPreset::IncludeOptions, ReadFileResult>(
+ JSONHelperBuilder::Optional<TestPreset::IncludeOptions>(
ReadFileResult::READ_OK,
- cmJSONObjectHelper<TestPreset::IncludeOptions, ReadFileResult>(
+ JSONHelperBuilder::Object<TestPreset::IncludeOptions>(
ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET)
.Bind("name"_s, &TestPreset::IncludeOptions::Name,
cmCMakePresetsGraphInternal::PresetStringHelper, false)
@@ -140,12 +173,10 @@ auto const TestPresetOptionalFilterIncludeHelper =
cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false));
auto const TestPresetOptionalFilterExcludeFixturesHelper =
- cmJSONOptionalHelper<TestPreset::ExcludeOptions::FixturesOptions,
- ReadFileResult>(
+ JSONHelperBuilder::Optional<TestPreset::ExcludeOptions::FixturesOptions>(
ReadFileResult::READ_OK,
- cmJSONObjectHelper<TestPreset::ExcludeOptions::FixturesOptions,
- ReadFileResult>(ReadFileResult::READ_OK,
- ReadFileResult::INVALID_PRESET)
+ JSONHelperBuilder::Object<TestPreset::ExcludeOptions::FixturesOptions>(
+ ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET)
.Bind("any"_s, &TestPreset::ExcludeOptions::FixturesOptions::Any,
cmCMakePresetsGraphInternal::PresetStringHelper, false)
.Bind("setup"_s, &TestPreset::ExcludeOptions::FixturesOptions::Setup,
@@ -154,9 +185,9 @@ auto const TestPresetOptionalFilterExcludeFixturesHelper =
cmCMakePresetsGraphInternal::PresetStringHelper, false));
auto const TestPresetOptionalFilterExcludeHelper =
- cmJSONOptionalHelper<TestPreset::ExcludeOptions, ReadFileResult>(
+ JSONHelperBuilder::Optional<TestPreset::ExcludeOptions>(
ReadFileResult::READ_OK,
- cmJSONObjectHelper<TestPreset::ExcludeOptions, ReadFileResult>(
+ JSONHelperBuilder::Object<TestPreset::ExcludeOptions>(
ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET)
.Bind("name"_s, &TestPreset::ExcludeOptions::Name,
cmCMakePresetsGraphInternal::PresetStringHelper, false)
@@ -186,9 +217,8 @@ ReadFileResult TestPresetExecutionShowOnlyHelper(
}
auto const TestPresetOptionalExecutionShowOnlyHelper =
- cmJSONOptionalHelper<TestPreset::ExecutionOptions::ShowOnlyEnum,
- ReadFileResult>(ReadFileResult::READ_OK,
- TestPresetExecutionShowOnlyHelper);
+ JSONHelperBuilder::Optional<TestPreset::ExecutionOptions::ShowOnlyEnum>(
+ ReadFileResult::READ_OK, TestPresetExecutionShowOnlyHelper);
ReadFileResult TestPresetExecutionModeHelper(
TestPreset::ExecutionOptions::RepeatOptions::ModeEnum& out,
@@ -221,12 +251,10 @@ ReadFileResult TestPresetExecutionModeHelper(
}
auto const TestPresetOptionalExecutionRepeatHelper =
- cmJSONOptionalHelper<TestPreset::ExecutionOptions::RepeatOptions,
- ReadFileResult>(
+ JSONHelperBuilder::Optional<TestPreset::ExecutionOptions::RepeatOptions>(
ReadFileResult::READ_OK,
- cmJSONObjectHelper<TestPreset::ExecutionOptions::RepeatOptions,
- ReadFileResult>(ReadFileResult::READ_OK,
- ReadFileResult::INVALID_PRESET)
+ JSONHelperBuilder::Object<TestPreset::ExecutionOptions::RepeatOptions>(
+ ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET)
.Bind("mode"_s, &TestPreset::ExecutionOptions::RepeatOptions::Mode,
TestPresetExecutionModeHelper, true)
.Bind("count"_s, &TestPreset::ExecutionOptions::RepeatOptions::Count,
@@ -264,14 +292,13 @@ ReadFileResult TestPresetExecutionNoTestsActionHelper(
}
auto const TestPresetOptionalExecutionNoTestsActionHelper =
- cmJSONOptionalHelper<TestPreset::ExecutionOptions::NoTestsActionEnum,
- ReadFileResult>(ReadFileResult::READ_OK,
- TestPresetExecutionNoTestsActionHelper);
+ JSONHelperBuilder::Optional<TestPreset::ExecutionOptions::NoTestsActionEnum>(
+ ReadFileResult::READ_OK, TestPresetExecutionNoTestsActionHelper);
auto const TestPresetExecutionHelper =
- cmJSONOptionalHelper<TestPreset::ExecutionOptions, ReadFileResult>(
+ JSONHelperBuilder::Optional<TestPreset::ExecutionOptions>(
ReadFileResult::READ_OK,
- cmJSONObjectHelper<TestPreset::ExecutionOptions, ReadFileResult>(
+ JSONHelperBuilder::Object<TestPreset::ExecutionOptions>(
ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET)
.Bind("stopOnFailure"_s, &TestPreset::ExecutionOptions::StopOnFailure,
cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false)
@@ -299,9 +326,9 @@ auto const TestPresetExecutionHelper =
TestPresetOptionalExecutionNoTestsActionHelper, false));
auto const TestPresetFilterHelper =
- cmJSONOptionalHelper<TestPreset::FilterOptions, ReadFileResult>(
+ JSONHelperBuilder::Optional<TestPreset::FilterOptions>(
ReadFileResult::READ_OK,
- cmJSONObjectHelper<TestPreset::FilterOptions, ReadFileResult>(
+ JSONHelperBuilder::Object<TestPreset::FilterOptions>(
ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET)
.Bind("include"_s, &TestPreset::FilterOptions::Include,
TestPresetOptionalFilterIncludeHelper, false)
@@ -309,8 +336,8 @@ auto const TestPresetFilterHelper =
TestPresetOptionalFilterExcludeHelper, false));
auto const TestPresetHelper =
- cmJSONObjectHelper<TestPreset, ReadFileResult>(
- ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
+ JSONHelperBuilder::Object<TestPreset>(ReadFileResult::READ_OK,
+ ReadFileResult::INVALID_PRESET, false)
.Bind("name"_s, &TestPreset::Name,
cmCMakePresetsGraphInternal::PresetStringHelper)
.Bind("inherits"_s, &TestPreset::Inherits,
@@ -351,7 +378,7 @@ namespace cmCMakePresetsGraphInternal {
cmCMakePresetsGraph::ReadFileResult TestPresetsHelper(
std::vector<cmCMakePresetsGraph::TestPreset>& out, const Json::Value* value)
{
- static auto const helper = cmJSONVectorHelper<TestPreset, ReadFileResult>(
+ static auto const helper = JSONHelperBuilder::Vector<TestPreset>(
ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS,
TestPresetHelper);
diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx
index 1b11f20..abec968 100644
--- a/Source/cmCPluginAPI.cxx
+++ b/Source/cmCPluginAPI.cxx
@@ -432,7 +432,7 @@ static int CCONV cmExecuteCommand(void* arg, const char* name, int numArgs,
lffArgs.emplace_back(args[i], cmListFileArgument::Quoted, 0);
}
- cmListFileFunction lff{ name, 0, std::move(lffArgs) };
+ cmListFileFunction lff{ name, 0, 0, std::move(lffArgs) };
cmExecutionStatus status(*mf);
return mf->ExecuteCommand(lff, status);
}
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index a1e920e..710b4d7 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -2036,6 +2036,13 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
"Invalid value for '--test-output-size-failed': " << args[i]
<< "\n");
}
+ } else if (this->CheckArgument(arg, "--test-output-truncation"_s) &&
+ i < args.size() - 1) {
+ i++;
+ if (!this->Impl->TestHandler.SetTestOutputTruncation(args[i])) {
+ errormsg = "Invalid value for '--test-output-truncation': " + args[i];
+ return false;
+ }
} else if (this->CheckArgument(arg, "-N"_s, "--show-only")) {
this->Impl->ShowOnly = true;
} else if (cmHasLiteralPrefix(arg, "--show-only=")) {
@@ -2464,6 +2471,11 @@ bool cmCTest::SetArgsFromPreset(const std::string& presetName,
*expandedPreset->Output->MaxFailedTestOutputSize);
}
+ if (expandedPreset->Output->TestOutputTruncation) {
+ this->Impl->TestHandler.TestOutputTruncation =
+ *expandedPreset->Output->TestOutputTruncation;
+ }
+
if (expandedPreset->Output->MaxTestNameWidth) {
this->Impl->MaxTestNameWidth = *expandedPreset->Output->MaxTestNameWidth;
}
diff --git a/Source/cmCommandLineArgument.h b/Source/cmCommandLineArgument.h
index 72ab045..33c91bc 100644
--- a/Source/cmCommandLineArgument.h
+++ b/Source/cmCommandLineArgument.h
@@ -201,7 +201,57 @@ struct cmCommandLineArgument
return (parseState == ParseMode::Valid);
}
+ template <typename... Values>
+ static std::function<FunctionSignature> setToTrue(Values&&... values)
+ {
+ return ArgumentLambdaHelper<FunctionSignature>::generateSetToTrue(
+ std::forward<Values>(values)...);
+ }
+
+ template <typename... Values>
+ static std::function<FunctionSignature> setToValue(Values&&... values)
+ {
+ return ArgumentLambdaHelper<FunctionSignature>::generateSetToValue(
+ std::forward<Values>(values)...);
+ }
+
private:
+ template <typename T>
+ class ArgumentLambdaHelper;
+
+ template <typename... CallState>
+ class ArgumentLambdaHelper<bool(const std::string&, CallState...)>
+ {
+ public:
+ static std::function<bool(const std::string&, CallState...)>
+ generateSetToTrue(bool& value1)
+ {
+ return [&value1](const std::string&, CallState&&...) -> bool {
+ value1 = true;
+ return true;
+ };
+ }
+
+ static std::function<bool(const std::string&, CallState...)>
+ generateSetToTrue(bool& value1, bool& value2)
+ {
+ return [&value1, &value2](const std::string&, CallState&&...) -> bool {
+ value1 = true;
+ value2 = true;
+ return true;
+ };
+ }
+
+ static std::function<bool(const std::string&, CallState...)>
+ generateSetToValue(std::string& value1)
+ {
+ return [&value1](const std::string& arg, CallState&&...) -> bool {
+ value1 = arg;
+ return true;
+ };
+ }
+ };
+
std::string extract_single_value(std::string const& input,
ParseMode& parseState) const
{
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
index 129ef4b..b172c20 100644
--- a/Source/cmCommonTargetGenerator.cxx
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -2,7 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCommonTargetGenerator.h"
-#include <set>
+#include <algorithm>
#include <sstream>
#include <utility>
@@ -13,9 +13,11 @@
#include "cmLocalCommonGenerator.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
+#include "cmMessageType.h"
#include "cmOutputConverter.h"
#include "cmRange.h"
#include "cmSourceFile.h"
+#include "cmState.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmTarget.h"
@@ -321,3 +323,29 @@ std::string cmCommonTargetGenerator::GetLinkerLauncher(
}
return std::string();
}
+
+bool cmCommonTargetGenerator::HaveRequiredLanguages(
+ const std::vector<cmSourceFile const*>& sources,
+ std::set<std::string>& languagesNeeded) const
+{
+ for (cmSourceFile const* sf : sources) {
+ languagesNeeded.insert(sf->GetLanguage());
+ }
+
+ auto* makefile = this->Makefile;
+ auto* state = makefile->GetState();
+ auto unary = [&state, &makefile](const std::string& lang) -> bool {
+ const bool valid = state->GetLanguageEnabled(lang);
+ if (!valid) {
+ makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("The language ", lang,
+ " was requested for compilation but was not enabled."
+ " To enable a language it needs to be specified in a"
+ " 'project' or 'enable_language' command in the root"
+ " CMakeLists.txt"));
+ }
+ return valid;
+ };
+ return std::all_of(languagesNeeded.cbegin(), languagesNeeded.cend(), unary);
+}
diff --git a/Source/cmCommonTargetGenerator.h b/Source/cmCommonTargetGenerator.h
index 5aba1c6..1b804b4 100644
--- a/Source/cmCommonTargetGenerator.h
+++ b/Source/cmCommonTargetGenerator.h
@@ -5,6 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <map>
+#include <set>
#include <string>
#include <vector>
@@ -74,6 +75,9 @@ protected:
std::string GetLinkerLauncher(const std::string& config);
+ bool HaveRequiredLanguages(const std::vector<cmSourceFile const*>& sources,
+ std::set<std::string>& languagesNeeded) const;
+
private:
using ByLanguageMap = std::map<std::string, std::string>;
struct ByConfig
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index 370ddff..8cbdcaa 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -11,13 +11,18 @@
#include <utility>
#include <cm/memory>
+#include <cm/string_view>
+#include <cmext/string_view>
#include "cmComputeComponentGraph.h"
+#include "cmGeneratorExpression.h"
+#include "cmGeneratorExpressionDAGChecker.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
+#include "cmMessageType.h"
#include "cmRange.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
@@ -174,8 +179,62 @@ items that we know the linker will re-use automatically (shared libs).
*/
+namespace {
+// LINK_LIBRARY helpers
+const auto LL_BEGIN = "<LINK_LIBRARY:"_s;
+const auto LL_END = "</LINK_LIBRARY:"_s;
+
+inline std::string ExtractFeature(std::string const& item)
+{
+ return item.substr(LL_BEGIN.length(),
+ item.find('>', LL_BEGIN.length()) - LL_BEGIN.length());
+}
+
+bool IsFeatureSupported(cmMakefile* makefile, std::string const& linkLanguage,
+ std::string const& feature)
+{
+ auto featureSupported = cmStrCat(
+ "CMAKE_", linkLanguage, "_LINK_LIBRARY_USING_", feature, "_SUPPORTED");
+ if (makefile->GetDefinition(featureSupported).IsOn()) {
+ return true;
+ }
+
+ featureSupported =
+ cmStrCat("CMAKE_LINK_LIBRARY_USING_", feature, "_SUPPORTED");
+ return makefile->GetDefinition(featureSupported).IsOn();
+}
+
+// LINK_GROUP helpers
+const auto LG_BEGIN = "<LINK_GROUP:"_s;
+const auto LG_END = "</LINK_GROUP:"_s;
+
+inline std::string ExtractGroupFeature(std::string const& item)
+{
+ return item.substr(LG_BEGIN.length(),
+ item.find(':', LG_BEGIN.length()) - LG_BEGIN.length());
+}
+
+bool IsGroupFeatureSupported(cmMakefile* makefile,
+ std::string const& linkLanguage,
+ std::string const& feature)
+{
+ auto featureSupported = cmStrCat(
+ "CMAKE_", linkLanguage, "_LINK_GROUP_USING_", feature, "_SUPPORTED");
+ if (makefile->GetDefinition(featureSupported).IsOn()) {
+ return true;
+ }
+
+ featureSupported =
+ cmStrCat("CMAKE_LINK_GROUP_USING_", feature, "_SUPPORTED");
+ return makefile->GetDefinition(featureSupported).IsOn();
+}
+}
+
+const std::string cmComputeLinkDepends::LinkEntry::DEFAULT = "DEFAULT";
+
cmComputeLinkDepends::cmComputeLinkDepends(const cmGeneratorTarget* target,
- const std::string& config)
+ const std::string& config,
+ const std::string& linkLanguage)
{
// Store context information.
this->Target = target;
@@ -183,6 +242,50 @@ cmComputeLinkDepends::cmComputeLinkDepends(const cmGeneratorTarget* target,
this->GlobalGenerator =
this->Target->GetLocalGenerator()->GetGlobalGenerator();
this->CMakeInstance = this->GlobalGenerator->GetCMakeInstance();
+ this->LinkLanguage = linkLanguage;
+
+ // target oriented feature override property takes precedence over
+ // global override property
+ cm::string_view lloPrefix = "LINK_LIBRARY_OVERRIDE_"_s;
+ auto const& keys = this->Target->GetPropertyKeys();
+ std::for_each(
+ keys.cbegin(), keys.cend(),
+ [this, &lloPrefix, &config, &linkLanguage](std::string const& key) {
+ if (cmHasPrefix(key, lloPrefix)) {
+ if (cmValue feature = this->Target->GetProperty(key)) {
+ if (!feature->empty() && key.length() > lloPrefix.length()) {
+ auto item = key.substr(lloPrefix.length());
+ cmGeneratorExpressionDAGChecker dag{ this->Target->GetBacktrace(),
+ this->Target,
+ "LINK_LIBRARY_OVERRIDE",
+ nullptr, nullptr };
+ auto overrideFeature = cmGeneratorExpression::Evaluate(
+ feature, this->Target->GetLocalGenerator(), config, this->Target,
+ &dag, this->Target, linkLanguage);
+ this->LinkLibraryOverride.emplace(item, overrideFeature);
+ }
+ }
+ }
+ });
+ // global override property
+ if (cmValue linkLibraryOverride =
+ this->Target->GetProperty("LINK_LIBRARY_OVERRIDE")) {
+ cmGeneratorExpressionDAGChecker dag{ target->GetBacktrace(), target,
+ "LINK_LIBRARY_OVERRIDE", nullptr,
+ nullptr };
+ auto overrideValue = cmGeneratorExpression::Evaluate(
+ linkLibraryOverride, target->GetLocalGenerator(), config, target, &dag,
+ target, linkLanguage);
+
+ auto overrideList = cmTokenize(overrideValue, ","_s);
+ if (overrideList.size() >= 2) {
+ auto const& feature = overrideList.front();
+ for_each(overrideList.cbegin() + 1, overrideList.cend(),
+ [this, &feature](std::string const& item) {
+ this->LinkLibraryOverride.emplace(item, feature);
+ });
+ }
+ }
// The configuration being linked.
this->HasConfig = !config.empty();
@@ -234,6 +337,11 @@ cmComputeLinkDepends::Compute()
// Infer dependencies of targets for which they were not known.
this->InferDependencies();
+ // finalize groups dependencies
+ // All dependencies which are raw items must be replaced by the group
+ // it belongs to, if any.
+ this->UpdateGroupDependencies();
+
// Cleanup the constraint graph.
this->CleanConstraintGraph();
@@ -248,8 +356,21 @@ cmComputeLinkDepends::Compute()
this->DisplayConstraintGraph();
}
+ // Compute the DAG of strongly connected components. The algorithm
+ // used by cmComputeComponentGraph should identify the components in
+ // the same order in which the items were originally discovered in
+ // the BFS. This should preserve the original order when no
+ // constraints disallow it.
+ this->CCG =
+ cm::make_unique<cmComputeComponentGraph>(this->EntryConstraintGraph);
+ this->CCG->Compute();
+
+ if (!this->CheckCircularDependencies()) {
+ return this->FinalLinkEntries;
+ }
+
// Compute the final ordering.
- this->OrderLinkEntires();
+ this->OrderLinkEntries();
// Compute the final set of link entries.
// Iterate in reverse order so we can keep only the last occurrence
@@ -273,6 +394,29 @@ cmComputeLinkDepends::Compute()
// Reverse the resulting order since we iterated in reverse.
std::reverse(this->FinalLinkEntries.begin(), this->FinalLinkEntries.end());
+ // Expand group items
+ if (!this->GroupItems.empty()) {
+ for (const auto& group : this->GroupItems) {
+ const LinkEntry& groupEntry = this->EntryList[group.first];
+ auto it = this->FinalLinkEntries.begin();
+ while (true) {
+ it = std::find_if(it, this->FinalLinkEntries.end(),
+ [&groupEntry](const LinkEntry& entry) -> bool {
+ return groupEntry.Item == entry.Item;
+ });
+ if (it == this->FinalLinkEntries.end()) {
+ break;
+ }
+ it->Item.Value = "</LINK_GROUP>";
+ for (auto i = group.second.rbegin(); i != group.second.rend(); ++i) {
+ it = this->FinalLinkEntries.insert(it, this->EntryList[*i]);
+ }
+ it = this->FinalLinkEntries.insert(it, groupEntry);
+ it->Item.Value = "<LINK_GROUP>";
+ }
+ }
+ }
+
// Display the final set.
if (this->DebugMode) {
this->DisplayFinalEntries();
@@ -281,76 +425,91 @@ cmComputeLinkDepends::Compute()
return this->FinalLinkEntries;
}
-std::map<cmLinkItem, int>::iterator cmComputeLinkDepends::AllocateLinkEntry(
- cmLinkItem const& item)
+std::string const& cmComputeLinkDepends::GetCurrentFeature(
+ std::string const& item, std::string const& defaultFeature) const
+{
+ auto it = this->LinkLibraryOverride.find(item);
+ return it == this->LinkLibraryOverride.end() ? defaultFeature : it->second;
+}
+
+std::pair<std::map<cmLinkItem, int>::iterator, bool>
+cmComputeLinkDepends::AllocateLinkEntry(cmLinkItem const& item)
{
std::map<cmLinkItem, int>::value_type index_entry(
item, static_cast<int>(this->EntryList.size()));
- auto lei = this->LinkEntryIndex.insert(index_entry).first;
- this->EntryList.emplace_back();
- this->InferredDependSets.emplace_back();
- this->EntryConstraintGraph.emplace_back();
+ auto lei = this->LinkEntryIndex.insert(index_entry);
+ if (lei.second) {
+ this->EntryList.emplace_back();
+ this->InferredDependSets.emplace_back();
+ this->EntryConstraintGraph.emplace_back();
+ }
return lei;
}
-int cmComputeLinkDepends::AddLinkEntry(cmLinkItem const& item)
+std::pair<int, bool> cmComputeLinkDepends::AddLinkEntry(cmLinkItem const& item,
+ int groupIndex)
{
+ // Allocate a spot for the item entry.
+ auto lei = this->AllocateLinkEntry(item);
+
// Check if the item entry has already been added.
- auto lei = this->LinkEntryIndex.find(item);
- if (lei != this->LinkEntryIndex.end()) {
+ if (!lei.second) {
// Yes. We do not need to follow the item's dependencies again.
- return lei->second;
+ return { lei.first->second, false };
}
- // Allocate a spot for the item entry.
- lei = this->AllocateLinkEntry(item);
-
// Initialize the item entry.
- int index = lei->second;
+ int index = lei.first->second;
LinkEntry& entry = this->EntryList[index];
entry.Item = BT<std::string>(item.AsStr(), item.Backtrace);
entry.Target = item.Target;
- entry.IsFlag = (!entry.Target && entry.Item.Value[0] == '-' &&
- entry.Item.Value[1] != 'l' &&
- entry.Item.Value.substr(0, 10) != "-framework");
+ if (!entry.Target && entry.Item.Value[0] == '-' &&
+ entry.Item.Value[1] != 'l' &&
+ entry.Item.Value.substr(0, 10) != "-framework") {
+ entry.Kind = LinkEntry::Flag;
+ } else if (cmHasPrefix(entry.Item.Value, LG_BEGIN) &&
+ cmHasSuffix(entry.Item.Value, '>')) {
+ entry.Kind = LinkEntry::Group;
+ }
- // If the item has dependencies queue it to follow them.
- if (entry.Target) {
- // Target dependencies are always known. Follow them.
- BFSEntry qe = { index, nullptr };
- this->BFSQueue.push(qe);
- } else {
- // Look for an old-style <item>_LIB_DEPENDS variable.
- std::string var = cmStrCat(entry.Item.Value, "_LIB_DEPENDS");
- if (cmValue val = this->Makefile->GetDefinition(var)) {
- // The item dependencies are known. Follow them.
- BFSEntry qe = { index, val->c_str() };
+ if (entry.Kind != LinkEntry::Group) {
+ // If the item has dependencies queue it to follow them.
+ if (entry.Target) {
+ // Target dependencies are always known. Follow them.
+ BFSEntry qe = { index, groupIndex, nullptr };
this->BFSQueue.push(qe);
- } else if (!entry.IsFlag) {
- // The item dependencies are not known. We need to infer them.
- this->InferredDependSets[index].Initialized = true;
+ } else {
+ // Look for an old-style <item>_LIB_DEPENDS variable.
+ std::string var = cmStrCat(entry.Item.Value, "_LIB_DEPENDS");
+ if (cmValue val = this->Makefile->GetDefinition(var)) {
+ // The item dependencies are known. Follow them.
+ BFSEntry qe = { index, groupIndex, val->c_str() };
+ this->BFSQueue.push(qe);
+ } else if (entry.Kind != LinkEntry::Flag) {
+ // The item dependencies are not known. We need to infer them.
+ this->InferredDependSets[index].Initialized = true;
+ }
}
}
- return index;
+ return { index, true };
}
void cmComputeLinkDepends::AddLinkObject(cmLinkItem const& item)
{
+ // Allocate a spot for the item entry.
+ auto lei = this->AllocateLinkEntry(item);
+
// Check if the item entry has already been added.
- auto lei = this->LinkEntryIndex.find(item);
- if (lei != this->LinkEntryIndex.end()) {
+ if (!lei.second) {
return;
}
- // Allocate a spot for the item entry.
- lei = this->AllocateLinkEntry(item);
-
// Initialize the item entry.
- int index = lei->second;
+ int index = lei.first->second;
LinkEntry& entry = this->EntryList[index];
entry.Item = BT<std::string>(item.AsStr(), item.Backtrace);
- entry.IsObject = true;
+ entry.Kind = LinkEntry::Object;
// Record explicitly linked object files separately.
this->ObjectEntries.emplace_back(index);
@@ -359,8 +518,8 @@ void cmComputeLinkDepends::AddLinkObject(cmLinkItem const& item)
void cmComputeLinkDepends::FollowLinkEntry(BFSEntry qe)
{
// Get this entry representation.
- int depender_index = qe.Index;
- LinkEntry const& entry = this->EntryList[depender_index];
+ int depender_index = qe.GroupIndex == -1 ? qe.Index : qe.GroupIndex;
+ LinkEntry const& entry = this->EntryList[qe.Index];
// Follow the item's dependencies.
if (entry.Target) {
@@ -423,25 +582,24 @@ void cmComputeLinkDepends::QueueSharedDependencies(
void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
{
- // Check if the target already has an entry.
- auto lei = this->LinkEntryIndex.find(dep.Item);
- if (lei == this->LinkEntryIndex.end()) {
- // Allocate a spot for the item entry.
- lei = this->AllocateLinkEntry(dep.Item);
+ // Allocate a spot for the item entry.
+ auto lei = this->AllocateLinkEntry(dep.Item);
+ int index = lei.first->second;
+ // Check if the target does not already has an entry.
+ if (lei.second) {
// Initialize the item entry.
- LinkEntry& entry = this->EntryList[lei->second];
+ LinkEntry& entry = this->EntryList[index];
entry.Item = BT<std::string>(dep.Item.AsStr(), dep.Item.Backtrace);
entry.Target = dep.Item.Target;
// This item was added specifically because it is a dependent
// shared library. It may get special treatment
// in cmComputeLinkInformation.
- entry.IsSharedDep = true;
+ entry.Kind = LinkEntry::SharedDep;
}
// Get the link entry for this target.
- int index = lei->second;
LinkEntry& entry = this->EntryList[index];
// This shared library dependency must follow the item that listed
@@ -519,8 +677,8 @@ void cmComputeLinkDepends::AddVarLinkEntries(int depender_index,
void cmComputeLinkDepends::AddDirectLinkEntries()
{
// Add direct link dependencies in this configuration.
- cmLinkImplementation const* impl =
- this->Target->GetLinkImplementation(this->Config);
+ cmLinkImplementation const* impl = this->Target->GetLinkImplementation(
+ this->Config, cmGeneratorTarget::LinkInterfaceFor::Link);
this->AddLinkEntries(-1, impl->Libraries);
this->AddLinkObjects(impl->Objects);
@@ -541,6 +699,11 @@ void cmComputeLinkDepends::AddLinkEntries(int depender_index,
{
// Track inferred dependency sets implied by this list.
std::map<int, DependSet> dependSets;
+ std::string feature = LinkEntry::DEFAULT;
+
+ bool inGroup = false;
+ std::pair<int, bool> groupIndex{ -1, false };
+ std::vector<int> groupItems;
// Loop over the libraries linked directly by the depender.
for (T const& l : libs) {
@@ -551,35 +714,233 @@ void cmComputeLinkDepends::AddLinkEntries(int depender_index,
continue;
}
+ if (cmHasPrefix(item.AsStr(), LL_BEGIN) &&
+ cmHasSuffix(item.AsStr(), '>')) {
+ feature = ExtractFeature(item.AsStr());
+ // emit a warning if an undefined feature is used as part of
+ // an imported target
+ if (depender_index >= 0) {
+ const auto& depender = this->EntryList[depender_index];
+ if (depender.Target != nullptr && depender.Target->IsImported() &&
+ !IsFeatureSupported(this->Makefile, this->LinkLanguage, feature)) {
+ this->CMakeInstance->IssueMessage(
+ MessageType::AUTHOR_ERROR,
+ cmStrCat("The 'IMPORTED' target '", depender.Target->GetName(),
+ "' uses the generator-expression '$<LINK_LIBRARY>' with "
+ "the feature '",
+ feature,
+ "', which is undefined or unsupported.\nDid you miss to "
+ "define it by setting variables \"CMAKE_",
+ this->LinkLanguage, "_LINK_LIBRARY_USING_", feature,
+ "\" and \"CMAKE_", this->LinkLanguage,
+ "_LINK_LIBRARY_USING_", feature, "_SUPPORTED\"?"),
+ this->Target->GetBacktrace());
+ }
+ }
+ continue;
+ }
+ if (cmHasPrefix(item.AsStr(), LL_END) && cmHasSuffix(item.AsStr(), '>')) {
+ feature = LinkEntry::DEFAULT;
+ continue;
+ }
+
+ if (cmHasPrefix(item.AsStr(), LG_BEGIN) &&
+ cmHasSuffix(item.AsStr(), '>')) {
+ groupIndex = this->AddLinkEntry(item);
+ if (groupIndex.second) {
+ LinkEntry& entry = this->EntryList[groupIndex.first];
+ entry.Feature = ExtractGroupFeature(item.AsStr());
+ }
+ inGroup = true;
+ if (depender_index >= 0) {
+ this->EntryConstraintGraph[depender_index].emplace_back(
+ groupIndex.first, false, false, cmListFileBacktrace());
+ } else {
+ // This is a direct dependency of the target being linked.
+ this->OriginalEntries.push_back(groupIndex.first);
+ }
+ continue;
+ }
+
+ int dependee_index;
+
+ if (cmHasPrefix(item.AsStr(), LG_END) && cmHasSuffix(item.AsStr(), '>')) {
+ dependee_index = groupIndex.first;
+ if (groupIndex.second) {
+ this->GroupItems.emplace(groupIndex.first, groupItems);
+ }
+ inGroup = false;
+ groupIndex = std::make_pair(-1, false);
+ groupItems.clear();
+ continue;
+ }
+
+ if (depender_index >= 0 && inGroup) {
+ const auto& depender = this->EntryList[depender_index];
+ const auto& groupFeature = this->EntryList[groupIndex.first].Feature;
+ if (depender.Target != nullptr && depender.Target->IsImported() &&
+ !IsGroupFeatureSupported(this->Makefile, this->LinkLanguage,
+ groupFeature)) {
+ this->CMakeInstance->IssueMessage(
+ MessageType::AUTHOR_ERROR,
+ cmStrCat("The 'IMPORTED' target '", depender.Target->GetName(),
+ "' uses the generator-expression '$<LINK_GROUP>' with "
+ "the feature '",
+ groupFeature,
+ "', which is undefined or unsupported.\nDid you miss to "
+ "define it by setting variables \"CMAKE_",
+ this->LinkLanguage, "_LINK_GROUP_USING_", groupFeature,
+ "\" and \"CMAKE_", this->LinkLanguage, "_LINK_GROUP_USING_",
+ groupFeature, "_SUPPORTED\"?"),
+ this->Target->GetBacktrace());
+ }
+ }
+
// Add a link entry for this item.
- int dependee_index = this->AddLinkEntry(l);
+ auto ale = this->AddLinkEntry(item, groupIndex.first);
+ dependee_index = ale.first;
+ LinkEntry& entry = this->EntryList[dependee_index];
+ auto const& itemFeature =
+ this->GetCurrentFeature(entry.Item.Value, feature);
+ if (inGroup && ale.second && entry.Target != nullptr &&
+ (entry.Target->GetType() == cmStateEnums::TargetType::OBJECT_LIBRARY ||
+ entry.Target->GetType() ==
+ cmStateEnums::TargetType::INTERFACE_LIBRARY)) {
+ const auto& groupFeature = this->EntryList[groupIndex.first].Feature;
+ this->CMakeInstance->IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat(
+ "The feature '", groupFeature,
+ "', specified as part of a generator-expression "
+ "'$",
+ LG_BEGIN, groupFeature, ">', will not be applied to the ",
+ (entry.Target->GetType() == cmStateEnums::TargetType::OBJECT_LIBRARY
+ ? "OBJECT"
+ : "INTERFACE"),
+ " library '", entry.Item.Value, "'."),
+ this->Target->GetBacktrace());
+ }
+ if (itemFeature != LinkEntry::DEFAULT) {
+ if (ale.second) {
+ // current item not yet defined
+ if (entry.Target != nullptr &&
+ (entry.Target->GetType() ==
+ cmStateEnums::TargetType::OBJECT_LIBRARY ||
+ entry.Target->GetType() ==
+ cmStateEnums::TargetType::INTERFACE_LIBRARY)) {
+ this->CMakeInstance->IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat("The feature '", feature,
+ "', specified as part of a generator-expression "
+ "'$",
+ LL_BEGIN, feature, ">', will not be applied to the ",
+ (entry.Target->GetType() ==
+ cmStateEnums::TargetType::OBJECT_LIBRARY
+ ? "OBJECT"
+ : "INTERFACE"),
+ " library '", entry.Item.Value, "'."),
+ this->Target->GetBacktrace());
+ } else {
+ entry.Feature = itemFeature;
+ }
+ }
+ }
- // The dependee must come after the depender.
- if (depender_index >= 0) {
- this->EntryConstraintGraph[depender_index].emplace_back(
- dependee_index, false, false, cmListFileBacktrace());
- } else {
- // This is a direct dependency of the target being linked.
- this->OriginalEntries.push_back(dependee_index);
- }
-
- // Update the inferred dependencies for earlier items.
- for (auto& dependSet : dependSets) {
- // Add this item to the inferred dependencies of other items.
- // Target items are never inferred dependees because unknown
- // items are outside libraries that should not be depending on
- // targets.
- if (!this->EntryList[dependee_index].Target &&
- !this->EntryList[dependee_index].IsFlag &&
- dependee_index != dependSet.first) {
- dependSet.second.insert(dependee_index);
+ bool supportedItem = entry.Target == nullptr ||
+ (entry.Target->GetType() != cmStateEnums::TargetType::OBJECT_LIBRARY &&
+ entry.Target->GetType() != cmStateEnums::TargetType::INTERFACE_LIBRARY);
+
+ if (supportedItem) {
+ if (inGroup) {
+ const auto& currentFeature = this->EntryList[groupIndex.first].Feature;
+ for (const auto& g : this->GroupItems) {
+ const auto& groupFeature = this->EntryList[g.first].Feature;
+ if (groupFeature == currentFeature) {
+ continue;
+ }
+ if (std::find(g.second.cbegin(), g.second.cend(), dependee_index) !=
+ g.second.cend()) {
+ this->CMakeInstance->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Impossible to link target '", this->Target->GetName(),
+ "' because the link item '", entry.Item.Value,
+ "', specified with the group feature '", currentFeature,
+ '\'', ", has already occurred with the feature '",
+ groupFeature, '\'', ", which is not allowed."),
+ this->Target->GetBacktrace());
+ continue;
+ }
+ }
+ }
+ if (entry.Feature != itemFeature) {
+ // incompatibles features occurred
+ this->CMakeInstance->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Impossible to link target '", this->Target->GetName(),
+ "' because the link item '", entry.Item.Value,
+ "', specified ",
+ (itemFeature == LinkEntry::DEFAULT
+ ? "without any feature or 'DEFAULT' feature"
+ : cmStrCat("with the feature '", itemFeature, '\'')),
+ ", has already occurred ",
+ (entry.Feature == LinkEntry::DEFAULT
+ ? "without any feature or 'DEFAULT' feature"
+ : cmStrCat("with the feature '", entry.Feature, '\'')),
+ ", which is not allowed."),
+ this->Target->GetBacktrace());
}
}
- // If this item needs to have dependencies inferred, do so.
- if (this->InferredDependSets[dependee_index].Initialized) {
- // Make sure an entry exists to hold the set for the item.
- dependSets[dependee_index];
+ if (inGroup) {
+ // store item index for dependencies handling
+ groupItems.push_back(dependee_index);
+ } else {
+ std::vector<int> indexes;
+ bool entryHandled = false;
+ // search any occurrence of the library in already defined groups
+ for (const auto& group : this->GroupItems) {
+ for (auto index : group.second) {
+ if (entry.Item.Value == this->EntryList[index].Item.Value) {
+ indexes.push_back(group.first);
+ entryHandled = true;
+ break;
+ }
+ }
+ }
+ if (!entryHandled) {
+ indexes.push_back(dependee_index);
+ }
+
+ for (auto index : indexes) {
+ // The dependee must come after the depender.
+ if (depender_index >= 0) {
+ this->EntryConstraintGraph[depender_index].emplace_back(
+ index, false, false, cmListFileBacktrace());
+ } else {
+ // This is a direct dependency of the target being linked.
+ this->OriginalEntries.push_back(index);
+ }
+
+ // Update the inferred dependencies for earlier items.
+ for (auto& dependSet : dependSets) {
+ // Add this item to the inferred dependencies of other items.
+ // Target items are never inferred dependees because unknown
+ // items are outside libraries that should not be depending on
+ // targets.
+ if (!this->EntryList[index].Target &&
+ this->EntryList[index].Kind != LinkEntry::Flag &&
+ this->EntryList[index].Kind != LinkEntry::Group &&
+ dependee_index != dependSet.first) {
+ dependSet.second.insert(index);
+ }
+ }
+
+ // If this item needs to have dependencies inferred, do so.
+ if (this->InferredDependSets[index].Initialized) {
+ // Make sure an entry exists to hold the set for the item.
+ dependSets[index];
+ }
+ }
}
}
@@ -642,6 +1003,36 @@ void cmComputeLinkDepends::InferDependencies()
}
}
+void cmComputeLinkDepends::UpdateGroupDependencies()
+{
+ if (this->GroupItems.empty()) {
+ return;
+ }
+
+ // Walks through all entries of the constraint graph to replace dependencies
+ // over raw items by the group it belongs to, if any.
+ for (auto& edgeList : this->EntryConstraintGraph) {
+ for (auto& edge : edgeList) {
+ int index = edge;
+ if (this->EntryList[index].Kind == LinkEntry::Group ||
+ this->EntryList[index].Kind == LinkEntry::Flag ||
+ this->EntryList[index].Kind == LinkEntry::Object) {
+ continue;
+ }
+ // search the item in the defined groups
+ for (const auto& groupItems : this->GroupItems) {
+ auto pos = std::find(groupItems.second.cbegin(),
+ groupItems.second.cend(), index);
+ if (pos != groupItems.second.cend()) {
+ // replace lib dependency by the group it belongs to
+ edge = cmGraphEdge{ groupItems.first, false, false,
+ cmListFileBacktrace() };
+ }
+ }
+ }
+ }
+}
+
void cmComputeLinkDepends::CleanConstraintGraph()
{
for (cmGraphEdgeList& edgeList : this->EntryConstraintGraph) {
@@ -655,6 +1046,76 @@ void cmComputeLinkDepends::CleanConstraintGraph()
}
}
+bool cmComputeLinkDepends::CheckCircularDependencies() const
+{
+ std::vector<NodeList> const& components = this->CCG->GetComponents();
+ int nc = static_cast<int>(components.size());
+ for (int c = 0; c < nc; ++c) {
+ // Get the current component.
+ NodeList const& nl = components[c];
+
+ // Skip trivial components.
+ if (nl.size() < 2) {
+ continue;
+ }
+
+ // no group must be evolved
+ bool cycleDetected = false;
+ for (int ni : nl) {
+ if (this->EntryList[ni].Kind == LinkEntry::Group) {
+ cycleDetected = true;
+ break;
+ }
+ }
+ if (!cycleDetected) {
+ continue;
+ }
+
+ // Construct the error message.
+ auto formatItem = [](LinkEntry const& entry) -> std::string {
+ if (entry.Kind == LinkEntry::Group) {
+ auto items =
+ entry.Item.Value.substr(entry.Item.Value.find(':', 12) + 1);
+ items.pop_back();
+ std::replace(items.begin(), items.end(), '|', ',');
+ return cmStrCat("group \"", ExtractGroupFeature(entry.Item.Value),
+ ":{", items, "}\"");
+ }
+ return cmStrCat('"', entry.Item.Value, '"');
+ };
+
+ std::ostringstream e;
+ e << "The inter-target dependency graph, for the target \""
+ << this->Target->GetName()
+ << "\", contains the following strongly connected component "
+ "(cycle):\n";
+ std::vector<int> const& cmap = this->CCG->GetComponentMap();
+ for (int i : nl) {
+ // Get the depender.
+ LinkEntry const& depender = this->EntryList[i];
+
+ // Describe the depender.
+ e << " " << formatItem(depender) << "\n";
+
+ // List its dependencies that are inside the component.
+ EdgeList const& el = this->EntryConstraintGraph[i];
+ for (cmGraphEdge const& ni : el) {
+ int j = ni;
+ if (cmap[j] == c) {
+ LinkEntry const& dependee = this->EntryList[j];
+ e << " depends on " << formatItem(dependee) << "\n";
+ }
+ }
+ }
+ this->CMakeInstance->IssueMessage(MessageType::FATAL_ERROR, e.str(),
+ this->Target->GetBacktrace());
+
+ return false;
+ }
+
+ return true;
+}
+
void cmComputeLinkDepends::DisplayConstraintGraph()
{
// Display the graph nodes and their edges.
@@ -667,17 +1128,8 @@ void cmComputeLinkDepends::DisplayConstraintGraph()
fprintf(stderr, "%s\n", e.str().c_str());
}
-void cmComputeLinkDepends::OrderLinkEntires()
+void cmComputeLinkDepends::OrderLinkEntries()
{
- // Compute the DAG of strongly connected components. The algorithm
- // used by cmComputeComponentGraph should identify the components in
- // the same order in which the items were originally discovered in
- // the BFS. This should preserve the original order when no
- // constraints disallow it.
- this->CCG =
- cm::make_unique<cmComputeComponentGraph>(this->EntryConstraintGraph);
- this->CCG->Compute();
-
// The component graph is guaranteed to be acyclic. Start a DFS
// from every entry to compute a topological order for the
// components.
@@ -867,12 +1319,23 @@ int cmComputeLinkDepends::ComputeComponentCount(NodeList const& nl)
void cmComputeLinkDepends::DisplayFinalEntries()
{
fprintf(stderr, "target [%s] links to:\n", this->Target->GetName().c_str());
+ char space[] = " ";
+ int count = 2;
for (LinkEntry const& lei : this->FinalLinkEntries) {
- if (lei.Target) {
- fprintf(stderr, " target [%s]\n", lei.Target->GetName().c_str());
+ if (lei.Kind == LinkEntry::Group) {
+ fprintf(stderr, " %s group",
+ lei.Item.Value == "<LINK_GROUP>" ? "start" : "end");
+ count = lei.Item.Value == "<LINK_GROUP>" ? 4 : 2;
+ } else if (lei.Target) {
+ fprintf(stderr, "%*starget [%s]", count, space,
+ lei.Target->GetName().c_str());
} else {
- fprintf(stderr, " item [%s]\n", lei.Item.Value.c_str());
+ fprintf(stderr, "%*sitem [%s]", count, space, lei.Item.Value.c_str());
+ }
+ if (lei.Feature != LinkEntry::DEFAULT) {
+ fprintf(stderr, ", feature [%s]", lei.Feature.c_str());
}
+ fprintf(stderr, "\n");
}
fprintf(stderr, "\n");
}
diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h
index 72316f1..8cc916a 100644
--- a/Source/cmComputeLinkDepends.h
+++ b/Source/cmComputeLinkDepends.h
@@ -9,6 +9,7 @@
#include <queue>
#include <set>
#include <string>
+#include <utility>
#include <vector>
#include "cmGraphAdjacencyList.h"
@@ -29,7 +30,8 @@ class cmComputeLinkDepends
{
public:
cmComputeLinkDepends(cmGeneratorTarget const* target,
- const std::string& config);
+ const std::string& config,
+ const std::string& linkLanguage);
~cmComputeLinkDepends();
cmComputeLinkDepends(const cmComputeLinkDepends&) = delete;
@@ -38,11 +40,32 @@ public:
// Basic information about each link item.
struct LinkEntry
{
+ LinkEntry() = default;
+ LinkEntry(BT<std::string> item, cmGeneratorTarget const* target = nullptr)
+ : Item(std::move(item))
+ , Target(target)
+ {
+ }
+
+ static const std::string DEFAULT;
+
+ enum EntryKind
+ {
+ Library,
+ Object,
+ SharedDep,
+ Flag,
+ // The following member is for the management of items specified
+ // through genex $<LINK_GROUP:...>
+ Group
+ };
+
BT<std::string> Item;
cmGeneratorTarget const* Target = nullptr;
- bool IsSharedDep = false;
- bool IsFlag = false;
- bool IsObject = false;
+ EntryKind Kind = Library;
+ // The following member is for the management of items specified
+ // through genex $<LINK_LIBRARY:...>
+ std::string Feature = std::string(DEFAULT);
};
using EntryVector = std::vector<LinkEntry>;
@@ -60,12 +83,18 @@ private:
cmMakefile* Makefile;
cmGlobalGenerator const* GlobalGenerator;
cmake* CMakeInstance;
+ std::string LinkLanguage;
std::string Config;
EntryVector FinalLinkEntries;
+ std::map<std::string, std::string> LinkLibraryOverride;
+
+ std::string const& GetCurrentFeature(
+ std::string const& item, std::string const& defaultFeature) const;
- std::map<cmLinkItem, int>::iterator AllocateLinkEntry(
+ std::pair<std::map<cmLinkItem, int>::iterator, bool> AllocateLinkEntry(
cmLinkItem const& item);
- int AddLinkEntry(cmLinkItem const& item);
+ std::pair<int, bool> AddLinkEntry(cmLinkItem const& item,
+ int groupIndex = -1);
void AddLinkObject(cmLinkItem const& item);
void AddVarLinkEntries(int depender_index, const char* value);
void AddDirectLinkEntries();
@@ -78,10 +107,14 @@ private:
std::vector<LinkEntry> EntryList;
std::map<cmLinkItem, int> LinkEntryIndex;
+ // map storing, for each group, the list of items
+ std::map<int, std::vector<int>> GroupItems;
+
// BFS of initial dependencies.
struct BFSEntry
{
int Index;
+ int GroupIndex;
const char* LibDepends;
};
std::queue<BFSEntry> BFSQueue;
@@ -114,16 +147,20 @@ private:
std::vector<DependSetList> InferredDependSets;
void InferDependencies();
+ // To finalize dependencies over groups in place of raw items
+ void UpdateGroupDependencies();
+
// Ordering constraint graph adjacency list.
using NodeList = cmGraphNodeList;
using EdgeList = cmGraphEdgeList;
using Graph = cmGraphAdjacencyList;
Graph EntryConstraintGraph;
void CleanConstraintGraph();
+ bool CheckCircularDependencies() const;
void DisplayConstraintGraph();
// Ordering algorithm.
- void OrderLinkEntires();
+ void OrderLinkEntries();
std::vector<char> ComponentVisited;
std::vector<int> ComponentOrder;
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index 2ff91fe..e156e3d 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -8,7 +8,9 @@
#include <utility>
#include <cm/memory>
+#include <cm/optional>
#include <cmext/algorithm>
+#include <cmext/string_view>
#include "cmComputeLinkDepends.h"
#include "cmGeneratorTarget.h"
@@ -18,7 +20,7 @@
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmOrderDirectories.h"
-#include "cmOutputConverter.h"
+#include "cmPlaceholderExpander.h"
#include "cmPolicies.h"
#include "cmState.h"
#include "cmStateTypes.h"
@@ -344,6 +346,29 @@ cmComputeLinkInformation::cmComputeLinkInformation(
this->LinkWithRuntimePath = this->Makefile->IsOn(var);
}
+ // Define some Feature descriptors to handle standard library and object link
+ if (!this->GetLibLinkFileFlag().empty()) {
+ this->LibraryFeatureDescriptors.emplace(
+ "__CMAKE_LINK_LIBRARY",
+ LibraryFeatureDescriptor{
+ "__CMAKE_LINK_LIBRARY",
+ cmStrCat(this->GetLibLinkFileFlag(), "<LIBRARY>") });
+ }
+ if (!this->GetObjLinkFileFlag().empty()) {
+ this->LibraryFeatureDescriptors.emplace(
+ "__CMAKE_LINK_OBJECT",
+ LibraryFeatureDescriptor{
+ "__CMAKE_LINK_OBJECT",
+ cmStrCat(this->GetObjLinkFileFlag(), "<LIBRARY>") });
+ }
+ if (!this->LoaderFlag->empty()) {
+ // Define a Feature descriptor for the link of an executable with exports
+ this->LibraryFeatureDescriptors.emplace(
+ "__CMAKE_LINK_EXECUTABLE",
+ LibraryFeatureDescriptor{ "__CMAKE_LINK_EXECUTABLE",
+ cmStrCat(this->LoaderFlag, "<LIBRARY>") });
+ }
+
// Check the platform policy for missing soname case.
this->NoSONameUsesPath =
this->Makefile->IsOn("CMAKE_PLATFORM_USES_PATH_WHEN_NO_SONAME");
@@ -409,6 +434,10 @@ cmComputeLinkInformation::cmComputeLinkInformation(
cmComputeLinkInformation::~cmComputeLinkInformation() = default;
+namespace {
+const std::string& DEFAULT = cmComputeLinkDepends::LinkEntry::DEFAULT;
+}
+
void cmComputeLinkInformation::AppendValues(
std::string& result, std::vector<BT<std::string>>& values)
{
@@ -510,17 +539,67 @@ bool cmComputeLinkInformation::Compute()
}
// Compute the ordered link line items.
- cmComputeLinkDepends cld(this->Target, this->Config);
+ cmComputeLinkDepends cld(this->Target, this->Config, this->LinkLanguage);
cld.SetOldLinkDirMode(this->OldLinkDirMode);
cmComputeLinkDepends::EntryVector const& linkEntries = cld.Compute();
+ FeatureDescriptor const* currentFeature = nullptr;
// Add the link line items.
for (cmComputeLinkDepends::LinkEntry const& linkEntry : linkEntries) {
- if (linkEntry.IsSharedDep) {
- this->AddSharedDepItem(linkEntry.Item, linkEntry.Target);
+ if (linkEntry.Kind == cmComputeLinkDepends::LinkEntry::Group) {
+ const auto& groupFeature = this->GetGroupFeature(linkEntry.Feature);
+ if (groupFeature.Supported) {
+ this->Items.emplace_back(
+ BT<std::string>{ linkEntry.Item.Value == "<LINK_GROUP>"
+ ? groupFeature.Prefix
+ : groupFeature.Suffix,
+ linkEntry.Item.Backtrace },
+ ItemIsPath::No);
+ }
+ continue;
+ }
+
+ if (currentFeature != nullptr &&
+ linkEntry.Feature != currentFeature->Name) {
+ // emit feature suffix, if any
+ if (!currentFeature->Suffix.empty()) {
+ this->Items.emplace_back(
+ BT<std::string>{ currentFeature->Suffix,
+ this->Items.back().Value.Backtrace },
+ ItemIsPath::No);
+ }
+ currentFeature = nullptr;
+ }
+
+ if (linkEntry.Feature != DEFAULT &&
+ (currentFeature == nullptr ||
+ linkEntry.Feature != currentFeature->Name)) {
+ if (!this->AddLibraryFeature(linkEntry.Feature)) {
+ continue;
+ }
+ currentFeature = this->FindLibraryFeature(linkEntry.Feature);
+ // emit feature prefix, if any
+ if (!currentFeature->Prefix.empty()) {
+ this->Items.emplace_back(
+ BT<std::string>{ currentFeature->Prefix, linkEntry.Item.Backtrace },
+ ItemIsPath::No);
+ }
+ }
+
+ if (linkEntry.Kind == cmComputeLinkDepends::LinkEntry::SharedDep) {
+ this->AddSharedDepItem(linkEntry);
} else {
- this->AddItem(linkEntry.Item, linkEntry.Target,
- linkEntry.IsObject ? ItemIsObject::Yes : ItemIsObject::No);
+ this->AddItem(linkEntry);
+ }
+ }
+
+ if (currentFeature != nullptr) {
+ // emit feature suffix, if any
+ if (!currentFeature->Suffix.empty()) {
+ this->Items.emplace_back(
+ BT<std::string>{ currentFeature->Suffix,
+ this->Items.back().Value.Backtrace },
+ ItemIsPath::No);
}
}
@@ -576,6 +655,377 @@ bool cmComputeLinkInformation::Compute()
return true;
}
+namespace {
+void FinalizeFeatureFormat(std::string& format, const std::string& activeTag,
+ const std::string& otherTag)
+{
+ auto pos = format.find(otherTag);
+ if (pos != std::string::npos) {
+ format.erase(pos, format.find('}', pos) - pos + 1);
+ }
+ pos = format.find(activeTag);
+ if (pos != std::string::npos) {
+ format.erase(pos, activeTag.length());
+ pos = format.find('}', pos);
+ if (pos != std::string::npos) {
+ format.erase(pos, 1);
+ }
+ }
+}
+
+bool IsValidFeatureFormat(const std::string& format)
+{
+ return format.find("<LIBRARY>") != std::string::npos ||
+ format.find("<LIB_ITEM>") != std::string::npos ||
+ format.find("<LINK_ITEM>") != std::string::npos;
+}
+
+class FeaturePlaceHolderExpander : public cmPlaceholderExpander
+{
+public:
+ FeaturePlaceHolderExpander(const std::string* library,
+ const std::string* libItem = nullptr,
+ const std::string* linkItem = nullptr)
+ : Library(library)
+ , LibItem(libItem)
+ , LinkItem(linkItem)
+ {
+ }
+
+private:
+ std::string ExpandVariable(std::string const& variable) override
+ {
+ if (this->Library != nullptr && variable == "LIBRARY") {
+ return *this->Library;
+ }
+ if (this->LibItem != nullptr && variable == "LIB_ITEM") {
+ return *this->LibItem;
+ }
+ if (this->LinkItem != nullptr && variable == "LINK_ITEM") {
+ return *this->LinkItem;
+ }
+
+ return variable;
+ }
+
+ const std::string* Library = nullptr;
+ const std::string* LibItem = nullptr;
+ const std::string* LinkItem = nullptr;
+};
+}
+
+cmComputeLinkInformation::FeatureDescriptor::FeatureDescriptor(
+ std::string name, std::string itemFormat)
+ : Name(std::move(name))
+ , Supported(true)
+ , ItemPathFormat(std::move(itemFormat))
+ , ItemNameFormat(this->ItemPathFormat)
+{
+}
+cmComputeLinkInformation::FeatureDescriptor::FeatureDescriptor(
+ std::string name, std::string itemPathFormat, std::string itemNameFormat)
+ : Name(std::move(name))
+ , Supported(true)
+ , ItemPathFormat(std::move(itemPathFormat))
+ , ItemNameFormat(std::move(itemNameFormat))
+{
+}
+cmComputeLinkInformation::FeatureDescriptor::FeatureDescriptor(
+ std::string name, std::string prefix, std::string itemPathFormat,
+ std::string itemNameFormat, std::string suffix)
+ : Name(std::move(name))
+ , Supported(true)
+ , Prefix(std::move(prefix))
+ , Suffix(std::move(suffix))
+ , ItemPathFormat(std::move(itemPathFormat))
+ , ItemNameFormat(std::move(itemNameFormat))
+{
+}
+cmComputeLinkInformation::FeatureDescriptor::FeatureDescriptor(
+ std::string name, std::string prefix, std::string suffix, bool)
+ : Name(std::move(name))
+ , Supported(true)
+ , Prefix(std::move(prefix))
+ , Suffix(std::move(suffix))
+{
+}
+
+std::string cmComputeLinkInformation::FeatureDescriptor::GetDecoratedItem(
+ std::string const& library, ItemIsPath isPath) const
+{
+ auto format =
+ isPath == ItemIsPath::Yes ? this->ItemPathFormat : this->ItemNameFormat;
+
+ // replace <LIBRARY>, <LIB_ITEM> and <LINK_ITEM> patterns with library path
+ FeaturePlaceHolderExpander expander(&library, &library, &library);
+ return expander.ExpandVariables(format);
+}
+std::string cmComputeLinkInformation::FeatureDescriptor::GetDecoratedItem(
+ std::string const& library, std::string const& libItem,
+ std::string const& linkItem, ItemIsPath isPath) const
+{
+ auto format =
+ isPath == ItemIsPath::Yes ? this->ItemPathFormat : this->ItemNameFormat;
+
+ // replace <LIBRARY>, <LIB_ITEM> and <LINK_ITEM> patterns
+ FeaturePlaceHolderExpander expander(&library, &libItem, &linkItem);
+ return expander.ExpandVariables(format);
+}
+
+cmComputeLinkInformation::LibraryFeatureDescriptor::LibraryFeatureDescriptor(
+ std::string name, std::string itemFormat)
+ : FeatureDescriptor(std::move(name), std::move(itemFormat))
+{
+}
+cmComputeLinkInformation::LibraryFeatureDescriptor::LibraryFeatureDescriptor(
+ std::string name, std::string itemPathFormat, std::string itemNameFormat)
+ : FeatureDescriptor(std::move(name), std::move(itemPathFormat),
+ std::move(itemNameFormat))
+{
+}
+cmComputeLinkInformation::LibraryFeatureDescriptor::LibraryFeatureDescriptor(
+ std::string name, std::string prefix, std::string itemPathFormat,
+ std::string itemNameFormat, std::string suffix)
+ : FeatureDescriptor(std::move(name), std::move(prefix),
+ std::move(itemPathFormat), std::move(itemNameFormat),
+ std::move(suffix))
+{
+}
+
+bool cmComputeLinkInformation::AddLibraryFeature(std::string const& feature)
+{
+ auto it = this->LibraryFeatureDescriptors.find(feature);
+ if (it != this->LibraryFeatureDescriptors.end()) {
+ return it->second.Supported;
+ }
+
+ auto featureName =
+ cmStrCat("CMAKE_", this->LinkLanguage, "_LINK_LIBRARY_USING_", feature);
+ cmValue featureSupported =
+ this->Makefile->GetDefinition(cmStrCat(featureName, "_SUPPORTED"));
+ if (!featureSupported) {
+ // language specific variable is not defined, fallback to the more generic
+ // one
+ featureName = cmStrCat("CMAKE_LINK_LIBRARY_USING_", feature);
+ featureSupported =
+ this->Makefile->GetDefinition(cmStrCat(featureName, "_SUPPORTED"));
+ }
+ if (!featureSupported.IsOn()) {
+ this->LibraryFeatureDescriptors.emplace(feature, FeatureDescriptor{});
+
+ this->CMakeInstance->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(
+ "Feature '", feature,
+ "', specified through generator-expression '$<LINK_LIBRARY>' to "
+ "link target '",
+ this->Target->GetName(), "', is not supported for the '",
+ this->LinkLanguage, "' link language."),
+ this->Target->GetBacktrace());
+
+ return false;
+ }
+
+ cmValue langFeature = this->Makefile->GetDefinition(featureName);
+ if (!langFeature) {
+ this->LibraryFeatureDescriptors.emplace(feature, FeatureDescriptor{});
+
+ this->CMakeInstance->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(
+ "Feature '", feature,
+ "', specified through generator-expression '$<LINK_LIBRARY>' to "
+ "link target '",
+ this->Target->GetName(), "', is not defined for the '",
+ this->LinkLanguage, "' link language."),
+ this->Target->GetBacktrace());
+
+ return false;
+ }
+
+ auto items =
+ cmExpandListWithBacktrace(langFeature, this->Target->GetBacktrace(), true);
+
+ if ((items.size() == 1 && !IsValidFeatureFormat(items.front().Value)) ||
+ (items.size() == 3 && !IsValidFeatureFormat(items[1].Value))) {
+ this->LibraryFeatureDescriptors.emplace(feature, FeatureDescriptor{});
+ this->CMakeInstance->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Feature '", feature, "', specified by variable '", featureName,
+ "', is malformed (\"<LIBRARY>\", \"<LIB_ITEM>\", or "
+ "\"<LINK_ITEM>\" patterns "
+ "are missing) and cannot be used to link target '",
+ this->Target->GetName(), "'."),
+ this->Target->GetBacktrace());
+
+ return false;
+ }
+
+ // now, handle possible "PATH{}" and "NAME{}" patterns
+ if (items.size() == 1) {
+ items.push_back(items.front());
+ FinalizeFeatureFormat(items[0].Value, "PATH{", "NAME{");
+ FinalizeFeatureFormat(items[1].Value, "NAME{", "PATH{");
+ } else if (items.size() == 3) {
+ items.insert(items.begin() + 1, items[1]);
+ FinalizeFeatureFormat(items[1].Value, "PATH{", "NAME{");
+ FinalizeFeatureFormat(items[2].Value, "NAME{", "PATH{");
+ } else {
+ this->LibraryFeatureDescriptors.emplace(feature, FeatureDescriptor{});
+ this->CMakeInstance->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Feature '", feature, "', specified by variable '", featureName,
+ "', is malformed (wrong number of elements) and cannot be used "
+ "to link target '",
+ this->Target->GetName(), "'."),
+ this->Target->GetBacktrace());
+
+ return false;
+ }
+ if ((items.size() == 2 && !IsValidFeatureFormat(items[0].Value)) ||
+ (items.size() == 4 && !IsValidFeatureFormat(items[1].Value))) {
+ // PATH{} has wrong format
+ this->LibraryFeatureDescriptors.emplace(feature, FeatureDescriptor{});
+ this->CMakeInstance->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Feature '", feature, "', specified by variable '", featureName,
+ "', is malformed (\"<LIBRARY>\", \"<LIB_ITEM>\", or "
+ "\"<LINK_ITEM>\" patterns "
+ "are missing for \"PATH{}\" alternative) and cannot be used to "
+ "link target '",
+ this->Target->GetName(), "'."),
+ this->Target->GetBacktrace());
+
+ return false;
+ }
+ if ((items.size() == 2 && !IsValidFeatureFormat(items[1].Value)) ||
+ (items.size() == 4 && !IsValidFeatureFormat(items[2].Value))) {
+ // NAME{} has wrong format
+ this->LibraryFeatureDescriptors.emplace(feature, FeatureDescriptor{});
+ this->CMakeInstance->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Feature '", feature, "', specified by variable '", featureName,
+ "', is malformed (\"<LIBRARY>\", \"<LIB_ITEM>\", or "
+ "\"<LINK_ITEM>\" patterns "
+ "are missing for \"NAME{}\" alternative) and cannot be used to "
+ "link target '",
+ this->Target->GetName(), "'."),
+ this->Target->GetBacktrace());
+
+ return false;
+ }
+
+ // replace LINKER: pattern
+ this->Target->ResolveLinkerWrapper(items, this->LinkLanguage, true);
+
+ if (items.size() == 2) {
+ this->LibraryFeatureDescriptors.emplace(
+ feature,
+ LibraryFeatureDescriptor{ feature, items[0].Value, items[1].Value });
+ } else {
+ this->LibraryFeatureDescriptors.emplace(
+ feature,
+ LibraryFeatureDescriptor{ feature, items[0].Value, items[1].Value,
+ items[2].Value, items[3].Value });
+ }
+
+ return true;
+}
+
+cmComputeLinkInformation::FeatureDescriptor const&
+cmComputeLinkInformation::GetLibraryFeature(std::string const& feature) const
+{
+ return this->LibraryFeatureDescriptors.find(feature)->second;
+}
+cmComputeLinkInformation::FeatureDescriptor const*
+cmComputeLinkInformation::FindLibraryFeature(std::string const& feature) const
+{
+ auto it = this->LibraryFeatureDescriptors.find(feature);
+ if (it == this->LibraryFeatureDescriptors.end()) {
+ return nullptr;
+ }
+
+ return &it->second;
+}
+
+cmComputeLinkInformation::GroupFeatureDescriptor::GroupFeatureDescriptor(
+ std::string name, std::string prefix, std::string suffix)
+ : FeatureDescriptor(std::move(name), std::move(prefix), std::move(suffix),
+ true)
+{
+}
+
+cmComputeLinkInformation::FeatureDescriptor const&
+cmComputeLinkInformation::GetGroupFeature(std::string const& feature)
+{
+ auto it = this->GroupFeatureDescriptors.find(feature);
+ if (it != this->GroupFeatureDescriptors.end()) {
+ return it->second;
+ }
+
+ auto featureName =
+ cmStrCat("CMAKE_", this->LinkLanguage, "_LINK_GROUP_USING_", feature);
+ cmValue featureSupported =
+ this->Makefile->GetDefinition(cmStrCat(featureName, "_SUPPORTED"));
+ if (!featureSupported) {
+ // language specific variable is not defined, fallback to the more generic
+ // one
+ featureName = cmStrCat("CMAKE_LINK_GROUP_USING_", feature);
+ featureSupported =
+ this->Makefile->GetDefinition(cmStrCat(featureName, "_SUPPORTED"));
+ }
+ if (!featureSupported.IsOn()) {
+ this->CMakeInstance->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Feature '", feature,
+ "', specified through generator-expression '$<LINK_GROUP>' to "
+ "link target '",
+ this->Target->GetName(), "', is not supported for the '",
+ this->LinkLanguage, "' link language."),
+ this->Target->GetBacktrace());
+ return this->GroupFeatureDescriptors.emplace(feature, FeatureDescriptor{})
+ .first->second;
+ }
+
+ cmValue langFeature = this->Makefile->GetDefinition(featureName);
+ if (!langFeature) {
+ this->CMakeInstance->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Feature '", feature,
+ "', specified through generator-expression '$<LINK_GROUP>' to "
+ "link target '",
+ this->Target->GetName(), "', is not defined for the '",
+ this->LinkLanguage, "' link language."),
+ this->Target->GetBacktrace());
+ return this->GroupFeatureDescriptors.emplace(feature, FeatureDescriptor{})
+ .first->second;
+ }
+
+ auto items =
+ cmExpandListWithBacktrace(langFeature, this->Target->GetBacktrace(), true);
+
+ // replace LINKER: pattern
+ this->Target->ResolveLinkerWrapper(items, this->LinkLanguage, true);
+
+ if (items.size() == 2) {
+ return this->GroupFeatureDescriptors
+ .emplace(
+ feature,
+ GroupFeatureDescriptor{ feature, items[0].Value, items[1].Value })
+ .first->second;
+ }
+
+ this->CMakeInstance->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Feature '", feature, "', specified by variable '", featureName,
+ "', is malformed (wrong number of elements) and cannot be used "
+ "to link target '",
+ this->Target->GetName(), "'."),
+ this->Target->GetBacktrace());
+ return this->GroupFeatureDescriptors.emplace(feature, FeatureDescriptor{})
+ .first->second;
+}
+
void cmComputeLinkInformation::AddImplicitLinkInfo()
{
// The link closure lists all languages whose implicit info is needed.
@@ -610,7 +1060,7 @@ void cmComputeLinkInformation::AddRuntimeLinkLibrary(std::string const& lang)
std::vector<std::string> libsVec = cmExpandedList(*runtimeLinkOptions);
for (std::string const& i : libsVec) {
if (!cm::contains(this->ImplicitLinkLibs, i)) {
- this->AddItem(i, nullptr);
+ this->AddItem({ i });
}
}
}
@@ -625,7 +1075,7 @@ void cmComputeLinkInformation::AddImplicitLinkInfo(std::string const& lang)
std::vector<std::string> libsVec = cmExpandedList(*libs);
for (std::string const& i : libsVec) {
if (!cm::contains(this->ImplicitLinkLibs, i)) {
- this->AddItem(i, nullptr);
+ this->AddItem({ i });
}
}
}
@@ -639,10 +1089,11 @@ void cmComputeLinkInformation::AddImplicitLinkInfo(std::string const& lang)
}
}
-void cmComputeLinkInformation::AddItem(BT<std::string> const& item,
- cmGeneratorTarget const* tgt,
- ItemIsObject isObject)
+void cmComputeLinkInformation::AddItem(LinkEntry const& entry)
{
+ cmGeneratorTarget const* tgt = entry.Target;
+ BT<std::string> const& item = entry.Item;
+
// Compute the proper name to use to link this library.
const std::string& config = this->Config;
bool impexe = (tgt && tgt->IsExecutableWithExports());
@@ -657,28 +1108,27 @@ void cmComputeLinkInformation::AddItem(BT<std::string> const& item,
if (impexe && this->LoaderFlag) {
// This link item is an executable that may provide symbols
// used by this target. A special flag is needed on this
- // platform. Add it now.
- std::string linkItem = this->LoaderFlag;
+ // platform. Add it now using a special feature.
cmStateEnums::ArtifactType artifact = tgt->HasImportLibrary(config)
? cmStateEnums::ImportLibraryArtifact
: cmStateEnums::RuntimeBinaryArtifact;
-
std::string exe = tgt->GetFullPath(config, artifact, true);
- linkItem += exe;
- this->Items.emplace_back(BT<std::string>(linkItem, item.Backtrace),
- ItemIsPath::Yes, ItemIsObject::No, tgt);
+ this->Items.emplace_back(
+ BT<std::string>(exe, item.Backtrace), ItemIsPath::Yes, tgt,
+ this->FindLibraryFeature(entry.Feature == DEFAULT
+ ? "__CMAKE_LINK_EXECUTABLE"
+ : entry.Feature));
this->Depends.push_back(std::move(exe));
} else if (tgt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
// Add the interface library as an item so it can be considered as part
// of COMPATIBLE_INTERFACE_ enforcement. The generators will ignore
// this for the actual link line.
- this->Items.emplace_back(std::string(), ItemIsPath::No, ItemIsObject::No,
- tgt);
+ this->Items.emplace_back(std::string(), ItemIsPath::No, tgt);
// Also add the item the interface specifies to be used in its place.
std::string const& libName = tgt->GetImportedLibName(config);
if (!libName.empty()) {
- this->AddItem(BT<std::string>(libName, item.Backtrace), nullptr);
+ this->AddItem(BT<std::string>(libName, item.Backtrace));
}
} else if (tgt->GetType() == cmStateEnums::OBJECT_LIBRARY) {
// Ignore object library!
@@ -706,7 +1156,9 @@ void cmComputeLinkInformation::AddItem(BT<std::string> const& item,
this->Depends.push_back(lib.Value);
}
- this->AddTargetItem(lib, tgt);
+ LinkEntry libEntry{ entry };
+ libEntry.Item = lib;
+ this->AddTargetItem(libEntry);
this->AddLibraryRuntimeInfo(lib.Value, tgt);
if (tgt && tgt->GetType() == cmStateEnums::SHARED_LIBRARY &&
this->Target->IsDLLPlatform()) {
@@ -715,30 +1167,34 @@ void cmComputeLinkInformation::AddItem(BT<std::string> const& item,
}
} else {
// This is not a CMake target. Use the name given.
- if (cmSystemTools::FileIsFullPath(item.Value)) {
- if (cmSystemTools::IsPathToFramework(item.Value) &&
- this->Makefile->IsOn("APPLE")) {
- // This is a framework.
- this->AddFrameworkItem(item.Value);
- } else if (cmSystemTools::FileIsDirectory(item.Value)) {
+ if (cmHasSuffix(entry.Feature, "FRAMEWORK"_s) ||
+ (entry.Feature == DEFAULT &&
+ cmSystemTools::IsPathToFramework(item.Value) &&
+ this->Makefile->IsOn("APPLE"))) {
+ // This is a framework.
+ this->AddFrameworkItem(entry);
+ } else if (cmSystemTools::FileIsFullPath(item.Value)) {
+ if (cmSystemTools::FileIsDirectory(item.Value)) {
// This is a directory.
this->DropDirectoryItem(item);
} else {
// Use the full path given to the library file.
this->Depends.push_back(item.Value);
- this->AddFullItem(item, isObject);
+ this->AddFullItem(entry);
this->AddLibraryRuntimeInfo(item.Value);
}
} else {
// This is a library or option specified by the user.
- this->AddUserItem(item, true);
+ this->AddUserItem(entry, true);
}
}
}
-void cmComputeLinkInformation::AddSharedDepItem(BT<std::string> const& item,
- const cmGeneratorTarget* tgt)
+void cmComputeLinkInformation::AddSharedDepItem(LinkEntry const& entry)
{
+ BT<std::string> const& item = entry.Item;
+ const cmGeneratorTarget* tgt = entry.Target;
+
// Record dependencies on DLLs.
if (tgt && tgt->GetType() == cmStateEnums::SHARED_LIBRARY &&
this->Target->IsDLLPlatform() &&
@@ -776,7 +1232,7 @@ void cmComputeLinkInformation::AddSharedDepItem(BT<std::string> const& item,
// If in linking mode, just link to the shared library.
if (this->SharedDependencyMode == SharedDepModeLink) {
- this->AddItem(item, tgt);
+ this->AddItem(entry);
return;
}
@@ -1058,8 +1514,7 @@ void cmComputeLinkInformation::SetCurrentLinkType(LinkType lt)
}
}
-void cmComputeLinkInformation::AddTargetItem(BT<std::string> const& item,
- cmGeneratorTarget const* target)
+void cmComputeLinkInformation::AddTargetItem(LinkEntry const& entry)
{
// This is called to handle a link item that is a full path to a target.
// If the target is not a static library make sure the link type is
@@ -1067,6 +1522,9 @@ void cmComputeLinkInformation::AddTargetItem(BT<std::string> const& item,
// shared and static libraries but static-mode can handle only
// static libraries. If a previous user item changed the link type
// to static we need to make sure it is back to shared.
+ BT<std::string> const& item = entry.Item;
+ cmGeneratorTarget const* target = entry.Target;
+
if (target->GetType() != cmStateEnums::STATIC_LIBRARY) {
this->SetCurrentLinkType(LinkShared);
}
@@ -1079,7 +1537,7 @@ void cmComputeLinkInformation::AddTargetItem(BT<std::string> const& item,
// Handle case of an imported shared library with no soname.
if (this->NoSONameUsesPath &&
target->IsImportedSharedLibWithoutSOName(this->Config)) {
- this->AddSharedLibNoSOName(item.Value);
+ this->AddSharedLibNoSOName(entry);
return;
}
@@ -1091,20 +1549,60 @@ void cmComputeLinkInformation::AddTargetItem(BT<std::string> const& item,
this->OldLinkDirItems.push_back(item.Value);
}
- // Now add the full path to the library.
- this->Items.emplace_back(item, ItemIsPath::Yes, ItemIsObject::No, target);
+ if (target->IsFrameworkOnApple() && this->GlobalGenerator->IsXcode() &&
+ entry.Feature == DEFAULT) {
+ // ensure FRAMEWORK feature is loaded
+ this->AddLibraryFeature("FRAMEWORK");
+ }
+
+ if (target->IsFrameworkOnApple() && !this->GlobalGenerator->IsXcode()) {
+ // Add the framework directory and the framework item itself
+ auto fwItems = this->GlobalGenerator->SplitFrameworkPath(item.Value, true);
+ if (!fwItems) {
+ this->CMakeInstance->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Could not parse framework path \"", item.Value,
+ "\" linked by target ", this->Target->GetName(), '.'),
+ item.Backtrace);
+ return;
+ }
+ if (!fwItems->first.empty()) {
+ // Add the directory portion to the framework search path.
+ this->AddFrameworkPath(fwItems->first);
+ }
+ if (cmHasSuffix(entry.Feature, "FRAMEWORK"_s)) {
+ this->Items.emplace_back(fwItems->second, ItemIsPath::Yes, target,
+ this->FindLibraryFeature(entry.Feature));
+ } else {
+ this->Items.emplace_back(
+ item, ItemIsPath::Yes, target,
+ this->FindLibraryFeature(
+ entry.Feature == DEFAULT ? "__CMAKE_LINK_LIBRARY" : entry.Feature));
+ }
+ } else {
+ // Now add the full path to the library.
+ this->Items.emplace_back(
+ item, ItemIsPath::Yes, target,
+ this->FindLibraryFeature(
+ entry.Feature == DEFAULT
+ ? (target->IsFrameworkOnApple() && this->GlobalGenerator->IsXcode()
+ ? "FRAMEWORK"
+ : "__CMAKE_LINK_LIBRARY")
+ : entry.Feature));
+ }
}
-void cmComputeLinkInformation::AddFullItem(BT<std::string> const& item,
- ItemIsObject isObject)
+void cmComputeLinkInformation::AddFullItem(LinkEntry const& entry)
{
+ BT<std::string> const& item = entry.Item;
+
// Check for the implicit link directory special case.
- if (this->CheckImplicitDirItem(item.Value)) {
+ if (this->CheckImplicitDirItem(entry)) {
return;
}
// Check for case of shared library with no builtin soname.
- if (this->NoSONameUsesPath && this->CheckSharedLibNoSOName(item.Value)) {
+ if (this->NoSONameUsesPath && this->CheckSharedLibNoSOName(entry)) {
return;
}
@@ -1116,7 +1614,7 @@ void cmComputeLinkInformation::AddFullItem(BT<std::string> const& item,
generator.find("Xcode") != std::string::npos)) {
std::string file = cmSystemTools::GetFilenameName(item.Value);
if (!this->ExtractAnyLibraryName.find(file)) {
- this->HandleBadFullItem(item.Value, file);
+ this->HandleBadFullItem(entry, file);
return;
}
}
@@ -1147,11 +1645,20 @@ void cmComputeLinkInformation::AddFullItem(BT<std::string> const& item,
}
// Now add the full path to the library.
- this->Items.emplace_back(item, ItemIsPath::Yes, isObject);
+ this->Items.emplace_back(
+ item, ItemIsPath::Yes, nullptr,
+ this->FindLibraryFeature(
+ entry.Feature == DEFAULT
+ ? (entry.Kind == cmComputeLinkDepends::LinkEntry::Object
+ ? "__CMAKE_LINK_OBJECT"
+ : "__CMAKE_LINK_LIBRARY")
+ : entry.Feature));
}
-bool cmComputeLinkInformation::CheckImplicitDirItem(std::string const& item)
+bool cmComputeLinkInformation::CheckImplicitDirItem(LinkEntry const& entry)
{
+ BT<std::string> const& item = entry.Item;
+
// We only switch to a pathless item if the link type may be
// enforced. Fortunately only platforms that support link types
// seem to have magic per-architecture implicit link directories.
@@ -1160,7 +1667,7 @@ bool cmComputeLinkInformation::CheckImplicitDirItem(std::string const& item)
}
// Check if this item is in an implicit link directory.
- std::string dir = cmSystemTools::GetFilenamePath(item);
+ std::string dir = cmSystemTools::GetFilenamePath(item.Value);
if (!cm::contains(this->ImplicitLinkDirs, dir)) {
// Only libraries in implicit link directories are converted to
// pathless items.
@@ -1169,7 +1676,7 @@ bool cmComputeLinkInformation::CheckImplicitDirItem(std::string const& item)
// Only apply the policy below if the library file is one that can
// be found by the linker.
- std::string file = cmSystemTools::GetFilenameName(item);
+ std::string file = cmSystemTools::GetFilenameName(item.Value);
if (!this->ExtractAnyLibraryName.find(file)) {
return false;
}
@@ -1179,10 +1686,10 @@ bool cmComputeLinkInformation::CheckImplicitDirItem(std::string const& item)
case cmPolicies::WARN:
if (this->CMP0060Warn) {
// Print the warning at most once for this item.
- std::string const& wid = "CMP0060-WARNING-GIVEN-" + item;
+ std::string const& wid = "CMP0060-WARNING-GIVEN-" + item.Value;
if (!this->CMakeInstance->GetPropertyAsBool(wid)) {
this->CMakeInstance->SetProperty(wid, "1");
- this->CMP0060WarnItems.insert(item);
+ this->CMP0060WarnItems.insert(item.Value);
}
}
CM_FALLTHROUGH;
@@ -1200,15 +1707,17 @@ bool cmComputeLinkInformation::CheckImplicitDirItem(std::string const& item)
// directory then just report the file name without the directory
// portion. This will allow the system linker to locate the proper
// library for the architecture at link time.
- this->AddUserItem(file, false);
+ LinkEntry fileEntry{ entry };
+ fileEntry.Item = file;
+ this->AddUserItem(fileEntry, false);
// Make sure the link directory ordering will find the library.
- this->OrderLinkerSearchPath->AddLinkLibrary(item);
+ this->OrderLinkerSearchPath->AddLinkLibrary(item.Value);
return true;
}
-void cmComputeLinkInformation::AddUserItem(BT<std::string> const& item,
+void cmComputeLinkInformation::AddUserItem(LinkEntry const& entry,
bool pathNotKnown)
{
// This is called to handle a link item that does not match a CMake
@@ -1219,8 +1728,10 @@ void cmComputeLinkInformation::AddUserItem(BT<std::string> const& item,
// foo ==> -lfoo
// libfoo.a ==> -Wl,-Bstatic -lfoo
- // Pass flags through untouched.
+ BT<std::string> const& item = entry.Item;
+
if (item.Value[0] == '-' || item.Value[0] == '$' || item.Value[0] == '`') {
+ // Pass flags through untouched.
// if this is a -l option then we might need to warn about
// CMP0003 so put it in OldUserFlagItems, if it is not a -l
// or -Wl,-l (-framework -pthread), then allow it without a
@@ -1305,9 +1816,20 @@ void cmComputeLinkInformation::AddUserItem(BT<std::string> const& item,
}
// Create an option to ask the linker to search for the library.
- std::string out = cmStrCat(this->LibLinkFlag, lib, this->LibLinkSuffix);
- this->Items.emplace_back(BT<std::string>(out, item.Backtrace),
- ItemIsPath::No);
+ auto out = cmStrCat(this->LibLinkFlag, lib, this->LibLinkSuffix);
+
+ if (entry.Feature != DEFAULT) {
+ auto const& feature = this->GetLibraryFeature(entry.Feature);
+ this->Items.emplace_back(
+ BT<std::string>(
+ feature.GetDecoratedItem(cmStrCat(lib, this->LibLinkSuffix),
+ item.Value, out, ItemIsPath::No),
+ item.Backtrace),
+ ItemIsPath::No);
+ } else {
+ this->Items.emplace_back(BT<std::string>(out, item.Backtrace),
+ ItemIsPath::No);
+ }
// Here we could try to find the library the linker will find and
// add a runtime information entry for it. It would probably not be
@@ -1315,10 +1837,14 @@ void cmComputeLinkInformation::AddUserItem(BT<std::string> const& item,
// specification.
}
-void cmComputeLinkInformation::AddFrameworkItem(std::string const& item)
+void cmComputeLinkInformation::AddFrameworkItem(LinkEntry const& entry)
{
+ std::string const& item = entry.Item.Value;
+
// Try to separate the framework name and path.
- if (!this->SplitFramework.find(item)) {
+ auto fwItems =
+ this->GlobalGenerator->SplitFrameworkPath(item, entry.Feature != DEFAULT);
+ if (!fwItems) {
std::ostringstream e;
e << "Could not parse framework path \"" << item << "\" "
<< "linked by target " << this->Target->GetName() << ".";
@@ -1326,26 +1852,36 @@ void cmComputeLinkInformation::AddFrameworkItem(std::string const& item)
return;
}
- std::string fw_path = this->SplitFramework.match(1);
- std::string fw = this->SplitFramework.match(2);
- std::string full_fw = cmStrCat(fw_path, '/', fw, ".framework/", fw);
+ std::string fw_path = std::move(fwItems->first);
+ std::string fw = std::move(fwItems->second);
+ std::string full_fw = cmStrCat(fw, ".framework/", fw);
- // Add the directory portion to the framework search path.
- this->AddFrameworkPath(fw_path);
+ if (!fw_path.empty()) {
+ full_fw = cmStrCat(fw_path, '/', full_fw);
+ // Add the directory portion to the framework search path.
+ this->AddFrameworkPath(fw_path);
+ }
// add runtime information
this->AddLibraryRuntimeInfo(full_fw);
+ if (entry.Feature == DEFAULT) {
+ // ensure FRAMEWORK feature is loaded
+ this->AddLibraryFeature("FRAMEWORK");
+ }
+
if (this->GlobalGenerator->IsXcode()) {
// Add framework path - it will be handled by Xcode after it's added to
// "Link Binary With Libraries" build phase
- this->Items.emplace_back(item, ItemIsPath::Yes);
+ this->Items.emplace_back(item, ItemIsPath::Yes, nullptr,
+ this->FindLibraryFeature(entry.Feature == DEFAULT
+ ? "FRAMEWORK"
+ : entry.Feature));
} else {
- // Add the item using the -framework option.
- this->Items.emplace_back(std::string("-framework"), ItemIsPath::No);
- cmOutputConverter converter(this->Makefile->GetStateSnapshot());
- fw = converter.EscapeForShell(fw);
- this->Items.emplace_back(fw, ItemIsPath::No);
+ this->Items.emplace_back(fw, ItemIsPath::Yes, nullptr,
+ this->FindLibraryFeature(entry.Feature == DEFAULT
+ ? "FRAMEWORK"
+ : entry.Feature));
}
}
@@ -1355,10 +1891,10 @@ void cmComputeLinkInformation::DropDirectoryItem(BT<std::string> const& item)
// user.
this->CMakeInstance->IssueMessage(
MessageType::WARNING,
- cmStrCat(
- "Target \"", this->Target->GetName(),
- "\" requests linking to directory \"", item.Value,
- "\". Targets may link only to libraries. CMake is dropping the item."),
+ cmStrCat("Target \"", this->Target->GetName(),
+ "\" requests linking to directory \"", item.Value,
+ "\". Targets may link only to libraries. CMake is dropping "
+ "the item."),
item.Backtrace);
}
@@ -1378,9 +1914,6 @@ void cmComputeLinkInformation::ComputeFrameworkInfo()
this->FrameworkPathsEmitted.insert(implicitDirVec.begin(),
implicitDirVec.end());
-
- // Regular expression to extract a framework path and name.
- this->SplitFramework.compile("(.*)/(.*)\\.framework$");
}
void cmComputeLinkInformation::AddFrameworkPath(std::string const& p)
@@ -1390,42 +1923,44 @@ void cmComputeLinkInformation::AddFrameworkPath(std::string const& p)
}
}
-bool cmComputeLinkInformation::CheckSharedLibNoSOName(std::string const& item)
+bool cmComputeLinkInformation::CheckSharedLibNoSOName(LinkEntry const& entry)
{
// This platform will use the path to a library as its soname if the
// library is given via path and was not built with an soname. If
// this is a shared library that might be the case.
- std::string file = cmSystemTools::GetFilenameName(item);
+ std::string file = cmSystemTools::GetFilenameName(entry.Item.Value);
if (this->ExtractSharedLibraryName.find(file)) {
// If we can guess the soname fairly reliably then assume the
// library has one. Otherwise assume the library has no builtin
// soname.
std::string soname;
- if (!cmSystemTools::GuessLibrarySOName(item, soname)) {
- this->AddSharedLibNoSOName(item);
+ if (!cmSystemTools::GuessLibrarySOName(entry.Item.Value, soname)) {
+ this->AddSharedLibNoSOName(entry);
return true;
}
}
return false;
}
-void cmComputeLinkInformation::AddSharedLibNoSOName(std::string const& item)
+void cmComputeLinkInformation::AddSharedLibNoSOName(LinkEntry const& entry)
{
// We have a full path to a shared library with no soname. We need
// to ask the linker to locate the item because otherwise the path
// we give to it will be embedded in the target linked. Then at
// runtime the dynamic linker will search for the library using the
// path instead of just the name.
- std::string file = cmSystemTools::GetFilenameName(item);
- this->AddUserItem(file, false);
+ LinkEntry fileEntry{ entry };
+ fileEntry.Item = cmSystemTools::GetFilenameName(entry.Item.Value);
+ this->AddUserItem(fileEntry, false);
// Make sure the link directory ordering will find the library.
- this->OrderLinkerSearchPath->AddLinkLibrary(item);
+ this->OrderLinkerSearchPath->AddLinkLibrary(entry.Item.Value);
}
-void cmComputeLinkInformation::HandleBadFullItem(std::string const& item,
+void cmComputeLinkInformation::HandleBadFullItem(LinkEntry const& entry,
std::string const& file)
{
+ std::string const& item = entry.Item.Value;
// Do not depend on things that do not exist.
auto i = std::find(this->Depends.begin(), this->Depends.end(), item);
if (i != this->Depends.end()) {
@@ -1435,7 +1970,9 @@ void cmComputeLinkInformation::HandleBadFullItem(std::string const& item,
// Tell the linker to search for the item and provide the proper
// path for it. Do not contribute to any CMP0003 warning (do not
// put in OldLinkDirItems or OldUserFlagItems).
- this->AddUserItem(file, false);
+ LinkEntry fileEntry{ entry };
+ fileEntry.Item = file;
+ this->AddUserItem(fileEntry, false);
this->OrderLinkerSearchPath->AddLinkLibrary(item);
// Produce any needed message.
@@ -1781,8 +2318,8 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
// Add directories explicitly specified by user
std::string build_rpath;
if (this->Target->GetBuildRPATH(this->Config, build_rpath)) {
- // This will not resolve entries to use $ORIGIN, the user is expected to
- // do that if necessary.
+ // This will not resolve entries to use $ORIGIN, the user is expected
+ // to do that if necessary.
cmCLI_ExpandListUnique(build_rpath, runtimeDirs, emitted);
}
}
diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h
index 0315540..a4ada1f 100644
--- a/Source/cmComputeLinkInformation.h
+++ b/Source/cmComputeLinkInformation.h
@@ -5,6 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <iosfwd>
+#include <map>
#include <memory>
#include <set>
#include <string>
@@ -13,6 +14,7 @@
#include "cmsys/RegularExpression.hxx"
+#include "cmComputeLinkDepends.h"
#include "cmListFileCache.h"
#include "cmValue.h"
@@ -27,6 +29,9 @@ class cmake;
*/
class cmComputeLinkInformation
{
+private:
+ class FeatureDescriptor;
+
public:
cmComputeLinkInformation(cmGeneratorTarget const* target,
const std::string& config);
@@ -42,28 +47,38 @@ public:
Yes,
};
- enum class ItemIsObject
- {
- No,
- Yes,
- };
-
struct Item
{
- Item() = default;
Item(BT<std::string> v, ItemIsPath isPath,
- ItemIsObject isObject = ItemIsObject::No,
- cmGeneratorTarget const* target = nullptr)
+ cmGeneratorTarget const* target = nullptr,
+ FeatureDescriptor const* feature = nullptr)
: Value(std::move(v))
, IsPath(isPath)
- , IsObject(isObject)
, Target(target)
+ , Feature(feature)
{
}
BT<std::string> Value;
- ItemIsPath IsPath = ItemIsPath::Yes;
- ItemIsObject IsObject = ItemIsObject::No;
+ ItemIsPath IsPath = ItemIsPath::No;
cmGeneratorTarget const* Target = nullptr;
+
+ bool HasFeature() const { return this->Feature != nullptr; }
+ const std::string& GetFeatureName() const
+ {
+ return HasFeature() ? this->Feature->Name
+ : cmComputeLinkDepends::LinkEntry::DEFAULT;
+ }
+
+ BT<std::string> GetFormattedItem(std::string const& path) const
+ {
+ return { (this->Feature != nullptr)
+ ? this->Feature->GetDecoratedItem(path, this->IsPath)
+ : path,
+ Value.Backtrace };
+ }
+
+ private:
+ FeatureDescriptor const* Feature = nullptr;
};
using ItemVector = std::vector<Item>;
void AppendValues(std::string& result, std::vector<BT<std::string>>& values);
@@ -104,10 +119,10 @@ public:
const cmGeneratorTarget* GetTarget() { return this->Target; }
private:
- void AddItem(BT<std::string> const& item, const cmGeneratorTarget* tgt,
- ItemIsObject isObject = ItemIsObject::No);
- void AddSharedDepItem(BT<std::string> const& item,
- cmGeneratorTarget const* tgt);
+ using LinkEntry = cmComputeLinkDepends::LinkEntry;
+
+ void AddItem(LinkEntry const& entry);
+ void AddSharedDepItem(LinkEntry const& entry);
void AddRuntimeDLL(cmGeneratorTarget const* tgt);
// Output information.
@@ -181,22 +196,20 @@ private:
std::string NoCaseExpression(std::string const& str);
// Handling of link items.
- void AddTargetItem(BT<std::string> const& item,
- const cmGeneratorTarget* target);
- void AddFullItem(BT<std::string> const& item, ItemIsObject isObject);
- bool CheckImplicitDirItem(std::string const& item);
- void AddUserItem(BT<std::string> const& item, bool pathNotKnown);
- void AddFrameworkItem(std::string const& item);
+ void AddTargetItem(LinkEntry const& entry);
+ void AddFullItem(LinkEntry const& entry);
+ bool CheckImplicitDirItem(LinkEntry const& entry);
+ void AddUserItem(LinkEntry const& entry, bool pathNotKnown);
+ void AddFrameworkItem(LinkEntry const& entry);
void DropDirectoryItem(BT<std::string> const& item);
- bool CheckSharedLibNoSOName(std::string const& item);
- void AddSharedLibNoSOName(std::string const& item);
- void HandleBadFullItem(std::string const& item, std::string const& file);
+ bool CheckSharedLibNoSOName(LinkEntry const& entry);
+ void AddSharedLibNoSOName(LinkEntry const& entry);
+ void HandleBadFullItem(LinkEntry const& entry, std::string const& file);
// Framework info.
void ComputeFrameworkInfo();
void AddFrameworkPath(std::string const& p);
std::set<std::string> FrameworkPathsEmitted;
- cmsys::RegularExpression SplitFramework;
// Linker search path computation.
std::unique_ptr<cmOrderDirectories> OrderLinkerSearchPath;
@@ -237,4 +250,61 @@ private:
void AddLibraryRuntimeInfo(std::string const& fullPath,
const cmGeneratorTarget* target);
void AddLibraryRuntimeInfo(std::string const& fullPath);
+
+ class FeatureDescriptor
+ {
+ public:
+ FeatureDescriptor() = default;
+
+ const std::string Name;
+ const bool Supported = false;
+ const std::string Prefix;
+ const std::string Suffix;
+ std::string GetDecoratedItem(std::string const& library,
+ ItemIsPath isPath) const;
+ std::string GetDecoratedItem(std::string const& library,
+ std::string const& linkItem,
+ std::string const& defaultValue,
+ ItemIsPath isPath) const;
+
+ protected:
+ FeatureDescriptor(std::string name, std::string itemFormat);
+ FeatureDescriptor(std::string name, std::string itemPathFormat,
+ std::string itemNameFormat);
+ FeatureDescriptor(std::string name, std::string prefix,
+ std::string itemPathFormat, std::string itemNameFormat,
+ std::string suffix);
+
+ FeatureDescriptor(std::string name, std::string prefix, std::string suffix,
+ bool isGroup);
+
+ private:
+ std::string ItemPathFormat;
+ std::string ItemNameFormat;
+ };
+
+ class LibraryFeatureDescriptor : public FeatureDescriptor
+ {
+ public:
+ LibraryFeatureDescriptor(std::string name, std::string itemFormat);
+ LibraryFeatureDescriptor(std::string name, std::string itemPathFormat,
+ std::string itemNameFormat);
+ LibraryFeatureDescriptor(std::string name, std::string prefix,
+ std::string itemPathFormat,
+ std::string itemNameFormat, std::string suffix);
+ };
+ std::map<std::string, FeatureDescriptor> LibraryFeatureDescriptors;
+ bool AddLibraryFeature(std::string const& feature);
+ FeatureDescriptor const& GetLibraryFeature(std::string const& feature) const;
+ FeatureDescriptor const* FindLibraryFeature(
+ std::string const& feature) const;
+
+ class GroupFeatureDescriptor : public FeatureDescriptor
+ {
+ public:
+ GroupFeatureDescriptor(std::string name, std::string prefix,
+ std::string suffix);
+ };
+ std::map<std::string, FeatureDescriptor> GroupFeatureDescriptors;
+ FeatureDescriptor const& GetGroupFeature(std::string const& feature);
};
diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index ef89c8b..3ff16a4 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -218,8 +218,8 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
emitted.insert(cmLinkItem(depender, false, cmListFileBacktrace()));
emitted.insert(cmLinkItem(depender, true, cmListFileBacktrace()));
- if (cmLinkImplementation const* impl =
- depender->GetLinkImplementation(it)) {
+ if (cmLinkImplementation const* impl = depender->GetLinkImplementation(
+ it, cmGeneratorTarget::LinkInterfaceFor::Link)) {
for (cmLinkImplItem const& lib : impl->Libraries) {
// Don't emit the same library twice for this target.
if (emitted.insert(lib).second) {
diff --git a/Source/cmComputeTargetDepends.h b/Source/cmComputeTargetDepends.h
index 0eab368..cdb66f8 100644
--- a/Source/cmComputeTargetDepends.h
+++ b/Source/cmComputeTargetDepends.h
@@ -10,12 +10,12 @@
#include <vector>
#include "cmGraphAdjacencyList.h"
-#include "cmListFileCache.h"
class cmComputeComponentGraph;
class cmGeneratorTarget;
class cmGlobalGenerator;
class cmLinkItem;
+class cmListFileBacktrace;
class cmSourceFile;
class cmTargetDependSet;
diff --git a/Source/cmConstStack.h b/Source/cmConstStack.h
new file mode 100644
index 0000000..f0bca32
--- /dev/null
+++ b/Source/cmConstStack.h
@@ -0,0 +1,39 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <memory>
+
+/** Base class template for CRTP to represent a stack of constant values.
+ Provide value semantics, but use efficient reference-counting underneath
+ to avoid copies. */
+template <typename T, typename Stack>
+class cmConstStack
+{
+ struct Entry;
+ std::shared_ptr<Entry const> TopEntry;
+
+public:
+ /** Default-construct an empty stack. */
+ cmConstStack();
+
+ /** Get a stack with the given call context added to the top. */
+ Stack Push(T value) const;
+
+ /** Get a stack with the top level removed.
+ May not be called until after a matching Push. */
+ Stack Pop() const;
+
+ /** Get the value at the top of the stack.
+ This may be called only if Empty() would return false. */
+ T const& Top() const;
+
+ /** Return true if this stack is empty. */
+ bool Empty() const;
+
+protected:
+ cmConstStack(std::shared_ptr<Entry const> parent, T value);
+ cmConstStack(std::shared_ptr<Entry const> top);
+};
diff --git a/Source/cmConstStack.tcc b/Source/cmConstStack.tcc
new file mode 100644
index 0000000..81918ee
--- /dev/null
+++ b/Source/cmConstStack.tcc
@@ -0,0 +1,62 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include <cassert>
+#include <memory>
+#include <utility>
+
+template <typename T, typename Stack>
+struct cmConstStack<T, Stack>::Entry
+{
+ Entry(std::shared_ptr<Entry const> parent, T value)
+ : Value(std::move(value))
+ , Parent(std::move(parent))
+ {
+ }
+
+ T Value;
+ std::shared_ptr<Entry const> Parent;
+};
+
+template <typename T, typename Stack>
+cmConstStack<T, Stack>::cmConstStack() = default;
+
+template <typename T, typename Stack>
+Stack cmConstStack<T, Stack>::Push(T value) const
+{
+ return Stack(this->TopEntry, std::move(value));
+}
+
+template <typename T, typename Stack>
+Stack cmConstStack<T, Stack>::Pop() const
+{
+ assert(this->TopEntry);
+ return Stack(this->TopEntry->Parent);
+}
+
+template <typename T, typename Stack>
+T const& cmConstStack<T, Stack>::Top() const
+{
+ assert(this->TopEntry);
+ return this->TopEntry->Value;
+}
+
+template <typename T, typename Stack>
+bool cmConstStack<T, Stack>::Empty() const
+{
+ return !this->TopEntry;
+}
+
+template <typename T, typename Stack>
+cmConstStack<T, Stack>::cmConstStack(std::shared_ptr<Entry const> parent,
+ T value)
+ : TopEntry(
+ std::make_shared<Entry const>(std::move(parent), std::move(value)))
+{
+}
+
+template <typename T, typename Stack>
+cmConstStack<T, Stack>::cmConstStack(std::shared_ptr<Entry const> top)
+ : TopEntry(std::move(top))
+{
+}
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index 324ce87..caa413b 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -108,7 +108,7 @@ public:
std::string value = makefile->GetSafeDefinition(var);
if (warnCMP0067 && !value.empty()) {
value.clear();
- warnCMP0067Variables.push_back(var);
+ warnCMP0067Variables.emplace_back(var);
}
return value;
};
@@ -228,6 +228,8 @@ std::string const kCMAKE_TRY_COMPILE_OSX_ARCHITECTURES =
std::string const kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES =
"CMAKE_TRY_COMPILE_PLATFORM_VARIABLES";
std::string const kCMAKE_WARN_DEPRECATED = "CMAKE_WARN_DEPRECATED";
+std::string const kCMAKE_WATCOM_RUNTIME_LIBRARY_DEFAULT =
+ "CMAKE_WATCOM_RUNTIME_LIBRARY_DEFAULT";
/* GHS Multi platform variables */
std::set<std::string> const ghs_platform_vars{
@@ -335,11 +337,11 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
} else if (argv[i] == "__CMAKE_INTERNAL") {
doing = DoingCMakeInternal;
} else if (doing == DoingCMakeFlags) {
- cmakeFlags.push_back(argv[i]);
+ cmakeFlags.emplace_back(argv[i]);
} else if (doing == DoingCompileDefinitions) {
cmExpandList(argv[i], compileDefs);
} else if (doing == DoingLinkOptions) {
- linkOptions.push_back(argv[i]);
+ linkOptions.emplace_back(argv[i]);
} else if (doing == DoingLinkLibraries) {
libsToLink += "\"" + cmTrimWhitespace(argv[i]) + "\" ";
if (cmTarget* tgt = this->Makefile->FindTargetToUse(argv[i])) {
@@ -364,7 +366,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
return -1;
}
if (tgt->IsImported()) {
- targets.push_back(argv[i]);
+ targets.emplace_back(argv[i]);
}
}
} else if (doing == DoingOutputVariable) {
@@ -377,7 +379,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
copyFileError = argv[i];
doing = DoingNone;
} else if (doing == DoingSources) {
- sources.push_back(argv[i]);
+ sources.emplace_back(argv[i]);
} else if (doing == DoingCMakeInternal) {
cmakeInternal = argv[i];
doing = DoingNone;
@@ -488,7 +490,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
// Choose sources.
if (!useSources) {
- sources.push_back(argv[2]);
+ sources.emplace_back(argv[2]);
}
// Detect languages to enable.
@@ -555,6 +557,13 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
!msvcRuntimeLibraryDefault->empty() ? "NEW" : "OLD");
}
+ /* Set Watcom runtime library policy to match our selection. */
+ if (cmValue watcomRuntimeLibraryDefault = this->Makefile->GetDefinition(
+ kCMAKE_WATCOM_RUNTIME_LIBRARY_DEFAULT)) {
+ fprintf(fout, "cmake_policy(SET CMP0136 %s)\n",
+ !watcomRuntimeLibraryDefault->empty() ? "NEW" : "OLD");
+ }
+
/* Set CUDA architectures policy to match outer project. */
if (this->Makefile->GetPolicyStatus(cmPolicies::CMP0104) !=
cmPolicies::NEW &&
@@ -720,103 +729,6 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
fname.c_str());
}
- // Forward a set of variables to the inner project cache.
- {
- std::set<std::string> vars;
- vars.insert(&c_properties[lang_property_start],
- &c_properties[lang_property_start + lang_property_size]);
- vars.insert(&cxx_properties[lang_property_start],
- &cxx_properties[lang_property_start + lang_property_size]);
- vars.insert(&cuda_properties[lang_property_start],
- &cuda_properties[lang_property_start + lang_property_size]);
- vars.insert(
- &fortran_properties[lang_property_start],
- &fortran_properties[lang_property_start + lang_property_size]);
- vars.insert(&hip_properties[lang_property_start],
- &hip_properties[lang_property_start + lang_property_size]);
- vars.insert(&objc_properties[lang_property_start],
- &objc_properties[lang_property_start + lang_property_size]);
- vars.insert(
- &objcxx_properties[lang_property_start],
- &objcxx_properties[lang_property_start + lang_property_size]);
- vars.insert(&ispc_properties[lang_property_start],
- &ispc_properties[lang_property_start + lang_property_size]);
- vars.insert(&swift_properties[lang_property_start],
- &swift_properties[lang_property_start + lang_property_size]);
- vars.insert(kCMAKE_CUDA_ARCHITECTURES);
- vars.insert(kCMAKE_CUDA_RUNTIME_LIBRARY);
- vars.insert(kCMAKE_ENABLE_EXPORTS);
- vars.insert(kCMAKE_HIP_ARCHITECTURES);
- vars.insert(kCMAKE_HIP_RUNTIME_LIBRARY);
- vars.insert(kCMAKE_ISPC_INSTRUCTION_SETS);
- vars.insert(kCMAKE_ISPC_HEADER_SUFFIX);
- vars.insert(kCMAKE_LINK_SEARCH_END_STATIC);
- vars.insert(kCMAKE_LINK_SEARCH_START_STATIC);
- vars.insert(kCMAKE_OSX_ARCHITECTURES);
- vars.insert(kCMAKE_OSX_DEPLOYMENT_TARGET);
- vars.insert(kCMAKE_OSX_SYSROOT);
- vars.insert(kCMAKE_APPLE_ARCH_SYSROOTS);
- vars.insert(kCMAKE_POSITION_INDEPENDENT_CODE);
- vars.insert(kCMAKE_SYSROOT);
- vars.insert(kCMAKE_SYSROOT_COMPILE);
- vars.insert(kCMAKE_SYSROOT_LINK);
- vars.insert(kCMAKE_WARN_DEPRECATED);
- vars.emplace("CMAKE_MSVC_RUNTIME_LIBRARY"_s);
-
- if (cmValue varListStr = this->Makefile->GetDefinition(
- kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES)) {
- std::vector<std::string> varList = cmExpandedList(*varListStr);
- vars.insert(varList.begin(), varList.end());
- }
-
- if (this->Makefile->GetPolicyStatus(cmPolicies::CMP0083) ==
- cmPolicies::NEW) {
- // To ensure full support of PIE, propagate cache variables
- // driving the link options
- vars.insert(&c_properties[pie_property_start],
- &c_properties[pie_property_start + pie_property_size]);
- vars.insert(&cxx_properties[pie_property_start],
- &cxx_properties[pie_property_start + pie_property_size]);
- vars.insert(&cuda_properties[pie_property_start],
- &cuda_properties[pie_property_start + pie_property_size]);
- vars.insert(
- &fortran_properties[pie_property_start],
- &fortran_properties[pie_property_start + pie_property_size]);
- vars.insert(&hip_properties[pie_property_start],
- &hip_properties[pie_property_start + pie_property_size]);
- vars.insert(&objc_properties[pie_property_start],
- &objc_properties[pie_property_start + pie_property_size]);
- vars.insert(
- &objcxx_properties[pie_property_start],
- &objcxx_properties[pie_property_start + pie_property_size]);
- vars.insert(&ispc_properties[pie_property_start],
- &ispc_properties[pie_property_start + pie_property_size]);
- vars.insert(&swift_properties[pie_property_start],
- &swift_properties[pie_property_start + pie_property_size]);
- }
-
- /* for the TRY_COMPILEs we want to be able to specify the architecture.
- So the user can set CMAKE_OSX_ARCHITECTURES to i386;ppc and then set
- CMAKE_TRY_COMPILE_OSX_ARCHITECTURES first to i386 and then to ppc to
- have the tests run for each specific architecture. Since
- cmLocalGenerator doesn't allow building for "the other"
- architecture only via CMAKE_OSX_ARCHITECTURES.
- */
- if (cmValue tcArchs = this->Makefile->GetDefinition(
- kCMAKE_TRY_COMPILE_OSX_ARCHITECTURES)) {
- vars.erase(kCMAKE_OSX_ARCHITECTURES);
- std::string flag = "-DCMAKE_OSX_ARCHITECTURES=" + *tcArchs;
- cmakeFlags.push_back(std::move(flag));
- }
-
- for (std::string const& var : vars) {
- if (cmValue val = this->Makefile->GetDefinition(var)) {
- std::string flag = "-D" + var + "=" + *val;
- cmakeFlags.push_back(std::move(flag));
- }
- }
- }
-
/* Set the appropriate policy information for ENABLE_EXPORTS */
fprintf(fout, "cmake_policy(SET CMP0065 %s)\n",
this->Makefile->GetPolicyStatus(cmPolicies::CMP0065) ==
@@ -959,12 +871,109 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
projectName = "CMAKE_TRY_COMPILE";
}
+ // Forward a set of variables to the inner project cache.
+ if ((this->SrcFileSignature ||
+ this->Makefile->GetPolicyStatus(cmPolicies::CMP0137) ==
+ cmPolicies::NEW) &&
+ !this->Makefile->IsOn("CMAKE_TRY_COMPILE_NO_PLATFORM_VARIABLES")) {
+ std::set<std::string> vars;
+ vars.insert(&c_properties[lang_property_start],
+ &c_properties[lang_property_start + lang_property_size]);
+ vars.insert(&cxx_properties[lang_property_start],
+ &cxx_properties[lang_property_start + lang_property_size]);
+ vars.insert(&cuda_properties[lang_property_start],
+ &cuda_properties[lang_property_start + lang_property_size]);
+ vars.insert(&fortran_properties[lang_property_start],
+ &fortran_properties[lang_property_start + lang_property_size]);
+ vars.insert(&hip_properties[lang_property_start],
+ &hip_properties[lang_property_start + lang_property_size]);
+ vars.insert(&objc_properties[lang_property_start],
+ &objc_properties[lang_property_start + lang_property_size]);
+ vars.insert(&objcxx_properties[lang_property_start],
+ &objcxx_properties[lang_property_start + lang_property_size]);
+ vars.insert(&ispc_properties[lang_property_start],
+ &ispc_properties[lang_property_start + lang_property_size]);
+ vars.insert(&swift_properties[lang_property_start],
+ &swift_properties[lang_property_start + lang_property_size]);
+ vars.insert(kCMAKE_CUDA_ARCHITECTURES);
+ vars.insert(kCMAKE_CUDA_RUNTIME_LIBRARY);
+ vars.insert(kCMAKE_ENABLE_EXPORTS);
+ vars.insert(kCMAKE_HIP_ARCHITECTURES);
+ vars.insert(kCMAKE_HIP_RUNTIME_LIBRARY);
+ vars.insert(kCMAKE_ISPC_INSTRUCTION_SETS);
+ vars.insert(kCMAKE_ISPC_HEADER_SUFFIX);
+ vars.insert(kCMAKE_LINK_SEARCH_END_STATIC);
+ vars.insert(kCMAKE_LINK_SEARCH_START_STATIC);
+ vars.insert(kCMAKE_OSX_ARCHITECTURES);
+ vars.insert(kCMAKE_OSX_DEPLOYMENT_TARGET);
+ vars.insert(kCMAKE_OSX_SYSROOT);
+ vars.insert(kCMAKE_APPLE_ARCH_SYSROOTS);
+ vars.insert(kCMAKE_POSITION_INDEPENDENT_CODE);
+ vars.insert(kCMAKE_SYSROOT);
+ vars.insert(kCMAKE_SYSROOT_COMPILE);
+ vars.insert(kCMAKE_SYSROOT_LINK);
+ vars.insert(kCMAKE_WARN_DEPRECATED);
+ vars.emplace("CMAKE_MSVC_RUNTIME_LIBRARY"_s);
+ vars.emplace("CMAKE_WATCOM_RUNTIME_LIBRARY"_s);
+
+ if (cmValue varListStr = this->Makefile->GetDefinition(
+ kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES)) {
+ std::vector<std::string> varList = cmExpandedList(*varListStr);
+ vars.insert(varList.begin(), varList.end());
+ }
+
+ if (this->Makefile->GetPolicyStatus(cmPolicies::CMP0083) ==
+ cmPolicies::NEW) {
+ // To ensure full support of PIE, propagate cache variables
+ // driving the link options
+ vars.insert(&c_properties[pie_property_start],
+ &c_properties[pie_property_start + pie_property_size]);
+ vars.insert(&cxx_properties[pie_property_start],
+ &cxx_properties[pie_property_start + pie_property_size]);
+ vars.insert(&cuda_properties[pie_property_start],
+ &cuda_properties[pie_property_start + pie_property_size]);
+ vars.insert(&fortran_properties[pie_property_start],
+ &fortran_properties[pie_property_start + pie_property_size]);
+ vars.insert(&hip_properties[pie_property_start],
+ &hip_properties[pie_property_start + pie_property_size]);
+ vars.insert(&objc_properties[pie_property_start],
+ &objc_properties[pie_property_start + pie_property_size]);
+ vars.insert(&objcxx_properties[pie_property_start],
+ &objcxx_properties[pie_property_start + pie_property_size]);
+ vars.insert(&ispc_properties[pie_property_start],
+ &ispc_properties[pie_property_start + pie_property_size]);
+ vars.insert(&swift_properties[pie_property_start],
+ &swift_properties[pie_property_start + pie_property_size]);
+ }
+
+ /* for the TRY_COMPILEs we want to be able to specify the architecture.
+ So the user can set CMAKE_OSX_ARCHITECTURES to i386;ppc and then set
+ CMAKE_TRY_COMPILE_OSX_ARCHITECTURES first to i386 and then to ppc to
+ have the tests run for each specific architecture. Since
+ cmLocalGenerator doesn't allow building for "the other"
+ architecture only via CMAKE_OSX_ARCHITECTURES.
+ */
+ if (cmValue tcArchs = this->Makefile->GetDefinition(
+ kCMAKE_TRY_COMPILE_OSX_ARCHITECTURES)) {
+ vars.erase(kCMAKE_OSX_ARCHITECTURES);
+ std::string flag = "-DCMAKE_OSX_ARCHITECTURES=" + *tcArchs;
+ cmakeFlags.emplace_back(std::move(flag));
+ }
+
+ for (std::string const& var : vars) {
+ if (cmValue val = this->Makefile->GetDefinition(var)) {
+ std::string flag = "-D" + var + "=" + *val;
+ cmakeFlags.emplace_back(std::move(flag));
+ }
+ }
+ }
+
if (this->Makefile->GetState()->UseGhsMultiIDE()) {
// Forward the GHS variables to the inner project cache.
for (std::string const& var : ghs_platform_vars) {
if (cmValue val = this->Makefile->GetDefinition(var)) {
std::string flag = "-D" + var + "=" + "'" + *val + "'";
- cmakeFlags.push_back(std::move(flag));
+ cmakeFlags.emplace_back(std::move(flag));
}
}
}
@@ -1109,18 +1118,18 @@ void cmCoreTryCompile::FindOutputFile(const std::string& targetName,
// if a config was specified try that first
if (cmNonempty(config)) {
std::string tmp = cmStrCat('/', *config);
- searchDirs.push_back(std::move(tmp));
+ searchDirs.emplace_back(std::move(tmp));
}
searchDirs.emplace_back("/Debug");
#if defined(__APPLE__)
std::string app = "/" + targetName + ".app";
if (cmNonempty(config)) {
std::string tmp = cmStrCat('/', *config, app);
- searchDirs.push_back(std::move(tmp));
+ searchDirs.emplace_back(std::move(tmp));
}
std::string tmp = "/Debug" + app;
searchDirs.emplace_back(std::move(tmp));
- searchDirs.push_back(std::move(app));
+ searchDirs.emplace_back(std::move(app));
#endif
searchDirs.emplace_back("/Development");
diff --git a/Source/cmCreateTestSourceList.cxx b/Source/cmCreateTestSourceList.cxx
index a2fac73..2a52d1a 100644
--- a/Source/cmCreateTestSourceList.cxx
+++ b/Source/cmCreateTestSourceList.cxx
@@ -102,7 +102,6 @@ bool cmCreateTestSourceList(std::vector<std::string> const& args,
}
std::string functionMapCode;
- int numTests = 0;
std::vector<std::string>::iterator j;
for (i = testsBegin, j = tests_func_name.begin(); i != tests.end();
++i, ++j) {
@@ -121,7 +120,6 @@ bool cmCreateTestSourceList(std::vector<std::string> const& args,
functionMapCode += *j;
functionMapCode += "\n"
" },\n";
- numTests++;
}
if (!extraInclude.empty()) {
mf.AddDefinition("CMAKE_TESTDRIVER_EXTRA_INCLUDES", extraInclude);
diff --git a/Source/cmEnableTestingCommand.h b/Source/cmEnableTestingCommand.h
index 1722511..a1374f3 100644
--- a/Source/cmEnableTestingCommand.h
+++ b/Source/cmEnableTestingCommand.h
@@ -14,10 +14,10 @@ class cmExecutionStatus;
*
* Produce the output testfile. This produces a file in the build directory
* called CMakeTestfile with a syntax similar to CMakeLists.txt. It contains
- * the SUBDIRS() and ADD_TEST() commands from the source CMakeLists.txt
+ * the subdirs() and add_test() commands from the source CMakeLists.txt
* file with CMake variables expanded. Only the subdirs and tests
* within the valid control structures are replicated in Testfile
- * (i.e. SUBDIRS() and ADD_TEST() commands within IF() commands that are
+ * (i.e. subdirs() and add_test() commands within IF() commands that are
* not entered by CMake are not replicated in Testfile).
* Note that CTest expects to find this file in the build directory root;
* therefore, this command should be in the source directory root too.
diff --git a/Source/cmExportBuildAndroidMKGenerator.cxx b/Source/cmExportBuildAndroidMKGenerator.cxx
index bcd8c64..5d0b208 100644
--- a/Source/cmExportBuildAndroidMKGenerator.cxx
+++ b/Source/cmExportBuildAndroidMKGenerator.cxx
@@ -4,6 +4,7 @@
#include <sstream>
#include <utility>
+#include <vector>
#include <cmext/algorithm>
@@ -60,7 +61,7 @@ void cmExportBuildAndroidMKGenerator::GenerateImportPropertyCode(
}
void cmExportBuildAndroidMKGenerator::GenerateMissingTargetsCheckCode(
- std::ostream&, const std::vector<std::string>&)
+ std::ostream&)
{
}
@@ -168,7 +169,8 @@ void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
// Tell the NDK build system if prebuilt static libraries use C++.
if (target->GetType() == cmStateEnums::STATIC_LIBRARY) {
- cmLinkImplementation const* li = target->GetLinkImplementation(config);
+ cmLinkImplementation const* li = target->GetLinkImplementation(
+ config, cmGeneratorTarget::LinkInterfaceFor::Link);
if (cm::contains(li->Languages, "CXX")) {
os << "LOCAL_HAS_CPP := true\n";
}
diff --git a/Source/cmExportBuildAndroidMKGenerator.h b/Source/cmExportBuildAndroidMKGenerator.h
index 250564f..1a9a626 100644
--- a/Source/cmExportBuildAndroidMKGenerator.h
+++ b/Source/cmExportBuildAndroidMKGenerator.h
@@ -6,7 +6,6 @@
#include <iosfwd>
#include <string>
-#include <vector>
#include "cmExportBuildFileGenerator.h"
#include "cmExportFileGenerator.h"
@@ -21,7 +20,7 @@ class cmGeneratorTarget;
* a build tree. This exports the targets to the Android ndk build tool
* makefile format for prebuilt libraries.
*
- * This is used to implement the EXPORT() command.
+ * This is used to implement the export() command.
*/
class cmExportBuildAndroidMKGenerator : public cmExportBuildFileGenerator
{
@@ -56,8 +55,7 @@ protected:
std::ostream& os, const std::string& config,
cmGeneratorTarget const* target,
ImportPropertyMap const& properties) override;
- void GenerateMissingTargetsCheckCode(
- std::ostream& os, const std::vector<std::string>& missingTargets) override;
+ void GenerateMissingTargetsCheckCode(std::ostream& os) override;
void GenerateInterfaceProperties(
cmGeneratorTarget const* target, std::ostream& os,
const ImportPropertyMap& properties) override;
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index 2773b3b..6ce0c98 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -76,8 +76,6 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
this->GenerateExpectedTargetsCode(os, expectedTargets);
}
- std::vector<std::string> missingTargets;
-
// Create all the imported targets.
for (cmGeneratorTarget* gte : this->Exports) {
this->GenerateImportTargetCode(os, gte, this->GetExportTargetType(gte));
@@ -88,34 +86,34 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
this->PopulateInterfaceProperty("INTERFACE_INCLUDE_DIRECTORIES", gte,
cmGeneratorExpression::BuildInterface,
- properties, missingTargets);
+ properties);
this->PopulateInterfaceProperty("INTERFACE_SOURCES", gte,
cmGeneratorExpression::BuildInterface,
- properties, missingTargets);
+ properties);
this->PopulateInterfaceProperty("INTERFACE_COMPILE_DEFINITIONS", gte,
cmGeneratorExpression::BuildInterface,
- properties, missingTargets);
+ properties);
this->PopulateInterfaceProperty("INTERFACE_COMPILE_OPTIONS", gte,
cmGeneratorExpression::BuildInterface,
- properties, missingTargets);
+ properties);
this->PopulateInterfaceProperty("INTERFACE_PRECOMPILE_HEADERS", gte,
cmGeneratorExpression::BuildInterface,
- properties, missingTargets);
+ properties);
this->PopulateInterfaceProperty("INTERFACE_AUTOUIC_OPTIONS", gte,
cmGeneratorExpression::BuildInterface,
- properties, missingTargets);
+ properties);
this->PopulateInterfaceProperty("INTERFACE_COMPILE_FEATURES", gte,
cmGeneratorExpression::BuildInterface,
- properties, missingTargets);
+ properties);
this->PopulateInterfaceProperty("INTERFACE_LINK_OPTIONS", gte,
cmGeneratorExpression::BuildInterface,
- properties, missingTargets);
+ properties);
this->PopulateInterfaceProperty("INTERFACE_LINK_DIRECTORIES", gte,
cmGeneratorExpression::BuildInterface,
- properties, missingTargets);
+ properties);
this->PopulateInterfaceProperty("INTERFACE_LINK_DEPENDS", gte,
cmGeneratorExpression::BuildInterface,
- properties, missingTargets);
+ properties);
this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE", gte,
properties);
@@ -132,8 +130,7 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
gte->GetPolicyStatusCMP0022() != cmPolicies::OLD;
if (newCMP0022Behavior) {
this->PopulateInterfaceLinkLibrariesProperty(
- gte, cmGeneratorExpression::BuildInterface, properties,
- missingTargets);
+ gte, cmGeneratorExpression::BuildInterface, properties);
}
this->PopulateCompatibleInterfaceProperties(gte, properties);
@@ -144,17 +141,16 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
// Generate import file content for each configuration.
for (std::string const& c : this->Configurations) {
- this->GenerateImportConfig(os, c, missingTargets);
+ this->GenerateImportConfig(os, c);
}
- this->GenerateMissingTargetsCheckCode(os, missingTargets);
+ this->GenerateMissingTargetsCheckCode(os);
return true;
}
void cmExportBuildFileGenerator::GenerateImportTargetsConfig(
- std::ostream& os, const std::string& config, std::string const& suffix,
- std::vector<std::string>& missingTargets)
+ std::ostream& os, const std::string& config, std::string const& suffix)
{
for (cmGeneratorTarget* target : this->Exports) {
// Collect import properties for this target.
@@ -167,11 +163,10 @@ void cmExportBuildFileGenerator::GenerateImportTargetsConfig(
// Get the rest of the target details.
if (this->GetExportTargetType(target) !=
cmStateEnums::INTERFACE_LIBRARY) {
- this->SetImportDetailProperties(config, suffix, target, properties,
- missingTargets);
+ this->SetImportDetailProperties(config, suffix, target, properties);
this->SetImportLinkInterface(config, suffix,
cmGeneratorExpression::BuildInterface,
- target, properties, missingTargets);
+ target, properties);
}
// TODO: PUBLIC_HEADER_LOCATION
@@ -195,7 +190,7 @@ cmStateEnums::TargetType cmExportBuildFileGenerator::GetExportTargetType(
// to support transitive usage requirements on other targets that
// use the object library.
if (targetType == cmStateEnums::OBJECT_LIBRARY &&
- !this->LG->GetGlobalGenerator()->HasKnownObjectFileLocation(nullptr)) {
+ !target->Target->HasKnownObjectFileLocation(nullptr)) {
targetType = cmStateEnums::INTERFACE_LIBRARY;
}
return targetType;
@@ -259,8 +254,8 @@ void cmExportBuildFileGenerator::SetImportLocationProperty(
}
void cmExportBuildFileGenerator::HandleMissingTarget(
- std::string& link_libs, std::vector<std::string>& missingTargets,
- cmGeneratorTarget const* depender, cmGeneratorTarget* dependee)
+ std::string& link_libs, cmGeneratorTarget const* depender,
+ cmGeneratorTarget* dependee)
{
// The target is not in the export.
if (!this->AppendMode) {
@@ -275,7 +270,7 @@ void cmExportBuildFileGenerator::HandleMissingTarget(
missingTarget += dependee->GetExportName();
link_libs += missingTarget;
- missingTargets.push_back(std::move(missingTarget));
+ this->MissingTargets.emplace_back(std::move(missingTarget));
return;
}
// We are not appending, so all exported targets should be
diff --git a/Source/cmExportBuildFileGenerator.h b/Source/cmExportBuildFileGenerator.h
index a7985c7..5681e8f 100644
--- a/Source/cmExportBuildFileGenerator.h
+++ b/Source/cmExportBuildFileGenerator.h
@@ -28,7 +28,7 @@ class cmTargetExport;
* a build tree. A single file exports information for all
* configurations built.
*
- * This is used to implement the EXPORT() command.
+ * This is used to implement the export() command.
*/
class cmExportBuildFileGenerator : public cmExportFileGenerator
{
@@ -55,13 +55,11 @@ public:
protected:
// Implement virtual methods from the superclass.
bool GenerateMainFile(std::ostream& os) override;
- void GenerateImportTargetsConfig(
- std::ostream& os, const std::string& config, std::string const& suffix,
- std::vector<std::string>& missingTargets) override;
+ void GenerateImportTargetsConfig(std::ostream& os, const std::string& config,
+ std::string const& suffix) override;
cmStateEnums::TargetType GetExportTargetType(
cmGeneratorTarget const* target) const;
void HandleMissingTarget(std::string& link_libs,
- std::vector<std::string>& missingTargets,
cmGeneratorTarget const* depender,
cmGeneratorTarget* dependee) override;
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index ed1e4cb..452eb99 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmExportFileGenerator.h"
+#include <array>
#include <cassert>
#include <cstring>
#include <sstream>
@@ -15,7 +16,6 @@
#include "cmFileSet.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
-#include "cmGlobalGenerator.h"
#include "cmLinkItem.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
@@ -106,9 +106,8 @@ bool cmExportFileGenerator::GenerateImportFile()
return result;
}
-void cmExportFileGenerator::GenerateImportConfig(
- std::ostream& os, const std::string& config,
- std::vector<std::string>& missingTargets)
+void cmExportFileGenerator::GenerateImportConfig(std::ostream& os,
+ const std::string& config)
{
// Construct the property configuration suffix.
std::string suffix = "_";
@@ -119,7 +118,7 @@ void cmExportFileGenerator::GenerateImportConfig(
}
// Generate the per-config target information.
- this->GenerateImportTargetsConfig(os, config, suffix, missingTargets);
+ this->GenerateImportTargetsConfig(os, config, suffix);
}
void cmExportFileGenerator::PopulateInterfaceProperty(
@@ -136,7 +135,7 @@ void cmExportFileGenerator::PopulateInterfaceProperty(
const std::string& propName, const std::string& outputName,
cmGeneratorTarget const* target,
cmGeneratorExpression::PreprocessContext preprocessRule,
- ImportPropertyMap& properties, std::vector<std::string>& missingTargets)
+ ImportPropertyMap& properties)
{
cmValue input = target->GetProperty(propName);
if (input) {
@@ -149,8 +148,7 @@ void cmExportFileGenerator::PopulateInterfaceProperty(
std::string prepro =
cmGeneratorExpression::Preprocess(*input, preprocessRule);
if (!prepro.empty()) {
- this->ResolveTargetsInGeneratorExpressions(prepro, target,
- missingTargets);
+ this->ResolveTargetsInGeneratorExpressions(prepro, target);
properties[outputName] = prepro;
}
}
@@ -170,23 +168,29 @@ void cmExportFileGenerator::GenerateRequiredCMakeVersion(
bool cmExportFileGenerator::PopulateInterfaceLinkLibrariesProperty(
cmGeneratorTarget const* target,
cmGeneratorExpression::PreprocessContext preprocessRule,
- ImportPropertyMap& properties, std::vector<std::string>& missingTargets)
+ ImportPropertyMap& properties)
{
if (!target->IsLinkable()) {
return false;
}
- cmValue input = target->GetProperty("INTERFACE_LINK_LIBRARIES");
- if (input) {
- std::string prepro =
- cmGeneratorExpression::Preprocess(*input, preprocessRule);
- if (!prepro.empty()) {
- this->ResolveTargetsInGeneratorExpressions(
- prepro, target, missingTargets, ReplaceFreeTargets);
- properties["INTERFACE_LINK_LIBRARIES"] = prepro;
- return true;
+ static const std::array<std::string, 3> linkIfaceProps = {
+ { "INTERFACE_LINK_LIBRARIES", "INTERFACE_LINK_LIBRARIES_DIRECT",
+ "INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE" }
+ };
+ bool hadINTERFACE_LINK_LIBRARIES = false;
+ for (std::string const& linkIfaceProp : linkIfaceProps) {
+ if (cmValue input = target->GetProperty(linkIfaceProp)) {
+ std::string prepro =
+ cmGeneratorExpression::Preprocess(*input, preprocessRule);
+ if (!prepro.empty()) {
+ this->ResolveTargetsInGeneratorExpressions(prepro, target,
+ ReplaceFreeTargets);
+ properties[linkIfaceProp] = prepro;
+ hadINTERFACE_LINK_LIBRARIES = true;
+ }
}
}
- return false;
+ return hadINTERFACE_LINK_LIBRARIES;
}
static bool isSubDirectory(std::string const& a, std::string const& b)
@@ -337,7 +341,7 @@ static void prefixItems(std::string& exportDirs)
void cmExportFileGenerator::PopulateSourcesInterface(
cmGeneratorTarget const* gt,
cmGeneratorExpression::PreprocessContext preprocessRule,
- ImportPropertyMap& properties, std::vector<std::string>& missingTargets)
+ ImportPropertyMap& properties)
{
assert(preprocessRule == cmGeneratorExpression::InstallInterface);
@@ -356,7 +360,7 @@ void cmExportFileGenerator::PopulateSourcesInterface(
std::string prepro =
cmGeneratorExpression::Preprocess(*input, preprocessRule, true);
if (!prepro.empty()) {
- this->ResolveTargetsInGeneratorExpressions(prepro, gt, missingTargets);
+ this->ResolveTargetsInGeneratorExpressions(prepro, gt);
if (!checkInterfaceDirs(prepro, gt, propName)) {
return;
@@ -368,8 +372,7 @@ void cmExportFileGenerator::PopulateSourcesInterface(
void cmExportFileGenerator::PopulateIncludeDirectoriesInterface(
cmGeneratorTarget const* target,
cmGeneratorExpression::PreprocessContext preprocessRule,
- ImportPropertyMap& properties, std::vector<std::string>& missingTargets,
- cmTargetExport const& te)
+ ImportPropertyMap& properties, cmTargetExport const& te)
{
assert(preprocessRule == cmGeneratorExpression::InstallInterface);
@@ -416,7 +419,7 @@ void cmExportFileGenerator::PopulateIncludeDirectoriesInterface(
std::string prepro =
cmGeneratorExpression::Preprocess(includes, preprocessRule, true);
if (!prepro.empty()) {
- this->ResolveTargetsInGeneratorExpressions(prepro, target, missingTargets);
+ this->ResolveTargetsInGeneratorExpressions(prepro, target);
if (!checkInterfaceDirs(prepro, target, propName)) {
return;
@@ -428,7 +431,7 @@ void cmExportFileGenerator::PopulateIncludeDirectoriesInterface(
void cmExportFileGenerator::PopulateLinkDependsInterface(
cmGeneratorTarget const* gt,
cmGeneratorExpression::PreprocessContext preprocessRule,
- ImportPropertyMap& properties, std::vector<std::string>& missingTargets)
+ ImportPropertyMap& properties)
{
assert(preprocessRule == cmGeneratorExpression::InstallInterface);
@@ -447,7 +450,7 @@ void cmExportFileGenerator::PopulateLinkDependsInterface(
std::string prepro =
cmGeneratorExpression::Preprocess(*input, preprocessRule, true);
if (!prepro.empty()) {
- this->ResolveTargetsInGeneratorExpressions(prepro, gt, missingTargets);
+ this->ResolveTargetsInGeneratorExpressions(prepro, gt);
if (!checkInterfaceDirs(prepro, gt, propName)) {
return;
@@ -459,7 +462,7 @@ void cmExportFileGenerator::PopulateLinkDependsInterface(
void cmExportFileGenerator::PopulateLinkDirectoriesInterface(
cmGeneratorTarget const* gt,
cmGeneratorExpression::PreprocessContext preprocessRule,
- ImportPropertyMap& properties, std::vector<std::string>& missingTargets)
+ ImportPropertyMap& properties)
{
assert(preprocessRule == cmGeneratorExpression::InstallInterface);
@@ -478,7 +481,7 @@ void cmExportFileGenerator::PopulateLinkDirectoriesInterface(
std::string prepro =
cmGeneratorExpression::Preprocess(*input, preprocessRule, true);
if (!prepro.empty()) {
- this->ResolveTargetsInGeneratorExpressions(prepro, gt, missingTargets);
+ this->ResolveTargetsInGeneratorExpressions(prepro, gt);
if (!checkInterfaceDirs(prepro, gt, propName)) {
return;
@@ -490,10 +493,10 @@ void cmExportFileGenerator::PopulateLinkDirectoriesInterface(
void cmExportFileGenerator::PopulateInterfaceProperty(
const std::string& propName, cmGeneratorTarget const* target,
cmGeneratorExpression::PreprocessContext preprocessRule,
- ImportPropertyMap& properties, std::vector<std::string>& missingTargets)
+ ImportPropertyMap& properties)
{
this->PopulateInterfaceProperty(propName, propName, target, preprocessRule,
- properties, missingTargets);
+ properties);
}
static void getPropertyContents(cmGeneratorTarget const* tgt,
@@ -598,12 +601,12 @@ void cmExportFileGenerator::GenerateInterfaceProperties(
}
}
-bool cmExportFileGenerator::AddTargetNamespace(
- std::string& input, cmGeneratorTarget const* target,
- std::vector<std::string>& missingTargets)
+bool cmExportFileGenerator::AddTargetNamespace(std::string& input,
+ cmGeneratorTarget const* target,
+ cmLocalGenerator const* lg)
{
cmGeneratorTarget::TargetOrString resolved =
- target->ResolveTargetReference(input);
+ target->ResolveTargetReference(input, lg);
cmGeneratorTarget* tgt = resolved.Target;
if (!tgt) {
@@ -619,7 +622,7 @@ bool cmExportFileGenerator::AddTargetNamespace(
input = this->Namespace + tgt->GetExportName();
} else {
std::string namespacedTarget;
- this->HandleMissingTarget(namespacedTarget, missingTargets, target, tgt);
+ this->HandleMissingTarget(namespacedTarget, target, tgt);
if (!namespacedTarget.empty()) {
input = namespacedTarget;
} else {
@@ -631,10 +634,11 @@ bool cmExportFileGenerator::AddTargetNamespace(
void cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
std::string& input, cmGeneratorTarget const* target,
- std::vector<std::string>& missingTargets, FreeTargetsReplace replace)
+ FreeTargetsReplace replace)
{
+ cmLocalGenerator const* lg = target->GetLocalGenerator();
if (replace == NoReplaceFreeTargets) {
- this->ResolveTargetsInGeneratorExpression(input, target, missingTargets);
+ this->ResolveTargetsInGeneratorExpression(input, target, lg);
return;
}
std::vector<std::string> parts;
@@ -643,13 +647,13 @@ void cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
std::string sep;
input.clear();
for (std::string& li : parts) {
- if (cmHasLiteralPrefix(li, CMAKE_DIRECTORY_ID_SEP)) {
+ if (target->IsLinkLookupScope(li, lg)) {
continue;
}
if (cmGeneratorExpression::Find(li) == std::string::npos) {
- this->AddTargetNamespace(li, target, missingTargets);
+ this->AddTargetNamespace(li, target, lg);
} else {
- this->ResolveTargetsInGeneratorExpression(li, target, missingTargets);
+ this->ResolveTargetsInGeneratorExpression(li, target, lg);
}
input += sep + li;
sep = ";";
@@ -658,7 +662,7 @@ void cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
void cmExportFileGenerator::ResolveTargetsInGeneratorExpression(
std::string& input, cmGeneratorTarget const* target,
- std::vector<std::string>& missingTargets)
+ cmLocalGenerator const* lg)
{
std::string::size_type pos = 0;
std::string::size_type lastPos = pos;
@@ -682,7 +686,7 @@ void cmExportFileGenerator::ResolveTargetsInGeneratorExpression(
std::string targetName =
input.substr(nameStartPos, commaPos - nameStartPos);
- if (this->AddTargetNamespace(targetName, target, missingTargets)) {
+ if (this->AddTargetNamespace(targetName, target, lg)) {
input.replace(nameStartPos, commaPos - nameStartPos, targetName);
}
lastPos = nameStartPos + targetName.size() + 1;
@@ -704,7 +708,7 @@ void cmExportFileGenerator::ResolveTargetsInGeneratorExpression(
"literal.";
break;
}
- if (!this->AddTargetNamespace(targetName, target, missingTargets)) {
+ if (!this->AddTargetNamespace(targetName, target, lg)) {
errorString = "$<TARGET_NAME:...> requires its parameter to be a "
"reachable target.";
break;
@@ -725,7 +729,7 @@ void cmExportFileGenerator::ResolveTargetsInGeneratorExpression(
}
std::string libName = input.substr(nameStartPos, endPos - nameStartPos);
if (cmGeneratorExpression::IsValidTargetName(libName) &&
- this->AddTargetNamespace(libName, target, missingTargets)) {
+ this->AddTargetNamespace(libName, target, lg)) {
input.replace(nameStartPos, endPos - nameStartPos, libName);
}
lastPos = nameStartPos + libName.size() + 1;
@@ -747,8 +751,7 @@ void cmExportFileGenerator::ReplaceInstallPrefix(std::string& /*unused*/)
void cmExportFileGenerator::SetImportLinkInterface(
const std::string& config, std::string const& suffix,
cmGeneratorExpression::PreprocessContext preprocessRule,
- cmGeneratorTarget const* target, ImportPropertyMap& properties,
- std::vector<std::string>& missingTargets)
+ cmGeneratorTarget const* target, ImportPropertyMap& properties)
{
// Add the transitive link dependencies for this configuration.
cmLinkInterface const* iface = target->GetLinkInterface(config, target);
@@ -760,7 +763,7 @@ void cmExportFileGenerator::SetImportLinkInterface(
// Policy CMP0022 must not be NEW.
this->SetImportLinkProperty(
suffix, target, "IMPORTED_LINK_INTERFACE_LIBRARIES", iface->Libraries,
- properties, missingTargets, ImportLinkPropertyTargetNames::Yes);
+ properties, ImportLinkPropertyTargetNames::Yes);
return;
}
@@ -799,7 +802,7 @@ void cmExportFileGenerator::SetImportLinkInterface(
std::string prepro =
cmGeneratorExpression::Preprocess(*propContent, preprocessRule);
if (!prepro.empty()) {
- this->ResolveTargetsInGeneratorExpressions(prepro, target, missingTargets,
+ this->ResolveTargetsInGeneratorExpressions(prepro, target,
ReplaceFreeTargets);
properties["IMPORTED_LINK_INTERFACE_LIBRARIES" + suffix] = prepro;
}
@@ -807,8 +810,7 @@ void cmExportFileGenerator::SetImportLinkInterface(
void cmExportFileGenerator::SetImportDetailProperties(
const std::string& config, std::string const& suffix,
- cmGeneratorTarget* target, ImportPropertyMap& properties,
- std::vector<std::string>& missingTargets)
+ cmGeneratorTarget* target, ImportPropertyMap& properties)
{
// Get the makefile in which to lookup target information.
cmMakefile* mf = target->Makefile;
@@ -839,12 +841,11 @@ void cmExportFileGenerator::SetImportDetailProperties(
target->GetLinkInterface(config, target)) {
this->SetImportLinkProperty(
suffix, target, "IMPORTED_LINK_INTERFACE_LANGUAGES", iface->Languages,
- properties, missingTargets, ImportLinkPropertyTargetNames::No);
+ properties, ImportLinkPropertyTargetNames::No);
- std::vector<std::string> dummy;
this->SetImportLinkProperty(
suffix, target, "IMPORTED_LINK_DEPENDENT_LIBRARIES", iface->SharedDeps,
- properties, dummy, ImportLinkPropertyTargetNames::Yes);
+ properties, ImportLinkPropertyTargetNames::Yes);
if (iface->Multiplicity > 0) {
std::string prop =
cmStrCat("IMPORTED_LINK_INTERFACE_MULTIPLICITY", suffix);
@@ -885,14 +886,15 @@ template <typename T>
void cmExportFileGenerator::SetImportLinkProperty(
std::string const& suffix, cmGeneratorTarget const* target,
const std::string& propName, std::vector<T> const& entries,
- ImportPropertyMap& properties, std::vector<std::string>& missingTargets,
- ImportLinkPropertyTargetNames targetNames)
+ ImportPropertyMap& properties, ImportLinkPropertyTargetNames targetNames)
{
// Skip the property if there are no entries.
if (entries.empty()) {
return;
}
+ cmLocalGenerator const* lg = target->GetLocalGenerator();
+
// Construct the property value.
std::string link_entries;
const char* sep = "";
@@ -903,7 +905,7 @@ void cmExportFileGenerator::SetImportLinkProperty(
if (targetNames == ImportLinkPropertyTargetNames::Yes) {
std::string temp = asString(l);
- this->AddTargetNamespace(temp, target, missingTargets);
+ this->AddTargetNamespace(temp, target, lg);
link_entries += temp;
} else {
link_entries += asString(l);
@@ -920,20 +922,23 @@ void cmExportFileGenerator::GeneratePolicyHeaderCode(std::ostream& os)
// Protect that file against use with older CMake versions.
/* clang-format off */
os << "# Generated by CMake\n\n";
- os << "if(\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" LESS 2.6)\n"
- << " message(FATAL_ERROR \"CMake >= 2.6.0 required\")\n"
+ os << "if(\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" LESS 2.8)\n"
+ << " message(FATAL_ERROR \"CMake >= 2.8.0 required\")\n"
+ << "endif()\n"
+ << "if(CMAKE_VERSION VERSION_LESS \"2.8.3\")\n"
+ << " message(FATAL_ERROR \"CMake >= 2.8.3 required\")\n"
<< "endif()\n";
/* clang-format on */
// Isolate the file policy level.
// Support CMake versions as far back as 2.6 but also support using NEW
- // policy settings for up to CMake 3.21 (this upper limit may be reviewed
+ // policy settings for up to CMake 3.22 (this upper limit may be reviewed
// and increased from time to time). This reduces the opportunity for CMake
// warnings when an older export file is later used with newer CMake
// versions.
/* clang-format off */
os << "cmake_policy(PUSH)\n"
- << "cmake_policy(VERSION 2.6...3.21)\n";
+ << "cmake_policy(VERSION 2.8.3...3.22)\n";
/* clang-format on */
}
@@ -980,34 +985,36 @@ void cmExportFileGenerator::GenerateExpectedTargetsCode(
/* clang-format off */
os << "# Protect against multiple inclusion, which would fail when already "
"imported targets are added once more.\n"
- "set(_targetsDefined)\n"
- "set(_targetsNotDefined)\n"
- "set(_expectedTargets)\n"
- "foreach(_expectedTarget " << expectedTargets << ")\n"
- " list(APPEND _expectedTargets ${_expectedTarget})\n"
- " if(NOT TARGET ${_expectedTarget})\n"
- " list(APPEND _targetsNotDefined ${_expectedTarget})\n"
- " endif()\n"
- " if(TARGET ${_expectedTarget})\n"
- " list(APPEND _targetsDefined ${_expectedTarget})\n"
+ "set(_cmake_targets_defined \"\")\n"
+ "set(_cmake_targets_not_defined \"\")\n"
+ "set(_cmake_expected_targets \"\")\n"
+ "foreach(_cmake_expected_target IN ITEMS " << expectedTargets << ")\n"
+ " list(APPEND _cmake_expected_targets \"${_cmake_expected_target}\")\n"
+ " if(TARGET \"${_cmake_expected_target}\")\n"
+ " list(APPEND _cmake_targets_defined \"${_cmake_expected_target}\")\n"
+ " else()\n"
+ " list(APPEND _cmake_targets_not_defined \"${_cmake_expected_target}\")\n"
" endif()\n"
"endforeach()\n"
- "if(\"${_targetsDefined}\" STREQUAL \"${_expectedTargets}\")\n"
- " unset(_targetsDefined)\n"
- " unset(_targetsNotDefined)\n"
- " unset(_expectedTargets)\n"
- " set(CMAKE_IMPORT_FILE_VERSION)\n"
+ "unset(_cmake_expected_target)\n"
+ "if(_cmake_targets_defined STREQUAL _cmake_expected_targets)\n"
+ " unset(_cmake_targets_defined)\n"
+ " unset(_cmake_targets_not_defined)\n"
+ " unset(_cmake_expected_targets)\n"
+ " unset(CMAKE_IMPORT_FILE_VERSION)\n"
" cmake_policy(POP)\n"
" return()\n"
"endif()\n"
- "if(NOT \"${_targetsDefined}\" STREQUAL \"\")\n"
+ "if(NOT _cmake_targets_defined STREQUAL \"\")\n"
+ " string(REPLACE \";\" \", \" _cmake_targets_defined_text \"${_cmake_targets_defined}\")\n"
+ " string(REPLACE \";\" \", \" _cmake_targets_not_defined_text \"${_cmake_targets_not_defined}\")\n"
" message(FATAL_ERROR \"Some (but not all) targets in this export "
- "set were already defined.\\nTargets Defined: ${_targetsDefined}\\n"
- "Targets not yet defined: ${_targetsNotDefined}\\n\")\n"
+ "set were already defined.\\nTargets Defined: ${_cmake_targets_defined_text}\\n"
+ "Targets not yet defined: ${_cmake_targets_not_defined_text}\\n\")\n"
"endif()\n"
- "unset(_targetsDefined)\n"
- "unset(_targetsNotDefined)\n"
- "unset(_expectedTargets)\n"
+ "unset(_cmake_targets_defined)\n"
+ "unset(_cmake_targets_not_defined)\n"
+ "unset(_cmake_expected_targets)\n"
"\n\n";
/* clang-format on */
}
@@ -1113,10 +1120,9 @@ void cmExportFileGenerator::GenerateImportPropertyCode(
<< "\n";
}
-void cmExportFileGenerator::GenerateMissingTargetsCheckCode(
- std::ostream& os, const std::vector<std::string>& missingTargets)
+void cmExportFileGenerator::GenerateMissingTargetsCheckCode(std::ostream& os)
{
- if (missingTargets.empty()) {
+ if (this->MissingTargets.empty()) {
/* clang-format off */
os << "# This file does not depend on other imported targets which have\n"
"# been exported from the same project but in a separate "
@@ -1131,7 +1137,7 @@ void cmExportFileGenerator::GenerateMissingTargetsCheckCode(
"foreach(_target ";
/* clang-format on */
std::set<std::string> emitted;
- for (std::string const& missingTarget : missingTargets) {
+ for (std::string const& missingTarget : this->MissingTargets) {
if (emitted.insert(missingTarget).second) {
os << "\"" << missingTarget << "\" ";
}
@@ -1174,12 +1180,12 @@ void cmExportFileGenerator::GenerateImportedFileCheckLoop(std::ostream& os)
// but the development package was not installed.).
/* clang-format off */
os << "# Loop over all imported files and verify that they actually exist\n"
- "foreach(target ${_IMPORT_CHECK_TARGETS} )\n"
- " foreach(file ${_IMPORT_CHECK_FILES_FOR_${target}} )\n"
- " if(NOT EXISTS \"${file}\" )\n"
- " message(FATAL_ERROR \"The imported target \\\"${target}\\\""
+ "foreach(_cmake_target IN LISTS _cmake_import_check_targets)\n"
+ " foreach(_cmake_file IN LISTS \"_cmake_import_check_files_for_${_cmake_target}\")\n"
+ " if(NOT EXISTS \"${_cmake_file}\")\n"
+ " message(FATAL_ERROR \"The imported target \\\"${_cmake_target}\\\""
" references the file\n"
- " \\\"${file}\\\"\n"
+ " \\\"${_cmake_file}\\\"\n"
"but this file does not exist. Possible reasons include:\n"
"* The file was deleted, renamed, or moved to another location.\n"
"* An install or uninstall procedure did not complete successfully.\n"
@@ -1189,9 +1195,11 @@ void cmExportFileGenerator::GenerateImportedFileCheckLoop(std::ostream& os)
"\")\n"
" endif()\n"
" endforeach()\n"
- " unset(_IMPORT_CHECK_FILES_FOR_${target})\n"
+ " unset(_cmake_file)\n"
+ " unset(\"_cmake_import_check_files_for_${_cmake_target}\")\n"
"endforeach()\n"
- "unset(_IMPORT_CHECK_TARGETS)\n"
+ "unset(_cmake_target)\n"
+ "unset(_cmake_import_check_targets)\n"
"\n";
/* clang-format on */
}
@@ -1204,9 +1212,9 @@ void cmExportFileGenerator::GenerateImportedFileChecksCode(
// Construct the imported target name.
std::string targetName = cmStrCat(this->Namespace, target->GetExportName());
- os << "list(APPEND _IMPORT_CHECK_TARGETS " << targetName
+ os << "list(APPEND _cmake_import_check_targets " << targetName
<< " )\n"
- "list(APPEND _IMPORT_CHECK_FILES_FOR_"
+ "list(APPEND _cmake_import_check_files_for_"
<< targetName << " ";
for (std::string const& li : importedLocations) {
diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h
index d50f7e8..d27a555 100644
--- a/Source/cmExportFileGenerator.h
+++ b/Source/cmExportFileGenerator.h
@@ -17,6 +17,7 @@
class cmFileSet;
class cmGeneratorTarget;
+class cmLocalGenerator;
class cmTargetExport;
#define STRINGIFY_HELPER(X) #X
@@ -65,8 +66,7 @@ protected:
// Generate per-configuration target information to the given output
// stream.
- void GenerateImportConfig(std::ostream& os, const std::string& config,
- std::vector<std::string>& missingTargets);
+ void GenerateImportConfig(std::ostream& os, const std::string& config);
// Methods to implement export file code generation.
virtual void GeneratePolicyHeaderCode(std::ostream& os);
@@ -87,8 +87,7 @@ protected:
ImportPropertyMap const& properties,
const std::set<std::string>& importedLocations);
virtual void GenerateImportedFileCheckLoop(std::ostream& os);
- virtual void GenerateMissingTargetsCheckCode(
- std::ostream& os, const std::vector<std::string>& missingTargets);
+ virtual void GenerateMissingTargetsCheckCode(std::ostream& os);
virtual void GenerateExpectedTargetsCode(std::ostream& os,
const std::string& expectedTargets);
@@ -98,8 +97,7 @@ protected:
void SetImportDetailProperties(const std::string& config,
std::string const& suffix,
cmGeneratorTarget* target,
- ImportPropertyMap& properties,
- std::vector<std::string>& missingTargets);
+ ImportPropertyMap& properties);
enum class ImportLinkPropertyTargetNames
{
@@ -112,31 +110,28 @@ protected:
const std::string& propName,
std::vector<T> const& entries,
ImportPropertyMap& properties,
- std::vector<std::string>& missingTargets,
ImportLinkPropertyTargetNames targetNames);
/** Each subclass knows how to generate its kind of export file. */
virtual bool GenerateMainFile(std::ostream& os) = 0;
/** Each subclass knows where the target files are located. */
- virtual void GenerateImportTargetsConfig(
- std::ostream& os, const std::string& config, std::string const& suffix,
- std::vector<std::string>& missingTargets) = 0;
+ virtual void GenerateImportTargetsConfig(std::ostream& os,
+ const std::string& config,
+ std::string const& suffix) = 0;
/** Each subclass knows how to deal with a target that is missing from an
* export set. */
virtual void HandleMissingTarget(std::string& link_libs,
- std::vector<std::string>& missingTargets,
cmGeneratorTarget const* depender,
cmGeneratorTarget* dependee) = 0;
void PopulateInterfaceProperty(const std::string&,
cmGeneratorTarget const* target,
cmGeneratorExpression::PreprocessContext,
- ImportPropertyMap& properties,
- std::vector<std::string>& missingTargets);
+ ImportPropertyMap& properties);
bool PopulateInterfaceLinkLibrariesProperty(
cmGeneratorTarget const* target, cmGeneratorExpression::PreprocessContext,
- ImportPropertyMap& properties, std::vector<std::string>& missingTargets);
+ ImportPropertyMap& properties);
void PopulateInterfaceProperty(const std::string& propName,
cmGeneratorTarget const* target,
ImportPropertyMap& properties);
@@ -148,26 +143,24 @@ protected:
void PopulateIncludeDirectoriesInterface(
cmGeneratorTarget const* target,
cmGeneratorExpression::PreprocessContext preprocessRule,
- ImportPropertyMap& properties, std::vector<std::string>& missingTargets,
- cmTargetExport const& te);
+ ImportPropertyMap& properties, cmTargetExport const& te);
void PopulateSourcesInterface(
cmGeneratorTarget const* target,
cmGeneratorExpression::PreprocessContext preprocessRule,
- ImportPropertyMap& properties, std::vector<std::string>& missingTargets);
+ ImportPropertyMap& properties);
void PopulateLinkDirectoriesInterface(
cmGeneratorTarget const* target,
cmGeneratorExpression::PreprocessContext preprocessRule,
- ImportPropertyMap& properties, std::vector<std::string>& missingTargets);
+ ImportPropertyMap& properties);
void PopulateLinkDependsInterface(
cmGeneratorTarget const* target,
cmGeneratorExpression::PreprocessContext preprocessRule,
- ImportPropertyMap& properties, std::vector<std::string>& missingTargets);
+ ImportPropertyMap& properties);
void SetImportLinkInterface(
const std::string& config, std::string const& suffix,
cmGeneratorExpression::PreprocessContext preprocessRule,
- cmGeneratorTarget const* target, ImportPropertyMap& properties,
- std::vector<std::string>& missingTargets);
+ cmGeneratorTarget const* target, ImportPropertyMap& properties);
enum FreeTargetsReplace
{
@@ -177,7 +170,6 @@ protected:
void ResolveTargetsInGeneratorExpressions(
std::string& input, cmGeneratorTarget const* target,
- std::vector<std::string>& missingTargets,
FreeTargetsReplace replace = NoReplaceFreeTargets);
virtual void GenerateRequiredCMakeVersion(std::ostream& os,
@@ -215,19 +207,20 @@ protected:
// The set of targets included in the export.
std::set<cmGeneratorTarget*> ExportedTargets;
+ std::vector<std::string> MissingTargets;
+
private:
void PopulateInterfaceProperty(const std::string&, const std::string&,
cmGeneratorTarget const* target,
cmGeneratorExpression::PreprocessContext,
- ImportPropertyMap& properties,
- std::vector<std::string>& missingTargets);
+ ImportPropertyMap& properties);
bool AddTargetNamespace(std::string& input, cmGeneratorTarget const* target,
- std::vector<std::string>& missingTargets);
+ cmLocalGenerator const* lg);
- void ResolveTargetsInGeneratorExpression(
- std::string& input, cmGeneratorTarget const* target,
- std::vector<std::string>& missingTargets);
+ void ResolveTargetsInGeneratorExpression(std::string& input,
+ cmGeneratorTarget const* target,
+ cmLocalGenerator const* lg);
virtual void ReplaceInstallPrefix(std::string& input);
diff --git a/Source/cmExportInstallAndroidMKGenerator.cxx b/Source/cmExportInstallAndroidMKGenerator.cxx
index 80f776e..4e4f8a1 100644
--- a/Source/cmExportInstallAndroidMKGenerator.cxx
+++ b/Source/cmExportInstallAndroidMKGenerator.cxx
@@ -5,6 +5,7 @@
#include <cstddef>
#include <memory>
#include <ostream>
+#include <vector>
#include "cmExportBuildAndroidMKGenerator.h"
#include "cmExportSet.h"
@@ -86,7 +87,7 @@ void cmExportInstallAndroidMKGenerator::GenerateImportPropertyCode(
}
void cmExportInstallAndroidMKGenerator::GenerateMissingTargetsCheckCode(
- std::ostream&, const std::vector<std::string>&)
+ std::ostream&)
{
}
@@ -132,7 +133,7 @@ void cmExportInstallAndroidMKGenerator::GenerateImportedFileChecksCode(
}
bool cmExportInstallAndroidMKGenerator::GenerateImportFileConfig(
- const std::string&, std::vector<std::string>&)
+ const std::string&)
{
return true;
}
diff --git a/Source/cmExportInstallAndroidMKGenerator.h b/Source/cmExportInstallAndroidMKGenerator.h
index 40978e0..c05751a 100644
--- a/Source/cmExportInstallAndroidMKGenerator.h
+++ b/Source/cmExportInstallAndroidMKGenerator.h
@@ -7,7 +7,6 @@
#include <iosfwd>
#include <set>
#include <string>
-#include <vector>
#include "cmExportFileGenerator.h"
#include "cmExportInstallFileGenerator.h"
@@ -50,8 +49,7 @@ protected:
std::ostream& os, const std::string& config,
cmGeneratorTarget const* target,
ImportPropertyMap const& properties) override;
- void GenerateMissingTargetsCheckCode(
- std::ostream& os, const std::vector<std::string>& missingTargets) override;
+ void GenerateMissingTargetsCheckCode(std::ostream& os) override;
void GenerateInterfaceProperties(
cmGeneratorTarget const* target, std::ostream& os,
const ImportPropertyMap& properties) override;
@@ -65,6 +63,5 @@ protected:
std::ostream& os, cmGeneratorTarget* target,
ImportPropertyMap const& properties,
const std::set<std::string>& importedLocations) override;
- bool GenerateImportFileConfig(const std::string& config,
- std::vector<std::string>&) override;
+ bool GenerateImportFileConfig(const std::string& config) override;
};
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index f232440..adccdfe 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -71,8 +71,6 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
// Compute the relative import prefix for the file
this->GenerateImportPrefix(os);
- std::vector<std::string> missingTargets;
-
bool require2_8_12 = false;
bool require3_0_0 = false;
bool require3_1_0 = false;
@@ -90,35 +88,34 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
ImportPropertyMap properties;
this->PopulateIncludeDirectoriesInterface(
- gt, cmGeneratorExpression::InstallInterface, properties, missingTargets,
- *te);
+ gt, cmGeneratorExpression::InstallInterface, properties, *te);
this->PopulateSourcesInterface(gt, cmGeneratorExpression::InstallInterface,
- properties, missingTargets);
+ properties);
this->PopulateInterfaceProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES", gt,
cmGeneratorExpression::InstallInterface,
- properties, missingTargets);
+ properties);
this->PopulateInterfaceProperty("INTERFACE_COMPILE_DEFINITIONS", gt,
cmGeneratorExpression::InstallInterface,
- properties, missingTargets);
+ properties);
this->PopulateInterfaceProperty("INTERFACE_COMPILE_OPTIONS", gt,
cmGeneratorExpression::InstallInterface,
- properties, missingTargets);
+ properties);
this->PopulateInterfaceProperty("INTERFACE_PRECOMPILE_HEADERS", gt,
cmGeneratorExpression::InstallInterface,
- properties, missingTargets);
+ properties);
this->PopulateInterfaceProperty("INTERFACE_AUTOUIC_OPTIONS", gt,
cmGeneratorExpression::InstallInterface,
- properties, missingTargets);
+ properties);
this->PopulateInterfaceProperty("INTERFACE_COMPILE_FEATURES", gt,
cmGeneratorExpression::InstallInterface,
- properties, missingTargets);
+ properties);
this->PopulateInterfaceProperty("INTERFACE_LINK_OPTIONS", gt,
cmGeneratorExpression::InstallInterface,
- properties, missingTargets);
+ properties);
this->PopulateLinkDirectoriesInterface(
- gt, cmGeneratorExpression::InstallInterface, properties, missingTargets);
+ gt, cmGeneratorExpression::InstallInterface, properties);
this->PopulateLinkDependsInterface(
- gt, cmGeneratorExpression::InstallInterface, properties, missingTargets);
+ gt, cmGeneratorExpression::InstallInterface, properties);
std::string errorMessage;
if (!this->PopulateExportProperties(gt, properties, errorMessage)) {
@@ -131,8 +128,7 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
gt->GetPolicyStatusCMP0022() != cmPolicies::OLD;
if (newCMP0022Behavior) {
if (this->PopulateInterfaceLinkLibrariesProperty(
- gt, cmGeneratorExpression::InstallInterface, properties,
- missingTargets) &&
+ gt, cmGeneratorExpression::InstallInterface, properties) &&
!this->ExportOld) {
require2_8_12 = true;
}
@@ -174,13 +170,13 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
// Don't do this if we only export INTERFACE_LIBRARY targets.
if (requiresConfigFiles) {
for (std::string const& c : this->Configurations) {
- if (!this->GenerateImportFileConfig(c, missingTargets)) {
+ if (!this->GenerateImportFileConfig(c)) {
result = false;
}
}
}
- this->GenerateMissingTargetsCheckCode(os, missingTargets);
+ this->GenerateMissingTargetsCheckCode(os);
return result;
}
@@ -257,12 +253,13 @@ void cmExportInstallFileGenerator::LoadConfigFiles(std::ostream& os)
// Now load per-configuration properties for them.
/* clang-format off */
os << "# Load information for each installed configuration.\n"
- << "get_filename_component(_DIR \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n"
- << "file(GLOB CONFIG_FILES \"${_DIR}/"
+ << "file(GLOB _cmake_config_files \"${CMAKE_CURRENT_LIST_DIR}/"
<< this->GetConfigImportFileGlob() << "\")\n"
- << "foreach(f ${CONFIG_FILES})\n"
- << " include(${f})\n"
+ << "foreach(_cmake_config_file IN LISTS _cmake_config_files)\n"
+ << " include(\"${_cmake_config_file}\")\n"
<< "endforeach()\n"
+ << "unset(_cmake_config_file)\n"
+ << "unset(_cmake_config_files)\n"
<< "\n";
/* clang-format on */
}
@@ -273,7 +270,7 @@ void cmExportInstallFileGenerator::ReplaceInstallPrefix(std::string& input)
}
bool cmExportInstallFileGenerator::GenerateImportFileConfig(
- const std::string& config, std::vector<std::string>& missingTargets)
+ const std::string& config)
{
// Skip configurations not enabled for this export.
if (!this->IEGen->InstallsForConfig(config)) {
@@ -305,7 +302,7 @@ bool cmExportInstallFileGenerator::GenerateImportFileConfig(
this->GenerateImportHeaderCode(os, config);
// Generate the per-config target information.
- this->GenerateImportConfig(os, config, missingTargets);
+ this->GenerateImportConfig(os, config);
// End with the import file footer.
this->GenerateImportFooterCode(os);
@@ -317,8 +314,7 @@ bool cmExportInstallFileGenerator::GenerateImportFileConfig(
}
void cmExportInstallFileGenerator::GenerateImportTargetsConfig(
- std::ostream& os, const std::string& config, std::string const& suffix,
- std::vector<std::string>& missingTargets)
+ std::ostream& os, const std::string& config, std::string const& suffix)
{
// Add each target in the set to the export.
for (std::unique_ptr<cmTargetExport> const& te :
@@ -350,12 +346,11 @@ void cmExportInstallFileGenerator::GenerateImportTargetsConfig(
if (!properties.empty()) {
// Get the rest of the target details.
cmGeneratorTarget* gtgt = te->Target;
- this->SetImportDetailProperties(config, suffix, gtgt, properties,
- missingTargets);
+ this->SetImportDetailProperties(config, suffix, gtgt, properties);
this->SetImportLinkInterface(config, suffix,
cmGeneratorExpression::InstallInterface,
- gtgt, properties, missingTargets);
+ gtgt, properties);
// TODO: PUBLIC_HEADER_LOCATION
// This should wait until the build feature propagation stuff
@@ -454,8 +449,8 @@ cmStateEnums::TargetType cmExportInstallFileGenerator::GetExportTargetType(
}
void cmExportInstallFileGenerator::HandleMissingTarget(
- std::string& link_libs, std::vector<std::string>& missingTargets,
- cmGeneratorTarget const* depender, cmGeneratorTarget* dependee)
+ std::string& link_libs, cmGeneratorTarget const* depender,
+ cmGeneratorTarget* dependee)
{
const std::string name = dependee->GetName();
cmGlobalGenerator* gg = dependee->GetLocalGenerator()->GetGlobalGenerator();
@@ -466,7 +461,7 @@ void cmExportInstallFileGenerator::HandleMissingTarget(
missingTarget += dependee->GetExportName();
link_libs += missingTarget;
- missingTargets.push_back(std::move(missingTarget));
+ this->MissingTargets.emplace_back(std::move(missingTarget));
} else {
// All exported targets should be known here and should be unique.
// This is probably user-error.
diff --git a/Source/cmExportInstallFileGenerator.h b/Source/cmExportInstallFileGenerator.h
index 9374c6b..86fb505 100644
--- a/Source/cmExportInstallFileGenerator.h
+++ b/Source/cmExportInstallFileGenerator.h
@@ -57,13 +57,11 @@ public:
protected:
// Implement virtual methods from the superclass.
bool GenerateMainFile(std::ostream& os) override;
- void GenerateImportTargetsConfig(
- std::ostream& os, const std::string& config, std::string const& suffix,
- std::vector<std::string>& missingTargets) override;
+ void GenerateImportTargetsConfig(std::ostream& os, const std::string& config,
+ std::string const& suffix) override;
cmStateEnums::TargetType GetExportTargetType(
cmTargetExport const* targetExport) const;
void HandleMissingTarget(std::string& link_libs,
- std::vector<std::string>& missingTargets,
cmGeneratorTarget const* depender,
cmGeneratorTarget* dependee) override;
@@ -85,8 +83,7 @@ protected:
virtual void CleanupTemporaryVariables(std::ostream&);
/** Generate a per-configuration file for the targets. */
- virtual bool GenerateImportFileConfig(
- const std::string& config, std::vector<std::string>& missingTargets);
+ virtual bool GenerateImportFileConfig(const std::string& config);
/** Fill in properties indicating installed file locations. */
void SetImportLocationProperty(const std::string& config,
diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx
index db9b05b..e98aa05 100644
--- a/Source/cmExportTryCompileFileGenerator.cxx
+++ b/Source/cmExportTryCompileFileGenerator.cxx
@@ -111,6 +111,8 @@ void cmExportTryCompileFileGenerator::PopulateProperties(
std::vector<std::string> props = target->GetPropertyKeys();
// Include special properties that might be relevant here.
props.emplace_back("INTERFACE_LINK_LIBRARIES");
+ props.emplace_back("INTERFACE_LINK_LIBRARIES_DIRECT");
+ props.emplace_back("INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE");
for (std::string const& p : props) {
cmValue v = target->GetProperty(p);
if (!v) {
diff --git a/Source/cmExportTryCompileFileGenerator.h b/Source/cmExportTryCompileFileGenerator.h
index 8a1fd7e..1dd8a20 100644
--- a/Source/cmExportTryCompileFileGenerator.h
+++ b/Source/cmExportTryCompileFileGenerator.h
@@ -33,12 +33,10 @@ protected:
bool GenerateMainFile(std::ostream& os) override;
void GenerateImportTargetsConfig(std::ostream&, const std::string&,
- std::string const&,
- std::vector<std::string>&) override
+ std::string const&) override
{
}
- void HandleMissingTarget(std::string&, std::vector<std::string>&,
- cmGeneratorTarget const*,
+ void HandleMissingTarget(std::string&, cmGeneratorTarget const*,
cmGeneratorTarget*) override
{
}
diff --git a/Source/cmFLTKWrapUICommand.cxx b/Source/cmFLTKWrapUICommand.cxx
index 80c069f..373a3cf 100644
--- a/Source/cmFLTKWrapUICommand.cxx
+++ b/Source/cmFLTKWrapUICommand.cxx
@@ -10,7 +10,6 @@
#include "cmCustomCommand.h"
#include "cmCustomCommandLines.h"
#include "cmExecutionStatus.h"
-#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -20,6 +19,7 @@
#include "cmSystemTools.h"
#include "cmake.h"
+class cmListFileBacktrace;
class cmTarget;
static void FinalAction(cmMakefile& makefile, std::string const& name,
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx
index 40e1d2e..dd0540c 100644
--- a/Source/cmFileAPICodemodel.cxx
+++ b/Source/cmFileAPICodemodel.cxx
@@ -1728,7 +1728,7 @@ Json::Value Target::DumpArtifacts()
// Object libraries have only object files as artifacts.
if (this->GT->GetType() == cmStateEnums::OBJECT_LIBRARY) {
- if (!this->GT->GetGlobalGenerator()->HasKnownObjectFileLocation(nullptr)) {
+ if (!this->GT->Target->HasKnownObjectFileLocation(nullptr)) {
return artifacts;
}
std::vector<cmSourceFile const*> objectSources;
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index da2f15f..e4728ac 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -15,6 +15,7 @@
#include <vector>
#include <cm/memory>
+#include <cm/optional>
#include <cm/string_view>
#include <cmext/algorithm>
#include <cmext/string_view>
@@ -1778,6 +1779,7 @@ bool HandleDownloadCommand(std::vector<std::string> const& args,
std::string userpwd;
std::vector<std::string> curl_headers;
+ std::vector<std::pair<std::string, cm::optional<std::string>>> curl_ranges;
while (i != args.end()) {
if (*i == "TIMEOUT") {
@@ -1890,6 +1892,27 @@ bool HandleDownloadCommand(std::vector<std::string> const& args,
return false;
}
curl_headers.push_back(*i);
+ } else if (*i == "RANGE_START") {
+ ++i;
+ if (i == args.end()) {
+ status.SetError("DOWNLOAD missing value for RANGE_START.");
+ return false;
+ }
+ curl_ranges.emplace_back(*i, cm::nullopt);
+ } else if (*i == "RANGE_END") {
+ ++i;
+ if (curl_ranges.empty()) {
+ curl_ranges.emplace_back("0", *i);
+ } else {
+ auto& last_range = curl_ranges.back();
+ if (!last_range.second.has_value()) {
+ last_range.second = *i;
+ } else {
+ status.SetError("Multiple RANGE_END values is provided without "
+ "the corresponding RANGE_START.");
+ return false;
+ }
+ }
} else if (file.empty()) {
file = *i;
} else {
@@ -1899,6 +1922,7 @@ bool HandleDownloadCommand(std::vector<std::string> const& args,
}
++i;
}
+
// Can't calculate hash if we don't save the file.
// TODO Incrementally calculate hash in the write callback as the file is
// being downloaded so this check can be relaxed.
@@ -1984,6 +2008,13 @@ bool HandleDownloadCommand(std::vector<std::string> const& args,
check_curl_result(res, "DOWNLOAD cannot set TLS/SSL Verify off: ");
}
+ for (const auto& range : curl_ranges) {
+ std::string curl_range = range.first + '-' +
+ (range.second.has_value() ? range.second.value() : "");
+ res = ::curl_easy_setopt(curl, CURLOPT_RANGE, curl_range.c_str());
+ check_curl_result(res, "DOWNLOAD cannot set range: ");
+ }
+
// check to see if a CAINFO file has been specified
// command arg comes first
std::string const& cainfo_err = cmCurlSetCAInfo(curl, cainfo);
@@ -3476,6 +3507,7 @@ bool HandleArchiveExtractCommand(std::vector<std::string> const& args,
bool ListOnly = false;
std::string Destination;
std::vector<std::string> Patterns;
+ bool Touch = false;
};
static auto const parser = cmArgumentParser<Arguments>{}
@@ -3483,7 +3515,8 @@ bool HandleArchiveExtractCommand(std::vector<std::string> const& args,
.Bind("VERBOSE"_s, &Arguments::Verbose)
.Bind("LIST_ONLY"_s, &Arguments::ListOnly)
.Bind("DESTINATION"_s, &Arguments::Destination)
- .Bind("PATTERNS"_s, &Arguments::Patterns);
+ .Bind("PATTERNS"_s, &Arguments::Patterns)
+ .Bind("TOUCH"_s, &Arguments::Touch);
std::vector<std::string> unrecognizedArguments;
std::vector<std::string> keywordsMissingValues;
@@ -3546,8 +3579,11 @@ bool HandleArchiveExtractCommand(std::vector<std::string> const& args,
return false;
}
- if (!cmSystemTools::ExtractTar(inFile, parsedArgs.Patterns,
- parsedArgs.Verbose)) {
+ if (!cmSystemTools::ExtractTar(
+ inFile, parsedArgs.Patterns,
+ parsedArgs.Touch ? cmSystemTools::cmTarExtractTimestamps::No
+ : cmSystemTools::cmTarExtractTimestamps::Yes,
+ parsedArgs.Verbose)) {
status.SetError(cmStrCat("failed to extract: ", inFile));
cmSystemTools::SetFatalErrorOccured();
return false;
diff --git a/Source/cmFileSet.cxx b/Source/cmFileSet.cxx
index 1d1d29e..d6665a2 100644
--- a/Source/cmFileSet.cxx
+++ b/Source/cmFileSet.cxx
@@ -45,9 +45,12 @@ cmFileSetVisibility cmFileSetVisibilityFromName(cm::string_view name,
if (name == "PRIVATE"_s) {
return cmFileSetVisibility::Private;
}
- mf->IssueMessage(
- MessageType::FATAL_ERROR,
- cmStrCat("File set visibility \"", name, "\" is not valid."));
+ auto msg = cmStrCat("File set visibility \"", name, "\" is not valid.");
+ if (mf) {
+ mf->IssueMessage(MessageType::FATAL_ERROR, msg);
+ } else {
+ cmSystemTools::Error(msg);
+ }
return cmFileSetVisibility::Private;
}
diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx
index efc4e3a..702d9fe 100644
--- a/Source/cmFindBase.cxx
+++ b/Source/cmFindBase.cxx
@@ -7,6 +7,7 @@
#include <map>
#include <utility>
+#include <cm/optional>
#include <cmext/algorithm>
#include "cmCMakePath.h"
@@ -20,6 +21,7 @@
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
+#include "cmWindowsRegistry.h"
#include "cmake.h"
class cmExecutionStatus;
@@ -123,6 +125,19 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
doing = DoingNone;
this->Required = true;
newStyle = true;
+ } else if (args[j] == "REGISTRY_VIEW") {
+ if (++j == args.size()) {
+ this->SetError("missing required argument for \"REGISTRY_VIEW\"");
+ return false;
+ }
+ auto view = cmWindowsRegistry::ToView(args[j]);
+ if (view) {
+ this->RegistryView = *view;
+ } else {
+ this->SetError(
+ cmStrCat("given invalid value for \"REGISTRY_VIEW\": ", args[j]));
+ return false;
+ }
} else if (this->CheckCommonArgument(args[j])) {
doing = DoingNone;
} else {
@@ -267,8 +282,61 @@ void cmFindBase::FillCMakeSystemVariablePath()
{
cmSearchPath& paths = this->LabeledPaths[PathLabel::CMakeSystem];
+ const bool install_prefix_in_list =
+ !this->Makefile->IsOn("CMAKE_FIND_NO_INSTALL_PREFIX");
+ const bool remove_install_prefix = this->NoCMakeInstallPath;
+ const bool add_install_prefix = !this->NoCMakeInstallPath &&
+ this->Makefile->IsDefinitionSet("CMAKE_FIND_USE_INSTALL_PREFIX");
+
+ // We have 3 possible states for `CMAKE_SYSTEM_PREFIX_PATH` and
+ // `CMAKE_INSTALL_PREFIX`.
+ // Either we need to remove `CMAKE_INSTALL_PREFIX`, add
+ // `CMAKE_INSTALL_PREFIX`, or do nothing.
+ //
+ // When we need to remove `CMAKE_INSTALL_PREFIX` we remove the Nth occurrence
+ // of `CMAKE_INSTALL_PREFIX` from `CMAKE_SYSTEM_PREFIX_PATH`, where `N` is
+ // computed by `CMakeSystemSpecificInformation.cmake` while constructing
+ // `CMAKE_SYSTEM_PREFIX_PATH`. This ensures that if projects / toolchains
+ // have removed `CMAKE_INSTALL_PREFIX` from the list, we don't remove
+ // some other entry by mistake
+ long install_prefix_count = -1;
+ std::string install_path_to_remove;
+ if (cmValue to_skip = this->Makefile->GetDefinition(
+ "_CMAKE_SYSTEM_PREFIX_PATH_INSTALL_PREFIX_COUNT")) {
+ cmStrToLong(to_skip, &install_prefix_count);
+ }
+ if (cmValue install_value = this->Makefile->GetDefinition(
+ "_CMAKE_SYSTEM_PREFIX_PATH_INSTALL_PREFIX_VALUE")) {
+ install_path_to_remove = *install_value;
+ }
+
+ if (remove_install_prefix && install_prefix_in_list &&
+ install_prefix_count > 0 && !install_path_to_remove.empty()) {
+ 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);
+ long index_to_remove = 0;
+ for (const auto& path : expanded) {
+ if (path == install_path_to_remove && --install_prefix_count == 0) {
+ break;
+ }
+ ++index_to_remove;
+ }
+ expanded.erase(expanded.begin() + index_to_remove);
+ paths.AddPrefixPaths(expanded,
+ this->Makefile->GetCurrentSourceDirectory().c_str());
+ } else if (add_install_prefix && !install_prefix_in_list) {
+
+ paths.AddCMakePrefixPath("CMAKE_INSTALL_PREFIX");
+ paths.AddCMakePrefixPath("CMAKE_SYSTEM_PREFIX_PATH");
+ } else {
+ // Otherwise the current setup of `CMAKE_SYSTEM_PREFIX_PATH` is correct
+ paths.AddCMakePrefixPath("CMAKE_SYSTEM_PREFIX_PATH");
+ }
+
std::string var = cmStrCat("CMAKE_SYSTEM_", this->CMakePathName, "_PATH");
- paths.AddCMakePrefixPath("CMAKE_SYSTEM_PREFIX_PATH");
paths.AddCMakePath(var);
if (this->CMakePathName == "PROGRAM") {
@@ -496,7 +564,9 @@ cmFindBaseDebugState::~cmFindBaseDebugState()
" CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: ",
!this->FindCommand->NoSystemEnvironmentPath, "\n",
" CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: ",
- !this->FindCommand->NoCMakeSystemPath, "\n");
+ !this->FindCommand->NoCMakeSystemPath, "\n",
+ " CMAKE_FIND_USE_INSTALL_PREFIX: ",
+ !this->FindCommand->NoCMakeInstallPath, "\n");
}
buffer +=
diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx
index 7106e4b..c3fb907 100644
--- a/Source/cmFindCommon.cxx
+++ b/Source/cmFindCommon.cxx
@@ -11,6 +11,7 @@
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmPolicies.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
@@ -39,6 +40,7 @@ cmFindCommon::cmFindCommon(cmExecutionStatus& status)
this->NoCMakeEnvironmentPath = false;
this->NoSystemEnvironmentPath = false;
this->NoCMakeSystemPath = false;
+ this->NoCMakeInstallPath = false;
// OS X Bundle and Framework search policy. The default is to
// search frameworks first on apple.
@@ -57,6 +59,17 @@ cmFindCommon::cmFindCommon(cmExecutionStatus& status)
this->InitializeSearchPathGroups();
this->DebugMode = false;
+
+ // Windows Registry views
+ // When policy CMP0134 is not NEW, rely on previous behavior:
+ if (this->Makefile->GetPolicyStatus(cmPolicies::CMP0134) !=
+ cmPolicies::NEW) {
+ if (this->Makefile->GetDefinition("CMAKE_SIZEOF_VOID_P") == "8") {
+ this->RegistryView = cmWindowsRegistry::View::Reg64;
+ } else {
+ this->RegistryView = cmWindowsRegistry::View::Reg32;
+ }
+ }
}
void cmFindCommon::SetError(std::string const& e)
@@ -179,14 +192,15 @@ void cmFindCommon::SelectDefaultMacMode()
void cmFindCommon::SelectDefaultSearchModes()
{
- const std::array<std::pair<bool&, std::string>, 5> search_paths = {
+ const std::array<std::pair<bool&, std::string>, 6> search_paths = {
{ { this->NoPackageRootPath, "CMAKE_FIND_USE_PACKAGE_ROOT_PATH" },
{ this->NoCMakePath, "CMAKE_FIND_USE_CMAKE_PATH" },
{ this->NoCMakeEnvironmentPath,
"CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH" },
{ this->NoSystemEnvironmentPath,
"CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH" },
- { this->NoCMakeSystemPath, "CMAKE_FIND_USE_CMAKE_SYSTEM_PATH" } }
+ { this->NoCMakeSystemPath, "CMAKE_FIND_USE_CMAKE_SYSTEM_PATH" },
+ { this->NoCMakeInstallPath, "CMAKE_FIND_USE_INSTALL_PREFIX" } }
};
for (auto const& path : search_paths) {
@@ -348,6 +362,8 @@ bool cmFindCommon::CheckCommonArgument(std::string const& arg)
this->NoSystemEnvironmentPath = true;
} else if (arg == "NO_CMAKE_SYSTEM_PATH") {
this->NoCMakeSystemPath = true;
+ } else if (arg == "NO_CMAKE_INSTALL_PREFIX") {
+ this->NoCMakeInstallPath = true;
} else if (arg == "NO_CMAKE_FIND_ROOT_PATH") {
this->FindRootPathMode = RootPathModeNever;
} else if (arg == "ONLY_CMAKE_FIND_ROOT_PATH") {
diff --git a/Source/cmFindCommon.h b/Source/cmFindCommon.h
index 5d9b3e1..41de797 100644
--- a/Source/cmFindCommon.h
+++ b/Source/cmFindCommon.h
@@ -11,6 +11,7 @@
#include "cmPathLabel.h"
#include "cmSearchPath.h"
+#include "cmWindowsRegistry.h"
class cmExecutionStatus;
class cmMakefile;
@@ -130,6 +131,8 @@ protected:
bool NoCMakeEnvironmentPath;
bool NoSystemEnvironmentPath;
bool NoCMakeSystemPath;
+ bool NoCMakeInstallPath;
+ cmWindowsRegistry::View RegistryView = cmWindowsRegistry::View::Target;
std::vector<std::string> SearchPathSuffixes;
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index f55d838..6586c69 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -13,6 +13,7 @@
#include <utility>
#include <cm/memory>
+#include <cm/optional>
#include <cmext/string_view>
#include "cmsys/Directory.hxx"
@@ -22,6 +23,7 @@
#include "cmsys/String.h"
#include "cmAlgorithms.h"
+#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
@@ -33,6 +35,7 @@
#include "cmSystemTools.h"
#include "cmValue.h"
#include "cmVersion.h"
+#include "cmWindowsRegistry.h"
#if defined(__HAIKU__)
# include <FindDirectory.h>
@@ -42,6 +45,8 @@
class cmExecutionStatus;
class cmFileList;
+cmFindPackageCommand::PathLabel
+ cmFindPackageCommand::PathLabel::PackageRedirect("PACKAGE_REDIRECT");
cmFindPackageCommand::PathLabel cmFindPackageCommand::PathLabel::UserRegistry(
"PACKAGE_REGISTRY");
cmFindPackageCommand::PathLabel cmFindPackageCommand::PathLabel::Builds(
@@ -109,8 +114,10 @@ void cmFindPackageCommand::AppendSearchPathGroups()
{
std::vector<cmFindCommon::PathLabel>* labels;
- // Update the All group with new paths
+ // Update the All group with new paths. Note that package redirection must
+ // take precedence over everything else, so it has to be first in the array.
labels = &this->PathGroupLabelMap[PathGroup::All];
+ labels->insert(labels->begin(), PathLabel::PackageRedirect);
labels->insert(
std::find(labels->begin(), labels->end(), PathLabel::CMakeSystem),
PathLabel::UserRegistry);
@@ -122,6 +129,8 @@ void cmFindPackageCommand::AppendSearchPathGroups()
// Create the new path objects
this->LabeledPaths.insert(
+ std::make_pair(PathLabel::PackageRedirect, cmSearchPath(this)));
+ this->LabeledPaths.insert(
std::make_pair(PathLabel::UserRegistry, cmSearchPath(this)));
this->LabeledPaths.insert(
std::make_pair(PathLabel::Builds, cmSearchPath(this)));
@@ -262,6 +271,9 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
} else if (args[i] == "EXACT") {
this->VersionExact = true;
doing = DoingNone;
+ } else if (args[i] == "GLOBAL") {
+ this->GlobalScope = true;
+ doing = DoingNone;
} else if (args[i] == "MODULE") {
moduleArgs.insert(i);
doing = DoingNone;
@@ -314,6 +326,20 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
// Ignore legacy option.
configArgs.insert(i);
doing = DoingNone;
+ } else if (args[i] == "REGISTRY_VIEW") {
+ if (++i == args.size()) {
+ this->SetError("missing required argument for \"REGISTRY_VIEW\"");
+ return false;
+ }
+ auto view = cmWindowsRegistry::ToView(args[i]);
+ if (view) {
+ this->RegistryView = *view;
+ this->RegistryViewDefined = true;
+ } else {
+ this->SetError(
+ cmStrCat("given invalid value for \"REGISTRY_VIEW\": ", args[i]));
+ return false;
+ }
} else if (this->CheckCommonArgument(args[i])) {
configArgs.insert(i);
doing = DoingNone;
@@ -364,6 +390,12 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
}
}
+ if (!this->GlobalScope) {
+ cmValue value(
+ this->Makefile->GetDefinition("CMAKE_FIND_PACKAGE_TARGETS_GLOBAL"));
+ this->GlobalScope = value.IsOn();
+ }
+
std::vector<std::string> doubledComponents;
std::set_intersection(requiredComponents.begin(), requiredComponents.end(),
optionalComponents.begin(), optionalComponents.end(),
@@ -543,9 +575,62 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
this->SetModuleVariables(components);
+ // See if we have been told to delegate to FetchContent or some other
+ // redirected config package first. We have to check all names that
+ // find_package() may look for, but only need to invoke the override for the
+ // first one that matches.
+ auto overrideNames = this->Names;
+ if (overrideNames.empty()) {
+ overrideNames.push_back(this->Name);
+ }
+ bool forceConfigMode = false;
+ const auto redirectsDir =
+ this->Makefile->GetSafeDefinition("CMAKE_FIND_PACKAGE_REDIRECTS_DIR");
+ for (const auto& overrideName : overrideNames) {
+ const auto nameLower = cmSystemTools::LowerCase(overrideName);
+ const auto delegatePropName =
+ cmStrCat("_FetchContent_", nameLower, "_override_find_package");
+ const cmValue delegateToFetchContentProp =
+ this->Makefile->GetState()->GetGlobalProperty(delegatePropName);
+ if (delegateToFetchContentProp.IsOn()) {
+ // When this property is set, the FetchContent module has already been
+ // included at least once, so we know the FetchContent_MakeAvailable()
+ // command will be defined. Any future find_package() calls after this
+ // one for this package will by-pass this once-only delegation.
+ // The following call will typically create a <name>-config.cmake file
+ // in the redirectsDir, which we still want to process like any other
+ // config file to ensure we follow normal find_package() processing.
+ cmListFileFunction func(
+ "FetchContent_MakeAvailable", 0, 0,
+ { cmListFileArgument(overrideName, cmListFileArgument::Unquoted, 0) });
+ if (!this->Makefile->ExecuteCommand(func, this->Status)) {
+ return false;
+ }
+ }
+
+ if (cmSystemTools::FileExists(
+ cmStrCat(redirectsDir, '/', nameLower, "-config.cmake")) ||
+ cmSystemTools::FileExists(
+ cmStrCat(redirectsDir, '/', overrideName, "Config.cmake"))) {
+ // Force the use of this redirected config package file, regardless of
+ // the type of find_package() call. Files in the redirectsDir must always
+ // take priority over everything else.
+ forceConfigMode = true;
+ this->UseConfigFiles = true;
+ this->UseFindModules = false;
+ this->Names.clear();
+ this->Names.emplace_back(overrideName); // Force finding this one
+ this->Variable = cmStrCat(this->Name, "_DIR");
+ this->SetConfigDirCacheVariable(redirectsDir);
+ break;
+ }
+ }
+
// See if there is a Find<PackageName>.cmake module.
bool loadedPackage = false;
- if (this->Makefile->IsOn("CMAKE_FIND_PACKAGE_PREFER_CONFIG")) {
+ if (forceConfigMode) {
+ loadedPackage = this->FindPackageUsingConfigMode();
+ } else if (this->Makefile->IsOn("CMAKE_FIND_PACKAGE_PREFER_CONFIG")) {
if (this->UseConfigFiles && this->FindPackageUsingConfigMode()) {
loadedPackage = true;
} else {
@@ -758,6 +843,11 @@ void cmFindPackageCommand::SetModuleVariables(const std::string& components)
id = cmStrCat(this->Name, "_FIND_VERSION_RANGE_MAX");
this->AddFindDefinition(id, this->VersionRangeMax);
}
+
+ if (this->RegistryViewDefined) {
+ this->AddFindDefinition(cmStrCat(this->Name, "_FIND_REGISTRY_VIEW"),
+ cmWindowsRegistry::FromView(this->RegistryView));
+ }
}
void cmFindPackageCommand::AddFindDefinition(const std::string& var,
@@ -1155,19 +1245,24 @@ bool cmFindPackageCommand::FindConfig()
} else {
init = this->Variable + "-NOTFOUND";
}
+ // We force the value since we do not get here if it was already set.
+ this->SetConfigDirCacheVariable(init);
+
+ return found;
+}
+
+void cmFindPackageCommand::SetConfigDirCacheVariable(const std::string& value)
+{
std::string help =
cmStrCat("The directory containing a CMake configuration file for ",
this->Name, '.');
- // We force the value since we do not get here if it was already set.
- this->Makefile->AddCacheDefinition(this->Variable, init, help.c_str(),
+ this->Makefile->AddCacheDefinition(this->Variable, value, help.c_str(),
cmStateEnums::PATH, true);
if (this->Makefile->GetPolicyStatus(cmPolicies::CMP0126) ==
cmPolicies::NEW &&
this->Makefile->IsNormalDefinitionSet(this->Variable)) {
- this->Makefile->AddDefinition(this->Variable, init);
+ this->Makefile->AddDefinition(this->Variable, value);
}
-
- return found;
}
bool cmFindPackageCommand::FindPrefixedConfig()
@@ -1200,6 +1295,11 @@ bool cmFindPackageCommand::ReadListFile(const std::string& f,
PolicyScopeRule psr)
{
const bool noPolicyScope = !this->PolicyScope || psr == NoPolicyScope;
+
+ using ITScope = cmMakefile::ImportedTargetScope;
+ ITScope scope = this->GlobalScope ? ITScope::Global : ITScope::Local;
+ cmMakefile::SetGlobalTargetImportScope globScope(this->Makefile, scope);
+
if (this->Makefile->ReadDependentFile(f, noPolicyScope)) {
return true;
}
@@ -1313,6 +1413,8 @@ inline std::size_t collectPathsForDebug(std::string& buffer,
void cmFindPackageCommand::ComputePrefixes()
{
+ this->FillPrefixesPackageRedirect();
+
if (!this->NoDefaultPath) {
if (!this->NoPackageRootPath) {
this->FillPrefixesPackageRoot();
@@ -1346,6 +1448,23 @@ void cmFindPackageCommand::ComputePrefixes()
this->ComputeFinalPaths(IgnorePaths::No);
}
+void cmFindPackageCommand::FillPrefixesPackageRedirect()
+{
+ cmSearchPath& paths = this->LabeledPaths[PathLabel::PackageRedirect];
+
+ const auto redirectDir =
+ this->Makefile->GetDefinition("CMAKE_FIND_PACKAGE_REDIRECTS_DIR");
+ if (redirectDir && !redirectDir->empty()) {
+ paths.AddPath(*redirectDir);
+ }
+ if (this->DebugMode) {
+ std::string debugBuffer =
+ "The internally managed CMAKE_FIND_PACKAGE_REDIRECTS_DIR.\n";
+ collectPathsForDebug(debugBuffer, paths);
+ this->DebugBuffer = cmStrCat(this->DebugBuffer, debugBuffer);
+ }
+}
+
void cmFindPackageCommand::FillPrefixesPackageRoot()
{
cmSearchPath& paths = this->LabeledPaths[PathLabel::PackageRoot];
@@ -1668,7 +1787,57 @@ void cmFindPackageCommand::FillPrefixesCMakeSystemVariable()
{
cmSearchPath& paths = this->LabeledPaths[PathLabel::CMakeSystem];
- paths.AddCMakePath("CMAKE_SYSTEM_PREFIX_PATH");
+ const bool install_prefix_in_list =
+ !this->Makefile->IsOn("CMAKE_FIND_NO_INSTALL_PREFIX");
+ const bool remove_install_prefix = this->NoCMakeInstallPath;
+ const bool add_install_prefix = !this->NoCMakeInstallPath &&
+ this->Makefile->IsDefinitionSet("CMAKE_FIND_USE_INSTALL_PREFIX");
+
+ // We have 3 possible states for `CMAKE_SYSTEM_PREFIX_PATH` and
+ // `CMAKE_INSTALL_PREFIX`.
+ // Either we need to remove `CMAKE_INSTALL_PREFIX`, add
+ // `CMAKE_INSTALL_PREFIX`, or do nothing.
+ //
+ // When we need to remove `CMAKE_INSTALL_PREFIX` we remove the Nth occurrence
+ // of `CMAKE_INSTALL_PREFIX` from `CMAKE_SYSTEM_PREFIX_PATH`, where `N` is
+ // computed by `CMakeSystemSpecificInformation.cmake` while constructing
+ // `CMAKE_SYSTEM_PREFIX_PATH`. This ensures that if projects / toolchains
+ // have removed `CMAKE_INSTALL_PREFIX` from the list, we don't remove
+ // some other entry by mistake
+ long install_prefix_count = -1;
+ std::string install_path_to_remove;
+ if (cmValue to_skip = this->Makefile->GetDefinition(
+ "_CMAKE_SYSTEM_PREFIX_PATH_INSTALL_PREFIX_COUNT")) {
+ cmStrToLong(to_skip, &install_prefix_count);
+ }
+ if (cmValue install_value = this->Makefile->GetDefinition(
+ "_CMAKE_SYSTEM_PREFIX_PATH_INSTALL_PREFIX_VALUE")) {
+ install_path_to_remove = *install_value;
+ }
+
+ if (remove_install_prefix && install_prefix_in_list &&
+ install_prefix_count > 0 && !install_path_to_remove.empty()) {
+
+ 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);
+ long count = 0;
+ for (const auto& path : expanded) {
+ bool to_add =
+ !(path == install_path_to_remove && ++count == install_prefix_count);
+ if (to_add) {
+ paths.AddPath(path);
+ }
+ }
+ } else if (add_install_prefix && !install_prefix_in_list) {
+ paths.AddCMakePath("CMAKE_INSTALL_PREFIX");
+ paths.AddCMakePath("CMAKE_SYSTEM_PREFIX_PATH");
+ } else {
+ // Otherwise the current setup of `CMAKE_SYSTEM_PREFIX_PATH` is correct
+ paths.AddCMakePath("CMAKE_SYSTEM_PREFIX_PATH");
+ }
+
paths.AddCMakePath("CMAKE_SYSTEM_FRAMEWORK_PATH");
paths.AddCMakePath("CMAKE_SYSTEM_APPBUNDLE_PATH");
diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h
index f921bb0..902fa32 100644
--- a/Source/cmFindPackageCommand.h
+++ b/Source/cmFindPackageCommand.h
@@ -76,6 +76,7 @@ private:
: cmFindCommon::PathLabel(label)
{
}
+ static PathLabel PackageRedirect;
static PathLabel UserRegistry;
static PathLabel Builds;
static PathLabel SystemRegistry;
@@ -119,8 +120,10 @@ private:
};
bool ReadListFile(const std::string& f, PolicyScopeRule psr);
void StoreVersionFound();
+ void SetConfigDirCacheVariable(const std::string& value);
void ComputePrefixes();
+ void FillPrefixesPackageRedirect();
void FillPrefixesPackageRoot();
void FillPrefixesCMakeEnvironment();
void FillPrefixesCMakeVariable();
@@ -199,6 +202,8 @@ private:
bool UseLibx32Paths = false;
bool UseRealPath = false;
bool PolicyScope = true;
+ bool GlobalScope = false;
+ bool RegistryViewDefined = false;
std::string LibraryArchitecture;
std::vector<std::string> Names;
std::vector<std::string> Configs;
diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx
index 780b256..a64e0e4 100644
--- a/Source/cmFindProgramCommand.cxx
+++ b/Source/cmFindProgramCommand.cxx
@@ -12,6 +12,8 @@
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmValue.h"
+#include "cmWindowsRegistry.h"
class cmExecutionStatus;
@@ -172,6 +174,18 @@ cmFindProgramCommand::cmFindProgramCommand(cmExecutionStatus& status)
this->NamesPerDirAllowed = true;
this->VariableDocumentation = "Path to a program.";
this->VariableType = cmStateEnums::FILEPATH;
+ // Windows Registry views
+ // When policy CMP0134 is not NEW, rely on previous behavior:
+ if (this->Makefile->GetPolicyStatus(cmPolicies::CMP0134) !=
+ cmPolicies::NEW) {
+ if (this->Makefile->GetDefinition("CMAKE_SIZEOF_VOID_P") == "8") {
+ this->RegistryView = cmWindowsRegistry::View::Reg64_32;
+ } else {
+ this->RegistryView = cmWindowsRegistry::View::Reg32_64;
+ }
+ } else {
+ this->RegistryView = cmWindowsRegistry::View::Both;
+ }
}
// cmFindProgramCommand
diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx
index 187db73..d35d428 100644
--- a/Source/cmGeneratorExpressionDAGChecker.cxx
+++ b/Source/cmGeneratorExpressionDAGChecker.cxx
@@ -167,7 +167,7 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingLinkExpression() const
cm::string_view property(this->Top()->Property);
return property == "LINK_DIRECTORIES"_s || property == "LINK_OPTIONS"_s ||
- property == "LINK_DEPENDS"_s;
+ property == "LINK_DEPENDS"_s || property == "LINK_LIBRARY_OVERRIDE"_s;
}
bool cmGeneratorExpressionDAGChecker::EvaluatingLinkOptionsExpression() const
@@ -189,6 +189,8 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(
}
return prop == "LINK_LIBRARIES"_s || prop == "INTERFACE_LINK_LIBRARIES"_s ||
+ prop == "INTERFACE_LINK_LIBRARIES_DIRECT"_s ||
+ prop == "INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE"_s ||
prop == "LINK_INTERFACE_LIBRARIES"_s ||
prop == "IMPORTED_LINK_INTERFACE_LIBRARIES"_s ||
cmHasLiteralPrefix(prop, "LINK_INTERFACE_LIBRARIES_") ||
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 396e9c9..26ffd4b 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -1198,6 +1198,152 @@ static const struct LinkLanguageAndIdNode : public cmGeneratorExpressionNode
}
} linkLanguageAndIdNode;
+static const struct LinkLibraryNode : public cmGeneratorExpressionNode
+{
+ LinkLibraryNode() {} // NOLINT(modernize-use-equals-default)
+
+ int NumExpectedParameters() const override { return OneOrMoreParameters; }
+
+ std::string Evaluate(
+ const std::vector<std::string>& parameters,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content,
+ cmGeneratorExpressionDAGChecker* dagChecker) const override
+ {
+ if (!context->HeadTarget || !dagChecker ||
+ !dagChecker->EvaluatingLinkLibraries()) {
+ reportError(context, content->GetOriginalExpression(),
+ "$<LINK_LIBRARY:...> may only be used with binary targets "
+ "to specify link libraries.");
+ return std::string();
+ }
+
+ std::vector<std::string> list;
+ cmExpandLists(parameters.begin(), parameters.end(), list);
+ if (list.empty()) {
+ reportError(
+ context, content->GetOriginalExpression(),
+ "$<LINK_LIBRARY:...> expects a feature name as first argument.");
+ return std::string();
+ }
+ if (list.size() == 1) {
+ // no libraries specified, ignore this genex
+ return std::string();
+ }
+
+ static cmsys::RegularExpression featureNameValidator("^[A-Za-z0-9_]+$");
+ auto const& feature = list.front();
+ if (!featureNameValidator.find(feature)) {
+ reportError(context, content->GetOriginalExpression(),
+ cmStrCat("The feature name '", feature,
+ "' contains invalid characters."));
+ return std::string();
+ }
+
+ const auto LL_BEGIN = cmStrCat("<LINK_LIBRARY:", feature, '>');
+ const auto LL_END = cmStrCat("</LINK_LIBRARY:", feature, '>');
+
+ // filter out $<LINK_LIBRARY:..> tags with same feature
+ // and raise an error for any different feature
+ cm::erase_if(list, [&](const std::string& item) -> bool {
+ return item == LL_BEGIN || item == LL_END;
+ });
+ auto it =
+ std::find_if(list.cbegin() + 1, list.cend(),
+ [&feature](const std::string& item) -> bool {
+ return cmHasPrefix(item, "<LINK_LIBRARY:"_s) &&
+ item.substr(14, item.find('>', 14) - 14) != feature;
+ });
+ if (it != list.cend()) {
+ reportError(
+ context, content->GetOriginalExpression(),
+ "$<LINK_LIBRARY:...> with different features cannot be nested.");
+ return std::string();
+ }
+ // $<LINK_GROUP:...> must not appear as part of $<LINK_LIBRARY:...>
+ it = std::find_if(list.cbegin() + 1, list.cend(),
+ [](const std::string& item) -> bool {
+ return cmHasPrefix(item, "<LINK_GROUP:"_s);
+ });
+ if (it != list.cend()) {
+ reportError(context, content->GetOriginalExpression(),
+ "$<LINK_GROUP:...> cannot be nested inside a "
+ "$<LINK_LIBRARY:...> expression.");
+ return std::string();
+ }
+
+ list.front() = LL_BEGIN;
+ list.push_back(LL_END);
+
+ return cmJoin(list, ";"_s);
+ }
+} linkLibraryNode;
+
+static const struct LinkGroupNode : public cmGeneratorExpressionNode
+{
+ LinkGroupNode() {} // NOLINT(modernize-use-equals-default)
+
+ int NumExpectedParameters() const override { return OneOrMoreParameters; }
+
+ std::string Evaluate(
+ const std::vector<std::string>& parameters,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content,
+ cmGeneratorExpressionDAGChecker* dagChecker) const override
+ {
+ if (!context->HeadTarget || !dagChecker ||
+ !dagChecker->EvaluatingLinkLibraries()) {
+ reportError(context, content->GetOriginalExpression(),
+ "$<LINK_GROUP:...> may only be used with binary targets "
+ "to specify group of link libraries.");
+ return std::string();
+ }
+
+ std::vector<std::string> list;
+ cmExpandLists(parameters.begin(), parameters.end(), list);
+ if (list.empty()) {
+ reportError(
+ context, content->GetOriginalExpression(),
+ "$<LINK_GROUP:...> expects a feature name as first argument.");
+ return std::string();
+ }
+ // $<LINK_GROUP:..> cannot be nested
+ if (std::find_if(list.cbegin(), list.cend(),
+ [](const std::string& item) -> bool {
+ return cmHasPrefix(item, "<LINK_GROUP"_s);
+ }) != list.cend()) {
+ reportError(context, content->GetOriginalExpression(),
+ "$<LINK_GROUP:...> cannot be nested.");
+ return std::string();
+ }
+ if (list.size() == 1) {
+ // no libraries specified, ignore this genex
+ return std::string();
+ }
+
+ static cmsys::RegularExpression featureNameValidator("^[A-Za-z0-9_]+$");
+ auto const& feature = list.front();
+ if (!featureNameValidator.find(feature)) {
+ reportError(context, content->GetOriginalExpression(),
+ cmStrCat("The feature name '", feature,
+ "' contains invalid characters."));
+ return std::string();
+ }
+
+ const auto LG_BEGIN = cmStrCat(
+ "<LINK_GROUP:", feature, ':',
+ cmJoin(cmRange<decltype(list.cbegin())>(list.cbegin() + 1, list.cend()),
+ "|"_s),
+ '>');
+ const auto LG_END = cmStrCat("</LINK_GROUP:", feature, '>');
+
+ list.front() = LG_BEGIN;
+ list.push_back(LG_END);
+
+ return cmJoin(list, ";"_s);
+ }
+} linkGroupNode;
+
static const struct HostLinkNode : public cmGeneratorExpressionNode
{
HostLinkNode() {} // NOLINT(modernize-use-equals-default)
@@ -1269,7 +1415,8 @@ static std::string getLinkedTargetsContent(
{
std::string result;
if (cmLinkImplementationLibraries const* impl =
- target->GetLinkImplementationLibraries(context->Config)) {
+ target->GetLinkImplementationLibraries(
+ context->Config, cmGeneratorTarget::LinkInterfaceFor::Usage)) {
for (cmLinkImplItem const& lib : impl->Libraries) {
if (lib.Target) {
// Pretend $<TARGET_PROPERTY:lib.Target,prop> appeared in our
@@ -1638,7 +1785,7 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
{
std::string reason;
if (!context->EvaluateForBuildsystem &&
- !gg->HasKnownObjectFileLocation(&reason)) {
+ !gt->Target->HasKnownObjectFileLocation(&reason)) {
std::ostringstream e;
e << "The evaluation of the TARGET_OBJECTS generator expression "
"is only suitable for consumption by CMake (limited"
@@ -1951,6 +2098,7 @@ class ArtifactPathTag;
class ArtifactPdbTag;
class ArtifactSonameTag;
class ArtifactBundleDirTag;
+class ArtifactBundleDirNameTag;
class ArtifactBundleContentDirTag;
template <typename ArtifactT, typename ComponentT>
@@ -2011,6 +2159,12 @@ struct TargetFilesystemArtifactDependency<ArtifactBundleDirTag,
{
};
template <>
+struct TargetFilesystemArtifactDependency<ArtifactBundleDirNameTag,
+ ArtifactPathTag>
+ : TargetFilesystemArtifactDependencyCMP0112
+{
+};
+template <>
struct TargetFilesystemArtifactDependency<ArtifactBundleContentDirTag,
ArtifactPathTag>
: TargetFilesystemArtifactDependencyCMP0112
@@ -2138,6 +2292,31 @@ struct TargetFilesystemArtifactResultCreator<ArtifactBundleDirTag>
};
template <>
+struct TargetFilesystemArtifactResultCreator<ArtifactBundleDirNameTag>
+{
+ static std::string Create(cmGeneratorTarget* target,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content)
+ {
+ if (target->IsImported()) {
+ ::reportError(
+ context, content->GetOriginalExpression(),
+ "TARGET_BUNDLE_DIR_NAME not allowed for IMPORTED targets.");
+ return std::string();
+ }
+ if (!target->IsBundleOnApple()) {
+ ::reportError(
+ context, content->GetOriginalExpression(),
+ "TARGET_BUNDLE_DIR_NAME is allowed only for Bundle targets.");
+ return std::string();
+ }
+
+ return target->GetAppBundleDirectory(context->Config,
+ cmGeneratorTarget::BundleDirLevel);
+ }
+};
+
+template <>
struct TargetFilesystemArtifactResultCreator<ArtifactBundleContentDirTag>
{
static std::string Create(cmGeneratorTarget* target,
@@ -2270,7 +2449,8 @@ struct TargetFilesystemArtifact : public TargetArtifactBase
return std::string();
}
// Not a dependent target if we are querying for ArtifactDirTag,
- // ArtifactNameTag, ArtifactBundleDirTag, and ArtifactBundleContentDirTag
+ // ArtifactNameTag, ArtifactBundleDirTag, ArtifactBundleDirNameTag,
+ // and ArtifactBundleContentDirTag
TargetFilesystemArtifactDependency<ArtifactT, ComponentT>::AddDependency(
target, context);
@@ -2311,6 +2491,10 @@ static const TargetFilesystemArtifactNodeGroup<ArtifactPdbTag>
static const TargetFilesystemArtifact<ArtifactBundleDirTag, ArtifactPathTag>
targetBundleDirNode;
+static const TargetFilesystemArtifact<ArtifactBundleDirNameTag,
+ ArtifactNameTag>
+ targetBundleDirNameNode;
+
static const TargetFilesystemArtifact<ArtifactBundleContentDirTag,
ArtifactPathTag>
targetBundleContentDirNode;
@@ -2636,6 +2820,7 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
{ "TARGET_SONAME_FILE_DIR", &targetSoNameNodeGroup.FileDir },
{ "TARGET_PDB_FILE_DIR", &targetPdbNodeGroup.FileDir },
{ "TARGET_BUNDLE_DIR", &targetBundleDirNode },
+ { "TARGET_BUNDLE_DIR_NAME", &targetBundleDirNameNode },
{ "TARGET_BUNDLE_CONTENT_DIR", &targetBundleContentDirNode },
{ "STREQUAL", &strEqualNode },
{ "EQUAL", &equalNode },
@@ -2668,6 +2853,8 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
{ "COMPILE_LANGUAGE", &languageNode },
{ "LINK_LANG_AND_ID", &linkLanguageAndIdNode },
{ "LINK_LANGUAGE", &linkLanguageNode },
+ { "LINK_LIBRARY", &linkLibraryNode },
+ { "LINK_GROUP", &linkGroupNode },
{ "HOST_LINK", &hostLinkNode },
{ "DEVICE_LINK", &deviceLinkNode },
{ "SHELL_PATH", &shellPathNode }
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index fec4679..d8a7c39 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -58,6 +58,10 @@ using LinkInterfaceFor = cmGeneratorTarget::LinkInterfaceFor;
const cmsys::RegularExpression FrameworkRegularExpression(
"^(.*/)?([^/]*)\\.framework/(.*)$");
const std::string kINTERFACE_LINK_LIBRARIES = "INTERFACE_LINK_LIBRARIES";
+const std::string kINTERFACE_LINK_LIBRARIES_DIRECT =
+ "INTERFACE_LINK_LIBRARIES_DIRECT";
+const std::string kINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE =
+ "INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE";
}
template <>
@@ -748,6 +752,7 @@ void cmGeneratorTarget::ClearSourcesCache()
this->Objects.clear();
this->VisitedConfigsForObjects.clear();
this->LinkImplMap.clear();
+ this->LinkImplUsageRequirementsOnlyMap.clear();
}
void cmGeneratorTarget::ClearLinkInterfaceCache()
@@ -1300,7 +1305,8 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(
&dagChecker, result, excludeImported, language);
}
- cmLinkImplementation const* impl = this->GetLinkImplementation(config);
+ cmLinkImplementation const* impl =
+ this->GetLinkImplementation(config, LinkInterfaceFor::Usage);
if (impl != nullptr) {
auto runtimeEntries = impl->LanguageRuntimeLibraries.find(language);
if (runtimeEntries != impl->LanguageRuntimeLibraries.end()) {
@@ -1517,7 +1523,8 @@ void AddLangSpecificImplicitIncludeDirectories(
const std::string& config, const std::string& propertyName,
IncludeDirectoryFallBack mode, EvaluatedTargetPropertyEntries& entries)
{
- if (const auto* libraries = target->GetLinkImplementationLibraries(config)) {
+ if (const auto* libraries = target->GetLinkImplementationLibraries(
+ config, LinkInterfaceFor::Usage)) {
cmGeneratorExpressionDAGChecker dag{ target->GetBacktrace(), target,
propertyName, nullptr, nullptr };
@@ -1607,7 +1614,7 @@ void AddInterfaceEntries(
{
if (searchRuntime == IncludeRuntimeInterface::Yes) {
if (cmLinkImplementation const* impl =
- headTarget->GetLinkImplementation(config)) {
+ headTarget->GetLinkImplementation(config, interfaceFor)) {
entries.HadContextSensitiveCondition =
impl->HadContextSensitiveCondition;
@@ -1621,7 +1628,7 @@ void AddInterfaceEntries(
}
} else {
if (cmLinkImplementationLibraries const* impl =
- headTarget->GetLinkImplementationLibraries(config)) {
+ headTarget->GetLinkImplementationLibraries(config, interfaceFor)) {
entries.HadContextSensitiveCondition =
impl->HadContextSensitiveCondition;
addInterfaceEntry(headTarget, config, prop, lang, dagChecker, entries,
@@ -1636,7 +1643,8 @@ void AddObjectEntries(cmGeneratorTarget const* headTarget,
EvaluatedTargetPropertyEntries& entries)
{
if (cmLinkImplementationLibraries const* impl =
- headTarget->GetLinkImplementationLibraries(config)) {
+ headTarget->GetLinkImplementationLibraries(config,
+ LinkInterfaceFor::Usage)) {
entries.HadContextSensitiveCondition = impl->HadContextSensitiveCondition;
for (cmLinkImplItem const& lib : impl->Libraries) {
if (lib.Target &&
@@ -2045,7 +2053,11 @@ void cmGeneratorTarget::ComputeKindedSources(KindedSources& files,
} else if (ext == "appxmanifest") {
kind = SourceKindAppManifest;
} else if (ext == "manifest") {
- kind = SourceKindManifest;
+ if (sf->GetPropertyAsBool("VS_DEPLOYMENT_CONTENT")) {
+ kind = SourceKindExtra;
+ } else {
+ kind = SourceKindManifest;
+ }
} else if (ext == "pfx") {
kind = SourceKindCertificate;
} else if (ext == "xaml") {
@@ -2815,7 +2827,7 @@ bool cmGeneratorTarget::ComputeLinkClosure(const std::string& config,
// Get languages built in this target.
std::unordered_set<std::string> languages;
cmLinkImplementation const* impl =
- this->GetLinkImplementation(config, secondPass);
+ this->GetLinkImplementation(config, LinkInterfaceFor::Link, secondPass);
assert(impl);
languages.insert(impl->Languages.cbegin(), impl->Languages.cend());
@@ -3083,7 +3095,7 @@ cmGeneratorTarget::GetLinkImplementationClosure(
std::set<cmGeneratorTarget const*> emitted;
cmLinkImplementationLibraries const* impl =
- this->GetLinkImplementationLibraries(config);
+ this->GetLinkImplementationLibraries(config, LinkInterfaceFor::Usage);
assert(impl);
for (cmLinkImplItem const& lib : impl->Libraries) {
@@ -3461,6 +3473,23 @@ void cmGeneratorTarget::AddCUDAArchitectureFlags(std::string& flags) const
property =
*this->Makefile->GetDefinition("CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR");
}
+ } else if (property == "native") {
+ cmValue native =
+ this->Makefile->GetDefinition("CMAKE_CUDA_ARCHITECTURES_NATIVE");
+ if (native.IsEmpty()) {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ "CUDA_ARCHITECTURES is set to \"native\", but no GPU was detected.");
+ }
+ if (compiler == "NVIDIA" &&
+ cmSystemTools::VersionCompare(
+ cmSystemTools::OP_GREATER_EQUAL,
+ this->Makefile->GetDefinition("CMAKE_CUDA_COMPILER_VERSION"),
+ "11.6")) {
+ flags = cmStrCat(flags, " -arch=", property);
+ return;
+ }
+ property = *native;
}
struct CudaArchitecture
@@ -3808,7 +3837,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
if (this->Makefile->IsOn("APPLE")) {
if (cmLinkImplementationLibraries const* impl =
- this->GetLinkImplementationLibraries(config)) {
+ this->GetLinkImplementationLibraries(config,
+ LinkInterfaceFor::Usage)) {
for (cmLinkImplItem const& lib : impl->Libraries) {
std::string libDir = cmSystemTools::CollapseFullPath(
lib.AsStr(), this->Makefile->GetHomeOutputDirectory());
@@ -4621,7 +4651,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions(
}
std::vector<BT<std::string>>& cmGeneratorTarget::ResolveLinkerWrapper(
- std::vector<BT<std::string>>& result, const std::string& language) const
+ std::vector<BT<std::string>>& result, const std::string& language,
+ bool joinItems) const
{
// replace "LINKER:" prefixed elements by actual linker wrapper
const std::string wrapper(this->Makefile->GetSafeDefinition(
@@ -4680,7 +4711,14 @@ std::vector<BT<std::string>>& cmGeneratorTarget::ResolveLinkerWrapper(
std::vector<BT<std::string>> options = wrapOptions(
linkerOptions, bt, wrapperFlag, wrapperSep, concatFlagAndArgs);
- result.insert(entry, options.begin(), options.end());
+ if (joinItems) {
+ result.insert(entry,
+ cmJoin(cmRange<decltype(options.cbegin())>(
+ options.cbegin(), options.cend()),
+ " "_s));
+ } else {
+ result.insert(entry, options.begin(), options.end());
+ }
}
return result;
}
@@ -6327,7 +6365,8 @@ cm::string_view missingTargetPossibleReasons =
bool cmGeneratorTarget::VerifyLinkItemColons(LinkItemRole role,
cmLinkItem const& item) const
{
- if (item.Target || item.AsStr().find("::") == std::string::npos) {
+ if (item.Target || cmHasPrefix(item.AsStr(), "<LINK_GROUP:"_s) ||
+ item.AsStr().find("::") == std::string::npos) {
return true;
}
MessageType messageType = MessageType::FATAL_ERROR;
@@ -6373,7 +6412,9 @@ bool cmGeneratorTarget::VerifyLinkItemIsTarget(LinkItemRole role,
std::string const& str = item.AsStr();
if (!str.empty() &&
(str[0] == '-' || str[0] == '$' || str[0] == '`' ||
- str.find_first_of("/\\") != std::string::npos)) {
+ str.find_first_of("/\\") != std::string::npos ||
+ cmHasPrefix(str, "<LINK_LIBRARY:"_s) ||
+ cmHasPrefix(str, "<LINK_GROUP:"_s))) {
return true;
}
@@ -6669,12 +6710,10 @@ cm::optional<cmLinkItem> cmGeneratorTarget::LookupLinkItem(
return maybeItem;
}
-void cmGeneratorTarget::ExpandLinkItems(std::string const& prop,
- cmBTStringRange entries,
- std::string const& config,
- cmGeneratorTarget const* headTarget,
- LinkInterfaceFor interfaceFor,
- cmLinkInterface& iface) const
+void cmGeneratorTarget::ExpandLinkItems(
+ std::string const& prop, cmBTStringRange entries, std::string const& config,
+ cmGeneratorTarget const* headTarget, LinkInterfaceFor interfaceFor,
+ LinkInterfaceField field, cmLinkInterface& iface) const
{
if (entries.empty()) {
return;
@@ -6698,9 +6737,19 @@ void cmGeneratorTarget::ExpandLinkItems(std::string const& prop,
this, headTarget->LinkerLanguage));
for (std::string const& lib : libs) {
if (cm::optional<cmLinkItem> maybeItem = this->LookupLinkItem(
- lib, cge->GetBacktrace(), &scope, LookupSelf::No)) {
+ lib, cge->GetBacktrace(), &scope,
+ field == LinkInterfaceField::Libraries ? LookupSelf::No
+ : LookupSelf::Yes)) {
cmLinkItem item = std::move(*maybeItem);
+ if (field == LinkInterfaceField::HeadInclude) {
+ iface.HeadInclude.emplace_back(std::move(item));
+ continue;
+ }
+ if (field == LinkInterfaceField::HeadExclude) {
+ iface.HeadExclude.emplace_back(std::move(item));
+ continue;
+ }
if (!item.Target) {
// Report explicitly linked object files separately.
std::string const& maybeObj = item.AsStr();
@@ -6803,8 +6852,8 @@ void cmGeneratorTarget::ComputeLinkInterface(
emitted.insert(lib);
}
if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
- cmLinkImplementation const* impl =
- this->GetLinkImplementation(config, secondPass);
+ cmLinkImplementation const* impl = this->GetLinkImplementation(
+ config, LinkInterfaceFor::Link, secondPass);
for (cmLinkImplItem const& lib : impl->Libraries) {
if (emitted.insert(lib).second) {
if (lib.Target) {
@@ -6826,15 +6875,16 @@ void cmGeneratorTarget::ComputeLinkInterface(
this->GetPolicyStatusCMP0022() == cmPolicies::OLD) {
// The link implementation is the default link interface.
cmLinkImplementationLibraries const* impl =
- this->GetLinkImplementationLibrariesInternal(config, headTarget);
+ this->GetLinkImplementationLibrariesInternal(config, headTarget,
+ LinkInterfaceFor::Link);
iface.ImplementationIsInterface = true;
iface.WrongConfigLibraries = impl->WrongConfigLibraries;
}
if (this->LinkLanguagePropagatesToDependents()) {
// Targets using this archive need its language runtime libraries.
- if (cmLinkImplementation const* impl =
- this->GetLinkImplementation(config, secondPass)) {
+ if (cmLinkImplementation const* impl = this->GetLinkImplementation(
+ config, LinkInterfaceFor::Link, secondPass)) {
iface.Languages = impl->Languages;
}
}
@@ -7171,7 +7221,9 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
this->GetPolicyStatusCMP0022() != cmPolicies::WARN);
if (cmp0022NEW) {
// CMP0022 NEW behavior is to use INTERFACE_LINK_LIBRARIES.
- haveExplicitLibraries = !this->Target->GetLinkInterfaceEntries().empty();
+ haveExplicitLibraries = !this->Target->GetLinkInterfaceEntries().empty() ||
+ !this->Target->GetLinkInterfaceDirectEntries().empty() ||
+ !this->Target->GetLinkInterfaceDirectExcludeEntries().empty();
} else {
// CMP0022 OLD behavior is to use LINK_INTERFACE_LIBRARIES if set on a
// shared lib or executable.
@@ -7236,15 +7288,24 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
if (cmp0022NEW) {
// The interface libraries are specified by INTERFACE_LINK_LIBRARIES.
// Use its special representation directly to get backtraces.
- this->ExpandLinkItems(kINTERFACE_LINK_LIBRARIES,
- this->Target->GetLinkInterfaceEntries(), config,
- headTarget, interfaceFor, iface);
+ this->ExpandLinkItems(
+ kINTERFACE_LINK_LIBRARIES, this->Target->GetLinkInterfaceEntries(),
+ config, headTarget, interfaceFor, LinkInterfaceField::Libraries, iface);
+ this->ExpandLinkItems(kINTERFACE_LINK_LIBRARIES_DIRECT,
+ this->Target->GetLinkInterfaceDirectEntries(),
+ config, headTarget, interfaceFor,
+ LinkInterfaceField::HeadInclude, iface);
+ this->ExpandLinkItems(kINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE,
+ this->Target->GetLinkInterfaceDirectExcludeEntries(),
+ config, headTarget, interfaceFor,
+ LinkInterfaceField::HeadExclude, iface);
} else if (explicitLibrariesCMP0022OLD) {
// The interface libraries have been explicitly set in pre-CMP0022 style.
std::vector<BT<std::string>> entries;
entries.emplace_back(*explicitLibrariesCMP0022OLD);
this->ExpandLinkItems(linkIfacePropCMP0022OLD, cmMakeRange(entries),
- config, headTarget, interfaceFor, iface);
+ config, headTarget, interfaceFor,
+ LinkInterfaceField::Libraries, iface);
}
// If the link interface is explicit, do not fall back to the link impl.
@@ -7254,7 +7315,8 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
// The link implementation is the default link interface.
if (cmLinkImplementationLibraries const* impl =
- this->GetLinkImplementationLibrariesInternal(config, headTarget)) {
+ this->GetLinkImplementationLibrariesInternal(config, headTarget,
+ interfaceFor)) {
iface.Libraries.insert(iface.Libraries.end(), impl->Libraries.begin(),
impl->Libraries.end());
if (this->GetPolicyStatusCMP0022() == cmPolicies::WARN &&
@@ -7264,7 +7326,8 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
cmLinkInterface ifaceNew;
this->ExpandLinkItems(kINTERFACE_LINK_LIBRARIES,
this->Target->GetLinkInterfaceEntries(), config,
- headTarget, interfaceFor, ifaceNew);
+ headTarget, interfaceFor,
+ LinkInterfaceField::Libraries, ifaceNew);
if (ifaceNew.Libraries != iface.Libraries) {
std::string oldLibraries = cmJoin(impl->Libraries, ";");
std::string newLibraries = cmJoin(ifaceNew.Libraries, ";");
@@ -7404,8 +7467,17 @@ const cmLinkInterface* cmGeneratorTarget::GetImportLinkInterface(
iface.LibrariesDone = true;
iface.Multiplicity = info->Multiplicity;
cmExpandList(info->Languages, iface.Languages);
+ this->ExpandLinkItems(kINTERFACE_LINK_LIBRARIES_DIRECT,
+ cmMakeRange(info->LibrariesHeadInclude), config,
+ headTarget, interfaceFor,
+ LinkInterfaceField::HeadInclude, iface);
+ this->ExpandLinkItems(kINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE,
+ cmMakeRange(info->LibrariesHeadExclude), config,
+ headTarget, interfaceFor,
+ LinkInterfaceField::HeadExclude, iface);
this->ExpandLinkItems(info->LibrariesProp, cmMakeRange(info->Libraries),
- config, headTarget, interfaceFor, iface);
+ config, headTarget, interfaceFor,
+ LinkInterfaceField::Libraries, iface);
std::vector<std::string> deps = cmExpandedList(info->SharedDeps);
LookupLinkItemScope scope{ this->LocalGenerator };
for (std::string const& dep : deps) {
@@ -7498,6 +7570,14 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
}
}
}
+ for (BT<std::string> const& entry :
+ this->Target->GetLinkInterfaceDirectEntries()) {
+ info.LibrariesHeadInclude.emplace_back(entry);
+ }
+ for (BT<std::string> const& entry :
+ this->Target->GetLinkInterfaceDirectExcludeEntries()) {
+ info.LibrariesHeadExclude.emplace_back(entry);
+ }
if (this->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
if (loc) {
info.LibName = *loc;
@@ -7615,27 +7695,30 @@ cmGeneratorTarget::GetHeadToLinkInterfaceUsageRequirementsMap(
}
const cmLinkImplementation* cmGeneratorTarget::GetLinkImplementation(
- const std::string& config) const
+ const std::string& config, LinkInterfaceFor implFor) const
{
- return this->GetLinkImplementation(config, false);
+ return this->GetLinkImplementation(config, implFor, false);
}
const cmLinkImplementation* cmGeneratorTarget::GetLinkImplementation(
- const std::string& config, bool secondPass) const
+ const std::string& config, LinkInterfaceFor implFor, bool secondPass) const
{
// There is no link implementation for targets that cannot compile sources.
if (!this->CanCompileSources()) {
return nullptr;
}
- cmOptionalLinkImplementation& impl =
- this->LinkImplMap[cmSystemTools::UpperCase(config)][this];
+ HeadToLinkImplementationMap& hm =
+ (implFor == LinkInterfaceFor::Usage
+ ? this->GetHeadToLinkImplementationUsageRequirementsMap(config)
+ : this->GetHeadToLinkImplementationMap(config));
+ cmOptionalLinkImplementation& impl = hm[this];
if (secondPass) {
impl = cmOptionalLinkImplementation();
}
if (!impl.LibrariesDone) {
impl.LibrariesDone = true;
- this->ComputeLinkImplementationLibraries(config, impl, this);
+ this->ComputeLinkImplementationLibraries(config, impl, this, implFor);
}
if (!impl.LanguagesDone) {
impl.LanguagesDone = true;
@@ -7645,6 +7728,21 @@ const cmLinkImplementation* cmGeneratorTarget::GetLinkImplementation(
return &impl;
}
+cmGeneratorTarget::HeadToLinkImplementationMap&
+cmGeneratorTarget::GetHeadToLinkImplementationMap(
+ std::string const& config) const
+{
+ return this->LinkImplMap[cmSystemTools::UpperCase(config)];
+}
+
+cmGeneratorTarget::HeadToLinkImplementationMap&
+cmGeneratorTarget::GetHeadToLinkImplementationUsageRequirementsMap(
+ std::string const& config) const
+{
+ return this
+ ->LinkImplUsageRequirementsOnlyMap[cmSystemTools::UpperCase(config)];
+}
+
bool cmGeneratorTarget::GetConfigCommonSourceFilesForXcode(
std::vector<cmSourceFile*>& files) const
{
@@ -7885,7 +7983,7 @@ bool cmGeneratorTarget::HaveBuildTreeRPATH(const std::string& config) const
return true;
}
if (cmLinkImplementationLibraries const* impl =
- this->GetLinkImplementationLibraries(config)) {
+ this->GetLinkImplementationLibraries(config, LinkInterfaceFor::Link)) {
return !impl->Libraries.empty();
}
return false;
@@ -7893,14 +7991,15 @@ bool cmGeneratorTarget::HaveBuildTreeRPATH(const std::string& config) const
cmLinkImplementationLibraries const*
cmGeneratorTarget::GetLinkImplementationLibraries(
- const std::string& config) const
+ const std::string& config, LinkInterfaceFor implFor) const
{
- return this->GetLinkImplementationLibrariesInternal(config, this);
+ return this->GetLinkImplementationLibrariesInternal(config, this, implFor);
}
cmLinkImplementationLibraries const*
cmGeneratorTarget::GetLinkImplementationLibrariesInternal(
- const std::string& config, cmGeneratorTarget const* head) const
+ const std::string& config, cmGeneratorTarget const* head,
+ LinkInterfaceFor implFor) const
{
// There is no link implementation for targets that cannot compile sources.
if (!this->CanCompileSources()) {
@@ -7909,7 +8008,9 @@ cmGeneratorTarget::GetLinkImplementationLibrariesInternal(
// Populate the link implementation libraries for this configuration.
HeadToLinkImplementationMap& hm =
- this->LinkImplMap[cmSystemTools::UpperCase(config)];
+ (implFor == LinkInterfaceFor::Usage
+ ? this->GetHeadToLinkImplementationUsageRequirementsMap(config)
+ : this->GetHeadToLinkImplementationMap(config));
// If the link implementation does not depend on the head target
// then re-use the one from the head we computed first.
@@ -7920,7 +8021,7 @@ cmGeneratorTarget::GetLinkImplementationLibrariesInternal(
cmOptionalLinkImplementation& impl = hm[head];
if (!impl.LibrariesDone) {
impl.LibrariesDone = true;
- this->ComputeLinkImplementationLibraries(config, impl, head);
+ this->ComputeLinkImplementationLibraries(config, impl, head, implFor);
}
return &impl;
}
@@ -7931,9 +8032,118 @@ bool cmGeneratorTarget::IsNullImpliedByLinkLibraries(
return cm::contains(this->LinkImplicitNullProperties, p);
}
+namespace {
+class TransitiveLinkImpl
+{
+ cmGeneratorTarget const* Self;
+ std::string const& Config;
+ LinkInterfaceFor ImplFor;
+ cmLinkImplementation& Impl;
+
+ std::set<cmLinkItem> Emitted;
+ std::set<cmLinkItem> Excluded;
+ std::unordered_set<cmGeneratorTarget const*> Followed;
+
+ void Follow(cmGeneratorTarget const* target);
+
+public:
+ TransitiveLinkImpl(cmGeneratorTarget const* self, std::string const& config,
+ LinkInterfaceFor implFor, cmLinkImplementation& impl)
+ : Self(self)
+ , Config(config)
+ , ImplFor(implFor)
+ , Impl(impl)
+ {
+ }
+
+ void Compute();
+};
+
+void TransitiveLinkImpl::Follow(cmGeneratorTarget const* target)
+{
+ if (!target || !this->Followed.insert(target).second ||
+ target->GetPolicyStatusCMP0022() == cmPolicies::OLD ||
+ target->GetPolicyStatusCMP0022() == cmPolicies::WARN) {
+ return;
+ }
+
+ // Get this target's usage requirements.
+ cmLinkInterfaceLibraries const* iface =
+ target->GetLinkInterfaceLibraries(this->Config, this->Self, this->ImplFor);
+ if (!iface) {
+ return;
+ }
+ if (iface->HadContextSensitiveCondition) {
+ this->Impl.HadContextSensitiveCondition = true;
+ }
+
+ // Process 'INTERFACE_LINK_LIBRARIES_DIRECT' usage requirements.
+ for (cmLinkItem const& item : iface->HeadInclude) {
+ // Inject direct dependencies from the item's usage requirements
+ // before the item itself.
+ this->Follow(item.Target);
+
+ // Add the item itself, but at most once.
+ if (this->Emitted.insert(item).second) {
+ this->Impl.Libraries.emplace_back(item, /* checkCMP0027= */ false);
+ }
+ }
+
+ // Follow transitive dependencies.
+ for (cmLinkItem const& item : iface->Libraries) {
+ this->Follow(item.Target);
+ }
+
+ // Record exclusions from 'INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE'
+ // usage requirements.
+ for (cmLinkItem const& item : iface->HeadExclude) {
+ this->Excluded.insert(item);
+ }
+}
+
+void TransitiveLinkImpl::Compute()
+{
+ // Save the original items and start with an empty list.
+ std::vector<cmLinkImplItem> original = std::move(this->Impl.Libraries);
+
+ // Avoid injecting any original items as usage requirements.
+ // This gives LINK_LIBRARIES final control over the order
+ // if it explicitly lists everything.
+ this->Emitted.insert(original.cbegin(), original.cend());
+
+ // Process each original item.
+ for (cmLinkImplItem& item : original) {
+ // Inject direct dependencies listed in 'INTERFACE_LINK_LIBRARIES_DIRECT'
+ // usage requirements before the item itself.
+ this->Follow(item.Target);
+
+ // Add the item itself.
+ this->Impl.Libraries.emplace_back(std::move(item));
+ }
+
+ // Remove items listed in 'INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE'
+ // usage requirements found through any dependency above.
+ this->Impl.Libraries.erase(
+ std::remove_if(this->Impl.Libraries.begin(), this->Impl.Libraries.end(),
+ [this](cmLinkImplItem const& item) {
+ return this->Excluded.find(item) != this->Excluded.end();
+ }),
+ this->Impl.Libraries.end());
+}
+
+void ComputeLinkImplTransitive(cmGeneratorTarget const* self,
+ std::string const& config,
+ LinkInterfaceFor implFor,
+ cmLinkImplementation& impl)
+{
+ TransitiveLinkImpl transitiveLinkImpl(self, config, implFor, impl);
+ transitiveLinkImpl.Compute();
+}
+}
+
void cmGeneratorTarget::ComputeLinkImplementationLibraries(
const std::string& config, cmOptionalLinkImplementation& impl,
- cmGeneratorTarget const* head) const
+ cmGeneratorTarget const* head, LinkInterfaceFor implFor) const
{
cmLocalGenerator const* lg = this->LocalGenerator;
cmMakefile const* mf = lg->GetMakefile();
@@ -7944,6 +8154,20 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
// Keep this logic in sync with ExpandLinkItems.
cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_LIBRARIES", nullptr,
nullptr);
+ // The $<LINK_ONLY> expression may be used to specify link dependencies
+ // that are otherwise excluded from usage requirements.
+ if (implFor == LinkInterfaceFor::Usage) {
+ switch (this->GetPolicyStatusCMP0131()) {
+ case cmPolicies::WARN:
+ case cmPolicies::OLD:
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ dagChecker.SetTransitivePropertiesOnly();
+ break;
+ }
+ }
cmGeneratorExpression ge(entry.Backtrace);
std::unique_ptr<cmCompiledGeneratorExpression> const cge =
ge.Parse(entry.Value);
@@ -8037,6 +8261,11 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
cge->GetMaxLanguageStandard(this, this->MaxLanguageStandards);
}
+ // Update the list of direct link dependencies from usage requirements.
+ if (head == this) {
+ ComputeLinkImplTransitive(this, config, implFor, impl);
+ }
+
// Get the list of configurations considered to be DEBUG.
std::vector<std::string> debugConfigs =
this->Makefile->GetCMakeInstance()->GetDebugConfigs();
@@ -8295,3 +8524,176 @@ cmGeneratorTarget::ManagedType cmGeneratorTarget::GetManagedType(
// has to be set manually for C# targets.
return this->IsCSharpOnly() ? ManagedType::Managed : ManagedType::Native;
}
+
+bool cmGeneratorTarget::AddHeaderSetVerification()
+{
+ if (!this->GetPropertyAsBool("VERIFY_HEADER_SETS")) {
+ return true;
+ }
+
+ if (this->GetType() != cmStateEnums::STATIC_LIBRARY &&
+ this->GetType() != cmStateEnums::SHARED_LIBRARY &&
+ this->GetType() != cmStateEnums::UNKNOWN_LIBRARY &&
+ this->GetType() != cmStateEnums::OBJECT_LIBRARY &&
+ this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
+ !this->IsExecutableWithExports()) {
+ return true;
+ }
+
+ cmTarget* verifyTarget = nullptr;
+
+ auto interfaceFileSetEntries = this->Target->GetInterfaceHeaderSetsEntries();
+
+ std::set<cmFileSet*> fileSets;
+ auto const addFileSets = [&fileSets, this](const cmBTStringRange& entries) {
+ for (auto const& entry : entries) {
+ for (auto const& name : cmExpandedList(entry.Value)) {
+ fileSets.insert(this->Target->GetFileSet(name));
+ }
+ }
+ };
+ addFileSets(interfaceFileSetEntries);
+
+ cm::optional<std::set<std::string>> languages;
+ for (auto* fileSet : fileSets) {
+ auto dirCges = fileSet->CompileDirectoryEntries();
+ auto fileCges = fileSet->CompileFileEntries();
+
+ static auto const contextSensitive =
+ [](const std::unique_ptr<cmCompiledGeneratorExpression>& cge) {
+ return cge->GetHadContextSensitiveCondition();
+ };
+ bool dirCgesContextSensitive = false;
+ bool fileCgesContextSensitive = false;
+
+ std::vector<std::string> dirs;
+ std::map<std::string, std::vector<std::string>> filesPerDir;
+ bool first = true;
+ for (auto const& config : this->Makefile->GetGeneratorConfigs(
+ cmMakefile::GeneratorConfigQuery::IncludeEmptyConfig)) {
+ if (first || dirCgesContextSensitive) {
+ dirs = fileSet->EvaluateDirectoryEntries(dirCges, this->LocalGenerator,
+ config, this);
+ dirCgesContextSensitive =
+ std::any_of(dirCges.begin(), dirCges.end(), contextSensitive);
+ }
+ if (first || fileCgesContextSensitive) {
+ filesPerDir.clear();
+ for (auto const& fileCge : fileCges) {
+ fileSet->EvaluateFileEntry(dirs, filesPerDir, fileCge,
+ this->LocalGenerator, config, this);
+ if (fileCge->GetHadContextSensitiveCondition()) {
+ fileCgesContextSensitive = true;
+ }
+ }
+ }
+
+ for (auto const& files : filesPerDir) {
+ for (auto const& file : files.second) {
+ std::string filename = this->GenerateHeaderSetVerificationFile(
+ *this->Makefile->GetOrCreateSource(file), files.first, languages);
+ if (filename.empty()) {
+ continue;
+ }
+
+ if (!verifyTarget) {
+ {
+ cmMakefile::PolicyPushPop polScope(this->Makefile);
+ this->Makefile->SetPolicy(cmPolicies::CMP0119, cmPolicies::NEW);
+ verifyTarget = this->Makefile->AddLibrary(
+ cmStrCat(this->GetName(), "_verify_header_sets"),
+ cmStateEnums::OBJECT_LIBRARY, {}, true);
+ }
+
+ verifyTarget->AddLinkLibrary(
+ *this->Makefile, this->GetName(),
+ cmTargetLinkLibraryType::GENERAL_LibraryType);
+ verifyTarget->SetProperty("AUTOMOC", "OFF");
+ verifyTarget->SetProperty("AUTORCC", "OFF");
+ verifyTarget->SetProperty("AUTOUIC", "OFF");
+ verifyTarget->SetProperty("DISABLE_PRECOMPILE_HEADERS", "ON");
+ verifyTarget->SetProperty("UNITY_BUILD", "OFF");
+ }
+
+ if (fileCgesContextSensitive) {
+ filename = cmStrCat("$<$<CONFIG:", config, ">:", filename, ">");
+ }
+ verifyTarget->AddSource(filename);
+ }
+ }
+
+ if (!dirCgesContextSensitive && !fileCgesContextSensitive) {
+ break;
+ }
+ first = false;
+ }
+ }
+
+ if (verifyTarget) {
+ this->LocalGenerator->AddGeneratorTarget(
+ cm::make_unique<cmGeneratorTarget>(verifyTarget, this->LocalGenerator));
+ }
+
+ return true;
+}
+
+std::string cmGeneratorTarget::GenerateHeaderSetVerificationFile(
+ cmSourceFile& source, const std::string& dir,
+ cm::optional<std::set<std::string>>& languages) const
+{
+ std::string extension;
+ std::string language = source.GetOrDetermineLanguage();
+
+ if (language.empty()) {
+ if (!languages) {
+ languages.emplace();
+ for (auto const& tgtSource : this->GetAllConfigSources()) {
+ auto const& tgtSourceLanguage =
+ tgtSource.Source->GetOrDetermineLanguage();
+ if (tgtSourceLanguage == "CXX") {
+ languages->insert("CXX");
+ break; // C++ overrides everything else, so we don't need to keep
+ // checking.
+ }
+ if (tgtSourceLanguage == "C") {
+ languages->insert("C");
+ }
+ }
+ }
+
+ if (languages->count("CXX")) {
+ language = "CXX";
+ } else if (languages->count("C")) {
+ language = "C";
+ }
+ }
+
+ if (language == "C") {
+ extension = ".c";
+ } else if (language == "CXX") {
+ extension = ".cxx";
+ } else {
+ return "";
+ }
+
+ std::string headerFilename = dir;
+ if (!headerFilename.empty()) {
+ headerFilename += '/';
+ }
+ headerFilename += source.GetLocation().GetName();
+
+ auto filename = cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(),
+ '/', this->GetName(), "_verify_header_sets/",
+ headerFilename, extension);
+ auto* verificationSource = this->Makefile->GetOrCreateSource(filename);
+ verificationSource->SetProperty("LANGUAGE", language);
+
+ cmSystemTools::MakeDirectory(cmSystemTools::GetFilenamePath(filename));
+
+ cmGeneratedFileStream fout(filename);
+ fout.SetCopyIfDifferent(true);
+ fout << "#include <" << headerFilename << ">\n";
+ fout.close();
+
+ return filename;
+}
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 7cf1720..b927848 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -399,17 +399,18 @@ public:
LinkClosure const* GetLinkClosure(const std::string& config) const;
cmLinkImplementation const* GetLinkImplementation(
- const std::string& config) const;
+ const std::string& config, LinkInterfaceFor implFor) const;
void ComputeLinkImplementationLanguages(
const std::string& config, cmOptionalLinkImplementation& impl) const;
cmLinkImplementationLibraries const* GetLinkImplementationLibraries(
- const std::string& config) const;
+ const std::string& config, LinkInterfaceFor implFor) const;
void ComputeLinkImplementationLibraries(const std::string& config,
cmOptionalLinkImplementation& impl,
- const cmGeneratorTarget* head) const;
+ const cmGeneratorTarget* head,
+ LinkInterfaceFor implFor) const;
struct TargetOrString
{
@@ -513,7 +514,8 @@ public:
std::string const& config, std::string const& language) const;
std::vector<BT<std::string>>& ResolveLinkerWrapper(
- std::vector<BT<std::string>>& result, const std::string& language) const;
+ std::vector<BT<std::string>>& result, const std::string& language,
+ bool joinItems = false) const;
void GetStaticLibraryLinkOptions(std::vector<std::string>& result,
const std::string& config,
@@ -854,6 +856,9 @@ public:
std::string GetFortranModuleDirectory(std::string const& working_dir) const;
bool IsFortranBuildingInstrinsicModules() const;
+ bool IsLinkLookupScope(std::string const& n,
+ cmLocalGenerator const*& lg) const;
+
cmValue GetSourcesProperty() const;
void AddISPCGeneratedHeader(std::string const& header,
@@ -866,6 +871,11 @@ public:
std::vector<std::string> GetGeneratedISPCObjects(
std::string const& config) const;
+ bool AddHeaderSetVerification();
+ std::string GenerateHeaderSetVerificationFile(
+ cmSourceFile& source, const std::string& dir,
+ cm::optional<std::set<std::string>>& languages) const;
+
private:
void AddSourceCommon(const std::string& src, bool before = false);
@@ -983,6 +993,7 @@ private:
const cmGeneratorTarget* head,
bool secondPass) const;
cmLinkImplementation const* GetLinkImplementation(const std::string& config,
+ LinkInterfaceFor implFor,
bool secondPass) const;
enum class LinkItemRole
@@ -1006,6 +1017,8 @@ private:
std::string Languages;
std::string LibrariesProp;
std::vector<BT<std::string>> Libraries;
+ std::vector<BT<std::string>> LibrariesHeadInclude;
+ std::vector<BT<std::string>> LibrariesHeadExclude;
std::string SharedDeps;
};
@@ -1063,13 +1076,16 @@ private:
std::unordered_map<std::string, std::vector<std::string>>
ISPCGeneratedObjects;
- bool IsLinkLookupScope(std::string const& n,
- cmLocalGenerator const*& lg) const;
-
+ enum class LinkInterfaceField
+ {
+ Libraries,
+ HeadExclude,
+ HeadInclude,
+ };
void ExpandLinkItems(std::string const& prop, cmBTStringRange entries,
std::string const& config,
const cmGeneratorTarget* headTarget,
- LinkInterfaceFor interfaceFor,
+ LinkInterfaceFor interfaceFor, LinkInterfaceField field,
cmLinkInterface& iface) const;
struct LookupLinkItemScope
@@ -1099,9 +1115,16 @@ private:
};
using LinkImplMapType = std::map<std::string, HeadToLinkImplementationMap>;
mutable LinkImplMapType LinkImplMap;
+ mutable LinkImplMapType LinkImplUsageRequirementsOnlyMap;
+
+ HeadToLinkImplementationMap& GetHeadToLinkImplementationMap(
+ std::string const& config) const;
+ HeadToLinkImplementationMap& GetHeadToLinkImplementationUsageRequirementsMap(
+ std::string const& config) const;
cmLinkImplementationLibraries const* GetLinkImplementationLibrariesInternal(
- const std::string& config, const cmGeneratorTarget* head) const;
+ const std::string& config, const cmGeneratorTarget* head,
+ LinkInterfaceFor implFor) const;
bool ComputeOutputDir(const std::string& config,
cmStateEnums::ArtifactType artifact,
std::string& out) const;
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
index 47cefae..bf019c3 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -36,11 +36,6 @@ cmGhsMultiTargetGenerator::cmGhsMultiTargetGenerator(cmGeneratorTarget* target)
static_cast<cmLocalGhsMultiGenerator*>(target->GetLocalGenerator()))
, Makefile(target->Target->GetMakefile())
, Name(target->GetName())
-#ifdef _WIN32
- , CmdWindowsShell(true)
-#else
- , CmdWindowsShell(false)
-#endif
{
// Store the configuration name that is being used
if (cmValue config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE")) {
@@ -112,12 +107,6 @@ void cmGhsMultiTargetGenerator::Generate()
return;
}
- // Tell the global generator the name of the project file
- this->GeneratorTarget->Target->SetProperty("GENERATOR_FILE_NAME",
- this->Name);
- this->GeneratorTarget->Target->SetProperty(
- "GENERATOR_FILE_NAME_EXT", GhsMultiGpj::GetGpjTag(this->TagType));
-
this->GenerateTarget();
}
@@ -126,7 +115,14 @@ void cmGhsMultiTargetGenerator::GenerateTarget()
// Open the target file in copy-if-different mode.
std::string fproj =
cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), '/',
- this->Name, cmGlobalGhsMultiGenerator::FILE_EXTENSION);
+ this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
+ '/', this->Name, cmGlobalGhsMultiGenerator::FILE_EXTENSION);
+
+ // Tell the global generator the name of the project file
+ this->GeneratorTarget->Target->SetProperty("GENERATOR_FILE_NAME", fproj);
+ this->GeneratorTarget->Target->SetProperty(
+ "GENERATOR_FILE_NAME_EXT", GhsMultiGpj::GetGpjTag(this->TagType));
+
cmGeneratedFileStream fout(fproj);
fout.SetCopyIfDifferent(true);
@@ -160,10 +156,16 @@ void cmGhsMultiTargetGenerator::WriteTargetSpecifics(std::ostream& fout,
{
std::string outpath;
+ /* Determine paths from the target project file to where the output artifacts
+ * need to be located.
+ */
if (this->TagType != GhsMultiGpj::SUBPROJECT) {
// set target binary file destination
- outpath = this->GeneratorTarget->GetDirectory(config);
- outpath = this->LocalGenerator->MaybeRelativeToCurBinDir(outpath);
+ std::string binpath = cmStrCat(
+ this->LocalGenerator->GetCurrentBinaryDirectory(), '/',
+ this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget));
+ outpath = cmSystemTools::RelativePath(
+ binpath, this->GeneratorTarget->GetDirectory(config));
/* clang-format off */
fout << " :binDirRelative=\"" << outpath << "\"\n"
" -o \"" << this->TargetNameReal << "\"\n";
@@ -171,7 +173,7 @@ void cmGhsMultiTargetGenerator::WriteTargetSpecifics(std::ostream& fout,
}
// set target object file destination
- outpath = this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
+ outpath = ".";
fout << " :outputDirRelative=\"" << outpath << "\"\n";
}
@@ -187,6 +189,7 @@ void cmGhsMultiTargetGenerator::SetCompilerFlags(std::string const& config,
language, config);
this->LocalGenerator->AddVisibilityPresetFlags(
flags, this->GeneratorTarget, language);
+ this->LocalGenerator->AddColorDiagnosticsFlags(flags, language);
// Append old-style preprocessor definition flags.
if (this->Makefile->GetDefineFlags() != " ") {
@@ -316,19 +319,37 @@ void cmGhsMultiTargetGenerator::WriteTargetLinkLine(std::ostream& fout,
void cmGhsMultiTargetGenerator::WriteBuildEvents(std::ostream& fout)
{
- this->WriteBuildEventsHelper(
- fout, this->GeneratorTarget->GetPreBuildCommands(),
- std::string("prebuild"), std::string("preexecShell"));
+ this->WriteBuildEventsHelper(fout,
+ this->GeneratorTarget->GetPreBuildCommands(),
+ std::string("prebuild"),
+#ifdef _WIN32
+ std::string("preexecShell")
+#else
+ std::string("preexec")
+#endif
+ );
if (this->TagType != GhsMultiGpj::CUSTOM_TARGET) {
- this->WriteBuildEventsHelper(
- fout, this->GeneratorTarget->GetPreLinkCommands(),
- std::string("prelink"), std::string("preexecShell"));
+ this->WriteBuildEventsHelper(fout,
+ this->GeneratorTarget->GetPreLinkCommands(),
+ std::string("prelink"),
+#ifdef _WIN32
+ std::string("preexecShell")
+#else
+ std::string("preexec")
+#endif
+ );
}
- this->WriteBuildEventsHelper(
- fout, this->GeneratorTarget->GetPostBuildCommands(),
- std::string("postbuild"), std::string("postexecShell"));
+ this->WriteBuildEventsHelper(fout,
+ this->GeneratorTarget->GetPostBuildCommands(),
+ std::string("postbuild"),
+#ifdef _WIN32
+ std::string("postexecShell")
+#else
+ std::string("postexec")
+#endif
+ );
}
void cmGhsMultiTargetGenerator::WriteBuildEventsHelper(
@@ -336,6 +357,13 @@ void cmGhsMultiTargetGenerator::WriteBuildEventsHelper(
std::string const& name, std::string const& cmd)
{
int cmdcount = 0;
+#ifdef _WIN32
+ std::string fext = ".bat";
+ std::string shell;
+#else
+ std::string fext = ".sh";
+ std::string shell = "/bin/sh ";
+#endif
for (cmCustomCommand const& cc : ccv) {
cmCustomCommandGenerator ccg(cc, this->ConfigName, this->LocalGenerator);
@@ -343,14 +371,14 @@ void cmGhsMultiTargetGenerator::WriteBuildEventsHelper(
std::string fname =
cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), '/',
this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
- '/', this->Name, '_', name, cmdcount++,
- this->CmdWindowsShell ? ".bat" : ".sh");
+ '/', this->Name, '_', name, cmdcount++, fext);
+
cmGeneratedFileStream f(fname);
f.SetCopyIfDifferent(true);
this->WriteCustomCommandsHelper(f, ccg);
f.Close();
if (this->TagType != GhsMultiGpj::CUSTOM_TARGET) {
- fout << " :" << cmd << "=\"" << fname << "\"\n";
+ fout << " :" << cmd << "=\"" << shell << fname << "\"\n";
} else {
fout << fname << "\n :outputName=\"" << fname << ".rule\"\n";
}
@@ -409,15 +437,15 @@ void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper(
//
bool useCall = false;
- if (this->CmdWindowsShell) {
- std::string suffix;
- if (cmd.size() > 4) {
- suffix = cmSystemTools::LowerCase(cmd.substr(cmd.size() - 4));
- if (suffix == ".bat" || suffix == ".cmd") {
- useCall = true;
- }
+#ifdef _WIN32
+ std::string suffix;
+ if (cmd.size() > 4) {
+ suffix = cmSystemTools::LowerCase(cmd.substr(cmd.size() - 4));
+ if (suffix == ".bat" || suffix == ".cmd") {
+ useCall = true;
}
}
+#endif
cmSystemTools::ReplaceString(cmd, "/./", "/");
// Convert the command to a relative path only if the current
@@ -555,11 +583,12 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
// Open the filestream in copy-if-different mode.
std::string gname = sg;
cmsys::SystemTools::ReplaceString(gname, "\\", "_");
- std::string lpath = cmStrCat(
- this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget), '/',
- gname, cmGlobalGhsMultiGenerator::FILE_EXTENSION);
+ std::string lpath =
+ cmStrCat(gname, cmGlobalGhsMultiGenerator::FILE_EXTENSION);
std::string fpath = cmStrCat(
- this->LocalGenerator->GetCurrentBinaryDirectory(), '/', lpath);
+ this->LocalGenerator->GetCurrentBinaryDirectory(), '/',
+ this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget), '/',
+ lpath);
cmGeneratedFileStream* f = new cmGeneratedFileStream(fpath);
f->SetCopyIfDifferent(true);
gfiles.push_back(f);
@@ -605,13 +634,8 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
compile = false;
}
- *fout << comment << fname << '\n';
+ *fout << comment << fname << WriteObjectLangOverride(si) << '\n';
if (compile) {
- if ("ld" != si->GetExtension() && "int" != si->GetExtension() &&
- "bsp" != si->GetExtension()) {
- WriteObjectLangOverride(*fout, si);
- }
-
this->WriteSourceProperty(*fout, si, "INCLUDE_DIRECTORIES", "-I");
this->WriteSourceProperty(*fout, si, "COMPILE_DEFINITIONS", "-D");
this->WriteSourceProperty(*fout, si, "COMPILE_OPTIONS", "");
@@ -645,6 +669,11 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
}
}
int cmdcount = 0;
+#ifdef _WIN32
+ std::string fext = ".bat";
+#else
+ std::string fext = ".sh";
+#endif
for (auto& sf : customCommands) {
const cmCustomCommand* cc = sf->GetCustomCommand();
cmCustomCommandGenerator ccg(*cc, this->ConfigName,
@@ -655,8 +684,8 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
this->LocalGenerator->GetCurrentBinaryDirectory(), '/',
this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
'/', this->Name, "_cc", cmdcount++, '_',
- (sf->GetLocation()).GetName(),
- this->CmdWindowsShell ? ".bat" : ".sh");
+ (sf->GetLocation()).GetName(), fext);
+
cmGeneratedFileStream f(fname);
f.SetCopyIfDifferent(true);
this->WriteCustomCommandsHelper(f, ccg);
@@ -702,17 +731,16 @@ void cmGhsMultiTargetGenerator::WriteCustomCommandLine(
}
}
-void cmGhsMultiTargetGenerator::WriteObjectLangOverride(
- std::ostream& fout, const cmSourceFile* sourceFile)
+std::string cmGhsMultiTargetGenerator::WriteObjectLangOverride(
+ const cmSourceFile* sourceFile)
{
+ std::string ret;
cmValue rawLangProp = sourceFile->GetProperty("LANGUAGE");
if (rawLangProp) {
- std::string sourceLangProp(*rawLangProp);
- std::string const& extension = sourceFile->GetExtension();
- if ("CXX" == sourceLangProp && ("c" == extension || "C" == extension)) {
- fout << " -dotciscxx\n";
- }
+ ret = cmStrCat(" [", *rawLangProp, "]");
}
+
+ return ret;
}
bool cmGhsMultiTargetGenerator::DetermineIfIntegrityApp()
diff --git a/Source/cmGhsMultiTargetGenerator.h b/Source/cmGhsMultiTargetGenerator.h
index e9d7537..d3e80e6 100644
--- a/Source/cmGhsMultiTargetGenerator.h
+++ b/Source/cmGhsMultiTargetGenerator.h
@@ -65,8 +65,7 @@ private:
void WriteSourceProperty(std::ostream& fout, const cmSourceFile* sf,
std::string const& propName,
std::string const& propFlag);
- static void WriteObjectLangOverride(std::ostream& fout,
- const cmSourceFile* sourceFile);
+ static std::string WriteObjectLangOverride(const cmSourceFile* sourceFile);
bool DetermineIfIntegrityApp();
cmGeneratorTarget* GeneratorTarget;
@@ -78,6 +77,5 @@ private:
std::string TargetNameReal;
GhsMultiGpj::Types TagType;
std::string const Name;
- std::string ConfigName; /* CMAKE_BUILD_TYPE */
- bool const CmdWindowsShell; /* custom commands run in cmd.exe or /bin/sh */
+ std::string ConfigName; /* CMAKE_BUILD_TYPE */
};
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 156ecce..3831546 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -19,6 +19,7 @@
#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
+#include "cmsys/RegularExpression.hxx"
#if defined(_WIN32) && !defined(__CYGWIN__)
# include <windows.h>
@@ -687,6 +688,33 @@ void cmGlobalGenerator::EnableLanguage(
if (!this->FindMakeProgram(mf)) {
return;
}
+
+ // One-time includes of user-provided project setup files
+ std::string includes =
+ mf->GetSafeDefinition("CMAKE_PROJECT_TOP_LEVEL_INCLUDES");
+ std::vector<std::string> includesList = cmExpandedList(includes);
+ for (std::string const& setupFile : includesList) {
+ std::string absSetupFile = cmSystemTools::CollapseFullPath(
+ setupFile, mf->GetCurrentSourceDirectory());
+ if (!cmSystemTools::FileExists(absSetupFile)) {
+ cmSystemTools::Error(
+ "CMAKE_PROJECT_TOP_LEVEL_INCLUDES file does not exist: " +
+ setupFile);
+ return;
+ }
+ if (cmSystemTools::FileIsDirectory(absSetupFile)) {
+ cmSystemTools::Error(
+ "CMAKE_PROJECT_TOP_LEVEL_INCLUDES file is a directory: " +
+ setupFile);
+ return;
+ }
+ if (!mf->ReadListFile(absSetupFile)) {
+ cmSystemTools::Error(
+ "Failed reading CMAKE_PROJECT_TOP_LEVEL_INCLUDES file: " +
+ setupFile);
+ return;
+ }
+ }
}
// Check that the languages are supported by the generator and its
@@ -758,7 +786,9 @@ void cmGlobalGenerator::EnableLanguage(
needTestLanguage[lang] = true;
// Some generators like visual studio should not use the env variables
// So the global generator can specify that in this variable
- if (!mf->GetDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV")) {
+ if ((mf->GetPolicyStatus(cmPolicies::CMP0132) == cmPolicies::OLD ||
+ mf->GetPolicyStatus(cmPolicies::CMP0132) == cmPolicies::WARN) &&
+ !mf->GetDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV")) {
// put ${CMake_(LANG)_COMPILER_ENV_VAR}=${CMAKE_(LANG)_COMPILER
// into the environment, in case user scripts want to run
// configure, or sub cmakes
@@ -1498,6 +1528,11 @@ bool cmGlobalGenerator::Compute()
return false;
}
+ // Iterate through all targets and add verification targets for header sets
+ if (!this->AddHeaderSetVerification()) {
+ return false;
+ }
+
// Iterate through all targets and set up AUTOMOC, AUTOUIC and AUTORCC
if (!this->QtAutoGen()) {
return false;
@@ -1719,6 +1754,27 @@ bool cmGlobalGenerator::QtAutoGen()
#endif
}
+bool cmGlobalGenerator::AddHeaderSetVerification()
+{
+ for (auto const& gen : this->LocalGenerators) {
+ // Because AddHeaderSetVerification() adds generator targets, we need to
+ // cache the existing list of generator targets before starting.
+ std::vector<cmGeneratorTarget*> genTargets;
+ genTargets.reserve(gen->GetGeneratorTargets().size());
+ for (auto const& tgt : gen->GetGeneratorTargets()) {
+ genTargets.push_back(tgt.get());
+ }
+
+ for (auto* tgt : genTargets) {
+ if (!tgt->AddHeaderSetVerification()) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
bool cmGlobalGenerator::AddAutomaticSources()
{
for (const auto& lg : this->LocalGenerators) {
@@ -1735,6 +1791,7 @@ bool cmGlobalGenerator::AddAutomaticSources()
if (!gt->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM")) {
lg->AddPchDependencies(gt.get());
}
+ lg->AddXCConfigSources(gt.get());
}
}
for (const auto& lg : this->LocalGenerators) {
@@ -2522,6 +2579,47 @@ bool cmGlobalGenerator::NameResolvesToFramework(
return false;
}
+// If the file has no extension it's either a raw executable or might
+// be a direct reference to a binary within a framework (bad practice!).
+// This is where we change the path to point to the framework directory.
+// .tbd files also can be located in SDK frameworks (they are
+// placeholders for actual libraries shipped with the OS)
+cm::optional<std::pair<std::string, std::string>>
+cmGlobalGenerator::SplitFrameworkPath(const std::string& path,
+ bool extendedFormat) const
+{
+ // Check for framework structure:
+ // (/path/to/)?FwName.framework
+ // or (/path/to/)?FwName.framework/FwName(.tbd)?
+ // or (/path/to/)?FwName.framework/Versions/*/FwName(.tbd)?
+ static cmsys::RegularExpression frameworkPath(
+ "((.+)/)?(.+)\\.framework(/Versions/[^/]+)?(/(.+))?$");
+
+ auto ext = cmSystemTools::GetFilenameLastExtension(path);
+ if ((ext.empty() || ext == ".tbd" || ext == ".framework") &&
+ frameworkPath.find(path)) {
+ auto name = frameworkPath.match(3);
+ auto libname =
+ cmSystemTools::GetFilenameWithoutExtension(frameworkPath.match(6));
+ if (!libname.empty() && name != libname) {
+ return cm::nullopt;
+ }
+ return std::pair<std::string, std::string>{ frameworkPath.match(2), name };
+ }
+
+ if (extendedFormat) {
+ // path format can be more flexible: (/path/to/)?fwName(.framework)?
+ auto fwDir = cmSystemTools::GetParentDirectory(path);
+ auto name = cmSystemTools::GetFilenameLastExtension(path) == ".framework"
+ ? cmSystemTools::GetFilenameWithoutExtension(path)
+ : cmSystemTools::GetFilenameName(path);
+
+ return std::pair<std::string, std::string>{ fwDir, name };
+ }
+
+ return cm::nullopt;
+}
+
bool cmGlobalGenerator::CheckCMP0037(std::string const& targetName,
std::string const& reason) const
{
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index a43d4a6..dcef070 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -367,6 +367,13 @@ public:
/** Determine if a name resolves to a framework on disk or a built target
that is a framework. */
bool NameResolvesToFramework(const std::string& libname) const;
+ /** Split a framework path to the directory and name of the framework
+ * returns std::nullopt if the path does not match with framework format
+ * when extendedFormat is true, required format is relaxed (i.e. extension
+ * `.framework' is optional). Used when FRAMEWORK link feature is
+ * specified */
+ cm::optional<std::pair<std::string, std::string>> SplitFrameworkPath(
+ const std::string& path, bool extendedFormat = false) const;
cmMakefile* FindMakefile(const std::string& start_dir) const;
cmLocalGenerator* FindLocalGenerator(cmDirectoryId const& id) const;
@@ -452,10 +459,13 @@ public:
virtual bool IsNinja() const { return false; }
- /** Return true if we know the exact location of object files.
- If false, store the reason in the given string.
- This is meaningful only after EnableLanguage has been called. */
- virtual bool HasKnownObjectFileLocation(std::string*) const { return true; }
+ /** Return true if we know the exact location of object files for the given
+ cmTarget. If false, store the reason in the given string. This is
+ meaningful only after EnableLanguage has been called. */
+ virtual bool HasKnownObjectFileLocation(cmTarget const&, std::string*) const
+ {
+ return true;
+ }
virtual bool UseFolderProperty() const;
@@ -566,6 +576,8 @@ protected:
/// @return true on success
bool QtAutoGen();
+ bool AddHeaderSetVerification();
+
bool AddAutomaticSources();
std::string SelectMakeProgram(const std::string& makeProgram,
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
index 5e51dd2..9c334a5 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -2,14 +2,19 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalGhsMultiGenerator.h"
+#include <algorithm>
+#include <functional>
#include <map>
-#include <ostream>
+#include <sstream>
#include <utility>
#include <cm/memory>
#include <cm/string>
#include <cmext/algorithm>
+#include <cmext/memory>
+#include "cmCustomCommand.h"
+#include "cmCustomCommandLines.h"
#include "cmDocumentationEntry.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
@@ -18,10 +23,13 @@
#include "cmLocalGhsMultiGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmPolicies.h"
+#include "cmSourceFile.h"
#include "cmState.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmTarget.h"
#include "cmValue.h"
#include "cmVersion.h"
#include "cmake.h"
@@ -32,6 +40,8 @@ const char* cmGlobalGhsMultiGenerator::DEFAULT_BUILD_PROGRAM = "gbuild";
#elif defined(_WIN32)
const char* cmGlobalGhsMultiGenerator::DEFAULT_BUILD_PROGRAM = "gbuild.exe";
#endif
+const char* cmGlobalGhsMultiGenerator::CHECK_BUILD_SYSTEM_TARGET =
+ "RERUN_CMAKE";
cmGlobalGhsMultiGenerator::cmGlobalGhsMultiGenerator(cmake* cm)
: cmGlobalGenerator(cm)
@@ -279,7 +289,7 @@ void cmGlobalGhsMultiGenerator::WriteTopLevelProject(std::ostream& fout,
{
this->WriteFileHeader(fout);
this->WriteMacros(fout, root);
- this->WriteHighLevelDirectives(root, fout);
+ this->WriteHighLevelDirectives(fout, root);
GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, fout);
fout << "# Top Level Project File\n";
@@ -308,9 +318,13 @@ void cmGlobalGhsMultiGenerator::WriteTopLevelProject(std::ostream& fout,
}
void cmGlobalGhsMultiGenerator::WriteSubProjects(std::ostream& fout,
- std::string& all_target)
+ bool filterPredefined)
{
- fout << "CMakeFiles/" << all_target << " [Project]\n";
+ std::set<std::string> predefinedTargets;
+ predefinedTargets.insert(this->GetInstallTargetName());
+ predefinedTargets.insert(this->GetAllTargetName());
+ predefinedTargets.insert(std::string(CHECK_BUILD_SYSTEM_TARGET));
+
// All known targets
for (cmGeneratorTarget const* target : this->ProjectTargets) {
if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
@@ -320,8 +334,13 @@ void cmGlobalGhsMultiGenerator::WriteSubProjects(std::ostream& fout,
target->GetName() != this->GetInstallTargetName())) {
continue;
}
- fout << "CMakeFiles/" << target->GetName() + ".tgt" + FILE_EXTENSION
- << " [Project]\n";
+ /* Check if the current target is a predefined CMake target */
+ bool predefinedTarget =
+ predefinedTargets.find(target->GetName()) != predefinedTargets.end();
+ if ((filterPredefined && predefinedTarget) ||
+ (!filterPredefined && !predefinedTarget)) {
+ fout << target->GetName() + ".tgt" + FILE_EXTENSION << " [Project]\n";
+ }
}
}
@@ -329,36 +348,22 @@ void cmGlobalGhsMultiGenerator::WriteProjectLine(
std::ostream& fout, cmGeneratorTarget const* target,
std::string& rootBinaryDir)
{
- cmValue projName = target->GetProperty("GENERATOR_FILE_NAME");
+ cmValue projFile = target->GetProperty("GENERATOR_FILE_NAME");
cmValue projType = target->GetProperty("GENERATOR_FILE_NAME_EXT");
- if (projName && projType) {
- cmLocalGenerator* lg = target->GetLocalGenerator();
- std::string dir = lg->GetCurrentBinaryDirectory();
- dir = cmSystemTools::ForceToRelativePath(rootBinaryDir, dir);
- if (dir == ".") {
- dir.clear();
- } else {
- if (dir.back() != '/') {
- dir += "/";
- }
- }
+ /* If either value is not valid then this particular target is an
+ * unsupported target type and should be skipped.
+ */
+ if (projFile && projType) {
+ std::string path = cmSystemTools::RelativePath(rootBinaryDir, projFile);
- std::string projFile = dir + *projName + FILE_EXTENSION;
- fout << projFile;
+ fout << path;
fout << ' ' << *projType << '\n';
- } else {
- /* Should never happen */
- std::string message =
- "The project file for target [" + target->GetName() + "] is missing.\n";
- cmSystemTools::Error(message);
- fout << "{comment} " << target->GetName() << " [missing project file]\n";
}
}
void cmGlobalGhsMultiGenerator::WriteTargets(cmLocalGenerator* root)
{
- std::string rootBinaryDir =
- cmStrCat(root->GetCurrentBinaryDirectory(), "/CMakeFiles");
+ std::string rootBinaryDir = root->GetCurrentBinaryDirectory();
// All known targets
for (cmGeneratorTarget const* target : this->ProjectTargets) {
@@ -391,62 +396,6 @@ void cmGlobalGhsMultiGenerator::WriteTargets(cmLocalGenerator* root)
}
}
-void cmGlobalGhsMultiGenerator::WriteAllTarget(
- cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators,
- std::string& all_target)
-{
- this->ProjectTargets.clear();
-
- // create target build file
- all_target = root->GetProjectName() + "." + this->GetAllTargetName() +
- ".tgt" + FILE_EXTENSION;
- std::string fname =
- root->GetCurrentBinaryDirectory() + "/CMakeFiles/" + all_target;
- cmGeneratedFileStream fbld(fname);
- fbld.SetCopyIfDifferent(true);
- this->WriteFileHeader(fbld);
- GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, fbld);
-
- // Collect all targets under this root generator and the transitive
- // closure of their dependencies.
- TargetDependSet projectTargets;
- TargetDependSet originalTargets;
- this->GetTargetSets(projectTargets, originalTargets, root, generators);
- OrderedTargetDependSet sortedProjectTargets(projectTargets, "");
- std::vector<cmGeneratorTarget const*> defaultTargets;
- for (cmGeneratorTarget const* t : sortedProjectTargets) {
- /* save list of all targets in sorted order */
- this->ProjectTargets.push_back(t);
- }
- for (cmGeneratorTarget const* t : sortedProjectTargets) {
- if (!t->IsInBuildSystem()) {
- continue;
- }
- if (!this->IsExcluded(t->GetLocalGenerator(), t)) {
- defaultTargets.push_back(t);
- }
- }
- std::vector<cmGeneratorTarget const*> build;
- if (this->ComputeTargetBuildOrder(defaultTargets, build)) {
- std::string message = "The inter-target dependency graph for project [" +
- root->GetProjectName() + "] had a cycle.\n";
- cmSystemTools::Error(message);
- } else {
- // determine the targets for ALL target
- std::string rootBinaryDir =
- cmStrCat(root->GetCurrentBinaryDirectory(), "/CMakeFiles");
- for (cmGeneratorTarget const* target : build) {
- if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
- target->GetType() == cmStateEnums::MODULE_LIBRARY ||
- target->GetType() == cmStateEnums::SHARED_LIBRARY) {
- continue;
- }
- this->WriteProjectLine(fbld, target, rootBinaryDir);
- }
- }
- fbld.Close();
-}
-
void cmGlobalGhsMultiGenerator::Generate()
{
std::string fname;
@@ -482,12 +431,23 @@ void cmGlobalGhsMultiGenerator::OutputTopLevelProject(
cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators)
{
std::string fname;
- std::string all_target;
if (generators.empty()) {
return;
}
+ // Collect all targets under this root generator and the transitive
+ // closure of their dependencies.
+ TargetDependSet projectTargets;
+ TargetDependSet originalTargets;
+ this->GetTargetSets(projectTargets, originalTargets, root, generators);
+ OrderedTargetDependSet sortedProjectTargets(projectTargets, "");
+ this->ProjectTargets.clear();
+ for (cmGeneratorTarget const* t : sortedProjectTargets) {
+ /* save list of all targets in sorted order */
+ this->ProjectTargets.push_back(t);
+ }
+
/* Name top-level projects as filename.top.gpj to avoid name clashes
* with target projects. This avoid the issue where the project has
* the same name as the executable target.
@@ -498,11 +458,9 @@ void cmGlobalGhsMultiGenerator::OutputTopLevelProject(
cmGeneratedFileStream top(fname);
top.SetCopyIfDifferent(true);
this->WriteTopLevelProject(top, root);
-
- this->WriteAllTarget(root, generators, all_target);
this->WriteTargets(root);
-
- this->WriteSubProjects(top, all_target);
+ this->WriteSubProjects(top, true);
+ this->WriteSubProjects(top, false);
top.Close();
}
@@ -510,59 +468,62 @@ std::vector<cmGlobalGenerator::GeneratedMakeCommand>
cmGlobalGhsMultiGenerator::GenerateBuildCommand(
const std::string& makeProgram, const std::string& projectName,
const std::string& projectDir, std::vector<std::string> const& targetNames,
- const std::string& /*config*/, int jobs, bool /*verbose*/,
+ const std::string& /*config*/, int jobs, bool verbose,
const cmBuildOptions& /*buildOptions*/,
std::vector<std::string> const& makeOptions)
{
- GeneratedMakeCommand makeCommand = {};
- std::string gbuild;
- if (cmValue gbuildCached =
- this->CMakeInstance->GetCacheDefinition("CMAKE_MAKE_PROGRAM")) {
- gbuild = *gbuildCached;
- }
- makeCommand.Add(this->SelectMakeProgram(makeProgram, gbuild));
+ GeneratedMakeCommand makeCommand;
+
+ makeCommand.Add(this->SelectMakeProgram(makeProgram));
if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) {
- makeCommand.Add("-parallel");
- if (jobs != cmake::DEFAULT_BUILD_PARALLEL_LEVEL) {
- makeCommand.Add(std::to_string(jobs));
+ if (jobs == cmake::DEFAULT_BUILD_PARALLEL_LEVEL) {
+ makeCommand.Add("-parallel");
+ } else {
+ makeCommand.Add(std::string("-parallel=") + std::to_string(jobs));
}
}
- makeCommand.Add(makeOptions.begin(), makeOptions.end());
-
- /* determine which top-project file to use */
+ /* determine the top-project file in the project directory */
std::string proj = projectName + ".top" + FILE_EXTENSION;
std::vector<std::string> files;
cmSystemTools::Glob(projectDir, ".*\\.top\\.gpj", files);
if (!files.empty()) {
- /* if multiple top-projects are found in build directory
- * then prefer projectName top-project.
- */
- if (!cm::contains(files, proj)) {
- proj = files.at(0);
- }
+ /* use the real top-level project in the directory */
+ proj = files.at(0);
}
-
makeCommand.Add("-top", proj);
+
+ /* determine targets to build */
+ bool build_all = false;
if (!targetNames.empty()) {
- if (cm::contains(targetNames, "clean")) {
- makeCommand.Add("-clean");
- } else {
- for (const auto& tname : targetNames) {
- if (!tname.empty()) {
+ for (const auto& tname : targetNames) {
+ if (!tname.empty()) {
+ if (tname == "clean") {
+ makeCommand.Add("-clean");
+ } else {
makeCommand.Add(tname + ".tgt.gpj");
}
+ } else {
+ build_all = true;
}
}
} else {
+ build_all = true;
+ }
+
+ if (build_all) {
/* transform name to default build */;
- std::string all = proj;
- all.replace(all.end() - 7, all.end(),
- std::string(this->GetAllTargetName()) + ".tgt.gpj");
+ std::string all = std::string(this->GetAllTargetName()) + ".tgt.gpj";
makeCommand.Add(all);
}
- return { makeCommand };
+
+ if (verbose) {
+ makeCommand.Add("-commands");
+ }
+ makeCommand.Add(makeOptions.begin(), makeOptions.end());
+
+ return { std::move(makeCommand) };
}
void cmGlobalGhsMultiGenerator::WriteMacros(std::ostream& fout,
@@ -579,7 +540,7 @@ void cmGlobalGhsMultiGenerator::WriteMacros(std::ostream& fout,
}
void cmGlobalGhsMultiGenerator::WriteHighLevelDirectives(
- cmLocalGenerator* root, std::ostream& fout)
+ std::ostream& fout, cmLocalGenerator* root)
{
/* put primary target and customization files into project file */
cmValue const tgt = root->GetMakefile()->GetDefinition("GHS_PRIMARY_TARGET");
@@ -681,3 +642,153 @@ bool cmGlobalGhsMultiGenerator::VisitTarget(
/* already complete */
return false;
}
+
+bool cmGlobalGhsMultiGenerator::AddCheckTarget()
+{
+ // Skip the target if no regeneration is to be done.
+ if (this->GlobalSettingIsOn("CMAKE_SUPPRESS_REGENERATION")) {
+ return false;
+ }
+
+ // Get the generators.
+ std::vector<std::unique_ptr<cmLocalGenerator>> const& generators =
+ this->LocalGenerators;
+ auto& lg =
+ cm::static_reference_cast<cmLocalGhsMultiGenerator>(generators[0]);
+
+ // The name of the output file for the custom command.
+ this->StampFile = lg.GetBinaryDirectory() + std::string("/CMakeFiles/") +
+ CHECK_BUILD_SYSTEM_TARGET;
+
+ // Add a custom rule to re-run CMake if any input files changed.
+ {
+ // 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 the cache file.
+ listFiles.push_back(cmStrCat(
+ this->GetCMakeInstance()->GetHomeOutputDirectory(), "/CMakeCache.txt"));
+
+ // Print not implemented warning.
+ if (this->GetCMakeInstance()->DoWriteGlobVerifyTarget()) {
+ std::ostringstream msg;
+ msg << "Any pre-check scripts, such as those generated for file(GLOB "
+ "CONFIGURE_DEPENDS), will not be run by gbuild.";
+ this->GetCMakeInstance()->IssueMessage(MessageType::AUTHOR_WARNING,
+ msg.str());
+ }
+
+ // Sort the list of input files and remove duplicates.
+ std::sort(listFiles.begin(), listFiles.end(), std::less<std::string>());
+ auto newEnd = std::unique(listFiles.begin(), listFiles.end());
+ listFiles.erase(newEnd, listFiles.end());
+
+ // Create a rule to re-run CMake and create output file.
+ cmCustomCommandLines commandLines;
+ commandLines.emplace_back(
+ cmMakeCommandLine({ cmSystemTools::GetCMakeCommand(), "-E", "rm", "-f",
+ this->StampFile }));
+ std::string argS = cmStrCat("-S", lg.GetSourceDirectory());
+ std::string argB = cmStrCat("-B", lg.GetBinaryDirectory());
+ commandLines.emplace_back(
+ cmMakeCommandLine({ cmSystemTools::GetCMakeCommand(), argS, argB }));
+ commandLines.emplace_back(cmMakeCommandLine(
+ { cmSystemTools::GetCMakeCommand(), "-E", "touch", this->StampFile }));
+
+ /* Create the target(Exclude from ALL_BUILD).
+ *
+ * The build tool, currently, does not support rereading the project files
+ * if they get updated. So do not run this target as part of ALL_BUILD.
+ */
+ auto cc = cm::make_unique<cmCustomCommand>();
+ cmTarget* tgt =
+ lg.AddUtilityCommand(CHECK_BUILD_SYSTEM_TARGET, true, std::move(cc));
+ auto ptr = cm::make_unique<cmGeneratorTarget>(tgt, &lg);
+ auto* gt = ptr.get();
+ lg.AddGeneratorTarget(std::move(ptr));
+
+ // Add the rule.
+ cc = cm::make_unique<cmCustomCommand>();
+ cc->SetOutputs(this->StampFile);
+ cc->SetDepends(listFiles);
+ cc->SetCommandLines(commandLines);
+ cc->SetComment("Checking Build System");
+ cc->SetCMP0116Status(cmPolicies::NEW);
+ cc->SetEscapeOldStyle(false);
+ cc->SetStdPipesUTF8(true);
+
+ if (cmSourceFile* file =
+ lg.AddCustomCommandToOutput(std::move(cc), true)) {
+ gt->AddSource(file->ResolveFullPath());
+ } else {
+ cmSystemTools::Error("Error adding rule for " + this->StampFile);
+ }
+ // Organize in the "predefined targets" folder:
+ if (this->UseFolderProperty()) {
+ tgt->SetProperty("FOLDER", this->GetPredefinedTargetsFolder());
+ }
+ }
+
+ return true;
+}
+
+void cmGlobalGhsMultiGenerator::AddAllTarget()
+{
+ // Add a special target that depends on ALL projects for easy build
+ // of one configuration only.
+ for (auto const& it : this->ProjectMap) {
+ std::vector<cmLocalGenerator*> const& gen = it.second;
+ // add the ALL_BUILD to the first local generator of each project
+ if (!gen.empty()) {
+ // Use no actual command lines so that the target itself is not
+ // considered always out of date.
+ auto cc = cm::make_unique<cmCustomCommand>();
+ cc->SetCMP0116Status(cmPolicies::NEW);
+ cc->SetEscapeOldStyle(false);
+ cc->SetComment("Build all projects");
+ cmTarget* allBuild = gen[0]->AddUtilityCommand(this->GetAllTargetName(),
+ true, std::move(cc));
+
+ gen[0]->AddGeneratorTarget(
+ cm::make_unique<cmGeneratorTarget>(allBuild, gen[0]));
+
+ // Organize in the "predefined targets" folder:
+ if (this->UseFolderProperty()) {
+ allBuild->SetProperty("FOLDER", this->GetPredefinedTargetsFolder());
+ }
+
+ // Now make all targets depend on the ALL_BUILD target
+ for (cmLocalGenerator const* i : gen) {
+ for (const auto& tgt : i->GetGeneratorTargets()) {
+ // Skip global or imported targets
+ if (tgt->GetType() == cmStateEnums::GLOBAL_TARGET ||
+ tgt->IsImported()) {
+ continue;
+ }
+ // Skip Exclude From All Targets
+ if (!this->IsExcluded(gen[0], tgt.get())) {
+ allBuild->AddUtility(tgt->GetName(), false);
+ }
+ }
+ }
+ }
+ }
+}
+
+void cmGlobalGhsMultiGenerator::AddExtraIDETargets()
+{
+ // Add a special target that depends on ALL projects.
+ this->AddAllTarget();
+
+ /* Add Custom Target to check if CMake needs to be rerun.
+ *
+ * The build tool, currently, does not support rereading the project files
+ * if they get updated. So do not make the other targets dependent on this
+ * check.
+ */
+ this->AddCheckTarget();
+}
diff --git a/Source/cmGlobalGhsMultiGenerator.h b/Source/cmGlobalGhsMultiGenerator.h
index 26ea3c7..aa68d3b 100644
--- a/Source/cmGlobalGhsMultiGenerator.h
+++ b/Source/cmGlobalGhsMultiGenerator.h
@@ -81,8 +81,6 @@ public:
// Write the common disclaimer text at the top of each build file.
void WriteFileHeader(std::ostream& fout);
- const char* GetInstallTargetName() const override { return "install"; }
-
protected:
void Generate() override;
std::vector<GeneratedMakeCommand> GenerateBuildCommand(
@@ -92,6 +90,7 @@ protected:
const cmBuildOptions& buildOptions = cmBuildOptions(),
std::vector<std::string> const& makeOptions =
std::vector<std::string>()) override;
+ void AddExtraIDETargets() override;
private:
void GetToolset(cmMakefile* mf, std::string& tsd, const std::string& ts);
@@ -101,20 +100,21 @@ private:
std::vector<cmLocalGenerator*>& generators);
void WriteTopLevelProject(std::ostream& fout, cmLocalGenerator* root);
void WriteMacros(std::ostream& fout, cmLocalGenerator* root);
- void WriteHighLevelDirectives(cmLocalGenerator* root, std::ostream& fout);
- void WriteSubProjects(std::ostream& fout, std::string& all_target);
+ void WriteHighLevelDirectives(std::ostream& fout, cmLocalGenerator* root);
+ void WriteSubProjects(std::ostream& fout, bool filterPredefined);
void WriteTargets(cmLocalGenerator* root);
void WriteProjectLine(std::ostream& fout, cmGeneratorTarget const* target,
std::string& rootBinaryDir);
void WriteCustomRuleBOD(std::ostream& fout);
void WriteCustomTargetBOD(std::ostream& fout);
- void WriteAllTarget(cmLocalGenerator* root,
- std::vector<cmLocalGenerator*>& generators,
- std::string& all_target);
+ bool AddCheckTarget();
+ void AddAllTarget();
+ std::string StampFile;
static std::string TrimQuotes(std::string str);
static const char* DEFAULT_BUILD_PROGRAM;
+ static const char* CHECK_BUILD_SYSTEM_TARGET;
bool ComputeTargetBuildOrder(cmGeneratorTarget const* tgt,
std::vector<cmGeneratorTarget const*>& build);
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 4245037..3726aa4 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -2495,8 +2495,7 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
snapshot.GetDirectory().SetCurrentBinary(dir_cur_bld);
auto mfd = cm::make_unique<cmMakefile>(this, snapshot);
auto lgd = this->CreateLocalGenerator(mfd.get());
- lgd->SetRelativePathTopSource(dir_top_src);
- lgd->SetRelativePathTopBinary(dir_top_bld);
+ lgd->SetRelativePathTop(dir_top_src, dir_top_bld);
this->Makefiles.push_back(std::move(mfd));
this->LocalGenerators.push_back(std::move(lgd));
}
@@ -2535,6 +2534,11 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
}
}
+ const char* module_ext = "";
+ if (arg_modmapfmt == "gcc") {
+ module_ext = ".gcm";
+ }
+
// Extend the module map with those provided by this target.
// We do this after loading the modules provided by linked targets
// in case we have one of the same name that must be preferred.
@@ -2551,7 +2555,9 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
}
} else {
// Assume the module file path matches the logical module name.
- mod = cmStrCat(module_dir, p.LogicalName);
+ std::string safe_logical_name = p.LogicalName;
+ cmSystemTools::ReplaceString(safe_logical_name, ":", "-");
+ mod = cmStrCat(module_dir, safe_logical_name, module_ext);
}
mod_files[p.LogicalName] = mod;
tm[p.LogicalName] = mod;
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index db54b86..35448ee 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -1286,6 +1286,14 @@ cmGlobalVisualStudio10Generator::GenerateBuildCommand(
return makeCommands;
}
+bool cmGlobalVisualStudio10Generator::IsInSolution(
+ const cmGeneratorTarget* gt) const
+{
+ return gt->IsInBuildSystem() &&
+ !(this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS16 &&
+ gt->GetName() == CMAKE_CHECK_BUILD_SYSTEM_TARGET);
+}
+
bool cmGlobalVisualStudio10Generator::Find64BitTools(cmMakefile* mf)
{
if (this->DefaultPlatformToolset == "v100") {
diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h
index 4977a84..2203f71 100644
--- a/Source/cmGlobalVisualStudio10Generator.h
+++ b/Source/cmGlobalVisualStudio10Generator.h
@@ -118,6 +118,8 @@ public:
return this->WindowsTargetPlatformVersion;
}
+ bool IsInSolution(const cmGeneratorTarget* gt) const override;
+
/** Return true if building for WindowsCE */
bool TargetsWindowsCE() const override { return this->SystemIsWindowsCE; }
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index 134937e..1c10fb3 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -359,7 +359,7 @@ void cmGlobalVisualStudio7Generator::WriteTargetConfigurations(
// loop over again and write out configurations for each target
// in the solution
for (cmGeneratorTarget const* target : projectTargets) {
- if (!target->IsInBuildSystem()) {
+ if (!this->IsInSolution(target)) {
continue;
}
cmValue expath = target->GetProperty("EXTERNAL_MSPROJECT");
@@ -396,7 +396,7 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
VisualStudioFolders.clear();
for (cmGeneratorTarget const* target : projectTargets) {
- if (!target->IsInBuildSystem()) {
+ if (!this->IsInSolution(target)) {
continue;
}
bool written = false;
@@ -458,22 +458,6 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
}
}
-void cmGlobalVisualStudio7Generator::WriteTargetDepends(
- std::ostream& fout, OrderedTargetDependSet const& projectTargets)
-{
- for (cmGeneratorTarget const* target : projectTargets) {
- if (!target->IsInBuildSystem()) {
- continue;
- }
- cmValue vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
- if (vcprojName) {
- std::string dir =
- target->GetLocalGenerator()->GetCurrentSourceDirectory();
- this->WriteProjectDepends(fout, *vcprojName, dir, target);
- }
- }
-}
-
void cmGlobalVisualStudio7Generator::WriteFolders(std::ostream& fout)
{
cm::string_view const prefix = "CMAKE_FOLDER_GUID_";
diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h
index 33f1063..a55cf45 100644
--- a/Source/cmGlobalVisualStudio7Generator.h
+++ b/Source/cmGlobalVisualStudio7Generator.h
@@ -148,8 +148,6 @@ protected:
virtual void WriteTargetsToSolution(
std::ostream& fout, cmLocalGenerator* root,
OrderedTargetDependSet const& projectTargets);
- virtual void WriteTargetDepends(
- std::ostream& fout, OrderedTargetDependSet const& projectTargets);
virtual void WriteTargetConfigurations(
std::ostream& fout, std::vector<std::string> const& configs,
OrderedTargetDependSet const& projectTargets);
diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx
index dbd2de9..323ee67 100644
--- a/Source/cmGlobalVisualStudio8Generator.cxx
+++ b/Source/cmGlobalVisualStudio8Generator.cxx
@@ -392,7 +392,7 @@ void cmGlobalVisualStudio8Generator::WriteProjectDepends(
TargetDependSet const& unordered = this->GetTargetDirectDepends(gt);
OrderedTargetDependSet depends(unordered, std::string());
for (cmTargetDepend const& i : depends) {
- if (!i->IsInBuildSystem()) {
+ if (!this->IsInSolution(i)) {
continue;
}
std::string guid = this->GetGUID(i->GetName());
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index 141b5eb..cddaaa4 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -837,6 +837,12 @@ bool cmGlobalVisualStudioGenerator::TargetIsFortranOnly(
return languages.size() == 1 && *languages.begin() == "Fortran";
}
+bool cmGlobalVisualStudioGenerator::IsInSolution(
+ const cmGeneratorTarget* gt) const
+{
+ return gt->IsInBuildSystem();
+}
+
bool cmGlobalVisualStudioGenerator::TargetCompare::operator()(
cmGeneratorTarget const* l, cmGeneratorTarget const* r) const
{
diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h
index cb1b14b..4f5f100 100644
--- a/Source/cmGlobalVisualStudioGenerator.h
+++ b/Source/cmGlobalVisualStudioGenerator.h
@@ -98,6 +98,9 @@ public:
// return true if target is fortran only
bool TargetIsFortranOnly(const cmGeneratorTarget* gt);
+ // return true if target should be included in solution.
+ virtual bool IsInSolution(const cmGeneratorTarget* gt) const;
+
/** Get the top-level registry key for this VS version. */
std::string GetRegistryBase();
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 203addd..d53c3d5 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -616,6 +616,16 @@ void cmGlobalXCodeGenerator::AddExtraTargets(
cmTarget* allbuild =
root->AddUtilityCommand("ALL_BUILD", true, std::move(cc));
+ // Add xcconfig files to ALL_BUILD sources
+ for (auto& config : this->CurrentConfigurationTypes) {
+ auto xcconfig = cmGeneratorExpression::Evaluate(
+ this->CurrentMakefile->GetSafeDefinition("CMAKE_XCODE_XCCONFIG"),
+ this->CurrentLocalGenerator, config);
+ if (!xcconfig.empty()) {
+ allbuild->AddSource(xcconfig);
+ }
+ }
+
root->AddGeneratorTarget(cm::make_unique<cmGeneratorTarget>(allbuild, root));
// Add XCODE depend helper
@@ -1142,6 +1152,9 @@ std::string GetSourcecodeValueFromFileExtension(
} else if (ext == "xcassets") {
keepLastKnownFileType = true;
sourcecode = "folder.assetcatalog";
+ } else if (ext == "xcconfig") {
+ keepLastKnownFileType = true;
+ sourcecode = "text.xcconfig";
}
// else
// {
@@ -1154,47 +1167,39 @@ std::string GetSourcecodeValueFromFileExtension(
return sourcecode;
}
-// If the file has no extension it's either a raw executable or might
-// be a direct reference to a binary within a framework (bad practice!).
-// This is where we change the path to point to the framework directory.
-// .tbd files also can be located in SDK frameworks (they are
-// placeholders for actual libraries shipped with the OS)
-std::string GetLibraryOrFrameworkPath(const std::string& path)
+template <class T>
+std::string GetTargetObjectDirArch(T const& target,
+ const std::string& defaultVal)
{
- auto ext = cmSystemTools::GetFilenameLastExtension(path);
- if (ext.empty() || ext == ".tbd") {
- auto name = cmSystemTools::GetFilenameWithoutExtension(path);
- // Check for iOS framework structure:
- // FwName.framework/FwName (and also on macOS where FwName lib is a
- // symlink)
- auto parentDir = cmSystemTools::GetParentDirectory(path);
- auto parentName = cmSystemTools::GetFilenameWithoutExtension(parentDir);
- ext = cmSystemTools::GetFilenameLastExtension(parentDir);
- if (ext == ".framework" && name == parentName) {
- return parentDir;
- }
- // Check for macOS framework structure:
- // FwName.framework/Versions/*/FwName
- std::vector<std::string> components;
- cmSystemTools::SplitPath(path, components);
- if (components.size() > 3 &&
- components[components.size() - 3] == "Versions") {
- ext = cmSystemTools::GetFilenameLastExtension(
- components[components.size() - 4]);
- parentName = cmSystemTools::GetFilenameWithoutExtension(
- components[components.size() - 4]);
- if (ext == ".framework" && name == parentName) {
- components.erase(components.begin() + components.size() - 3,
- components.end());
- return cmSystemTools::JoinPath(components);
- }
- }
+ auto archs = cmExpandedList(target.GetSafeProperty("OSX_ARCHITECTURES"));
+ if (archs.size() > 1) {
+ return "$(CURRENT_ARCH)";
+ } else if (archs.size() == 1) {
+ return archs.front();
+ } else {
+ return defaultVal;
}
- return path;
}
} // anonymous
+// Extracts the framework directory, if path matches the framework syntax
+// otherwise returns the path untouched
+std::string cmGlobalXCodeGenerator::GetLibraryOrFrameworkPath(
+ const std::string& path) const
+{
+ auto fwItems = this->SplitFrameworkPath(path);
+ if (fwItems) {
+ if (fwItems->first.empty()) {
+ return cmStrCat(fwItems->second, ".framework");
+ } else {
+ return cmStrCat(fwItems->first, '/', fwItems->second, ".framework");
+ }
+ }
+
+ return path;
+}
+
cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeFileReferenceFromPath(
const std::string& fullpath, cmGeneratorTarget* target,
const std::string& lang, cmSourceFile* sf)
@@ -1217,7 +1222,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeFileReferenceFromPath(
ext = ext.substr(1);
}
if (fileType.empty()) {
- path = GetLibraryOrFrameworkPath(path);
+ path = this->GetLibraryOrFrameworkPath(path);
ext = cmSystemTools::GetFilenameLastExtension(path);
if (!ext.empty()) {
ext = ext.substr(1);
@@ -1649,7 +1654,10 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmGeneratorTarget* gtgt)
// If the language is compiled as a source trust Xcode to link with it.
for (auto const& Language :
- gtgt->GetLinkImplementation("NOCONFIG")->Languages) {
+ gtgt
+ ->GetLinkImplementation("NOCONFIG",
+ cmGeneratorTarget::LinkInterfaceFor::Link)
+ ->Languages) {
if (Language == llang) {
return;
}
@@ -3064,6 +3072,8 @@ std::string cmGlobalXCodeGenerator::AddConfigurations(cmXCodeObject* target,
config->AddAttribute("name", this->CreateString(i));
config->SetComment(i);
config->AddAttribute("buildSettings", buildSettings);
+
+ this->CreateTargetXCConfigSettings(gtgt, config, i);
}
if (!configVector.empty()) {
configlist->AddAttribute("defaultConfigurationName",
@@ -3075,6 +3085,67 @@ std::string cmGlobalXCodeGenerator::AddConfigurations(cmXCodeObject* target,
return "";
}
+void cmGlobalXCodeGenerator::CreateGlobalXCConfigSettings(
+ cmLocalGenerator* root, cmXCodeObject* config, const std::string& configName)
+{
+ auto xcconfig = cmGeneratorExpression::Evaluate(
+ this->CurrentMakefile->GetSafeDefinition("CMAKE_XCODE_XCCONFIG"),
+ this->CurrentLocalGenerator, configName);
+ if (xcconfig.empty()) {
+ return;
+ }
+
+ auto sf = this->CurrentMakefile->GetSource(xcconfig);
+ if (!sf) {
+ cmSystemTools::Error(
+ cmStrCat("sources for ALL_BUILD do not contain xcconfig file: '",
+ xcconfig, "' (configuration: ", configName, ")"));
+ return;
+ }
+
+ cmXCodeObject* fileRef = this->CreateXCodeFileReferenceFromPath(
+ sf->ResolveFullPath(), root->FindGeneratorTargetToUse("ALL_BUILD"), "",
+ sf);
+
+ if (!fileRef) {
+ // error is already reported by CreateXCodeFileReferenceFromPath
+ return;
+ }
+
+ config->AddAttribute("baseConfigurationReference",
+ this->CreateObjectReference(fileRef));
+}
+
+void cmGlobalXCodeGenerator::CreateTargetXCConfigSettings(
+ cmGeneratorTarget* target, cmXCodeObject* config,
+ const std::string& configName)
+{
+ auto xcconfig =
+ cmGeneratorExpression::Evaluate(target->GetSafeProperty("XCODE_XCCONFIG"),
+ this->CurrentLocalGenerator, configName);
+ if (xcconfig.empty()) {
+ return;
+ }
+
+ auto sf = target->Makefile->GetSource(xcconfig);
+ if (!sf) {
+ cmSystemTools::Error(cmStrCat("target sources for target ",
+ target->Target->GetName(),
+ " do not contain xcconfig file: '", xcconfig,
+ "' (configuration: ", configName, ")"));
+ return;
+ }
+
+ cmXCodeObject* fileRef = this->CreateXCodeFileReferenceFromPath(
+ sf->ResolveFullPath(), target, "", sf);
+ if (!fileRef) {
+ // error is already reported by CreateXCodeFileReferenceFromPath
+ return;
+ }
+ config->AddAttribute("baseConfigurationReference",
+ this->CreateObjectReference(fileRef));
+}
+
const char* cmGlobalXCodeGenerator::GetTargetLinkFlagsVar(
cmGeneratorTarget const* target) const
{
@@ -3541,13 +3612,14 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
} else {
linkDir = libItem->Value.Value;
}
- linkDir = GetLibraryOrFrameworkPath(linkDir);
- bool isFramework = cmSystemTools::IsPathToFramework(linkDir);
- linkDir = cmSystemTools::GetParentDirectory(linkDir);
- if (isFramework) {
- if (std::find(frameworkSearchPaths.begin(), frameworkSearchPaths.end(),
- linkDir) == frameworkSearchPaths.end()) {
- frameworkSearchPaths.push_back(linkDir);
+ if (cmHasSuffix(libItem->GetFeatureName(), "FRAMEWORK"_s)) {
+ auto fwItems = this->SplitFrameworkPath(linkDir, true);
+ if (fwItems && !fwItems->first.empty()) {
+ linkDir = std::move(fwItems->first);
+ if (std::find(frameworkSearchPaths.begin(), frameworkSearchPaths.end(),
+ linkDir) == frameworkSearchPaths.end()) {
+ frameworkSearchPaths.push_back(linkDir);
+ }
}
} else {
if (std::find(linkSearchPaths.begin(), linkSearchPaths.end(), linkDir) ==
@@ -3555,7 +3627,7 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
linkSearchPaths.push_back(linkDir);
}
}
- // Add target dependency
+
if (libItem->Target && !libItem->Target->IsImported()) {
for (auto const& configName : this->CurrentConfigurationTypes) {
target->AddDependTarget(configName, libItem->Target->GetName());
@@ -3729,22 +3801,27 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
if (cmSystemTools::FileIsFullPath(cleanPath)) {
cleanPath = cmSystemTools::CollapseFullPath(cleanPath);
}
- const auto libPath = GetLibraryOrFrameworkPath(cleanPath);
- if (cmSystemTools::StringEndsWith(libPath.c_str(), ".framework")) {
- const auto fwName =
- cmSystemTools::GetFilenameWithoutExtension(libPath);
- const auto fwDir = cmSystemTools::GetParentDirectory(libPath);
- if (emitted.insert(fwDir).second) {
- // This is a search path we had not added before and it isn't an
- // implicit search path, so we need it
- libPaths.Add("-F " + this->XCodeEscapePath(fwDir));
+ bool isFramework =
+ cmHasSuffix(libName.GetFeatureName(), "FRAMEWORK"_s);
+ if (isFramework) {
+ const auto fwItems =
+ this->SplitFrameworkPath(cleanPath, isFramework);
+ if (!fwItems->first.empty() &&
+ emitted.insert(fwItems->first).second) {
+ // This is a search path we had not added before and it isn't
+ // an implicit search path, so we need it
+ libPaths.Add("-F " + this->XCodeEscapePath(fwItems->first));
}
- libPaths.Add("-framework " + this->XCodeEscapePath(fwName));
+ libPaths.Add(
+ libName.GetFormattedItem(this->XCodeEscapePath(fwItems->second))
+ .Value);
} else {
- libPaths.Add(this->XCodeEscapePath(cleanPath));
+ libPaths.Add(
+ libName.GetFormattedItem(this->XCodeEscapePath(cleanPath))
+ .Value);
}
if ((!libName.Target || libName.Target->IsImported()) &&
- IsLinkPhaseLibraryExtension(libPath)) {
+ (isFramework || IsLinkPhaseLibraryExtension(cleanPath))) {
// Create file reference for embedding
auto it = this->ExternalLibRefs.find(cleanPath);
if (it == this->ExternalLibRefs.end()) {
@@ -3912,8 +3989,8 @@ void cmGlobalXCodeGenerator::AddEmbeddedFrameworks(cmXCodeObject* target)
{
static const auto dstSubfolderSpec = "10";
- // Despite the name, by default Xcode uses "Embed Frameworks" build phase for
- // both frameworks and dynamic libraries
+ // Despite the name, by default Xcode uses "Embed Frameworks" build phase
+ // for both frameworks and dynamic libraries
this->AddEmbeddedObjects(target, "Embed Frameworks",
"XCODE_EMBED_FRAMEWORKS", dstSubfolderSpec,
NoActionOnCopyByDefault);
@@ -4258,6 +4335,8 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects(
}
for (auto& config : configs) {
+ CreateGlobalXCConfigSettings(root, config.second, config.first);
+
cmXCodeObject* buildSettingsForCfg = this->CreateFlatClone(buildSettings);
// Put this last so it can override existing settings
@@ -4711,10 +4790,12 @@ std::string cmGlobalXCodeGenerator::ConvertToRelativeForMake(
std::string cmGlobalXCodeGenerator::RelativeToSource(const std::string& p)
{
- // We force conversion because Xcode breakpoints do not work unless
- // they are in a file named relative to the source tree.
- return cmSystemTools::ForceToRelativePath(
- this->CurrentRootGenerator->GetCurrentSourceDirectory(), p);
+ std::string const& rootSrc =
+ this->CurrentRootGenerator->GetCurrentSourceDirectory();
+ if (cmSystemTools::IsSubDirectory(p, rootSrc)) {
+ return cmSystemTools::ForceToRelativePath(rootSrc, p);
+ }
+ return p;
}
std::string cmGlobalXCodeGenerator::RelativeToBinary(const std::string& p)
@@ -4857,9 +4938,11 @@ bool cmGlobalXCodeGenerator::IsMultiConfig() const
}
bool cmGlobalXCodeGenerator::HasKnownObjectFileLocation(
- std::string* reason) const
+ cmTarget const& target, std::string* reason) const
{
- if (this->ObjectDirArch.find('$') != std::string::npos) {
+ auto objectDirArch = GetTargetObjectDirArch(target, this->ObjectDirArch);
+
+ if (objectDirArch.find('$') != std::string::npos) {
if (reason != nullptr) {
*reason = " under Xcode with multiple architectures";
}
@@ -4890,10 +4973,12 @@ void cmGlobalXCodeGenerator::ComputeTargetObjectDirectory(
cmGeneratorTarget* gt) const
{
std::string configName = this->GetCMakeCFGIntDir();
+ auto objectDirArch = GetTargetObjectDirArch(*gt, this->ObjectDirArch);
+
std::string dir =
cmStrCat(this->GetObjectsDirectory("$(PROJECT_NAME)", configName, gt,
"$(OBJECT_FILE_DIR_normal:base)/"),
- this->ObjectDirArch, '/');
+ objectDirArch, '/');
gt->ObjectDirectory = dir;
}
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index ff6ffe8..92e4528 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -107,7 +107,8 @@ public:
bool IsXcode() const override { return true; }
- bool HasKnownObjectFileLocation(std::string* reason) const override;
+ bool HasKnownObjectFileLocation(cmTarget const&,
+ std::string* reason) const override;
bool IsIPOSupported() const override { return true; }
@@ -224,6 +225,12 @@ private:
void AddPositionIndependentLinkAttribute(cmGeneratorTarget* target,
cmXCodeObject* buildSettings,
const std::string& configName);
+ void CreateGlobalXCConfigSettings(cmLocalGenerator* root,
+ cmXCodeObject* config,
+ const std::string& configName);
+ void CreateTargetXCConfigSettings(cmGeneratorTarget* target,
+ cmXCodeObject* config,
+ const std::string& configName);
void CreateBuildSettings(cmGeneratorTarget* gtgt,
cmXCodeObject* buildSettings,
const std::string& buildType);
@@ -330,6 +337,8 @@ private:
{
}
+ std::string GetLibraryOrFrameworkPath(const std::string& path) const;
+
std::string GetObjectsDirectory(const std::string& projName,
const std::string& configName,
const cmGeneratorTarget* t,
diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx
index 55f6453..9cd1943 100644
--- a/Source/cmIfCommand.cxx
+++ b/Source/cmIfCommand.cxx
@@ -73,11 +73,11 @@ bool cmIfFunctionBlocker::Replay(std::vector<cmListFileFunction> functions,
}
// watch for our state change
if (scopeDepth == 0 && func.LowerCaseName() == "else") {
+ cmListFileBacktrace elseBT = mf.GetBacktrace().Push(
+ cmListFileContext{ func.OriginalName(),
+ this->GetStartingContext().FilePath, func.Line() });
if (this->ElseSeen) {
- cmListFileBacktrace elseBT = mf.GetBacktrace().Push(cmListFileContext{
- func.OriginalName(), this->GetStartingContext().FilePath,
- func.Line() });
mf.GetCMakeInstance()->IssueMessage(
MessageType::FATAL_ERROR,
"A duplicate ELSE command was found inside an IF block.", elseBT);
@@ -92,7 +92,8 @@ bool cmIfFunctionBlocker::Replay(std::vector<cmListFileFunction> functions,
// if trace is enabled, print a (trivially) evaluated "else"
// statement
if (!this->IsBlocking && mf.GetCMakeInstance()->GetTrace()) {
- mf.PrintCommandTrace(func);
+ mf.PrintCommandTrace(func, elseBT,
+ cmMakefile::CommandMissingFromStack::Yes);
}
} else if (scopeDepth == 0 && func.LowerCaseName() == "elseif") {
cmListFileBacktrace elseifBT = mf.GetBacktrace().Push(
@@ -111,7 +112,8 @@ bool cmIfFunctionBlocker::Replay(std::vector<cmListFileFunction> functions,
} else {
// if trace is enabled, print the evaluated "elseif" statement
if (mf.GetCMakeInstance()->GetTrace()) {
- mf.PrintCommandTrace(func);
+ mf.PrintCommandTrace(func, elseifBT,
+ cmMakefile::CommandMissingFromStack::Yes);
}
std::string errorString;
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index bb08215..7ca5b23 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -35,7 +35,6 @@
#include "cmInstallRuntimeDependencySetGenerator.h"
#include "cmInstallScriptGenerator.h"
#include "cmInstallTargetGenerator.h"
-#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
@@ -49,6 +48,8 @@
#include "cmTargetExport.h"
#include "cmValue.h"
+class cmListFileBacktrace;
+
namespace {
struct RuntimeDependenciesArgs
@@ -918,8 +919,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
if (!objectArgs.GetDestination().empty()) {
// Verify that we know where the objects are to install them.
std::string reason;
- if (!helper.Makefile->GetGlobalGenerator()
- ->HasKnownObjectFileLocation(&reason)) {
+ if (!target.HasKnownObjectFileLocation(&reason)) {
status.SetError(
cmStrCat("TARGETS given OBJECT library \"", target.GetName(),
"\" whose objects may not be installed", reason, "."));
diff --git a/Source/cmInstallDirectoryGenerator.cxx b/Source/cmInstallDirectoryGenerator.cxx
index 86362e4..8462b99 100644
--- a/Source/cmInstallDirectoryGenerator.cxx
+++ b/Source/cmInstallDirectoryGenerator.cxx
@@ -6,6 +6,7 @@
#include "cmGeneratorExpression.h"
#include "cmInstallType.h"
+#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
diff --git a/Source/cmInstallDirectoryGenerator.h b/Source/cmInstallDirectoryGenerator.h
index 0f91a59..419fd8c 100644
--- a/Source/cmInstallDirectoryGenerator.h
+++ b/Source/cmInstallDirectoryGenerator.h
@@ -9,9 +9,9 @@
#include <vector>
#include "cmInstallGenerator.h"
-#include "cmListFileCache.h"
#include "cmScriptGenerator.h"
+class cmListFileBacktrace;
class cmLocalGenerator;
/** \class cmInstallDirectoryGenerator
diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx
index 820f24a..f1ac656 100644
--- a/Source/cmInstallExportGenerator.cxx
+++ b/Source/cmInstallExportGenerator.cxx
@@ -2,7 +2,6 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmInstallExportGenerator.h"
-#include <algorithm>
#include <map>
#include <sstream>
#include <utility>
@@ -15,6 +14,7 @@
#include "cmExportInstallFileGenerator.h"
#include "cmExportSet.h"
#include "cmInstallType.h"
+#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -53,73 +53,36 @@ bool cmInstallExportGenerator::Compute(cmLocalGenerator* lg)
return true;
}
-void cmInstallExportGenerator::ComputeTempDir()
+std::string cmInstallExportGenerator::TempDirCalculate() const
{
// Choose a temporary directory in which to generate the import
// files to be installed.
- this->TempDir = cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(),
- "/CMakeFiles/Export");
+ std::string path = cmStrCat(
+ this->LocalGenerator->GetCurrentBinaryDirectory(), "/CMakeFiles/Export");
if (this->Destination.empty()) {
- return;
- }
- this->TempDir += "/";
-
- // Enforce a maximum length.
- bool useMD5 = false;
-#if defined(_WIN32) || defined(__CYGWIN__)
- std::string::size_type const max_total_len = 250;
-#else
- std::string::size_type const max_total_len = 1000;
-#endif
- // Will generate files of the form "<temp-dir>/<base>-<config>.<ext>".
- std::string::size_type const len = this->TempDir.size() + 1 +
- this->FileName.size() + 1 + this->GetMaxConfigLength();
- if (len < max_total_len) {
- // Keep the total path length below the limit.
- std::string::size_type const max_len = max_total_len - len;
- if (this->Destination.size() > max_len) {
- useMD5 = true;
- }
- } else {
- useMD5 = true;
+ return path;
}
- if (useMD5) {
- // Replace the destination path with a hash to keep it short.
+
#ifndef CMAKE_BOOTSTRAP
- this->TempDir += cmSystemTools::ComputeStringMD5(this->Destination);
+ path += '/';
+ // Replace the destination path with a hash to keep it short.
+ path += cmSystemTools::ComputeStringMD5(this->Destination);
#endif
- } else {
- std::string dest = this->Destination;
- // Avoid unix full paths.
- if (dest[0] == '/') {
- dest[0] = '_';
- }
- // Avoid windows full paths by removing colons.
- std::replace(dest.begin(), dest.end(), ':', '_');
- // Avoid relative paths that go up the tree.
- cmSystemTools::ReplaceString(dest, "../", "__/");
- // Avoid spaces.
- std::replace(dest.begin(), dest.end(), ' ', '_');
- this->TempDir += dest;
- }
+
+ return path;
}
-size_t cmInstallExportGenerator::GetMaxConfigLength() const
+void cmInstallExportGenerator::ComputeTempDir()
{
- // Always use at least 8 for "noconfig".
- size_t len = 8;
- if (this->ConfigurationTypes->empty()) {
- if (this->ConfigurationName.size() > 8) {
- len = this->ConfigurationName.size();
- }
- } else {
- for (std::string const& c : *this->ConfigurationTypes) {
- if (c.size() > len) {
- len = c.size();
- }
- }
+ this->TempDir = this->TempDirCalculate();
+}
+
+std::string cmInstallExportGenerator::GetTempDir() const
+{
+ if (this->TempDir.empty()) {
+ return this->TempDirCalculate();
}
- return len;
+ return this->TempDir;
}
void cmInstallExportGenerator::GenerateScript(std::ostream& os)
@@ -194,18 +157,22 @@ void cmInstallExportGenerator::GenerateScriptActions(std::ostream& os,
Indent indentNN = indentN.Next();
Indent indentNNN = indentNN.Next();
/* clang-format off */
- os << indentN << "file(DIFFERENT EXPORT_FILE_CHANGED FILES\n"
+ os << indentN << "file(DIFFERENT _cmake_export_file_changed FILES\n"
<< indentN << " \"" << installedFile << "\"\n"
<< indentN << " \"" << this->MainImportFile << "\")\n";
- os << indentN << "if(EXPORT_FILE_CHANGED)\n";
- os << indentNN << "file(GLOB OLD_CONFIG_FILES \"" << installedDir
+ os << indentN << "if(_cmake_export_file_changed)\n";
+ os << indentNN << "file(GLOB _cmake_old_config_files \"" << installedDir
<< this->EFGen->GetConfigImportFileGlob() << "\")\n";
- os << indentNN << "if(OLD_CONFIG_FILES)\n";
+ os << indentNN << "if(_cmake_old_config_files)\n";
+ os << indentNNN << "string(REPLACE \";\" \", \" _cmake_old_config_files_text \"${_cmake_old_config_files}\")\n";
os << indentNNN << R"(message(STATUS "Old export file \")" << installedFile
- << "\\\" will be replaced. Removing files [${OLD_CONFIG_FILES}].\")\n";
- os << indentNNN << "file(REMOVE ${OLD_CONFIG_FILES})\n";
+ << "\\\" will be replaced. Removing files [${_cmake_old_config_files_text}].\")\n";
+ os << indentNNN << "unset(_cmake_old_config_files_text)\n";
+ os << indentNNN << "file(REMOVE ${_cmake_old_config_files})\n";
os << indentNN << "endif()\n";
+ os << indentNN << "unset(_cmake_old_config_files)\n";
os << indentN << "endif()\n";
+ os << indentN << "unset(_cmake_export_file_changed)\n";
os << indent << "endif()\n";
/* clang-format on */
diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h
index efeae86..dc07d36 100644
--- a/Source/cmInstallExportGenerator.h
+++ b/Source/cmInstallExportGenerator.h
@@ -4,18 +4,17 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <cstddef>
#include <iosfwd>
#include <memory>
#include <string>
#include <vector>
#include "cmInstallGenerator.h"
-#include "cmListFileCache.h"
#include "cmScriptGenerator.h"
class cmExportInstallFileGenerator;
class cmExportSet;
+class cmListFileBacktrace;
class cmLocalGenerator;
/** \class cmInstallExportGenerator
@@ -50,6 +49,7 @@ public:
std::string const& GetDestination() const { return this->Destination; }
std::string GetDestinationFile() const;
std::string GetFileName() const { return this->FileName; }
+ std::string GetTempDir() const;
protected:
void GenerateScript(std::ostream& os) override;
@@ -57,8 +57,8 @@ protected:
void GenerateScriptActions(std::ostream& os, Indent indent) override;
void GenerateImportFile(cmExportSet const* exportSet);
void GenerateImportFile(const char* config, cmExportSet const* exportSet);
+ std::string TempDirCalculate() const;
void ComputeTempDir();
- size_t GetMaxConfigLength() const;
cmExportSet* const ExportSet;
std::string const FilePermissions;
diff --git a/Source/cmInstallFileSetGenerator.cxx b/Source/cmInstallFileSetGenerator.cxx
index 7121ea3..8c37312 100644
--- a/Source/cmInstallFileSetGenerator.cxx
+++ b/Source/cmInstallFileSetGenerator.cxx
@@ -11,6 +11,7 @@
#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
#include "cmInstallType.h"
+#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmStringAlgorithms.h"
diff --git a/Source/cmInstallFileSetGenerator.h b/Source/cmInstallFileSetGenerator.h
index 8d067d9..56341d4 100644
--- a/Source/cmInstallFileSetGenerator.h
+++ b/Source/cmInstallFileSetGenerator.h
@@ -8,11 +8,11 @@
#include <vector>
#include "cmInstallGenerator.h"
-#include "cmListFileCache.h"
#include "cmScriptGenerator.h"
class cmGeneratorTarget;
class cmFileSet;
+class cmListFileBacktrace;
class cmLocalGenerator;
class cmInstallFileSetGenerator : public cmInstallGenerator
diff --git a/Source/cmInstallFilesGenerator.cxx b/Source/cmInstallFilesGenerator.cxx
index 04aaa29..378b9fc 100644
--- a/Source/cmInstallFilesGenerator.cxx
+++ b/Source/cmInstallFilesGenerator.cxx
@@ -6,6 +6,7 @@
#include "cmGeneratorExpression.h"
#include "cmInstallType.h"
+#include "cmListFileCache.h"
#include "cmStringAlgorithms.h"
class cmLocalGenerator;
diff --git a/Source/cmInstallFilesGenerator.h b/Source/cmInstallFilesGenerator.h
index af7f113..2276ab8 100644
--- a/Source/cmInstallFilesGenerator.h
+++ b/Source/cmInstallFilesGenerator.h
@@ -9,9 +9,9 @@
#include <vector>
#include "cmInstallGenerator.h"
-#include "cmListFileCache.h"
#include "cmScriptGenerator.h"
+class cmListFileBacktrace;
class cmLocalGenerator;
/** \class cmInstallFilesGenerator
diff --git a/Source/cmInstallGenerator.cxx b/Source/cmInstallGenerator.cxx
index 4cfeb47..93abd45 100644
--- a/Source/cmInstallGenerator.cxx
+++ b/Source/cmInstallGenerator.cxx
@@ -41,10 +41,10 @@ void cmInstallGenerator::CheckCMP0082(bool& haveSubdirectoryInstall,
void cmInstallGenerator::AddInstallRule(
std::ostream& os, std::string const& dest, cmInstallType type,
std::vector<std::string> const& files, bool optional /* = false */,
- const char* permissions_file /* = 0 */,
- const char* permissions_dir /* = 0 */, const char* rename /* = 0 */,
- const char* literal_args /* = 0 */, Indent indent,
- const char* files_var /* = 0 */)
+ const char* permissions_file /* = nullptr */,
+ const char* permissions_dir /* = nullptr */,
+ const char* rename /* = nullptr */, const char* literal_args /* = nullptr */,
+ Indent indent, const char* files_var /* = nullptr */)
{
// Use the FILE command to install the file.
std::string stype;
@@ -91,21 +91,28 @@ void cmInstallGenerator::AddInstallRule(
os << "\")\n";
}
if (files_var) {
- os << indent << "foreach(_f IN LISTS " << files_var << ")\n";
- os << indent.Next() << "get_filename_component(_fn \"${_f}\" NAME)\n";
+ os << indent << "foreach(_cmake_abs_file IN LISTS " << files_var
+ << ")\n";
+ os << indent.Next()
+ << "get_filename_component(_cmake_abs_file_name "
+ "\"${_cmake_abs_file}\" NAME)\n";
os << indent.Next() << "list(APPEND CMAKE_ABSOLUTE_DESTINATION_FILES \""
- << dest << "/${_fn}\")\n";
+ << dest << "/${_cmake_abs_file_name}\")\n";
os << indent << "endforeach()\n";
+ os << indent << "unset(_cmake_abs_file_name)\n";
+ os << indent << "unset(_cmake_abs_file)\n";
}
os << indent << "if(CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION)\n";
- os << indent.Next() << "message(WARNING \"ABSOLUTE path INSTALL "
- << "DESTINATION : ${CMAKE_ABSOLUTE_DESTINATION_FILES}\")\n";
+ os << indent.Next()
+ << "message(WARNING \"ABSOLUTE path INSTALL "
+ "DESTINATION : ${CMAKE_ABSOLUTE_DESTINATION_FILES}\")\n";
os << indent << "endif()\n";
os << indent << "if(CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION)\n";
- os << indent.Next() << "message(FATAL_ERROR \"ABSOLUTE path INSTALL "
- << "DESTINATION forbidden (by caller): "
- << "${CMAKE_ABSOLUTE_DESTINATION_FILES}\")\n";
+ os << indent.Next()
+ << "message(FATAL_ERROR \"ABSOLUTE path INSTALL "
+ "DESTINATION forbidden (by caller): "
+ "${CMAKE_ABSOLUTE_DESTINATION_FILES}\")\n";
os << indent << "endif()\n";
}
std::string absDest = ConvertToAbsoluteDestination(dest);
@@ -158,14 +165,22 @@ void cmInstallGenerator::AddInstallRule(
}
std::string cmInstallGenerator::CreateComponentTest(
- const std::string& component, bool exclude_from_all)
+ const std::string& component, bool exclude_from_all, bool all_components)
{
- std::string result = R"("x${CMAKE_INSTALL_COMPONENT}x" STREQUAL "x)";
+ if (all_components) {
+ if (exclude_from_all) {
+ return "CMAKE_INSTALL_COMPONENT";
+ }
+ return {};
+ }
+
+ std::string result = "CMAKE_INSTALL_COMPONENT STREQUAL \"";
result += component;
- result += "x\"";
+ result += "\"";
if (!exclude_from_all) {
result += " OR NOT CMAKE_INSTALL_COMPONENT";
}
+
return result;
}
@@ -174,10 +189,11 @@ void cmInstallGenerator::GenerateScript(std::ostream& os)
// Track indentation.
Indent indent;
+ std::string component_test = this->CreateComponentTest(
+ this->Component, this->ExcludeFromAll, this->AllComponents);
+
// Begin this block of installation.
- if (!this->AllComponents) {
- std::string component_test =
- this->CreateComponentTest(this->Component, this->ExcludeFromAll);
+ if (!component_test.empty()) {
os << indent << "if(" << component_test << ")\n";
}
@@ -186,7 +202,7 @@ void cmInstallGenerator::GenerateScript(std::ostream& os)
this->AllComponents ? indent : indent.Next());
// End this block of installation.
- if (!this->AllComponents) {
+ if (!component_test.empty()) {
os << indent << "endif()\n\n";
}
}
diff --git a/Source/cmInstallGenerator.h b/Source/cmInstallGenerator.h
index d342c99..9fcd284 100644
--- a/Source/cmInstallGenerator.h
+++ b/Source/cmInstallGenerator.h
@@ -78,7 +78,8 @@ protected:
void GenerateScript(std::ostream& os) override;
std::string CreateComponentTest(const std::string& component,
- bool exclude_from_all);
+ bool exclude_from_all,
+ bool all_components = false);
using TweakMethod =
std::function<void(std::ostream& os, Indent indent,
diff --git a/Source/cmInstallGetRuntimeDependenciesGenerator.cxx b/Source/cmInstallGetRuntimeDependenciesGenerator.cxx
index 4d585ce..3e493bc 100644
--- a/Source/cmInstallGetRuntimeDependenciesGenerator.cxx
+++ b/Source/cmInstallGetRuntimeDependenciesGenerator.cxx
@@ -15,6 +15,7 @@
#include "cmGeneratorExpression.h"
#include "cmInstallRuntimeDependencySet.h"
+#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmOutputConverter.h"
diff --git a/Source/cmInstallGetRuntimeDependenciesGenerator.h b/Source/cmInstallGetRuntimeDependenciesGenerator.h
index 19f6cc6..a2d6593 100644
--- a/Source/cmInstallGetRuntimeDependenciesGenerator.h
+++ b/Source/cmInstallGetRuntimeDependenciesGenerator.h
@@ -7,9 +7,9 @@
#include <vector>
#include "cmInstallGenerator.h"
-#include "cmListFileCache.h"
#include "cmScriptGenerator.h"
+class cmListFileBacktrace;
class cmLocalGenerator;
class cmInstallRuntimeDependencySet;
diff --git a/Source/cmInstallRuntimeDependencySetGenerator.h b/Source/cmInstallRuntimeDependencySetGenerator.h
index 8e98b57..680361b 100644
--- a/Source/cmInstallRuntimeDependencySetGenerator.h
+++ b/Source/cmInstallRuntimeDependencySetGenerator.h
@@ -7,10 +7,10 @@
#include <vector>
#include "cmInstallGenerator.h"
-#include "cmListFileCache.h"
#include "cmScriptGenerator.h"
class cmInstallRuntimeDependencySet;
+class cmListFileBacktrace;
class cmLocalGenerator;
class cmInstallRuntimeDependencySetGenerator : public cmInstallGenerator
diff --git a/Source/cmInstallSubdirectoryGenerator.cxx b/Source/cmInstallSubdirectoryGenerator.cxx
index 0a8e065..dd71332 100644
--- a/Source/cmInstallSubdirectoryGenerator.cxx
+++ b/Source/cmInstallSubdirectoryGenerator.cxx
@@ -7,6 +7,7 @@
#include <utility>
#include <vector>
+#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmPolicies.h"
diff --git a/Source/cmInstallSubdirectoryGenerator.h b/Source/cmInstallSubdirectoryGenerator.h
index f174d07..7a472ed 100644
--- a/Source/cmInstallSubdirectoryGenerator.h
+++ b/Source/cmInstallSubdirectoryGenerator.h
@@ -8,8 +8,8 @@
#include <string>
#include "cmInstallGenerator.h"
-#include "cmListFileCache.h"
+class cmListFileBacktrace;
class cmLocalGenerator;
class cmMakefile;
diff --git a/Source/cmJSONHelpers.h b/Source/cmJSONHelpers.h
index 6690aef..48decbc 100644
--- a/Source/cmJSONHelpers.h
+++ b/Source/cmJSONHelpers.h
@@ -14,146 +14,126 @@
#include <cm3p/json/value.h>
-template <typename T, typename E>
-using cmJSONHelper = std::function<E(T& out, const Json::Value* value)>;
+template <typename T, typename E, typename... CallState>
+using cmJSONHelper =
+ std::function<E(T& out, const Json::Value* value, CallState&&... state)>;
-template <typename T, typename E>
-class cmJSONObjectHelper
+template <typename E, typename... CallState>
+struct cmJSONHelperBuilder
{
-public:
- cmJSONObjectHelper(E&& success, E&& fail, bool allowExtra = true);
-
- template <typename U, typename M, typename F>
- cmJSONObjectHelper& Bind(const cm::string_view& name, M U::*member, F func,
- bool required = true);
- template <typename M, typename F>
- cmJSONObjectHelper& Bind(const cm::string_view& name, std::nullptr_t, F func,
- bool required = true);
- template <typename F>
- cmJSONObjectHelper& Bind(const cm::string_view& name, F func,
- bool required = true);
-
- E operator()(T& out, const Json::Value* value) const;
-
-private:
- // Not a true cmJSONHelper, it just happens to match the signature
- using MemberFunction = std::function<E(T& out, const Json::Value* value)>;
- struct Member
+ template <typename T>
+ class Object
{
- cm::string_view Name;
- MemberFunction Function;
- bool Required;
- };
- std::vector<Member> Members;
- bool AnyRequired = false;
- E Success;
- E Fail;
- bool AllowExtra;
-
- cmJSONObjectHelper& BindPrivate(const cm::string_view& name,
- MemberFunction&& func, bool required);
-};
-
-template <typename T, typename E>
-cmJSONObjectHelper<T, E>::cmJSONObjectHelper(E&& success, E&& fail,
- bool allowExtra)
- : Success(std::move(success))
- , Fail(std::move(fail))
- , AllowExtra(allowExtra)
-{
-}
+ public:
+ Object(E&& success, E&& fail, bool allowExtra = true)
+ : Success(std::move(success))
+ , Fail(std::move(fail))
+ , AllowExtra(allowExtra)
+ {
+ }
-template <typename T, typename E>
-template <typename U, typename M, typename F>
-cmJSONObjectHelper<T, E>& cmJSONObjectHelper<T, E>::Bind(
- const cm::string_view& name, M U::*member, F func, bool required)
-{
- return this->BindPrivate(
- name,
- [func, member](T& out, const Json::Value* value) -> E {
- return func(out.*member, value);
- },
- required);
-}
+ template <typename U, typename M, typename F>
+ Object& Bind(const cm::string_view& name, M U::*member, F func,
+ bool required = true)
+ {
+ return this->BindPrivate(name,
+ [func, member](T& out, const Json::Value* value,
+ CallState&&... state) -> E {
+ return func(out.*member, value,
+ std::forward(state)...);
+ },
+ required);
+ }
+ template <typename M, typename F>
+ Object& Bind(const cm::string_view& name, std::nullptr_t, F func,
+ bool required = true)
+ {
+ return this->BindPrivate(name,
+ [func](T& /*out*/, const Json::Value* value,
+ CallState&&... state) -> E {
+ M dummy;
+ return func(dummy, value,
+ std::forward(state)...);
+ },
+ required);
+ }
+ template <typename F>
+ Object& Bind(const cm::string_view& name, F func, bool required = true)
+ {
+ return this->BindPrivate(name, MemberFunction(func), required);
+ }
-template <typename T, typename E>
-template <typename M, typename F>
-cmJSONObjectHelper<T, E>& cmJSONObjectHelper<T, E>::Bind(
- const cm::string_view& name, std::nullptr_t, F func, bool required)
-{
- return this->BindPrivate(name,
- [func](T& /*out*/, const Json::Value* value) -> E {
- M dummy;
- return func(dummy, value);
- },
- required);
-}
+ E operator()(T& out, const Json::Value* value, CallState&&... state) const
+ {
+ if (!value && this->AnyRequired) {
+ return this->Fail;
+ }
+ if (value && !value->isObject()) {
+ return this->Fail;
+ }
+ Json::Value::Members extraFields;
+ if (value) {
+ extraFields = value->getMemberNames();
+ }
-template <typename T, typename E>
-template <typename F>
-cmJSONObjectHelper<T, E>& cmJSONObjectHelper<T, E>::Bind(
- const cm::string_view& name, F func, bool required)
-{
- return this->BindPrivate(name, MemberFunction(func), required);
-}
+ for (auto const& m : this->Members) {
+ std::string name(m.Name.data(), m.Name.size());
+ if (value && value->isMember(name)) {
+ E result = m.Function(out, &(*value)[name], std::forward(state)...);
+ if (result != this->Success) {
+ return result;
+ }
+ extraFields.erase(
+ std::find(extraFields.begin(), extraFields.end(), name));
+ } else if (!m.Required) {
+ E result = m.Function(out, nullptr, std::forward(state)...);
+ if (result != this->Success) {
+ return result;
+ }
+ } else {
+ return this->Fail;
+ }
+ }
-template <typename T, typename E>
-cmJSONObjectHelper<T, E>& cmJSONObjectHelper<T, E>::BindPrivate(
- const cm::string_view& name, MemberFunction&& func, bool required)
-{
- Member m;
- m.Name = name;
- m.Function = std::move(func);
- m.Required = required;
- this->Members.push_back(std::move(m));
- if (required) {
- this->AnyRequired = true;
- }
- return *this;
-}
+ return this->AllowExtra || extraFields.empty() ? this->Success
+ : this->Fail;
+ }
-template <typename T, typename E>
-E cmJSONObjectHelper<T, E>::operator()(T& out, const Json::Value* value) const
-{
- if (!value && this->AnyRequired) {
- return this->Fail;
- }
- if (value && !value->isObject()) {
- return this->Fail;
- }
- Json::Value::Members extraFields;
- if (value) {
- extraFields = value->getMemberNames();
- }
+ private:
+ // Not a true cmJSONHelper, it just happens to match the signature
+ using MemberFunction =
+ std::function<E(T& out, const Json::Value* value, CallState&&... state)>;
+ struct Member
+ {
+ cm::string_view Name;
+ MemberFunction Function;
+ bool Required;
+ };
+ std::vector<Member> Members;
+ bool AnyRequired = false;
+ E Success;
+ E Fail;
+ bool AllowExtra;
- for (auto const& m : this->Members) {
- std::string name(m.Name.data(), m.Name.size());
- if (value && value->isMember(name)) {
- E result = m.Function(out, &(*value)[name]);
- if (result != this->Success) {
- return result;
- }
- extraFields.erase(
- std::find(extraFields.begin(), extraFields.end(), name));
- } else if (!m.Required) {
- E result = m.Function(out, nullptr);
- if (result != this->Success) {
- return result;
+ Object& BindPrivate(const cm::string_view& name, MemberFunction&& func,
+ bool required)
+ {
+ Member m;
+ m.Name = name;
+ m.Function = std::move(func);
+ m.Required = required;
+ this->Members.push_back(std::move(m));
+ if (required) {
+ this->AnyRequired = true;
}
- } else {
- return this->Fail;
+ return *this;
}
- }
-
- return this->AllowExtra || extraFields.empty() ? this->Success : this->Fail;
-}
-
-template <typename E>
-cmJSONHelper<std::string, E> cmJSONStringHelper(E success, E fail,
- const std::string& defval = "")
-{
- return
- [success, fail, defval](std::string& out, const Json::Value* value) -> E {
+ };
+ static cmJSONHelper<std::string, E, CallState...> String(
+ E success, E fail, const std::string& defval = "")
+ {
+ return [success, fail, defval](std::string& out, const Json::Value* value,
+ CallState&&... /*state*/) -> E {
if (!value) {
out = defval;
return success;
@@ -164,30 +144,30 @@ cmJSONHelper<std::string, E> cmJSONStringHelper(E success, E fail,
out = value->asString();
return success;
};
-}
+ }
-template <typename E>
-cmJSONHelper<int, E> cmJSONIntHelper(E success, E fail, int defval = 0)
-{
- return [success, fail, defval](int& out, const Json::Value* value) -> E {
- if (!value) {
- out = defval;
+ static cmJSONHelper<int, E, CallState...> Int(E success, E fail,
+ int defval = 0)
+ {
+ return [success, fail, defval](int& out, const Json::Value* value,
+ CallState&&... /*state*/) -> E {
+ if (!value) {
+ out = defval;
+ return success;
+ }
+ if (!value->isInt()) {
+ return fail;
+ }
+ out = value->asInt();
return success;
- }
- if (!value->isInt()) {
- return fail;
- }
- out = value->asInt();
- return success;
- };
-}
+ };
+ }
-template <typename E>
-cmJSONHelper<unsigned int, E> cmJSONUIntHelper(E success, E fail,
- unsigned int defval = 0)
-{
- return
- [success, fail, defval](unsigned int& out, const Json::Value* value) -> E {
+ static cmJSONHelper<unsigned int, E, CallState...> UInt(
+ E success, E fail, unsigned int defval = 0)
+ {
+ return [success, fail, defval](unsigned int& out, const Json::Value* value,
+ CallState&&... /*state*/) -> E {
if (!value) {
out = defval;
return success;
@@ -198,118 +178,126 @@ cmJSONHelper<unsigned int, E> cmJSONUIntHelper(E success, E fail,
out = value->asUInt();
return success;
};
-}
+ }
-template <typename E>
-cmJSONHelper<bool, E> cmJSONBoolHelper(E success, E fail, bool defval = false)
-{
- return [success, fail, defval](bool& out, const Json::Value* value) -> E {
- if (!value) {
- out = defval;
+ static cmJSONHelper<bool, E, CallState...> Bool(E success, E fail,
+ bool defval = false)
+ {
+ return [success, fail, defval](bool& out, const Json::Value* value,
+ CallState&&... /*state*/) -> E {
+ if (!value) {
+ out = defval;
+ return success;
+ }
+ if (!value->isBool()) {
+ return fail;
+ }
+ out = value->asBool();
return success;
- }
- if (!value->isBool()) {
- return fail;
- }
- out = value->asBool();
- return success;
- };
-}
+ };
+ }
-template <typename T, typename E, typename F, typename Filter>
-cmJSONHelper<std::vector<T>, E> cmJSONVectorFilterHelper(E success, E fail,
- F func, Filter filter)
-{
- return [success, fail, func, filter](std::vector<T>& out,
- const Json::Value* value) -> E {
- if (!value) {
- out.clear();
- return success;
- }
- if (!value->isArray()) {
- return fail;
- }
- out.clear();
- for (auto const& item : *value) {
- T t;
- E result = func(t, &item);
- if (result != success) {
- return result;
+ template <typename T, typename F, typename Filter>
+ static cmJSONHelper<std::vector<T>, E, CallState...> VectorFilter(
+ E success, E fail, F func, Filter filter)
+ {
+ return [success, fail, func, filter](std::vector<T>& out,
+ const Json::Value* value,
+ CallState&&... state) -> E {
+ if (!value) {
+ out.clear();
+ return success;
}
- if (!filter(t)) {
- continue;
+ if (!value->isArray()) {
+ return fail;
}
- out.push_back(std::move(t));
- }
- return success;
- };
-}
-
-template <typename T, typename E, typename F>
-cmJSONHelper<std::vector<T>, E> cmJSONVectorHelper(E success, E fail, F func)
-{
- return cmJSONVectorFilterHelper<T, E, F>(success, fail, func,
- [](const T&) { return true; });
-}
-
-template <typename T, typename E, typename F, typename Filter>
-cmJSONHelper<std::map<std::string, T>, E> cmJSONMapFilterHelper(E success,
- E fail, F func,
- Filter filter)
-{
- return [success, fail, func, filter](std::map<std::string, T>& out,
- const Json::Value* value) -> E {
- if (!value) {
out.clear();
+ for (auto const& item : *value) {
+ T t;
+ E result = func(t, &item, std::forward(state)...);
+ if (result != success) {
+ return result;
+ }
+ if (!filter(t)) {
+ continue;
+ }
+ out.push_back(std::move(t));
+ }
return success;
- }
- if (!value->isObject()) {
- return fail;
- }
- out.clear();
- for (auto const& key : value->getMemberNames()) {
- if (!filter(key)) {
- continue;
+ };
+ }
+
+ template <typename T, typename F>
+ static cmJSONHelper<std::vector<T>, E, CallState...> Vector(E success,
+ E fail, F func)
+ {
+ return VectorFilter<T, F>(success, fail, func,
+ [](const T&) { return true; });
+ }
+
+ template <typename T, typename F, typename Filter>
+ static cmJSONHelper<std::map<std::string, T>, E, CallState...> MapFilter(
+ E success, E fail, F func, Filter filter)
+ {
+ return [success, fail, func, filter](std::map<std::string, T>& out,
+ const Json::Value* value,
+ CallState&&... state) -> E {
+ if (!value) {
+ out.clear();
+ return success;
}
- T t;
- E result = func(t, &(*value)[key]);
- if (result != success) {
- return result;
+ if (!value->isObject()) {
+ return fail;
}
- out[key] = std::move(t);
- }
- return success;
- };
-}
+ out.clear();
+ for (auto const& key : value->getMemberNames()) {
+ if (!filter(key)) {
+ continue;
+ }
+ T t;
+ E result = func(t, &(*value)[key], std::forward(state)...);
+ if (result != success) {
+ return result;
+ }
+ out[key] = std::move(t);
+ }
+ return success;
+ };
+ }
-template <typename T, typename E, typename F>
-cmJSONHelper<std::map<std::string, T>, E> cmJSONMapHelper(E success, E fail,
- F func)
-{
- return cmJSONMapFilterHelper<T, E, F>(
- success, fail, func, [](const std::string&) { return true; });
-}
+ template <typename T, typename F>
+ static cmJSONHelper<std::map<std::string, T>, E, CallState...> Map(E success,
+ E fail,
+ F func)
+ {
+ return MapFilter<T, F>(success, fail, func,
+ [](const std::string&) { return true; });
+ }
-template <typename T, typename E, typename F>
-cmJSONHelper<cm::optional<T>, E> cmJSONOptionalHelper(E success, F func)
-{
- return [success, func](cm::optional<T>& out, const Json::Value* value) -> E {
- if (!value) {
- out.reset();
- return success;
- }
- out.emplace();
- return func(*out, value);
- };
-}
+ template <typename T, typename F>
+ static cmJSONHelper<cm::optional<T>, E, CallState...> Optional(E success,
+ F func)
+ {
+ return [success, func](cm::optional<T>& out, const Json::Value* value,
+ CallState&&... state) -> E {
+ if (!value) {
+ out.reset();
+ return success;
+ }
+ out.emplace();
+ return func(*out, value, std::forward(state)...);
+ };
+ }
-template <typename T, typename E, typename F>
-cmJSONHelper<T, E> cmJSONRequiredHelper(E fail, F func)
-{
- return [fail, func](T& out, const Json::Value* value) -> E {
- if (!value) {
- return fail;
- }
- return func(out, value);
- };
-}
+ template <typename T, typename F>
+ static cmJSONHelper<T, E, CallState...> Required(E fail, F func)
+ {
+ return [fail, func](T& out, const Json::Value* value,
+ CallState&&... state) -> E {
+ if (!value) {
+ return fail;
+ }
+ return func(out, value, std::forward(state)...);
+ };
+ }
+};
diff --git a/Source/cmLinkItem.h b/Source/cmLinkItem.h
index e715659..262728b 100644
--- a/Source/cmLinkItem.h
+++ b/Source/cmLinkItem.h
@@ -70,6 +70,12 @@ struct cmLinkInterfaceLibraries
// Object files listed in the interface.
std::vector<cmLinkItem> Objects;
+ // Items to be included as if directly linked by the head target.
+ std::vector<cmLinkItem> HeadInclude;
+
+ // Items to be excluded from direct linking by the head target.
+ std::vector<cmLinkItem> HeadExclude;
+
// Whether the list depends on a genex referencing the head target.
bool HadHeadSensitiveCondition = false;
diff --git a/Source/cmLinkItemGraphVisitor.cxx b/Source/cmLinkItemGraphVisitor.cxx
index d87d183..0ad846b 100644
--- a/Source/cmLinkItemGraphVisitor.cxx
+++ b/Source/cmLinkItemGraphVisitor.cxx
@@ -98,8 +98,8 @@ void cmLinkItemGraphVisitor::GetDependencies(cmGeneratorTarget const& target,
std::string const& config,
DependencyMap& dependencies)
{
- const auto* implementationLibraries =
- target.GetLinkImplementationLibraries(config);
+ const auto* implementationLibraries = target.GetLinkImplementationLibraries(
+ config, cmGeneratorTarget::LinkInterfaceFor::Link);
if (implementationLibraries != nullptr) {
for (auto const& lib : implementationLibraries->Libraries) {
auto const& name = lib.AsStr();
diff --git a/Source/cmLinkLibrariesCommand.cxx b/Source/cmLinkLibrariesCommand.cxx
index 2b8f836..ed89e91 100644
--- a/Source/cmLinkLibrariesCommand.cxx
+++ b/Source/cmLinkLibrariesCommand.cxx
@@ -35,5 +35,7 @@ bool cmLinkLibrariesCommand(std::vector<std::string> const& args,
mf.AppendProperty("LINK_LIBRARIES", *i);
}
+ mf.CheckProperty("LINK_LIBRARIES");
+
return true;
}
diff --git a/Source/cmLinkLineComputer.cxx b/Source/cmLinkLineComputer.cxx
index 5646368..290642b 100644
--- a/Source/cmLinkLineComputer.cxx
+++ b/Source/cmLinkLineComputer.cxx
@@ -75,14 +75,8 @@ void cmLinkLineComputer::ComputeLinkLibs(
BT<std::string> linkLib;
if (item.IsPath == cmComputeLinkInformation::ItemIsPath::Yes) {
- if (item.IsObject == cmComputeLinkInformation::ItemIsObject::Yes) {
- linkLib.Value += cli.GetObjLinkFileFlag();
- } else {
- linkLib.Value += cli.GetLibLinkFileFlag();
- }
- linkLib.Value += this->ConvertToOutputFormat(
- this->ConvertToLinkReference(item.Value.Value));
- linkLib.Backtrace = item.Value.Backtrace;
+ linkLib = item.GetFormattedItem(this->ConvertToOutputFormat(
+ this->ConvertToLinkReference(item.Value.Value)));
} else {
linkLib = item.Value;
}
diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx
index 43f161b..43f1b8e 100644
--- a/Source/cmLinkLineDeviceComputer.cxx
+++ b/Source/cmLinkLineDeviceComputer.cxx
@@ -118,8 +118,10 @@ void cmLinkLineDeviceComputer::ComputeLinkLibraries(
// can tolerate '.so' or '.dylib' it cannot tolerate '.so.1'.
if (cmHasLiteralSuffix(item.Value.Value, ".a") ||
cmHasLiteralSuffix(item.Value.Value, ".lib")) {
- linkLib.Value += this->ConvertToOutputFormat(
- this->ConvertToLinkReference(item.Value.Value));
+ linkLib.Value = item
+ .GetFormattedItem(this->ConvertToOutputFormat(
+ this->ConvertToLinkReference(item.Value.Value)))
+ .Value;
}
} else if (item.Value == "-framework") {
// This is the first part of '-framework Name' where the framework
@@ -127,14 +129,15 @@ void cmLinkLineDeviceComputer::ComputeLinkLibraries(
skipItemAfterFramework = true;
continue;
} else if (cmLinkItemValidForDevice(item.Value.Value)) {
- linkLib.Value += item.Value.Value;
+ linkLib.Value = item.Value.Value;
}
if (emitted.insert(linkLib.Value).second) {
linkLib.Value += " ";
const cmLinkImplementation* linkImpl =
- cli.GetTarget()->GetLinkImplementation(cli.GetConfig());
+ cli.GetTarget()->GetLinkImplementation(
+ cli.GetConfig(), cmGeneratorTarget::LinkInterfaceFor::Link);
for (const cmLinkImplItem& iter : linkImpl->Libraries) {
if (iter.Target != nullptr &&
diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx
index 3da266d..5133521 100644
--- a/Source/cmListFileCache.cxx
+++ b/Source/cmListFileCache.cxx
@@ -1,8 +1,8 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
+#define cmListFileCache_cxx
#include "cmListFileCache.h"
-#include <cassert>
#include <memory>
#include <sstream>
#include <utility>
@@ -40,6 +40,7 @@ struct cmListFileParser
cmListFileLexer* Lexer;
std::string FunctionName;
long FunctionLine;
+ long FunctionLineEnd;
std::vector<cmListFileArgument> FunctionArguments;
enum
{
@@ -146,7 +147,7 @@ bool cmListFileParser::Parse()
if (this->ParseFunction(token->text, token->line)) {
this->ListFile->Functions.emplace_back(
std::move(this->FunctionName), this->FunctionLine,
- std::move(this->FunctionArguments));
+ this->FunctionLineEnd, std::move(this->FunctionArguments));
} else {
return false;
}
@@ -259,6 +260,7 @@ bool cmListFileParser::ParseFunction(const char* name, long line)
}
} else if (token->type == cmListFileLexer_Token_ParenRight) {
if (parenDepth == 0) {
+ this->FunctionLineEnd = token->line;
return true;
}
parenDepth--;
@@ -443,64 +445,8 @@ cm::optional<cmListFileContext> cmListFileParser::CheckNesting() const
return cm::nullopt;
}
-// We hold a call/file context.
-struct cmListFileBacktrace::Entry
-{
- Entry(std::shared_ptr<Entry const> parent, cmListFileContext lfc)
- : Context(std::move(lfc))
- , Parent(std::move(parent))
- {
- }
-
- cmListFileContext Context;
- std::shared_ptr<Entry const> Parent;
-};
-
-/* NOLINTNEXTLINE(performance-unnecessary-value-param) */
-cmListFileBacktrace::cmListFileBacktrace(std::shared_ptr<Entry const> parent,
- cmListFileContext const& lfc)
- : TopEntry(std::make_shared<Entry const>(std::move(parent), lfc))
-{
-}
-
-cmListFileBacktrace::cmListFileBacktrace(std::shared_ptr<Entry const> top)
- : TopEntry(std::move(top))
-{
-}
-
-cmListFileBacktrace cmListFileBacktrace::Push(std::string const& file) const
-{
- // We are entering a file-level scope but have not yet reached
- // any specific line or command invocation within it. This context
- // is useful to print when it is at the top but otherwise can be
- // skipped during call stack printing.
- cmListFileContext lfc;
- lfc.FilePath = file;
- return this->Push(lfc);
-}
-
-cmListFileBacktrace cmListFileBacktrace::Push(
- cmListFileContext const& lfc) const
-{
- return cmListFileBacktrace(this->TopEntry, lfc);
-}
-
-cmListFileBacktrace cmListFileBacktrace::Pop() const
-{
- assert(this->TopEntry);
- return cmListFileBacktrace(this->TopEntry->Parent);
-}
-
-cmListFileContext const& cmListFileBacktrace::Top() const
-{
- assert(this->TopEntry);
- return this->TopEntry->Context;
-}
-
-bool cmListFileBacktrace::Empty() const
-{
- return !this->TopEntry;
-}
+#include "cmConstStack.tcc"
+template class cmConstStack<cmListFileContext, cmListFileBacktrace>;
std::ostream& operator<<(std::ostream& os, cmListFileContext const& lfc)
{
@@ -539,11 +485,11 @@ std::ostream& operator<<(std::ostream& os, BT<std::string> const& s)
return os << s.Value;
}
-std::vector<BT<std::string>> ExpandListWithBacktrace(
- std::string const& list, cmListFileBacktrace const& bt)
+std::vector<BT<std::string>> cmExpandListWithBacktrace(
+ std::string const& list, cmListFileBacktrace const& bt, bool emptyArgs)
{
std::vector<BT<std::string>> result;
- std::vector<std::string> tmp = cmExpandedList(list);
+ std::vector<std::string> tmp = cmExpandedList(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 5d45027..f7c2509 100644
--- a/Source/cmListFileCache.h
+++ b/Source/cmListFileCache.h
@@ -12,6 +12,7 @@
#include <cm/optional>
+#include "cmConstStack.h"
#include "cmSystemTools.h"
/** \class cmListFileCache
@@ -51,9 +52,9 @@ struct cmListFileArgument
class cmListFileFunction
{
public:
- cmListFileFunction(std::string name, long line,
+ cmListFileFunction(std::string name, long line, long lineEnd,
std::vector<cmListFileArgument> args)
- : Impl{ std::make_shared<Implementation>(std::move(name), line,
+ : Impl{ std::make_shared<Implementation>(std::move(name), line, lineEnd,
std::move(args)) }
{
}
@@ -69,6 +70,7 @@ public:
}
long Line() const noexcept { return this->Impl->Line; }
+ long LineEnd() const noexcept { return this->Impl->LineEnd; }
std::vector<cmListFileArgument> const& Arguments() const noexcept
{
@@ -78,11 +80,12 @@ public:
private:
struct Implementation
{
- Implementation(std::string name, long line,
+ Implementation(std::string name, long line, long lineEnd,
std::vector<cmListFileArgument> args)
: OriginalName{ std::move(name) }
, LowerCaseName{ cmSystemTools::LowerCase(this->OriginalName) }
, Line{ line }
+ , LineEnd{ lineEnd }
, Arguments{ std::move(args) }
{
}
@@ -90,6 +93,7 @@ private:
std::string OriginalName;
std::string LowerCaseName;
long Line = 0;
+ long LineEnd = 0;
std::vector<cmListFileArgument> Arguments;
};
@@ -125,6 +129,17 @@ public:
{
}
+ static cmListFileContext FromListFilePath(std::string const& filePath)
+ {
+ // We are entering a file-level scope but have not yet reached
+ // any specific line or command invocation within it. This context
+ // is useful to print when it is at the top but otherwise can be
+ // skipped during call stack printing.
+ cmListFileContext lfc;
+ lfc.FilePath = filePath;
+ return lfc;
+ }
+
static cmListFileContext FromListFileFunction(
cmListFileFunction const& lff, std::string const& fileName,
cm::optional<std::string> deferId = {})
@@ -143,38 +158,16 @@ bool operator<(const cmListFileContext& lhs, const cmListFileContext& rhs);
bool operator==(cmListFileContext const& lhs, cmListFileContext const& rhs);
bool operator!=(cmListFileContext const& lhs, cmListFileContext const& rhs);
-// Represent a backtrace (call stack). Provide value semantics
-// but use efficient reference-counting underneath to avoid copies.
+// Represent a backtrace (call stack) with efficient value semantics.
class cmListFileBacktrace
+ : public cmConstStack<cmListFileContext, cmListFileBacktrace>
{
-public:
- // Default-constructed backtrace is empty.
- cmListFileBacktrace() = default;
-
- // Get a backtrace with the given file scope added to the top.
- cmListFileBacktrace Push(std::string const& file) const;
-
- // Get a backtrace with the given call context added to the top.
- cmListFileBacktrace Push(cmListFileContext const& lfc) const;
-
- // Get a backtrace with the top level removed.
- // May not be called until after a matching Push.
- cmListFileBacktrace Pop() const;
-
- // Get the context at the top of the backtrace.
- // This may be called only if Empty() would return false.
- cmListFileContext const& Top() const;
-
- // Return true if this backtrace is empty.
- bool Empty() const;
-
-private:
- struct Entry;
- std::shared_ptr<Entry const> TopEntry;
- cmListFileBacktrace(std::shared_ptr<Entry const> parent,
- cmListFileContext const& lfc);
- cmListFileBacktrace(std::shared_ptr<Entry const> top);
+ using cmConstStack::cmConstStack;
+ friend class cmConstStack<cmListFileContext, cmListFileBacktrace>;
};
+#ifndef cmListFileCache_cxx
+extern template class cmConstStack<cmListFileContext, cmListFileBacktrace>;
+#endif
// Wrap type T as a value with a backtrace. For purposes of
// ordering and equality comparison, only the original value is
@@ -230,9 +223,10 @@ public:
friend bool operator==(T const& l, BTs<T> const& r) { return l == r.Value; }
};
-std::vector<BT<std::string>> ExpandListWithBacktrace(
+std::vector<BT<std::string>> cmExpandListWithBacktrace(
std::string const& list,
- cmListFileBacktrace const& bt = cmListFileBacktrace());
+ cmListFileBacktrace const& bt = cmListFileBacktrace(),
+ bool emptyArgs = false);
struct cmListFile
{
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index e39309c..e2bcea8 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1025,6 +1025,14 @@ void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags,
flags.emplace_back(std::move(compReqFlag));
}
+ // Add Warning as errors flags
+ const cmValue wError = target->GetProperty("COMPILE_WARNING_AS_ERROR");
+ const cmValue wErrorFlag = this->Makefile->GetDefinition(
+ cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_WARNING_AS_ERROR"));
+ if (wError.IsOn() && wErrorFlag.IsSet()) {
+ flags.emplace_back(wErrorFlag);
+ }
+
// Add compile flag for the MSVC compiler only.
cmMakefile* mf = this->GetMakefile();
if (cmValue jmc =
@@ -1609,6 +1617,7 @@ std::vector<BT<std::string>> cmLocalGenerator::GetTargetCompileFlags(
this->AddCMP0018Flags(compileFlags, target, lang, config);
this->AddVisibilityPresetFlags(compileFlags, target, lang);
+ this->AddColorDiagnosticsFlags(compileFlags, lang);
this->AppendFlags(compileFlags, mf->GetDefineFlags());
this->AppendFlags(compileFlags,
this->GetFrameworkFlags(lang, config, target));
@@ -1918,6 +1927,7 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags,
std::string compilerSimulateId = this->Makefile->GetSafeDefinition(
cmStrCat("CMAKE_", lang, "_SIMULATE_ID"));
+
if (lang == "Swift") {
if (cmValue v = target->GetProperty("Swift_LANGUAGE_VERSION")) {
if (cmSystemTools::VersionCompare(
@@ -1993,6 +2003,38 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags,
}
}
}
+
+ // Add Watcom runtime library flags. This is activated by the presence
+ // of a default selection whether or not it is overridden by a property.
+ cmValue watcomRuntimeLibraryDefault =
+ this->Makefile->GetDefinition("CMAKE_WATCOM_RUNTIME_LIBRARY_DEFAULT");
+ if (cmNonempty(watcomRuntimeLibraryDefault)) {
+ cmValue watcomRuntimeLibraryValue =
+ target->GetProperty("WATCOM_RUNTIME_LIBRARY");
+ if (!watcomRuntimeLibraryValue) {
+ watcomRuntimeLibraryValue = watcomRuntimeLibraryDefault;
+ }
+ std::string const watcomRuntimeLibrary = cmGeneratorExpression::Evaluate(
+ *watcomRuntimeLibraryValue, this, config, target);
+ if (!watcomRuntimeLibrary.empty()) {
+ if (cmValue watcomRuntimeLibraryOptions = this->Makefile->GetDefinition(
+ "CMAKE_" + lang + "_COMPILE_OPTIONS_WATCOM_RUNTIME_LIBRARY_" +
+ watcomRuntimeLibrary)) {
+ this->AppendCompileOptions(flags, *watcomRuntimeLibraryOptions);
+ } else if ((this->Makefile->GetSafeDefinition(
+ "CMAKE_" + lang + "_COMPILER_ID") == "OpenWatcom" ||
+ this->Makefile->GetSafeDefinition(
+ "CMAKE_" + lang + "_SIMULATE_ID") == "OpenWatcom") &&
+ !cmSystemTools::GetErrorOccuredFlag()) {
+ // The compiler uses the Watcom ABI so it needs a known runtime
+ // library.
+ this->IssueMessage(MessageType::FATAL_ERROR,
+ "WATCOM_RUNTIME_LIBRARY value '" +
+ watcomRuntimeLibrary + "' not known for this " +
+ lang + " compiler.");
+ }
+ }
+ }
}
void cmLocalGenerator::AddLanguageFlagsForLinking(
@@ -2354,6 +2396,29 @@ void cmLocalGenerator::AddPositionIndependentFlags(std::string& flags,
}
}
+void cmLocalGenerator::AddColorDiagnosticsFlags(std::string& flags,
+ const std::string& lang)
+{
+ cmValue diag = this->Makefile->GetDefinition("CMAKE_COLOR_DIAGNOSTICS");
+ if (diag.IsSet()) {
+ std::string colorFlagName;
+ if (diag.IsOn()) {
+ colorFlagName =
+ cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_COLOR_DIAGNOSTICS");
+ } else {
+ colorFlagName =
+ cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_COLOR_DIAGNOSTICS_OFF");
+ }
+
+ std::vector<std::string> options;
+ this->Makefile->GetDefExpandList(colorFlagName, options);
+
+ for (std::string const& option : options) {
+ this->AppendFlagEscape(flags, option);
+ }
+ }
+}
+
void cmLocalGenerator::AddConfigVariableFlags(std::string& flags,
const std::string& var,
const std::string& config)
@@ -3201,7 +3266,7 @@ void cmLocalGenerator::AppendDefines(std::set<std::string>& defines,
std::string const& defines_list) const
{
std::set<BT<std::string>> tmp;
- this->AppendDefines(tmp, ExpandListWithBacktrace(defines_list));
+ this->AppendDefines(tmp, cmExpandListWithBacktrace(defines_list));
for (BT<std::string> const& i : tmp) {
defines.emplace(i.Value);
}
@@ -3216,7 +3281,7 @@ void cmLocalGenerator::AppendDefines(std::set<BT<std::string>>& defines,
}
// Expand the list of definitions.
- this->AppendDefines(defines, ExpandListWithBacktrace(defines_list));
+ this->AppendDefines(defines, cmExpandListWithBacktrace(defines_list));
}
void cmLocalGenerator::AppendDefines(
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 115a54a..da3c9fd 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -159,6 +159,7 @@ public:
cmGeneratorTarget const* target,
const std::string& lang,
const std::string& config);
+ void AddColorDiagnosticsFlags(std::string& flags, const std::string& lang);
//! Append flags to a string.
virtual void AppendFlags(std::string& flags,
const std::string& newFlags) const;
@@ -169,6 +170,7 @@ public:
void AddISPCDependencies(cmGeneratorTarget* target);
void AddPchDependencies(cmGeneratorTarget* target);
void AddUnityBuild(cmGeneratorTarget* target);
+ virtual void AddXCConfigSources(cmGeneratorTarget* /* target */) {}
void AppendIPOLinkerFlags(std::string& flags, cmGeneratorTarget* target,
const std::string& config,
const std::string& lang);
diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h
index 3118bb4..4d393d9 100644
--- a/Source/cmLocalNinjaGenerator.h
+++ b/Source/cmLocalNinjaGenerator.h
@@ -10,7 +10,6 @@
#include <string>
#include <vector>
-#include "cmListFileCache.h"
#include "cmLocalCommonGenerator.h"
#include "cmNinjaTypes.h"
#include "cmOutputConverter.h"
@@ -21,6 +20,7 @@ class cmGeneratedFileStream;
class cmGeneratorTarget;
class cmGlobalGenerator;
class cmGlobalNinjaGenerator;
+class cmListFileBacktrace;
class cmMakefile;
class cmRulePlaceholderExpander;
class cmake;
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 0f8cdca..97a275a 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -133,7 +133,11 @@ void cmLocalUnixMakefileGenerator3::Generate()
// Record whether some options are enabled to avoid checking many
// times later.
if (!this->GetGlobalGenerator()->GetCMakeInstance()->GetIsInTryCompile()) {
- this->ColorMakefile = this->Makefile->IsOn("CMAKE_COLOR_MAKEFILE");
+ if (this->Makefile->IsSet("CMAKE_COLOR_MAKEFILE")) {
+ this->ColorMakefile = this->Makefile->IsOn("CMAKE_COLOR_MAKEFILE");
+ } else {
+ this->ColorMakefile = this->Makefile->IsOn("CMAKE_COLOR_DIAGNOSTICS");
+ }
}
this->SkipPreprocessedSourceRules =
this->Makefile->IsOn("CMAKE_SKIP_PREPROCESSED_SOURCE_RULES");
@@ -1508,13 +1512,12 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies(
}
// Setup relative path top directories.
- if (cmValue relativePathTopSource =
- mf->GetDefinition("CMAKE_RELATIVE_PATH_TOP_SOURCE")) {
- this->SetRelativePathTopSource(*relativePathTopSource);
- }
- if (cmValue relativePathTopBinary =
- mf->GetDefinition("CMAKE_RELATIVE_PATH_TOP_BINARY")) {
- this->SetRelativePathTopBinary(*relativePathTopBinary);
+ cmValue relativePathTopSource =
+ mf->GetDefinition("CMAKE_RELATIVE_PATH_TOP_SOURCE");
+ cmValue relativePathTopBinary =
+ mf->GetDefinition("CMAKE_RELATIVE_PATH_TOP_BINARY");
+ if (relativePathTopSource && relativePathTopBinary) {
+ this->SetRelativePathTop(*relativePathTopSource, *relativePathTopBinary);
}
} else {
cmSystemTools::Error("Directory Information file not found");
@@ -1849,7 +1852,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);
+ std::vector<std::string> dependencies = cmExpandedList(depsFiles, true);
cmDependsCompiler depsManager;
depsManager.SetVerbose(verbose);
depsManager.ClearDependencies(dependencies);
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index ed7e888..f65add1 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -1294,7 +1294,9 @@ void cmLocalVisualStudio7GeneratorInternals::OutputLibraries(
for (auto const& lib : libs) {
if (lib.IsPath == cmComputeLinkInformation::ItemIsPath::Yes) {
std::string rel = lg->MaybeRelativeToCurBinDir(lib.Value.Value);
- fout << lg->ConvertToXMLOutputPath(rel) << " ";
+ rel = lg->ConvertToXMLOutputPath(rel);
+ fout << (lib.HasFeature() ? lib.GetFormattedItem(rel).Value : rel)
+ << " ";
} else if (!lib.Target ||
lib.Target->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
fout << lib.Value.Value << " ";
diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx
index 93f01ed..2703c7b 100644
--- a/Source/cmLocalVisualStudioGenerator.cxx
+++ b/Source/cmLocalVisualStudioGenerator.cxx
@@ -252,7 +252,7 @@ std::string cmLocalVisualStudioGenerator::FinishConstructScript(
// Store the script in a string.
std::string script;
- if (useLocal && projectType == VsProjectType::csproj) {
+ if (useLocal && projectType != VsProjectType::vcxproj) {
// This label is not provided by MSBuild for C# projects.
script += newline;
script += this->GetReportErrorLabel();
diff --git a/Source/cmLocalXCodeGenerator.cxx b/Source/cmLocalXCodeGenerator.cxx
index dd064a1..e7a1f93 100644
--- a/Source/cmLocalXCodeGenerator.cxx
+++ b/Source/cmLocalXCodeGenerator.cxx
@@ -6,6 +6,7 @@
#include <ostream>
#include <utility>
+#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalXCodeGenerator.h"
#include "cmMakefile.h"
@@ -134,3 +135,22 @@ void cmLocalXCodeGenerator::ComputeObjectFilenames(
si.second = objectName;
}
}
+
+void cmLocalXCodeGenerator::AddXCConfigSources(cmGeneratorTarget* target)
+{
+ auto xcconfig = target->GetProperty("XCODE_XCCONFIG");
+ if (!xcconfig) {
+ return;
+ }
+ auto configs = target->Makefile->GetGeneratorConfigs(
+ cmMakefile::IncludeEmptyConfig);
+
+ for (auto& config : configs) {
+ auto file = cmGeneratorExpression::Evaluate(
+ xcconfig,
+ this, config);
+ if (!file.empty()) {
+ target->AddSource(file);
+ }
+ }
+}
diff --git a/Source/cmLocalXCodeGenerator.h b/Source/cmLocalXCodeGenerator.h
index ff6b356..b825161 100644
--- a/Source/cmLocalXCodeGenerator.h
+++ b/Source/cmLocalXCodeGenerator.h
@@ -38,5 +38,7 @@ public:
std::map<cmSourceFile const*, std::string>& mapping,
cmGeneratorTarget const* gt = nullptr) override;
+ void AddXCConfigSources(cmGeneratorTarget* target) override;
+
private:
};
diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx
index 154df63..ef12487 100644
--- a/Source/cmMacroCommand.cxx
+++ b/Source/cmMacroCommand.cxx
@@ -116,7 +116,7 @@ bool cmMacroHelperCommand::operator()(
newLFFArgs.push_back(std::move(arg));
}
cmListFileFunction newLFF{ func.OriginalName(), func.Line(),
- std::move(newLFFArgs) };
+ func.LineEnd(), std::move(newLFFArgs) };
cmExecutionStatus status(makefile);
if (!makefile.ExecuteCommand(newLFF, status) || status.GetNestedError()) {
// The error message should have already included the call stack
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 94d3be6..91d7ac5 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -241,14 +241,14 @@ cmListFileBacktrace cmMakefile::GetBacktrace() const
return this->Backtrace;
}
-void cmMakefile::PrintCommandTrace(
- cmListFileFunction const& lff,
- cm::optional<std::string> const& deferId) const
+void cmMakefile::PrintCommandTrace(cmListFileFunction const& lff,
+ cmListFileBacktrace const& bt,
+ CommandMissingFromStack missing) const
{
// Check if current file in the list of requested to trace...
std::vector<std::string> const& trace_only_this_files =
this->GetCMakeInstance()->GetTraceSources();
- std::string const& full_path = this->GetBacktrace().Top().FilePath;
+ std::string const& full_path = bt.Top().FilePath;
std::string const& only_filename = cmSystemTools::GetFilenameName(full_path);
bool trace = trace_only_this_files.empty();
if (!trace) {
@@ -282,6 +282,7 @@ void cmMakefile::PrintCommandTrace(
args.push_back(arg.Value);
}
}
+ cm::optional<std::string> const& deferId = bt.Top().DeferId;
switch (this->GetCMakeInstance()->GetTraceFormat()) {
case cmake::TraceFormat::TRACE_JSON_V1: {
@@ -291,6 +292,9 @@ void cmMakefile::PrintCommandTrace(
builder["indentation"] = "";
val["file"] = full_path;
val["line"] = static_cast<Json::Value::Int64>(lff.Line());
+ if (lff.Line() != lff.LineEnd()) {
+ val["line_end"] = static_cast<Json::Value::Int64>(lff.LineEnd());
+ }
if (deferId) {
val["defer"] = *deferId;
}
@@ -300,8 +304,10 @@ void cmMakefile::PrintCommandTrace(
val["args"].append(arg);
}
val["time"] = cmSystemTools::GetTime();
- val["frame"] =
+ val["frame"] = (missing == CommandMissingFromStack::Yes ? 1 : 0) +
static_cast<Json::Value::UInt64>(this->ExecutionStatusStack.size());
+ val["global_frame"] = (missing == CommandMissingFromStack::Yes ? 1 : 0) +
+ static_cast<Json::Value::UInt64>(this->RecursionDepth);
msg << Json::writeString(builder, val);
#endif
break;
@@ -422,7 +428,7 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff,
if (!cmSystemTools::GetFatalErrorOccured()) {
// if trace is enabled, print out invoke information
if (this->GetCMakeInstance()->GetTrace()) {
- this->PrintCommandTrace(lff, this->Backtrace.Top().DeferId);
+ this->PrintCommandTrace(lff, this->Backtrace);
}
// Try invoking the command.
bool invokeSucceeded = command(lff.Arguments(), status);
@@ -453,6 +459,11 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff,
return result;
}
+bool cmMakefile::IsImportedTargetGlobalScope() const
+{
+ return this->CurrentImportedTargetScope == ImportedTargetScope::Global;
+}
+
class cmMakefile::IncludeScope
{
public:
@@ -480,7 +491,8 @@ cmMakefile::IncludeScope::IncludeScope(cmMakefile* mf,
, CheckCMP0011(false)
, ReportError(true)
{
- this->Makefile->Backtrace = this->Makefile->Backtrace.Push(filenametoread);
+ this->Makefile->Backtrace = this->Makefile->Backtrace.Push(
+ cmListFileContext::FromListFilePath(filenametoread));
this->Makefile->PushFunctionBlockerBarrier();
@@ -613,7 +625,8 @@ public:
: Makefile(mf)
, ReportError(true)
{
- this->Makefile->Backtrace = this->Makefile->Backtrace.Push(filenametoread);
+ this->Makefile->Backtrace = this->Makefile->Backtrace.Push(
+ cmListFileContext::FromListFilePath(filenametoread));
this->Makefile->StateSnapshot =
this->Makefile->GetState()->CreateInlineListFileSnapshot(
@@ -1576,7 +1589,8 @@ void cmMakefile::Configure()
// Add the bottom of all backtraces within this directory.
// We will never pop this scope because it should be available
// for messages during the generate step too.
- this->Backtrace = this->Backtrace.Push(currentStart);
+ this->Backtrace =
+ this->Backtrace.Push(cmListFileContext::FromListFilePath(currentStart));
BuildsystemFileScope scope(this);
@@ -1663,6 +1677,7 @@ void cmMakefile::Configure()
this->Backtrace);
cmListFileFunction project{ "project",
0,
+ 0,
{ { "Project", cmListFileArgument::Unquoted,
0 },
{ "__CMAKE_INJECTED_PROJECT_COMMAND__",
@@ -3976,6 +3991,31 @@ std::vector<std::string> cmMakefile::GetPropertyKeys() const
return this->StateSnapshot.GetDirectory().GetPropertyKeys();
}
+void cmMakefile::CheckProperty(const std::string& prop) const
+{
+ // Certain properties need checking.
+ if (prop == "LINK_LIBRARIES") {
+ if (cmValue value = this->GetProperty(prop)) {
+ // Look for <LINK_LIBRARY:> internal pattern
+ static cmsys::RegularExpression linkPattern(
+ "(^|;)(</?LINK_(LIBRARY|GROUP):[^;>]*>)(;|$)");
+ if (!linkPattern.find(value)) {
+ return;
+ }
+
+ // Report an error.
+ this->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Property ", prop, " contains the invalid item \"",
+ linkPattern.match(2), "\". The ", prop,
+ " property may contain the generator-expression \"$<LINK_",
+ linkPattern.match(3),
+ ":...>\" which may be used to specify how the libraries are "
+ "linked."));
+ }
+ }
+}
+
cmTarget* cmMakefile::FindLocalNonAliasTarget(const std::string& name) const
{
auto i = this->Targets.find(name);
@@ -4395,12 +4435,14 @@ bool cmMakefile::SetPolicy(cmPolicies::PolicyID id,
}
// Deprecate old policies.
- if (status == cmPolicies::OLD && id <= cmPolicies::CMP0094 &&
+ if (status == cmPolicies::OLD && id <= cmPolicies::CMP0097 &&
!(this->GetCMakeInstance()->GetIsInTryCompile() &&
(
// Policies set by cmCoreTryCompile::TryCompileCode.
id == cmPolicies::CMP0065 || id == cmPolicies::CMP0083 ||
- id == cmPolicies::CMP0091))) {
+ id == cmPolicies::CMP0091)) &&
+ (!this->IsSet("CMAKE_WARN_DEPRECATED") ||
+ this->IsOn("CMAKE_WARN_DEPRECATED"))) {
this->IssueMessage(MessageType::DEPRECATION_WARNING,
cmPolicies::GetPolicyDeprecatedWarning(id));
}
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index f425697..c8e1e83 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -674,11 +674,18 @@ public:
bool copyonly, bool atOnly, bool escapeQuotes,
mode_t permissions = 0, cmNewLineStyle = cmNewLineStyle());
+ enum class CommandMissingFromStack
+ {
+ No,
+ Yes,
+ };
+
/**
* Print a command's invocation
*/
- void PrintCommandTrace(cmListFileFunction const& lff,
- cm::optional<std::string> const& deferId = {}) const;
+ void PrintCommandTrace(
+ cmListFileFunction const& lff, cmListFileBacktrace const& bt,
+ CommandMissingFromStack missing = CommandMissingFromStack::No) const;
/**
* Set a callback that is invoked whenever ExecuteCommand is called.
@@ -787,6 +794,7 @@ public:
cmValue GetProperty(const std::string& prop, bool chain) const;
bool GetPropertyAsBool(const std::string& prop) const;
std::vector<std::string> GetPropertyKeys() const;
+ void CheckProperty(const std::string& prop) const;
//! Initialize a makefile from its parent
void InitializeFromParent(cmMakefile* parent);
@@ -859,6 +867,44 @@ public:
void PushLoopBlockBarrier();
void PopLoopBlockBarrier();
+ bool IsImportedTargetGlobalScope() const;
+
+ enum class ImportedTargetScope
+ {
+ Local,
+ Global,
+ };
+
+ /** Helper class to manage whether imported packages
+ * should be globally scoped based off the find package command
+ */
+ class SetGlobalTargetImportScope
+ {
+ public:
+ SetGlobalTargetImportScope(cmMakefile* mk, ImportedTargetScope const scope)
+ : Makefile(mk)
+ {
+ if (scope == ImportedTargetScope::Global &&
+ !this->Makefile->IsImportedTargetGlobalScope()) {
+ this->Makefile->CurrentImportedTargetScope = scope;
+ this->Set = true;
+ } else {
+ this->Set = false;
+ }
+ }
+ ~SetGlobalTargetImportScope()
+ {
+ if (this->Set) {
+ this->Makefile->CurrentImportedTargetScope =
+ ImportedTargetScope::Local;
+ }
+ }
+
+ private:
+ cmMakefile* Makefile;
+ bool Set;
+ };
+
/** Helper class to push and pop scopes automatically. */
class ScopePushPop
{
@@ -1123,4 +1169,5 @@ private:
std::set<std::string> WarnedCMP0074;
bool IsSourceFileTryCompile;
mutable bool SuppressSideEffects;
+ ImportedTargetScope CurrentImportedTargetScope = ImportedTargetScope::Local;
};
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 1c92c7f..aec6577 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -305,9 +305,14 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
std::vector<cmSourceFile const*> objectSources;
this->GeneratorTarget->GetObjectSources(objectSources,
this->GetConfigName());
- for (cmSourceFile const* sf : objectSources) {
- // Generate this object file's rule file.
- this->WriteObjectRuleFiles(*sf);
+
+ // validate that all languages requested are enabled.
+ std::set<std::string> requiredLangs;
+ if (this->HaveRequiredLanguages(objectSources, requiredLangs)) {
+ for (cmSourceFile const* sf : objectSources) {
+ // Generate this object file's rule file.
+ this->WriteObjectRuleFiles(*sf);
+ }
}
}
@@ -532,8 +537,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
cmSourceFile const& source)
{
// Identify the language of the source file.
- const std::string& lang =
- this->LocalGenerator->GetSourceFileLanguage(source);
+ const std::string& lang = source.GetLanguage();
if (lang.empty()) {
// don't know anything about this file so skip it
return;
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 1c5bac8..4f6da0e 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -126,15 +126,11 @@ void cmNinjaNormalTargetGenerator::WriteLanguagesRules(
std::set<std::string> languages;
std::vector<cmSourceFile const*> sourceFiles;
this->GetGeneratorTarget()->GetObjectSources(sourceFiles, config);
- for (cmSourceFile const* sf : sourceFiles) {
- std::string const lang = sf->GetLanguage();
- if (!lang.empty()) {
- languages.insert(lang);
+ if (this->HaveRequiredLanguages(sourceFiles, languages)) {
+ for (std::string const& language : languages) {
+ this->WriteLanguageRules(language, config);
}
}
- for (std::string const& language : languages) {
- this->WriteLanguageRules(language, config);
- }
}
const char* cmNinjaNormalTargetGenerator::GetVisibleTypeName() const
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index e61b4b6..3fac7f5 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -21,6 +21,7 @@
#include "cmComputeLinkInformation.h"
#include "cmCustomCommandGenerator.h"
+#include "cmFileSet.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
@@ -28,6 +29,7 @@
#include "cmLocalGenerator.h"
#include "cmLocalNinjaGenerator.h"
#include "cmMakefile.h"
+#include "cmMessageType.h"
#include "cmNinjaNormalTargetGenerator.h"
#include "cmNinjaUtilityTargetGenerator.h"
#include "cmOutputConverter.h"
@@ -39,6 +41,7 @@
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmTarget.h"
#include "cmValue.h"
#include "cmake.h"
@@ -252,6 +255,55 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
flags, genexInterpreter.Evaluate(pchOptions, COMPILE_OPTIONS));
}
+ if (this->NeedCxxModuleSupport(language, config)) {
+ auto const& path = source->GetFullPath();
+ auto const* tgt = this->GeneratorTarget->Target;
+
+ std::string file_set_type;
+
+ for (auto const& name : tgt->GetAllFileSetNames()) {
+ auto const* file_set = tgt->GetFileSet(name);
+ if (!file_set) {
+ this->GetMakefile()->IssueMessage(
+ MessageType::INTERNAL_ERROR,
+ cmStrCat("Target `", tgt->GetName(),
+ "` is tracked to have file set `", name,
+ "`, but it was not found."));
+ continue;
+ }
+
+ auto fileEntries = file_set->CompileFileEntries();
+ auto directoryEntries = file_set->CompileDirectoryEntries();
+ auto directories = file_set->EvaluateDirectoryEntries(
+ directoryEntries, this->LocalGenerator, config, this->GeneratorTarget);
+
+ std::map<std::string, std::vector<std::string>> files;
+ for (auto const& entry : fileEntries) {
+ file_set->EvaluateFileEntry(directories, files, entry,
+ this->LocalGenerator, config,
+ this->GeneratorTarget);
+ }
+
+ for (auto const& it : files) {
+ for (auto const& filename : it.second) {
+ if (filename == path) {
+ file_set_type = file_set->GetType();
+ break;
+ }
+ }
+ }
+
+ if (!file_set_type.empty()) {
+ std::string source_type_var = cmStrCat(
+ "CMAKE_EXPERIMENTAL_CXX_MODULE_SOURCE_TYPE_FLAG_", file_set_type);
+ cmMakefile* mf = this->GetMakefile();
+ if (cmValue source_type_flag = mf->GetDefinition(source_type_var)) {
+ this->LocalGenerator->AppendFlags(flags, *source_type_flag);
+ }
+ }
+ }
+ }
+
return flags;
}
@@ -534,6 +586,7 @@ std::string GetScanCommand(const std::string& cmakeCmd, const std::string& tdi,
// not perform explicit preprocessing too.
cmNinjaRule GetScanRule(
std::string const& ruleName, std::string const& ppFileName,
+ std::string const& deptype,
cmRulePlaceholderExpander::RuleVariables const& vars,
const std::string& responseFlag, const std::string& flags,
cmRulePlaceholderExpander* const rulePlaceholderExpander,
@@ -542,8 +595,13 @@ cmNinjaRule GetScanRule(
{
cmNinjaRule rule(ruleName);
// Scanning always uses a depfile for preprocessor dependencies.
- rule.DepType = ""; // no deps= for multiple outputs
- rule.DepFile = "$DEP_FILE";
+ if (deptype == "msvc"_s) {
+ rule.DepType = deptype;
+ rule.DepFile = "";
+ } else {
+ rule.DepType = ""; // no deps= for multiple outputs
+ rule.DepFile = "$DEP_FILE";
+ }
cmRulePlaceholderExpander::RuleVariables scanVars;
scanVars.CMTargetName = vars.CMTargetName;
@@ -647,6 +705,9 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
if (needDyndep) {
+ const auto& scanDepType = this->GetMakefile()->GetSafeDefinition(
+ cmStrCat("CMAKE_EXPERIMENTAL_", lang, "_SCANDEP_DEPFILE_FORMAT"));
+
// Rule to scan dependencies of sources that need preprocessing.
{
std::vector<std::string> scanCommands;
@@ -674,10 +735,10 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
"$DYNDEP_INTERMEDIATE_FILE"));
}
- auto scanRule =
- GetScanRule(scanRuleName, ppFileName, vars, responseFlag, flags,
- rulePlaceholderExpander.get(), this->GetLocalGenerator(),
- std::move(scanCommands), config);
+ auto scanRule = GetScanRule(
+ scanRuleName, ppFileName, scanDepType, vars, responseFlag, flags,
+ rulePlaceholderExpander.get(), this->GetLocalGenerator(),
+ std::move(scanCommands), config);
scanRule.Comment =
cmStrCat("Rule for generating ", lang, " dependencies.");
@@ -705,9 +766,10 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
scanCommands.emplace_back(
GetScanCommand(cmakeCmd, tdi, lang, "$in", "$out"));
- auto scanRule = GetScanRule(
- scanRuleName, "", vars, "", flags, rulePlaceholderExpander.get(),
- this->GetLocalGenerator(), std::move(scanCommands), config);
+ auto scanRule =
+ GetScanRule(scanRuleName, "", scanDepType, vars, "", flags,
+ rulePlaceholderExpander.get(), this->GetLocalGenerator(),
+ std::move(scanCommands), config);
// Write the rule for generating dependencies for the given language.
scanRule.Comment = cmStrCat("Rule for generating ", lang,
@@ -1197,7 +1259,8 @@ cmNinjaBuild GetScanBuildStatement(const std::string& ruleName,
scanBuild.Variables["PREPROCESSED_OUTPUT_FILE"] = ppFileName;
}
- // Scanning always uses a depfile for preprocessor dependencies.
+ // Scanning always provides a depfile for preprocessor dependencies. This
+ // variable is unused in `msvc`-deptype scanners.
std::string const& depFileName = cmStrCat(scanBuild.Outputs.front(), ".d");
scanBuild.Variables["DEP_FILE"] =
lg->ConvertToOutputFormat(depFileName, cmOutputConverter::SHELL);
diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx
index b143170..e62e0cd 100644
--- a/Source/cmOutputConverter.cxx
+++ b/Source/cmOutputConverter.cxx
@@ -34,6 +34,7 @@ cmOutputConverter::cmOutputConverter(cmStateSnapshot const& snapshot)
assert(this->StateSnapshot.IsValid());
this->ComputeRelativePathTopSource();
this->ComputeRelativePathTopBinary();
+ this->ComputeRelativePathTopRelation();
}
void cmOutputConverter::ComputeRelativePathTopSource()
@@ -69,6 +70,22 @@ void cmOutputConverter::ComputeRelativePathTopBinary()
this->RelativePathTopBinary = snapshot.GetDirectory().GetCurrentBinary();
}
+void cmOutputConverter::ComputeRelativePathTopRelation()
+{
+ if (cmSystemTools::ComparePath(this->RelativePathTopSource,
+ this->RelativePathTopBinary)) {
+ this->RelativePathTopRelation = TopRelation::InSource;
+ } else if (cmSystemTools::IsSubDirectory(this->RelativePathTopBinary,
+ this->RelativePathTopSource)) {
+ this->RelativePathTopRelation = TopRelation::BinInSrc;
+ } else if (cmSystemTools::IsSubDirectory(this->RelativePathTopSource,
+ this->RelativePathTopBinary)) {
+ this->RelativePathTopRelation = TopRelation::SrcInBin;
+ } else {
+ this->RelativePathTopRelation = TopRelation::Separate;
+ }
+}
+
std::string const& cmOutputConverter::GetRelativePathTopSource() const
{
return this->RelativePathTopSource;
@@ -79,27 +96,45 @@ std::string const& cmOutputConverter::GetRelativePathTopBinary() const
return this->RelativePathTopBinary;
}
-void cmOutputConverter::SetRelativePathTopSource(std::string const& top)
-{
- this->RelativePathTopSource = top;
-}
-
-void cmOutputConverter::SetRelativePathTopBinary(std::string const& top)
+void cmOutputConverter::SetRelativePathTop(std::string const& topSource,
+ std::string const& topBinary)
{
- this->RelativePathTopBinary = top;
+ this->RelativePathTopSource = topSource;
+ this->RelativePathTopBinary = topBinary;
+ this->ComputeRelativePathTopRelation();
}
std::string cmOutputConverter::MaybeRelativeTo(
std::string const& local_path, std::string const& remote_path) const
{
- bool bothInBinary =
- PathEqOrSubDir(local_path, this->RelativePathTopBinary) &&
+ bool localInBinary = PathEqOrSubDir(local_path, this->RelativePathTopBinary);
+ bool remoteInBinary =
PathEqOrSubDir(remote_path, this->RelativePathTopBinary);
- bool bothInSource =
- PathEqOrSubDir(local_path, this->RelativePathTopSource) &&
+ bool localInSource = PathEqOrSubDir(local_path, this->RelativePathTopSource);
+ bool remoteInSource =
PathEqOrSubDir(remote_path, this->RelativePathTopSource);
+ switch (this->RelativePathTopRelation) {
+ case TopRelation::Separate:
+ // Checks are independent.
+ break;
+ case TopRelation::BinInSrc:
+ localInSource = localInSource && !localInBinary;
+ remoteInSource = remoteInSource && !remoteInBinary;
+ break;
+ case TopRelation::SrcInBin:
+ localInBinary = localInBinary && !localInSource;
+ remoteInBinary = remoteInBinary && !remoteInSource;
+ break;
+ case TopRelation::InSource:
+ // Checks are identical.
+ break;
+ };
+
+ bool const bothInBinary = localInBinary && remoteInBinary;
+ bool const bothInSource = localInSource && remoteInSource;
+
if (bothInBinary || bothInSource) {
return cmSystemTools::ForceToRelativePath(local_path, remote_path);
}
diff --git a/Source/cmOutputConverter.h b/Source/cmOutputConverter.h
index 335442d..d19bccc 100644
--- a/Source/cmOutputConverter.h
+++ b/Source/cmOutputConverter.h
@@ -29,8 +29,8 @@ public:
std::string const& GetRelativePathTopSource() const;
std::string const& GetRelativePathTopBinary() const;
- void SetRelativePathTopSource(std::string const& top);
- void SetRelativePathTopBinary(std::string const& top);
+ void SetRelativePathTop(std::string const& topSource,
+ std::string const& topBinary);
enum OutputFormat
{
@@ -147,8 +147,17 @@ private:
// safely by the build tools.
std::string RelativePathTopSource;
std::string RelativePathTopBinary;
+ enum class TopRelation
+ {
+ Separate,
+ BinInSrc,
+ SrcInBin,
+ InSource,
+ };
+ TopRelation RelativePathTopRelation = TopRelation::Separate;
void ComputeRelativePathTopSource();
void ComputeRelativePathTopBinary();
+ void ComputeRelativePathTopRelation();
std::string MaybeRelativeTo(std::string const& local_path,
std::string const& remote_path) const;
};
diff --git a/Source/cmPlaceholderExpander.cxx b/Source/cmPlaceholderExpander.cxx
new file mode 100644
index 0000000..118017e
--- /dev/null
+++ b/Source/cmPlaceholderExpander.cxx
@@ -0,0 +1,54 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmPlaceholderExpander.h"
+
+#include <cctype>
+
+std::string& cmPlaceholderExpander::ExpandVariables(std::string& s)
+{
+ std::string::size_type start = s.find('<');
+ // no variables to expand
+ if (start == std::string::npos) {
+ return s;
+ }
+ std::string::size_type pos = 0;
+ std::string expandedInput;
+ while (start != std::string::npos && start < s.size() - 2) {
+ std::string::size_type end = s.find('>', start);
+ // if we find a < with no > we are done
+ if (end == std::string::npos) {
+ s = expandedInput;
+ return s;
+ }
+ char c = s[start + 1];
+ // if the next char after the < is not A-Za-z then
+ // skip it and try to find the next < in the string
+ if (!isalpha(c)) {
+ start = s.find('<', start + 1);
+ } else {
+ // extract the var
+ std::string var = s.substr(start + 1, end - start - 1);
+ std::string replace = this->ExpandVariable(var);
+ expandedInput += s.substr(pos, start - pos);
+
+ // Prevent consecutive whitespace in the output if the rule variable
+ // expands to an empty string.
+ bool consecutive = replace.empty() && start > 0 && s[start - 1] == ' ' &&
+ end + 1 < s.size() && s[end + 1] == ' ';
+ if (consecutive) {
+ expandedInput.pop_back();
+ }
+
+ expandedInput += replace;
+
+ // move to next one
+ start = s.find('<', start + var.size() + 2);
+ pos = end + 1;
+ }
+ }
+ // add the rest of the input
+ expandedInput += s.substr(pos, s.size() - pos);
+ s = expandedInput;
+
+ return s;
+}
diff --git a/Source/cmPlaceholderExpander.h b/Source/cmPlaceholderExpander.h
new file mode 100644
index 0000000..24225cc
--- /dev/null
+++ b/Source/cmPlaceholderExpander.h
@@ -0,0 +1,19 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#pragma once
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <string>
+
+class cmPlaceholderExpander
+{
+public:
+ virtual ~cmPlaceholderExpander() = default;
+
+ std::string& ExpandVariables(std::string& string);
+
+protected:
+ virtual std::string ExpandVariable(std::string const& variable) = 0;
+};
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 99e2eb6..c8b037e 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -388,6 +388,32 @@ class cmMakefile;
22, 0, cmPolicies::WARN) \
SELECT(POLICY, CMP0129, \
"Compiler id for MCST LCC compilers is now LCC, not GNU.", 3, 23, 0, \
+ cmPolicies::WARN) \
+ SELECT(POLICY, CMP0130, "while() diagnoses condition evaluation errors.", \
+ 3, 24, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0131, \
+ "LINK_LIBRARIES supports the LINK_ONLY generator expression.", 3, \
+ 24, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0132, \
+ "Do not set compiler environment variables on first run", 3, 24, 0, \
+ cmPolicies::WARN) \
+ SELECT(POLICY, CMP0133, \
+ "The CPack module disables SLA by default in the CPack DragNDrop " \
+ "Generator.", \
+ 3, 24, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0134, \
+ "Fallback to \"HOST\" Windows registry view when \"TARGET\" view " \
+ "is not usable.", \
+ 3, 24, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0135, \
+ "ExternalProject ignores timestamps in archives by default for the " \
+ "URL download method", \
+ 3, 24, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0136, \
+ "Watcom runtime library flags are selected by an abstraction.", 3, \
+ 24, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0137, \
+ "try_compile() passes platform variables in project mode", 3, 24, 0, \
cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
@@ -424,7 +450,8 @@ class cmMakefile;
F(CMP0108) \
F(CMP0112) \
F(CMP0113) \
- F(CMP0119)
+ F(CMP0119) \
+ F(CMP0131)
/** \class cmPolicies
* \brief Handles changes in CMake behavior and policies
diff --git a/Source/cmQtAutoGen.cxx b/Source/cmQtAutoGen.cxx
index 0a394b5..adbdba8 100644
--- a/Source/cmQtAutoGen.cxx
+++ b/Source/cmQtAutoGen.cxx
@@ -76,6 +76,13 @@ static void MergeOptions(std::vector<std::string>& baseOpts,
unsigned int const cmQtAutoGen::ParallelMax = 64;
+#ifdef _WIN32
+// Actually 32767 (see
+// https://devblogs.microsoft.com/oldnewthing/20031210-00/?p=41553) but we
+// allow for a small margin
+size_t const cmQtAutoGen::CommandLineLengthMax = 32000;
+#endif
+
cm::string_view cmQtAutoGen::GeneratorName(GenT genType)
{
switch (genType) {
diff --git a/Source/cmQtAutoGen.h b/Source/cmQtAutoGen.h
index 5a23ae9..d111422 100644
--- a/Source/cmQtAutoGen.h
+++ b/Source/cmQtAutoGen.h
@@ -64,6 +64,11 @@ public:
/// @brief Maximum number of parallel threads/processes in a generator
static unsigned int const ParallelMax;
+#ifdef _WIN32
+ /// @brief Maximum number of characters on command line
+ static size_t const CommandLineLengthMax;
+#endif
+
/// @brief Returns the generator name
static cm::string_view GeneratorName(GenT genType);
/// @brief Returns the generator name in upper case
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index a01e6ae..a47b3c0 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -114,7 +114,8 @@ bool StaticLibraryCycle(cmGeneratorTarget const* targetOrigin,
}
// Collect all static_library dependencies from the test target
cmLinkImplementationLibraries const* libs =
- testTarget->GetLinkImplementationLibraries(config);
+ testTarget->GetLinkImplementationLibraries(
+ config, cmGeneratorTarget::LinkInterfaceFor::Link);
if (libs) {
for (cmLinkItem const& item : libs->Libraries) {
cmGeneratorTarget const* depTarget = item.Target;
@@ -1266,7 +1267,8 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
std::map<cmGeneratorTarget const*, std::size_t> commonTargets;
for (std::string const& config : this->ConfigsList) {
cmLinkImplementationLibraries const* libs =
- this->GenTarget->GetLinkImplementationLibraries(config);
+ this->GenTarget->GetLinkImplementationLibraries(
+ config, cmGeneratorTarget::LinkInterfaceFor::Link);
if (libs) {
for (cmLinkItem const& item : libs->Libraries) {
cmGeneratorTarget const* libTarget = item.Target;
diff --git a/Source/cmQtAutoMocUic.cxx b/Source/cmQtAutoMocUic.cxx
index 4ed728e..0d38dfb 100644
--- a/Source/cmQtAutoMocUic.cxx
+++ b/Source/cmQtAutoMocUic.cxx
@@ -497,6 +497,10 @@ public:
protected:
ParseCacheT::FileHandleT CacheEntry;
+
+ private:
+ void MaybeWriteMocResponseFile(std::string const& outputFile,
+ std::vector<std::string>& cmd) const;
};
/** uic compiles a file. */
@@ -2025,6 +2029,8 @@ void cmQtAutoMocUicT::JobCompileMocT::Process()
cmd.push_back(outputFile);
// Add source file
cmd.push_back(sourceFile);
+
+ MaybeWriteMocResponseFile(outputFile, cmd);
}
// Execute moc command
@@ -2070,6 +2076,51 @@ void cmQtAutoMocUicT::JobCompileMocT::Process()
}
}
+/*
+ * Check if command line exceeds maximum length supported by OS
+ * (if on Windows) and switch to using a response file instead.
+ */
+void cmQtAutoMocUicT::JobCompileMocT::MaybeWriteMocResponseFile(
+ std::string const& outputFile, std::vector<std::string>& cmd) const
+{
+#ifdef _WIN32
+ // Ensure cmd is less than CommandLineLengthMax characters
+ size_t commandLineLength = cmd.size(); // account for separating spaces
+ for (std::string const& str : cmd) {
+ commandLineLength += str.length();
+ }
+ if (commandLineLength >= CommandLineLengthMax) {
+ // Command line exceeds maximum size allowed by OS
+ // => create response file
+ std::string const responseFile = cmStrCat(outputFile, ".rsp");
+
+ cmsys::ofstream fout(responseFile.c_str());
+ if (!fout) {
+ this->LogError(
+ GenT::MOC,
+ cmStrCat("AUTOMOC was unable to create a response file at\n ",
+ this->MessagePath(responseFile)));
+ return;
+ }
+
+ auto it = cmd.begin();
+ while (++it != cmd.end()) {
+ fout << *it << "\n";
+ }
+ fout.close();
+
+ // Keep all but executable
+ cmd.resize(1);
+
+ // Specify response file
+ cmd.push_back(cmStrCat('@', responseFile));
+ }
+#else
+ static_cast<void>(outputFile);
+ static_cast<void>(cmd);
+#endif
+}
+
void cmQtAutoMocUicT::JobCompileUicT::Process()
{
std::string const& sourceFile = this->Mapping->SourceFile->FileName;
diff --git a/Source/cmRulePlaceholderExpander.cxx b/Source/cmRulePlaceholderExpander.cxx
index 4cee09d..b63d11c 100644
--- a/Source/cmRulePlaceholderExpander.cxx
+++ b/Source/cmRulePlaceholderExpander.cxx
@@ -2,7 +2,6 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmRulePlaceholderExpander.h"
-#include <cctype>
#include <utility>
#include "cmOutputConverter.h"
@@ -20,195 +19,194 @@ cmRulePlaceholderExpander::cmRulePlaceholderExpander(
{
}
-std::string cmRulePlaceholderExpander::ExpandRuleVariable(
- cmOutputConverter* outputConverter, std::string const& variable,
- const RuleVariables& replaceValues)
+std::string cmRulePlaceholderExpander::ExpandVariable(
+ std::string const& variable)
{
- if (replaceValues.LinkFlags) {
+ if (this->ReplaceValues->LinkFlags) {
if (variable == "LINK_FLAGS") {
- return replaceValues.LinkFlags;
+ return this->ReplaceValues->LinkFlags;
}
}
- if (replaceValues.Manifests) {
+ if (this->ReplaceValues->Manifests) {
if (variable == "MANIFESTS") {
- return replaceValues.Manifests;
+ return this->ReplaceValues->Manifests;
}
}
- if (replaceValues.Flags) {
+ if (this->ReplaceValues->Flags) {
if (variable == "FLAGS") {
- return replaceValues.Flags;
+ return this->ReplaceValues->Flags;
}
}
- if (replaceValues.Source) {
+ if (this->ReplaceValues->Source) {
if (variable == "SOURCE") {
- return replaceValues.Source;
+ return this->ReplaceValues->Source;
}
}
- if (replaceValues.DynDepFile) {
+ if (this->ReplaceValues->DynDepFile) {
if (variable == "DYNDEP_FILE") {
- return replaceValues.DynDepFile;
+ return this->ReplaceValues->DynDepFile;
}
}
- if (replaceValues.PreprocessedSource) {
+ if (this->ReplaceValues->PreprocessedSource) {
if (variable == "PREPROCESSED_SOURCE") {
- return replaceValues.PreprocessedSource;
+ return this->ReplaceValues->PreprocessedSource;
}
}
- if (replaceValues.AssemblySource) {
+ if (this->ReplaceValues->AssemblySource) {
if (variable == "ASSEMBLY_SOURCE") {
- return replaceValues.AssemblySource;
+ return this->ReplaceValues->AssemblySource;
}
}
- if (replaceValues.Object) {
+ if (this->ReplaceValues->Object) {
if (variable == "OBJECT") {
- return replaceValues.Object;
+ return this->ReplaceValues->Object;
}
}
- if (replaceValues.ObjectDir) {
+ if (this->ReplaceValues->ObjectDir) {
if (variable == "OBJECT_DIR") {
- return replaceValues.ObjectDir;
+ return this->ReplaceValues->ObjectDir;
}
}
- if (replaceValues.ObjectFileDir) {
+ if (this->ReplaceValues->ObjectFileDir) {
if (variable == "OBJECT_FILE_DIR") {
- return replaceValues.ObjectFileDir;
+ return this->ReplaceValues->ObjectFileDir;
}
}
- if (replaceValues.Objects) {
+ if (this->ReplaceValues->Objects) {
if (variable == "OBJECTS") {
- return replaceValues.Objects;
+ return this->ReplaceValues->Objects;
}
}
- if (replaceValues.ObjectsQuoted) {
+ if (this->ReplaceValues->ObjectsQuoted) {
if (variable == "OBJECTS_QUOTED") {
- return replaceValues.ObjectsQuoted;
+ return this->ReplaceValues->ObjectsQuoted;
}
}
- if (replaceValues.CudaCompileMode) {
+ if (this->ReplaceValues->CudaCompileMode) {
if (variable == "CUDA_COMPILE_MODE") {
- return replaceValues.CudaCompileMode;
+ return this->ReplaceValues->CudaCompileMode;
}
}
- if (replaceValues.AIXExports) {
+ if (this->ReplaceValues->AIXExports) {
if (variable == "AIX_EXPORTS") {
- return replaceValues.AIXExports;
+ return this->ReplaceValues->AIXExports;
}
}
- if (replaceValues.ISPCHeader) {
+ if (this->ReplaceValues->ISPCHeader) {
if (variable == "ISPC_HEADER") {
- return replaceValues.ISPCHeader;
+ return this->ReplaceValues->ISPCHeader;
}
}
- if (replaceValues.Defines && variable == "DEFINES") {
- return replaceValues.Defines;
+ if (this->ReplaceValues->Defines && variable == "DEFINES") {
+ return this->ReplaceValues->Defines;
}
- if (replaceValues.Includes && variable == "INCLUDES") {
- return replaceValues.Includes;
+ if (this->ReplaceValues->Includes && variable == "INCLUDES") {
+ return this->ReplaceValues->Includes;
}
- if (replaceValues.SwiftLibraryName) {
+ if (this->ReplaceValues->SwiftLibraryName) {
if (variable == "SWIFT_LIBRARY_NAME") {
- return replaceValues.SwiftLibraryName;
+ return this->ReplaceValues->SwiftLibraryName;
}
}
- if (replaceValues.SwiftModule) {
+ if (this->ReplaceValues->SwiftModule) {
if (variable == "SWIFT_MODULE") {
- return replaceValues.SwiftModule;
+ return this->ReplaceValues->SwiftModule;
}
}
- if (replaceValues.SwiftModuleName) {
+ if (this->ReplaceValues->SwiftModuleName) {
if (variable == "SWIFT_MODULE_NAME") {
- return replaceValues.SwiftModuleName;
+ return this->ReplaceValues->SwiftModuleName;
}
}
- if (replaceValues.SwiftOutputFileMap) {
+ if (this->ReplaceValues->SwiftOutputFileMap) {
if (variable == "SWIFT_OUTPUT_FILE_MAP") {
- return replaceValues.SwiftOutputFileMap;
+ return this->ReplaceValues->SwiftOutputFileMap;
}
}
- if (replaceValues.SwiftSources) {
+ if (this->ReplaceValues->SwiftSources) {
if (variable == "SWIFT_SOURCES") {
- return replaceValues.SwiftSources;
+ return this->ReplaceValues->SwiftSources;
}
}
- if (replaceValues.TargetPDB) {
+ if (this->ReplaceValues->TargetPDB) {
if (variable == "TARGET_PDB") {
- return replaceValues.TargetPDB;
+ return this->ReplaceValues->TargetPDB;
}
}
- if (replaceValues.TargetCompilePDB) {
+ if (this->ReplaceValues->TargetCompilePDB) {
if (variable == "TARGET_COMPILE_PDB") {
- return replaceValues.TargetCompilePDB;
+ return this->ReplaceValues->TargetCompilePDB;
}
}
- if (replaceValues.DependencyFile) {
+ if (this->ReplaceValues->DependencyFile) {
if (variable == "DEP_FILE") {
- return replaceValues.DependencyFile;
+ return this->ReplaceValues->DependencyFile;
}
}
- if (replaceValues.DependencyTarget) {
+ if (this->ReplaceValues->DependencyTarget) {
if (variable == "DEP_TARGET") {
- return replaceValues.DependencyTarget;
+ return this->ReplaceValues->DependencyTarget;
}
}
- if (replaceValues.Fatbinary) {
+ if (this->ReplaceValues->Fatbinary) {
if (variable == "FATBINARY") {
- return replaceValues.Fatbinary;
+ return this->ReplaceValues->Fatbinary;
}
}
- if (replaceValues.RegisterFile) {
+ if (this->ReplaceValues->RegisterFile) {
if (variable == "REGISTER_FILE") {
- return replaceValues.RegisterFile;
+ return this->ReplaceValues->RegisterFile;
}
}
- if (replaceValues.Target) {
+ if (this->ReplaceValues->Target) {
if (variable == "TARGET_QUOTED") {
- std::string targetQuoted = replaceValues.Target;
+ std::string targetQuoted = this->ReplaceValues->Target;
if (!targetQuoted.empty() && targetQuoted.front() != '\"') {
targetQuoted = '\"';
- targetQuoted += replaceValues.Target;
+ targetQuoted += this->ReplaceValues->Target;
targetQuoted += '\"';
}
return targetQuoted;
}
if (variable == "TARGET_UNQUOTED") {
- std::string unquoted = replaceValues.Target;
+ std::string unquoted = this->ReplaceValues->Target;
std::string::size_type sz = unquoted.size();
if (sz > 2 && unquoted.front() == '\"' && unquoted.back() == '\"') {
unquoted = unquoted.substr(1, sz - 2);
}
return unquoted;
}
- if (replaceValues.LanguageCompileFlags) {
+ if (this->ReplaceValues->LanguageCompileFlags) {
if (variable == "LANGUAGE_COMPILE_FLAGS") {
- return replaceValues.LanguageCompileFlags;
+ return this->ReplaceValues->LanguageCompileFlags;
}
}
- if (replaceValues.Target) {
+ if (this->ReplaceValues->Target) {
if (variable == "TARGET") {
- return replaceValues.Target;
+ return this->ReplaceValues->Target;
}
}
if (variable == "TARGET_IMPLIB") {
return this->TargetImpLib;
}
if (variable == "TARGET_VERSION_MAJOR") {
- if (replaceValues.TargetVersionMajor) {
- return replaceValues.TargetVersionMajor;
+ if (this->ReplaceValues->TargetVersionMajor) {
+ return this->ReplaceValues->TargetVersionMajor;
}
return "0";
}
if (variable == "TARGET_VERSION_MINOR") {
- if (replaceValues.TargetVersionMinor) {
- return replaceValues.TargetVersionMinor;
+ if (this->ReplaceValues->TargetVersionMinor) {
+ return this->ReplaceValues->TargetVersionMinor;
}
return "0";
}
- if (replaceValues.Target) {
+ if (this->ReplaceValues->Target) {
if (variable == "TARGET_BASE") {
// Strip the last extension off the target name.
- std::string targetBase = replaceValues.Target;
+ std::string targetBase = this->ReplaceValues->Target;
std::string::size_type pos = targetBase.rfind('.');
if (pos != std::string::npos) {
return targetBase.substr(0, pos);
@@ -220,54 +218,54 @@ std::string cmRulePlaceholderExpander::ExpandRuleVariable(
if (variable == "TARGET_SONAME" || variable == "SONAME_FLAG" ||
variable == "TARGET_INSTALLNAME_DIR") {
// All these variables depend on TargetSOName
- if (replaceValues.TargetSOName) {
+ if (this->ReplaceValues->TargetSOName) {
if (variable == "TARGET_SONAME") {
- return replaceValues.TargetSOName;
+ return this->ReplaceValues->TargetSOName;
}
- if (variable == "SONAME_FLAG" && replaceValues.SONameFlag) {
- return replaceValues.SONameFlag;
+ if (variable == "SONAME_FLAG" && this->ReplaceValues->SONameFlag) {
+ return this->ReplaceValues->SONameFlag;
}
- if (replaceValues.TargetInstallNameDir &&
+ if (this->ReplaceValues->TargetInstallNameDir &&
variable == "TARGET_INSTALLNAME_DIR") {
- return replaceValues.TargetInstallNameDir;
+ return this->ReplaceValues->TargetInstallNameDir;
}
}
return "";
}
- if (replaceValues.LinkLibraries) {
+ if (this->ReplaceValues->LinkLibraries) {
if (variable == "LINK_LIBRARIES") {
- return replaceValues.LinkLibraries;
+ return this->ReplaceValues->LinkLibraries;
}
}
- if (replaceValues.Language) {
+ if (this->ReplaceValues->Language) {
if (variable == "LANGUAGE") {
- return replaceValues.Language;
+ return this->ReplaceValues->Language;
}
}
- if (replaceValues.CMTargetName) {
+ if (this->ReplaceValues->CMTargetName) {
if (variable == "TARGET_NAME") {
- return replaceValues.CMTargetName;
+ return this->ReplaceValues->CMTargetName;
}
}
- if (replaceValues.CMTargetType) {
+ if (this->ReplaceValues->CMTargetType) {
if (variable == "TARGET_TYPE") {
- return replaceValues.CMTargetType;
+ return this->ReplaceValues->CMTargetType;
}
}
- if (replaceValues.Output) {
+ if (this->ReplaceValues->Output) {
if (variable == "OUTPUT") {
- return replaceValues.Output;
+ return this->ReplaceValues->Output;
}
}
if (variable == "CMAKE_COMMAND") {
- return outputConverter->ConvertToOutputFormat(
+ return this->OutputConverter->ConvertToOutputFormat(
cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL);
}
auto compIt = this->Compilers.find(variable);
if (compIt != this->Compilers.end()) {
- std::string ret = outputConverter->ConvertToOutputForExisting(
+ std::string ret = this->OutputConverter->ConvertToOutputForExisting(
this->VariableMappings["CMAKE_" + compIt->second + "_COMPILER"]);
std::string const& compilerArg1 =
this->VariableMappings["CMAKE_" + compIt->second + "_COMPILER_ARG1"];
@@ -286,11 +284,12 @@ std::string cmRulePlaceholderExpander::ExpandRuleVariable(
this->VariableMappings["CMAKE_" + compIt->second +
"_COMPILE_OPTIONS_SYSROOT"];
- if (compIt->second == replaceValues.Language && replaceValues.Launcher) {
+ if (compIt->second == this->ReplaceValues->Language &&
+ this->ReplaceValues->Launcher) {
// Add launcher as part of expansion so that it always appears
// immediately before the command itself, regardless of whether the
// overall rule template contains other content at the front.
- ret = cmStrCat(replaceValues.Launcher, " ", ret);
+ ret = cmStrCat(this->ReplaceValues->Launcher, " ", ret);
}
// if there are required arguments to the compiler add it
@@ -308,13 +307,14 @@ std::string cmRulePlaceholderExpander::ExpandRuleVariable(
!compilerOptionExternalToolchain.empty()) {
ret += " ";
ret += compilerOptionExternalToolchain;
- ret += outputConverter->EscapeForShell(compilerExternalToolchain, true);
+ ret +=
+ this->OutputConverter->EscapeForShell(compilerExternalToolchain, true);
}
std::string sysroot;
// Some platforms may use separate sysroots for compiling and linking.
// If we detect link flags, then we pass the link sysroot instead.
// FIXME: Use a more robust way to detect link line expansion.
- if (replaceValues.LinkFlags) {
+ if (this->ReplaceValues->LinkFlags) {
sysroot = this->LinkerSysroot;
} else {
sysroot = this->CompilerSysroot;
@@ -322,7 +322,7 @@ std::string cmRulePlaceholderExpander::ExpandRuleVariable(
if (!sysroot.empty() && !compilerOptionSysroot.empty()) {
ret += " ";
ret += compilerOptionSysroot;
- ret += outputConverter->EscapeForShell(sysroot, true);
+ ret += this->OutputConverter->EscapeForShell(sysroot, true);
}
return ret;
}
@@ -331,13 +331,13 @@ std::string cmRulePlaceholderExpander::ExpandRuleVariable(
if (mapIt != this->VariableMappings.end()) {
if (variable.find("_FLAG") == std::string::npos) {
std::string ret =
- outputConverter->ConvertToOutputForExisting(mapIt->second);
+ this->OutputConverter->ConvertToOutputForExisting(mapIt->second);
- if (replaceValues.Launcher && variable == "CMAKE_LINKER") {
+ if (this->ReplaceValues->Launcher && variable == "CMAKE_LINKER") {
// Add launcher as part of expansion so that it always appears
// immediately before the command itself, regardless of whether the
// overall rule template contains other content at the front.
- ret = cmStrCat(replaceValues.Launcher, " ", ret);
+ ret = cmStrCat(this->ReplaceValues->Launcher, " ", ret);
}
return ret;
@@ -351,47 +351,8 @@ void cmRulePlaceholderExpander::ExpandRuleVariables(
cmOutputConverter* outputConverter, std::string& s,
const RuleVariables& replaceValues)
{
- std::string::size_type start = s.find('<');
- // no variables to expand
- if (start == std::string::npos) {
- return;
- }
- std::string::size_type pos = 0;
- std::string expandedInput;
- while (start != std::string::npos && start < s.size() - 2) {
- std::string::size_type end = s.find('>', start);
- // if we find a < with no > we are done
- if (end == std::string::npos) {
- return;
- }
- char c = s[start + 1];
- // if the next char after the < is not A-Za-z then
- // skip it and try to find the next < in the string
- if (!isalpha(c)) {
- start = s.find('<', start + 1);
- } else {
- // extract the var
- std::string var = s.substr(start + 1, end - start - 1);
- std::string replace =
- this->ExpandRuleVariable(outputConverter, var, replaceValues);
- expandedInput += s.substr(pos, start - pos);
-
- // Prevent consecutive whitespace in the output if the rule variable
- // expands to an empty string.
- bool consecutive = replace.empty() && start > 0 && s[start - 1] == ' ' &&
- end + 1 < s.size() && s[end + 1] == ' ';
- if (consecutive) {
- expandedInput.pop_back();
- }
+ this->OutputConverter = outputConverter;
+ this->ReplaceValues = &replaceValues;
- expandedInput += replace;
-
- // move to next one
- start = s.find('<', start + var.size() + 2);
- pos = end + 1;
- }
- }
- // add the rest of the input
- expandedInput += s.substr(pos, s.size() - pos);
- s = expandedInput;
+ this->ExpandVariables(s);
}
diff --git a/Source/cmRulePlaceholderExpander.h b/Source/cmRulePlaceholderExpander.h
index 852954f..23ec405 100644
--- a/Source/cmRulePlaceholderExpander.h
+++ b/Source/cmRulePlaceholderExpander.h
@@ -8,9 +8,11 @@
#include <map>
#include <string>
+#include "cmPlaceholderExpander.h"
+
class cmOutputConverter;
-class cmRulePlaceholderExpander
+class cmRulePlaceholderExpander : public cmPlaceholderExpander
{
public:
cmRulePlaceholderExpander(
@@ -76,16 +78,16 @@ public:
std::string& string,
const RuleVariables& replaceValues);
- // Expand rule variables in a single string
- std::string ExpandRuleVariable(cmOutputConverter* outputConverter,
- std::string const& variable,
- const RuleVariables& replaceValues);
-
private:
+ std::string ExpandVariable(std::string const& variable) override;
+
std::string TargetImpLib;
std::map<std::string, std::string> Compilers;
std::map<std::string, std::string> VariableMappings;
std::string CompilerSysroot;
std::string LinkerSysroot;
+
+ cmOutputConverter* OutputConverter = nullptr;
+ RuleVariables const* ReplaceValues = nullptr;
};
diff --git a/Source/cmScriptGenerator.cxx b/Source/cmScriptGenerator.cxx
index 5ac7be9..437b938 100644
--- a/Source/cmScriptGenerator.cxx
+++ b/Source/cmScriptGenerator.cxx
@@ -52,8 +52,7 @@ static void cmScriptGeneratorEncodeConfig(const std::string& config,
std::string cmScriptGenerator::CreateConfigTest(const std::string& config)
{
- std::string result =
- cmStrCat("\"${", this->RuntimeConfigVariable, "}\" MATCHES \"^(");
+ std::string result = cmStrCat(this->RuntimeConfigVariable, " MATCHES \"^(");
if (!config.empty()) {
cmScriptGeneratorEncodeConfig(config, result);
}
@@ -64,8 +63,7 @@ std::string cmScriptGenerator::CreateConfigTest(const std::string& config)
std::string cmScriptGenerator::CreateConfigTest(
std::vector<std::string> const& configs)
{
- std::string result =
- cmStrCat("\"${", this->RuntimeConfigVariable, "}\" MATCHES \"^(");
+ std::string result = cmStrCat(this->RuntimeConfigVariable, " MATCHES \"^(");
const char* sep = "";
for (std::string const& config : configs) {
result += sep;
diff --git a/Source/cmSearchPath.cxx b/Source/cmSearchPath.cxx
index bfee64c..6c53b85 100644
--- a/Source/cmSearchPath.cxx
+++ b/Source/cmSearchPath.cxx
@@ -6,11 +6,14 @@
#include <cassert>
#include <utility>
+#include <cm/optional>
+
#include "cmFindCommon.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
+#include "cmWindowsRegistry.h"
cmSearchPath::cmSearchPath(cmFindCommon* findCmd)
: FC(findCmd)
@@ -46,26 +49,13 @@ void cmSearchPath::AddUserPath(const std::string& path)
std::vector<std::string> outPaths;
- // We should view the registry as the target application would view
- // it.
- cmSystemTools::KeyWOW64 view = cmSystemTools::KeyWOW64_32;
- cmSystemTools::KeyWOW64 other_view = cmSystemTools::KeyWOW64_64;
- if (this->FC->Makefile->PlatformIs64Bit()) {
- view = cmSystemTools::KeyWOW64_64;
- other_view = cmSystemTools::KeyWOW64_32;
- }
-
- // Expand using the view of the target application.
- std::string expanded = path;
- cmSystemTools::ExpandRegistryValues(expanded, view);
- cmSystemTools::GlobDirs(expanded, outPaths);
-
- // Executables can be either 32-bit or 64-bit, so expand using the
- // alternative view.
- if (expanded != path && this->FC->CMakePathName == "PROGRAM") {
- expanded = path;
- cmSystemTools::ExpandRegistryValues(expanded, other_view);
- cmSystemTools::GlobDirs(expanded, outPaths);
+ cmWindowsRegistry registry(*this->FC->Makefile,
+ cmWindowsRegistry::SimpleTypes);
+ auto expandedPaths = registry.ExpandExpression(path, this->FC->RegistryView);
+ if (expandedPaths) {
+ for (const auto& expandedPath : expandedPaths.value()) {
+ cmSystemTools::GlobDirs(expandedPath, outPaths);
+ }
}
// Process them all from the current directory
diff --git a/Source/cmState.h b/Source/cmState.h
index 4f2b7df..ee133fc 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -14,7 +14,6 @@
#include "cmDefinitions.h"
#include "cmLinkedTree.h"
-#include "cmListFileCache.h"
#include "cmPolicies.h"
#include "cmProperty.h"
#include "cmPropertyDefinition.h"
@@ -30,6 +29,11 @@ class cmMakefile;
class cmStateSnapshot;
class cmMessenger;
class cmExecutionStatus;
+class cmListFileBacktrace;
+struct cmListFileArgument;
+
+template <typename T>
+class BT;
class cmState
{
diff --git a/Source/cmStateDirectory.cxx b/Source/cmStateDirectory.cxx
index b42e5c3..20e4604 100644
--- a/Source/cmStateDirectory.cxx
+++ b/Source/cmStateDirectory.cxx
@@ -13,6 +13,7 @@
#include <cmext/string_view>
#include "cmAlgorithms.h"
+#include "cmListFileCache.h"
#include "cmProperty.h"
#include "cmPropertyMap.h"
#include "cmRange.h"
diff --git a/Source/cmStateDirectory.h b/Source/cmStateDirectory.h
index 6429f32..8c6b09d 100644
--- a/Source/cmStateDirectory.h
+++ b/Source/cmStateDirectory.h
@@ -10,11 +10,14 @@
#include "cmAlgorithms.h"
#include "cmLinkedTree.h"
-#include "cmListFileCache.h"
#include "cmStatePrivate.h"
#include "cmStateSnapshot.h"
#include "cmValue.h"
+class cmListFileBacktrace;
+template <typename T>
+class BT;
+
class cmStateDirectory
{
cmStateDirectory(
diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx
index e5935b8..c3ee695 100644
--- a/Source/cmStringCommand.cxx
+++ b/Source/cmStringCommand.cxx
@@ -55,7 +55,6 @@ bool joinImpl(std::vector<std::string> const& args, std::string const& glue,
bool HandleHashCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
-#if !defined(CMAKE_BOOTSTRAP)
if (args.size() != 3) {
status.SetError(
cmStrCat(args[0], " requires an output variable and an input string"));
@@ -69,10 +68,6 @@ bool HandleHashCommand(std::vector<std::string> const& args,
return true;
}
return false;
-#else
- status.SetError(cmStrCat(args[0], " not available during bootstrap"));
- return false;
-#endif
}
bool HandleToUpperLowerCommand(std::vector<std::string> const& args,
@@ -1106,8 +1101,8 @@ bool HandleJSONCommand(std::vector<std::string> const& arguments,
mode != "EQUAL"_s) {
throw json_error(
{ "got an invalid mode '"_s, mode,
- "', expected one of GET, GET_ARRAY, TYPE, MEMBER, MEMBERS,"
- " LENGTH, REMOVE, SET, EQUAL"_s });
+ "', expected one of GET, TYPE, MEMBER, LENGTH, REMOVE, SET, "
+ " EQUAL"_s });
}
const auto& jsonstr = args.PopFront("missing json string argument"_s);
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index effb837..527175d 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -1821,6 +1821,7 @@ bool copy_data(struct archive* ar, struct archive* aw)
bool extract_tar(const std::string& outFileName,
const std::vector<std::string>& files, bool verbose,
+ cmSystemTools::cmTarExtractTimestamps extractTimestamps,
bool extract)
{
cmLocaleRAII localeRAII;
@@ -1879,10 +1880,12 @@ bool extract_tar(const std::string& outFileName,
cmSystemTools::Stdout("\n");
}
if (extract) {
- r = archive_write_disk_set_options(ext, ARCHIVE_EXTRACT_TIME);
- if (r != ARCHIVE_OK) {
- ArchiveError("Problem with archive_write_disk_set_options(): ", ext);
- break;
+ if (extractTimestamps == cmSystemTools::cmTarExtractTimestamps::Yes) {
+ r = archive_write_disk_set_options(ext, ARCHIVE_EXTRACT_TIME);
+ if (r != ARCHIVE_OK) {
+ ArchiveError("Problem with archive_write_disk_set_options(): ", ext);
+ break;
+ }
}
r = archive_write_header(ext, entry);
@@ -1942,13 +1945,15 @@ bool extract_tar(const std::string& outFileName,
bool cmSystemTools::ExtractTar(const std::string& outFileName,
const std::vector<std::string>& files,
+ cmTarExtractTimestamps extractTimestamps,
bool verbose)
{
#if !defined(CMAKE_BOOTSTRAP)
- return extract_tar(outFileName, files, verbose, true);
+ return extract_tar(outFileName, files, verbose, extractTimestamps, true);
#else
(void)outFileName;
(void)files;
+ (void)extractTimestamps;
(void)verbose;
return false;
#endif
@@ -1959,7 +1964,8 @@ bool cmSystemTools::ListTar(const std::string& outFileName,
bool verbose)
{
#if !defined(CMAKE_BOOTSTRAP)
- return extract_tar(outFileName, files, verbose, false);
+ return extract_tar(outFileName, files, verbose, cmTarExtractTimestamps::Yes,
+ false);
#else
(void)outFileName;
(void)files;
@@ -3314,12 +3320,22 @@ cmsys::Status cmSystemTools::CreateSymlink(std::string const& origName,
uv_fs_t req;
int flags = 0;
#if defined(_WIN32)
- if (cmsys::SystemTools::FileIsDirectory(origName)) {
- flags |= UV_FS_SYMLINK_DIR;
+ bool const isDir = cmsys::SystemTools::FileIsDirectory(origName);
+ if (isDir) {
+ flags |= UV_FS_SYMLINK_JUNCTION;
}
#endif
int err = uv_fs_symlink(nullptr, &req, origName.c_str(), newName.c_str(),
flags, nullptr);
+#if defined(_WIN32)
+ if (err && uv_fs_get_system_error(&req) == ERROR_NOT_SUPPORTED && isDir) {
+ // Try fallback to symlink for network (requires additional permissions).
+ flags ^= UV_FS_SYMLINK_JUNCTION | UV_FS_SYMLINK_DIR;
+ err = uv_fs_symlink(nullptr, &req, origName.c_str(), newName.c_str(),
+ flags, nullptr);
+ }
+#endif
+
cmsys::Status status;
if (err) {
#if defined(_WIN32)
@@ -3413,3 +3429,12 @@ cm::string_view cmSystemTools::GetSystemName()
return "";
#endif
}
+
+char cmSystemTools::GetSystemPathlistSeparator()
+{
+#if defined(_WIN32)
+ return ';';
+#else
+ return ':';
+#endif
+}
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index 19dabe8..4865a4b 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -417,6 +417,12 @@ public:
TarCompressNone
};
+ enum class cmTarExtractTimestamps
+ {
+ Yes,
+ No
+ };
+
static bool ListTar(const std::string& outFileName,
const std::vector<std::string>& files, bool verbose);
static bool CreateTar(const std::string& outFileName,
@@ -426,7 +432,9 @@ public:
std::string const& format = std::string(),
int compressionLevel = 0);
static bool ExtractTar(const std::string& inFileName,
- const std::vector<std::string>& files, bool verbose);
+ const std::vector<std::string>& files,
+ cmTarExtractTimestamps extractTimestamps,
+ bool verbose);
// This should be called first thing in main
// it will keep child processes from inheriting the
// stdin and stdout of this process. This is important
@@ -527,6 +535,9 @@ public:
/** Get the system name. */
static cm::string_view GetSystemName();
+ /** Get the system path separator character */
+ static char GetSystemPathlistSeparator();
+
private:
static bool s_ForceUnixPaths;
static bool s_RunCommandHideConsole;
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 57e31b9..80d1940 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -13,6 +13,7 @@
#include <unordered_set>
#include <cm/memory>
+#include <cm/string_view>
#include <cmext/algorithm>
#include <cmext/string_view>
@@ -164,6 +165,66 @@ cmValue cmTargetPropertyComputer::GetSources<cmTarget>(cmTarget const* tgt,
return cmValue(srcs);
}
+namespace {
+struct FileSetEntries
+{
+ FileSetEntries(cm::static_string_view propertyName)
+ : PropertyName(propertyName)
+ {
+ }
+
+ cm::static_string_view const PropertyName;
+ std::vector<BT<std::string>> Entries;
+};
+
+struct FileSetType
+{
+ FileSetType(cm::static_string_view typeName,
+ cm::static_string_view defaultDirectoryProperty,
+ cm::static_string_view defaultPathProperty,
+ cm::static_string_view directoryPrefix,
+ cm::static_string_view pathPrefix,
+ cm::static_string_view typeDescription,
+ cm::static_string_view defaultDescription,
+ cm::static_string_view arbitraryDescription,
+ FileSetEntries selfEntries, FileSetEntries interfaceEntries)
+ : TypeName(typeName)
+ , DefaultDirectoryProperty(defaultDirectoryProperty)
+ , DefaultPathProperty(defaultPathProperty)
+ , DirectoryPrefix(directoryPrefix)
+ , PathPrefix(pathPrefix)
+ , TypeDescription(typeDescription)
+ , DefaultDescription(defaultDescription)
+ , ArbitraryDescription(arbitraryDescription)
+ , SelfEntries(std::move(selfEntries))
+ , InterfaceEntries(std::move(interfaceEntries))
+ {
+ }
+
+ cm::static_string_view const TypeName;
+ cm::static_string_view const DefaultDirectoryProperty;
+ cm::static_string_view const DefaultPathProperty;
+ cm::static_string_view const DirectoryPrefix;
+ cm::static_string_view const PathPrefix;
+ cm::static_string_view const TypeDescription;
+ cm::static_string_view const DefaultDescription;
+ cm::static_string_view const ArbitraryDescription;
+
+ FileSetEntries SelfEntries;
+ FileSetEntries InterfaceEntries;
+
+ template <typename ValueType>
+ bool WriteProperties(cmTarget* tgt, cmTargetInternals* impl,
+ const std::string& prop, ValueType value, bool clear);
+ std::pair<bool, cmValue> ReadProperties(cmTarget const* tgt,
+ cmTargetInternals const* impl,
+ const std::string& prop) const;
+
+ void AddFileSet(const std::string& name, cmFileSetVisibility vis,
+ cmListFileBacktrace bt);
+};
+}
+
class cmTargetInternals
{
public:
@@ -203,19 +264,154 @@ public:
std::vector<BT<std::string>> LinkDirectoriesEntries;
std::vector<BT<std::string>> LinkImplementationPropertyEntries;
std::vector<BT<std::string>> LinkInterfacePropertyEntries;
- std::vector<BT<std::string>> HeaderSetsEntries;
- std::vector<BT<std::string>> InterfaceHeaderSetsEntries;
+ std::vector<BT<std::string>> LinkInterfaceDirectPropertyEntries;
+ std::vector<BT<std::string>> LinkInterfaceDirectExcludePropertyEntries;
std::vector<std::pair<cmTarget::TLLSignature, cmListFileContext>>
TLLCommands;
std::map<std::string, cmFileSet> FileSets;
cmListFileBacktrace Backtrace;
+ FileSetType HeadersFileSets;
+
+ cmTargetInternals();
+
bool CheckImportedLibName(std::string const& prop,
std::string const& value) const;
std::string ProcessSourceItemCMP0049(const std::string& s) const;
+
+ template <typename ValueType>
+ void AddDirectoryToFileSet(cmTarget* self, std::string const& fileSetName,
+ ValueType value, cm::string_view fileSetType,
+ cm::string_view description, bool clear);
+ template <typename ValueType>
+ void AddPathToFileSet(cmTarget* self, std::string const& fileSetName,
+ ValueType value, cm::string_view fileSetType,
+ cm::string_view description, bool clear);
+ cmValue GetFileSetDirectories(cmTarget const* self,
+ std::string const& fileSetName,
+ cm::string_view fileSetType) const;
+ cmValue GetFileSetPaths(cmTarget const* self, std::string const& fileSetName,
+ cm::string_view fileSetType) const;
};
+cmTargetInternals::cmTargetInternals()
+ : HeadersFileSets("HEADERS"_s, "HEADER_DIRS"_s, "HEADER_SET"_s,
+ "HEADER_DIRS_"_s, "HEADER_SET_"_s, "Header"_s,
+ "The default header set"_s, "Header set"_s,
+ FileSetEntries("HEADER_SETS"_s),
+ FileSetEntries("INTERFACE_HEADER_SETS"_s))
+{
+}
+
+template <typename ValueType>
+bool FileSetType::WriteProperties(cmTarget* tgt, cmTargetInternals* impl,
+ const std::string& prop, ValueType value,
+ bool clear)
+{
+ if (prop == this->DefaultDirectoryProperty) {
+ impl->AddDirectoryToFileSet(tgt, std::string(this->TypeName), value,
+ this->TypeName, this->DefaultDescription,
+ clear);
+ return true;
+ }
+ if (prop == this->DefaultPathProperty) {
+ impl->AddPathToFileSet(tgt, std::string(this->TypeName), value,
+ this->TypeName, this->DefaultDescription, clear);
+ return true;
+ }
+ if (cmHasPrefix(prop, this->DirectoryPrefix)) {
+ auto fileSetName = prop.substr(this->DirectoryPrefix.size());
+ if (fileSetName.empty()) {
+ impl->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(this->ArbitraryDescription, " name cannot be empty."));
+ } else {
+ impl->AddDirectoryToFileSet(
+ tgt, fileSetName, value, this->TypeName,
+ cmStrCat(this->ArbitraryDescription, " \"", fileSetName, "\""), clear);
+ }
+ return true;
+ }
+ if (cmHasPrefix(prop, this->PathPrefix)) {
+ auto fileSetName = prop.substr(this->PathPrefix.size());
+ if (fileSetName.empty()) {
+ impl->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(this->ArbitraryDescription, " name cannot be empty."));
+ } else {
+ impl->AddPathToFileSet(
+ tgt, fileSetName, value, this->TypeName,
+ cmStrCat(this->ArbitraryDescription, " \"", fileSetName, "\""), clear);
+ }
+ return true;
+ }
+ if (prop == this->SelfEntries.PropertyName) {
+ impl->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(this->SelfEntries.PropertyName, " property is read-only\n"));
+ return true;
+ }
+ if (prop == this->InterfaceEntries.PropertyName) {
+ impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
+ cmStrCat(this->InterfaceEntries.PropertyName,
+ " property is read-only\n"));
+ return true;
+ }
+ return false;
+}
+
+std::pair<bool, cmValue> FileSetType::ReadProperties(
+ cmTarget const* tgt, cmTargetInternals const* impl,
+ const std::string& prop) const
+{
+ bool did_read = false;
+ cmValue value = nullptr;
+ if (prop == this->DefaultDirectoryProperty) {
+ value = impl->GetFileSetDirectories(tgt, std::string(this->TypeName),
+ this->TypeName);
+ did_read = true;
+ } else if (prop == this->DefaultPathProperty) {
+ value =
+ impl->GetFileSetPaths(tgt, std::string(this->TypeName), this->TypeName);
+ did_read = true;
+ } else if (prop == this->SelfEntries.PropertyName) {
+ static std::string output;
+ output = cmJoin(this->SelfEntries.Entries, ";"_s);
+ value = cmValue(output);
+ did_read = true;
+ } else if (prop == this->InterfaceEntries.PropertyName) {
+ static std::string output;
+ output = cmJoin(this->InterfaceEntries.Entries, ";"_s);
+ value = cmValue(output);
+ did_read = true;
+ } else if (cmHasPrefix(prop, this->DirectoryPrefix)) {
+ std::string fileSetName = prop.substr(this->DirectoryPrefix.size());
+ if (!fileSetName.empty()) {
+ value = impl->GetFileSetDirectories(tgt, fileSetName, this->TypeName);
+ }
+ did_read = true;
+ } else if (cmHasPrefix(prop, this->PathPrefix)) {
+ std::string fileSetName = prop.substr(this->PathPrefix.size());
+ if (!fileSetName.empty()) {
+ value = impl->GetFileSetPaths(tgt, fileSetName, this->TypeName);
+ }
+ did_read = true;
+ }
+ return { did_read, value };
+}
+
+void FileSetType::AddFileSet(const std::string& name, cmFileSetVisibility vis,
+ cmListFileBacktrace bt)
+{
+ if (cmFileSetVisibilityIsForSelf(vis)) {
+ this->SelfEntries.Entries.emplace_back(name, bt);
+ }
+ if (cmFileSetVisibilityIsForInterface(vis)) {
+ this->InterfaceEntries.Entries.emplace_back(name, std::move(bt));
+ }
+}
+
namespace {
#define SETUP_COMMON_LANGUAGE_PROPERTIES(lang) \
initProp(#lang "_COMPILER_LAUNCHER"); \
@@ -347,6 +543,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("LINK_DEPENDS_NO_SHARED");
initProp("LINK_INTERFACE_LIBRARIES");
initProp("MSVC_RUNTIME_LIBRARY");
+ initProp("WATCOM_RUNTIME_LIBRARY");
initProp("WIN32_EXECUTABLE");
initProp("MACOSX_BUNDLE");
initProp("MACOSX_RPATH");
@@ -391,6 +588,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("UNITY_BUILD_UNIQUE_ID");
initProp("OPTIMIZE_DEPENDENCIES");
initProp("EXPORT_COMPILE_COMMANDS");
+ initProp("COMPILE_WARNING_AS_ERROR");
initPropValue("UNITY_BUILD_BATCH_SIZE", "8");
initPropValue("UNITY_BUILD_MODE", "BATCH");
initPropValue("PCH_WARN_INVALID", "ON");
@@ -423,6 +621,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
}
initProp("FOLDER");
+ initProp("VERIFY_HEADER_SETS");
if (this->GetGlobalGenerator()->IsXcode()) {
initProp("XCODE_GENERATE_SCHEME");
@@ -688,6 +887,11 @@ bool cmTarget::IsAndroidGuiExecutable() const
this->impl->IsAndroid && this->GetPropertyAsBool("ANDROID_GUI"));
}
+bool cmTarget::HasKnownObjectFileLocation(std::string* reason) const
+{
+ return this->GetGlobalGenerator()->HasKnownObjectFileLocation(*this, reason);
+}
+
std::vector<cmCustomCommand> const& cmTarget::GetPreBuildCommands() const
{
return this->impl->PreBuildCommands;
@@ -1089,7 +1293,12 @@ void cmTarget::AddInstallIncludeDirectories(cmTargetExport const& te,
cmStringRange cmTarget::GetInstallIncludeDirectoriesEntries(
cmTargetExport const& te) const
{
- return cmMakeRange(this->impl->InstallIncludeDirectoriesEntries[&te]);
+ auto i = this->impl->InstallIncludeDirectoriesEntries.find(&te);
+ if (i == this->impl->InstallIncludeDirectoriesEntries.end()) {
+ decltype(i->second) empty;
+ return cmMakeRange(empty);
+ }
+ return cmMakeRange(i->second);
}
cmBTStringRange cmTarget::GetIncludeDirectoriesEntries() const
@@ -1142,14 +1351,24 @@ cmBTStringRange cmTarget::GetLinkInterfaceEntries() const
return cmMakeRange(this->impl->LinkInterfacePropertyEntries);
}
+cmBTStringRange cmTarget::GetLinkInterfaceDirectEntries() const
+{
+ return cmMakeRange(this->impl->LinkInterfaceDirectPropertyEntries);
+}
+
+cmBTStringRange cmTarget::GetLinkInterfaceDirectExcludeEntries() const
+{
+ return cmMakeRange(this->impl->LinkInterfaceDirectExcludePropertyEntries);
+}
+
cmBTStringRange cmTarget::GetHeaderSetsEntries() const
{
- return cmMakeRange(this->impl->HeaderSetsEntries);
+ return cmMakeRange(this->impl->HeadersFileSets.SelfEntries.Entries);
}
cmBTStringRange cmTarget::GetInterfaceHeaderSetsEntries() const
{
- return cmMakeRange(this->impl->InterfaceHeaderSetsEntries);
+ return cmMakeRange(this->impl->HeadersFileSets.InterfaceEntries.Entries);
}
namespace {
@@ -1181,11 +1400,9 @@ MAKE_PROP(BINARY_DIR);
MAKE_PROP(SOURCE_DIR);
MAKE_PROP(FALSE);
MAKE_PROP(TRUE);
-MAKE_PROP(HEADER_DIRS);
-MAKE_PROP(HEADER_SET);
-MAKE_PROP(HEADER_SETS);
-MAKE_PROP(INTERFACE_HEADER_SETS);
MAKE_PROP(INTERFACE_LINK_LIBRARIES);
+MAKE_PROP(INTERFACE_LINK_LIBRARIES_DIRECT);
+MAKE_PROP(INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE);
#undef MAKE_PROP
}
@@ -1207,19 +1424,25 @@ std::string ConvertToString<cmValue>(cmValue value)
}
template <typename ValueType>
-bool StringIsEmpty(ValueType value);
+bool StringIsEmpty(ValueType const& value);
template <>
-bool StringIsEmpty<const char*>(const char* value)
+bool StringIsEmpty<const char*>(const char* const& value)
{
return cmValue::IsEmpty(value);
}
template <>
-bool StringIsEmpty<cmValue>(cmValue value)
+bool StringIsEmpty<cmValue>(cmValue const& value)
{
return value.IsEmpty();
}
+
+template <>
+bool StringIsEmpty<std::string>(std::string const& value)
+{
+ return value.empty();
+}
}
template <typename ValueType>
@@ -1317,6 +1540,19 @@ void cmTarget::StoreProperty(const std::string& prop, ValueType value)
cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
this->impl->LinkInterfacePropertyEntries.emplace_back(value, lfbt);
}
+ } else if (prop == propINTERFACE_LINK_LIBRARIES_DIRECT) {
+ this->impl->LinkInterfaceDirectPropertyEntries.clear();
+ if (value) {
+ cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ this->impl->LinkInterfaceDirectPropertyEntries.emplace_back(value, lfbt);
+ }
+ } else if (prop == propINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE) {
+ this->impl->LinkInterfaceDirectExcludePropertyEntries.clear();
+ if (value) {
+ cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ this->impl->LinkInterfaceDirectExcludePropertyEntries.emplace_back(value,
+ lfbt);
+ }
} else if (prop == propSOURCES) {
this->impl->SourceEntries.clear();
if (value) {
@@ -1338,7 +1574,9 @@ void cmTarget::StoreProperty(const std::string& prop, ValueType value)
}
} else if (cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME") &&
!this->impl->CheckImportedLibName(
- prop, value ? value : std::string{})) {
+ prop,
+ value ? value
+ : std::string{})) { // NOLINT(bugprone-branch-clone)
/* error was reported by check method */
} else if (prop == propCUDA_PTX_COMPILATION &&
this->GetType() != cmStateEnums::OBJECT_LIBRARY) {
@@ -1389,81 +1627,9 @@ void cmTarget::StoreProperty(const std::string& prop, ValueType value)
} else {
this->impl->LanguageStandardProperties.erase(prop);
}
- } else if (prop == propHEADER_DIRS) {
- auto* fileSet = this->GetFileSet("HEADERS");
- if (!fileSet) {
- this->impl->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- "The default header set has not yet been created.");
- return;
- }
- fileSet->ClearDirectoryEntries();
- if (!StringIsEmpty(value)) {
- fileSet->AddDirectoryEntry(
- BT<std::string>(value, this->impl->Makefile->GetBacktrace()));
- }
- } else if (prop == propHEADER_SET) {
- auto* fileSet = this->GetFileSet("HEADERS");
- if (!fileSet) {
- this->impl->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- "The default header set has not yet been created.");
- return;
- }
- fileSet->ClearFileEntries();
- if (!StringIsEmpty(value)) {
- fileSet->AddFileEntry(
- BT<std::string>(value, this->impl->Makefile->GetBacktrace()));
- }
- } else if (cmHasLiteralPrefix(prop, "HEADER_DIRS_")) {
- auto fileSetName = prop.substr(cmStrLen("HEADER_DIRS_"));
- if (fileSetName.empty()) {
- this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
- "Header set name cannot be empty.");
- return;
- }
- auto* fileSet = this->GetFileSet(fileSetName);
- if (!fileSet) {
- this->impl->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- cmStrCat("Header set \"", fileSetName,
- "\" has not yet been created."));
- return;
- }
- fileSet->ClearDirectoryEntries();
- if (!StringIsEmpty(value)) {
- fileSet->AddDirectoryEntry(
- BT<std::string>(value, this->impl->Makefile->GetBacktrace()));
- }
- } else if (cmHasLiteralPrefix(prop, "HEADER_SET_")) {
- auto fileSetName = prop.substr(cmStrLen("HEADER_SET_"));
- if (fileSetName.empty()) {
- this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
- "Header set name cannot be empty.");
- return;
- }
- auto* fileSet = this->GetFileSet(fileSetName);
- if (!fileSet) {
- this->impl->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- cmStrCat("Header set \"", fileSetName,
- "\" has not yet been created."));
- return;
- }
- fileSet->ClearFileEntries();
- if (!StringIsEmpty(value)) {
- fileSet->AddFileEntry(
- BT<std::string>(value, this->impl->Makefile->GetBacktrace()));
- }
- } else if (prop == propHEADER_SETS) {
- this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
- "HEADER_SETS property is read-only\n");
- return;
- } else if (prop == propINTERFACE_HEADER_SETS) {
- this->impl->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- "INTERFACE_HEADER_SETS property is read-only\n");
- return;
+ } else if (this->impl->HeadersFileSets.WriteProperties(
+ this, this->impl.get(), prop, value, true)) {
+ /* Handled in the `if` condition. */
} else {
this->impl->Properties.SetProperty(prop, value);
}
@@ -1552,6 +1718,17 @@ void cmTarget::AppendProperty(const std::string& prop,
cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
this->impl->LinkInterfacePropertyEntries.emplace_back(value, lfbt);
}
+ } else if (prop == propINTERFACE_LINK_LIBRARIES_DIRECT) {
+ if (!value.empty()) {
+ cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ this->impl->LinkInterfaceDirectPropertyEntries.emplace_back(value, lfbt);
+ }
+ } else if (prop == propINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE) {
+ if (!value.empty()) {
+ cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ this->impl->LinkInterfaceDirectExcludePropertyEntries.emplace_back(value,
+ lfbt);
+ }
} else if (prop == "SOURCES") {
cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
this->impl->SourceEntries.emplace_back(value, lfbt);
@@ -1563,69 +1740,9 @@ void cmTarget::AppendProperty(const std::string& prop,
prop == "OBJC_STANDARD" || prop == "OBJCXX_STANDARD") {
this->impl->Makefile->IssueMessage(
MessageType::FATAL_ERROR, prop + " property may not be appended.");
- } else if (prop == "HEADER_DIRS") {
- auto* fileSet = this->GetFileSet("HEADERS");
- if (!fileSet) {
- this->impl->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- "The default header set has not yet been created.");
- return;
- }
- fileSet->AddDirectoryEntry(
- BT<std::string>(value, this->impl->Makefile->GetBacktrace()));
- } else if (cmHasLiteralPrefix(prop, "HEADER_DIRS_")) {
- auto fileSetName = prop.substr(cmStrLen("HEADER_DIRS_"));
- if (fileSetName.empty()) {
- this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
- "Header set name cannot be empty.");
- return;
- }
- auto* fileSet = this->GetFileSet(fileSetName);
- if (!fileSet) {
- this->impl->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- cmStrCat("Header set \"", fileSetName,
- "\" has not yet been created."));
- return;
- }
- fileSet->AddDirectoryEntry(
- BT<std::string>(value, this->impl->Makefile->GetBacktrace()));
- } else if (prop == "HEADER_SET") {
- auto* fileSet = this->GetFileSet("HEADERS");
- if (!fileSet) {
- this->impl->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- "The default header set has not yet been created.");
- return;
- }
- fileSet->AddFileEntry(
- BT<std::string>(value, this->impl->Makefile->GetBacktrace()));
- } else if (cmHasLiteralPrefix(prop, "HEADER_SET_")) {
- auto fileSetName = prop.substr(cmStrLen("HEADER_SET_"));
- if (fileSetName.empty()) {
- this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
- "Header set name cannot be empty.");
- return;
- }
- auto* fileSet = this->GetFileSet(fileSetName);
- if (!fileSet) {
- this->impl->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- cmStrCat("Header set \"", fileSetName,
- "\" has not yet been created."));
- return;
- }
- fileSet->AddFileEntry(
- BT<std::string>(value, this->impl->Makefile->GetBacktrace()));
- } else if (prop == "HEADER_SETS") {
- this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
- "HEADER_SETS property is read-only\n");
- return;
- } else if (prop == "INTERFACE_HEADER_SETS") {
- this->impl->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- "INTERFACE_HEADER_SETS property is read-only\n");
- return;
+ } else if (this->impl->HeadersFileSets.WriteProperties(
+ this, this->impl.get(), prop, value, false)) {
+ /* Handled in the `if` condition. */
} else {
this->impl->Properties.AppendProperty(prop, value, asString);
}
@@ -1640,6 +1757,102 @@ void cmTarget::SetProperty(const std::string& prop, cmValue value)
this->StoreProperty(prop, value);
}
+template <typename ValueType>
+void cmTargetInternals::AddDirectoryToFileSet(
+ cmTarget* self, std::string const& fileSetName, ValueType value,
+ cm::string_view fileSetType, cm::string_view description, bool clear)
+{
+ auto* fileSet = self->GetFileSet(fileSetName);
+ if (!fileSet) {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(description, "has not yet been created."));
+ return;
+ }
+ if (fileSet->GetType() != fileSetType) {
+ this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
+ cmStrCat("File set \"", fileSetName,
+ "\" is not of type \"", fileSetType,
+ "\"."));
+ return;
+ }
+ if (clear) {
+ fileSet->ClearDirectoryEntries();
+ }
+ if (!StringIsEmpty(value)) {
+ fileSet->AddDirectoryEntry(
+ BT<std::string>(value, this->Makefile->GetBacktrace()));
+ }
+}
+
+template <typename ValueType>
+void cmTargetInternals::AddPathToFileSet(
+ cmTarget* self, std::string const& fileSetName, ValueType value,
+ cm::string_view fileSetType, cm::string_view description, bool clear)
+{
+ auto* fileSet = self->GetFileSet(fileSetName);
+ if (!fileSet) {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(description, "has not yet been created."));
+ return;
+ }
+ if (fileSet->GetType() != fileSetType) {
+ this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
+ cmStrCat("File set \"", fileSetName,
+ "\" is not of type \"", fileSetType,
+ "\"."));
+ return;
+ }
+ if (clear) {
+ fileSet->ClearFileEntries();
+ }
+ if (!StringIsEmpty(value)) {
+ fileSet->AddFileEntry(
+ BT<std::string>(value, this->Makefile->GetBacktrace()));
+ }
+}
+
+cmValue cmTargetInternals::GetFileSetDirectories(
+ cmTarget const* self, std::string const& fileSetName,
+ cm::string_view fileSetType) const
+{
+ auto const* fileSet = self->GetFileSet(fileSetName);
+ if (!fileSet) {
+ return nullptr;
+ }
+ if (fileSet->GetType() != fileSetType) {
+ this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
+ cmStrCat("File set \"", fileSetName,
+ "\" is not of type \"", fileSetType,
+ "\"."));
+ return nullptr;
+ }
+ static std::string output;
+ output = cmJoin(fileSet->GetDirectoryEntries(), ";"_s);
+ return cmValue(output);
+}
+
+cmValue cmTargetInternals::GetFileSetPaths(cmTarget const* self,
+ std::string const& fileSetName,
+ cm::string_view fileSetType) const
+{
+ auto const* fileSet = self->GetFileSet(fileSetName);
+ if (!fileSet) {
+ return nullptr;
+ }
+ if (fileSet->GetType() != fileSetType) {
+ this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
+ cmStrCat("File set \"", fileSetName,
+ "\" is not of type \"", fileSetType,
+ "\"."));
+ return nullptr;
+ }
+ static std::string output;
+ output = cmJoin(fileSet->GetFileEntries(), ";"_s);
+ return cmValue(output);
+}
+
void cmTarget::AppendBuildInterfaceIncludes()
{
if (this->GetType() != cmStateEnums::SHARED_LIBRARY &&
@@ -1709,69 +1922,94 @@ void cmTarget::InsertPrecompileHeader(BT<std::string> const& entry)
this->impl->PrecompileHeadersEntries.push_back(entry);
}
-static void cmTargetCheckLINK_INTERFACE_LIBRARIES(const std::string& prop,
- const std::string& value,
- cmMakefile* context,
- bool imported)
+namespace {
+void CheckLinkLibraryPattern(const std::string& property,
+ const std::string& value, cmMakefile* context)
{
- // Look for link-type keywords in the value.
- static cmsys::RegularExpression keys("(^|;)(debug|optimized|general)(;|$)");
- if (!keys.find(value)) {
+ // Look for <LINK_LIBRARY:> and </LINK_LIBRARY:> internal tags
+ static cmsys::RegularExpression linkPattern(
+ "(^|;)(</?LINK_(LIBRARY|GROUP):[^;>]*>)(;|$)");
+ if (!linkPattern.find(value)) {
return;
}
+ // Report an error.
+ context->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(
+ "Property ", property, " contains the invalid item \"",
+ linkPattern.match(2), "\". The ", property,
+ " property may contain the generator-expression \"$<LINK_",
+ linkPattern.match(3),
+ ":...>\" which may be used to specify how the libraries are linked."));
+}
+
+void CheckLINK_INTERFACE_LIBRARIES(const std::string& prop,
+ const std::string& value,
+ cmMakefile* context, bool imported)
+{
// Support imported and non-imported versions of the property.
const char* base = (imported ? "IMPORTED_LINK_INTERFACE_LIBRARIES"
: "LINK_INTERFACE_LIBRARIES");
- // Report an error.
- std::ostringstream e;
- e << "Property " << prop << " may not contain link-type keyword \""
- << keys.match(2) << "\". "
- << "The " << base << " property has a per-configuration "
- << "version called " << base << "_<CONFIG> which may be "
- << "used to specify per-configuration rules.";
- if (!imported) {
- e << " "
- << "Alternatively, an IMPORTED library may be created, configured "
- << "with a per-configuration location, and then named in the "
- << "property value. "
- << "See the add_library command's IMPORTED mode for details."
- << "\n"
- << "If you have a list of libraries that already contains the "
- << "keyword, use the target_link_libraries command with its "
- << "LINK_INTERFACE_LIBRARIES mode to set the property. "
- << "The command automatically recognizes link-type keywords and sets "
- << "the LINK_INTERFACE_LIBRARIES and LINK_INTERFACE_LIBRARIES_DEBUG "
- << "properties accordingly.";
- }
- context->IssueMessage(MessageType::FATAL_ERROR, e.str());
-}
-
-static void cmTargetCheckINTERFACE_LINK_LIBRARIES(const std::string& value,
- cmMakefile* context)
-{
// Look for link-type keywords in the value.
static cmsys::RegularExpression keys("(^|;)(debug|optimized|general)(;|$)");
- if (!keys.find(value)) {
- return;
+ if (keys.find(value)) {
+ // Report an error.
+ std::ostringstream e;
+ e << "Property " << prop << " may not contain link-type keyword \""
+ << keys.match(2) << "\". "
+ << "The " << base << " property has a per-configuration "
+ << "version called " << base << "_<CONFIG> which may be "
+ << "used to specify per-configuration rules.";
+ if (!imported) {
+ e << " "
+ << "Alternatively, an IMPORTED library may be created, configured "
+ << "with a per-configuration location, and then named in the "
+ << "property value. "
+ << "See the add_library command's IMPORTED mode for details."
+ << "\n"
+ << "If you have a list of libraries that already contains the "
+ << "keyword, use the target_link_libraries command with its "
+ << "LINK_INTERFACE_LIBRARIES mode to set the property. "
+ << "The command automatically recognizes link-type keywords and sets "
+ << "the LINK_INTERFACE_LIBRARIES and LINK_INTERFACE_LIBRARIES_DEBUG "
+ << "properties accordingly.";
+ }
+ context->IssueMessage(MessageType::FATAL_ERROR, e.str());
}
- // Report an error.
- std::ostringstream e;
+ CheckLinkLibraryPattern(base, value, context);
+}
+
+void CheckLINK_LIBRARIES(const std::string& value, cmMakefile* context)
+{
+ CheckLinkLibraryPattern("LINK_LIBRARIES", value, context);
+}
+
+void CheckINTERFACE_LINK_LIBRARIES(const std::string& value,
+ cmMakefile* context)
+{
+ // Look for link-type keywords in the value.
+ static cmsys::RegularExpression keys("(^|;)(debug|optimized|general)(;|$)");
+ if (keys.find(value)) {
+ // Report an error.
+ std::ostringstream e;
- e << "Property INTERFACE_LINK_LIBRARIES may not contain link-type "
- "keyword \""
- << keys.match(2)
- << "\". The INTERFACE_LINK_LIBRARIES "
- "property may contain configuration-sensitive generator-expressions "
- "which may be used to specify per-configuration rules.";
+ e << "Property INTERFACE_LINK_LIBRARIES may not contain link-type "
+ "keyword \""
+ << keys.match(2)
+ << "\". The INTERFACE_LINK_LIBRARIES "
+ "property may contain configuration-sensitive generator-expressions "
+ "which may be used to specify per-configuration rules.";
- context->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ context->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ }
+
+ CheckLinkLibraryPattern("INTERFACE_LINK_LIBRARIES", value, context);
}
-static void cmTargetCheckIMPORTED_GLOBAL(const cmTarget* target,
- cmMakefile* context)
+void CheckIMPORTED_GLOBAL(const cmTarget* target, cmMakefile* context)
{
const auto& targets = context->GetOwnedImportedTargets();
auto it =
@@ -1787,6 +2025,7 @@ static void cmTargetCheckIMPORTED_GLOBAL(const cmTarget* target,
context->IssueMessage(MessageType::FATAL_ERROR, e.str());
}
}
+}
void cmTarget::CheckProperty(const std::string& prop,
cmMakefile* context) const
@@ -1794,22 +2033,23 @@ void cmTarget::CheckProperty(const std::string& prop,
// Certain properties need checking.
if (cmHasLiteralPrefix(prop, "LINK_INTERFACE_LIBRARIES")) {
if (cmValue value = this->GetProperty(prop)) {
- cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, *value, context, false);
+ CheckLINK_INTERFACE_LIBRARIES(prop, *value, context, false);
}
- }
- if (cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES")) {
+ } else if (cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES")) {
if (cmValue value = this->GetProperty(prop)) {
- cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, *value, context, true);
+ CheckLINK_INTERFACE_LIBRARIES(prop, *value, context, true);
}
- }
- if (prop == "INTERFACE_LINK_LIBRARIES") {
+ } else if (prop == "LINK_LIBRARIES") {
if (cmValue value = this->GetProperty(prop)) {
- cmTargetCheckINTERFACE_LINK_LIBRARIES(*value, context);
+ CheckLINK_LIBRARIES(*value, context);
}
- }
- if (prop == "IMPORTED_GLOBAL") {
+ } else if (prop == "INTERFACE_LINK_LIBRARIES") {
+ if (cmValue value = this->GetProperty(prop)) {
+ CheckINTERFACE_LINK_LIBRARIES(*value, context);
+ }
+ } else if (prop == "IMPORTED_GLOBAL") {
if (this->IsImported()) {
- cmTargetCheckIMPORTED_GLOBAL(this, context);
+ CheckIMPORTED_GLOBAL(this, context);
}
}
}
@@ -1844,11 +2084,9 @@ cmValue cmTarget::GetProperty(const std::string& prop) const
propBINARY_DIR,
propSOURCE_DIR,
propSOURCES,
- propHEADER_DIRS,
- propHEADER_SET,
- propHEADER_SETS,
- propINTERFACE_HEADER_SETS,
propINTERFACE_LINK_LIBRARIES,
+ propINTERFACE_LINK_LIBRARIES_DIRECT,
+ propINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE,
};
if (specialProps.count(prop)) {
if (prop == propC_STANDARD || prop == propCXX_STANDARD ||
@@ -1878,6 +2116,25 @@ cmValue cmTarget::GetProperty(const std::string& prop) const
output = cmJoin(this->impl->LinkInterfacePropertyEntries, ";");
return cmValue(output);
}
+ if (prop == propINTERFACE_LINK_LIBRARIES_DIRECT) {
+ if (this->impl->LinkInterfaceDirectPropertyEntries.empty()) {
+ return nullptr;
+ }
+
+ static std::string output;
+ output = cmJoin(this->impl->LinkInterfaceDirectPropertyEntries, ";");
+ return cmValue(output);
+ }
+ if (prop == propINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE) {
+ if (this->impl->LinkInterfaceDirectExcludePropertyEntries.empty()) {
+ return nullptr;
+ }
+
+ static std::string output;
+ output =
+ cmJoin(this->impl->LinkInterfaceDirectExcludePropertyEntries, ";");
+ return cmValue(output);
+ }
// the type property returns what type the target is
if (prop == propTYPE) {
return cmValue(cmState::GetTargetTypeName(this->GetType()));
@@ -1983,73 +2240,15 @@ cmValue cmTarget::GetProperty(const std::string& prop) const
.GetDirectory()
.GetCurrentSource());
}
- if (prop == propHEADER_DIRS) {
- auto const* fileSet = this->GetFileSet("HEADERS");
- if (!fileSet) {
- return nullptr;
- }
- static std::string output;
- output = cmJoin(fileSet->GetDirectoryEntries(), ";"_s);
- return cmValue(output);
- }
- if (prop == propHEADER_SET) {
- auto const* fileSet = this->GetFileSet("HEADERS");
- if (!fileSet) {
- return nullptr;
- }
- static std::string output;
- output = cmJoin(fileSet->GetFileEntries(), ";"_s);
- return cmValue(output);
- }
- if (prop == propHEADER_SETS) {
- std::vector<std::string> set_names;
- for (auto const& file_set : this->impl->FileSets) {
- if (cmFileSetVisibilityIsForSelf(file_set.second.GetVisibility())) {
- set_names.push_back(file_set.second.GetName());
- }
- }
- static std::string output;
- output = cmJoin(set_names, ";"_s);
- return cmValue(output);
- }
- if (prop == propINTERFACE_HEADER_SETS) {
- std::vector<std::string> set_names;
- for (auto const& file_set : this->impl->FileSets) {
- if (cmFileSetVisibilityIsForInterface(
- file_set.second.GetVisibility())) {
- set_names.push_back(file_set.second.GetName());
- }
- }
- static std::string output;
- output = cmJoin(set_names, ";"_s);
- return cmValue(output);
- }
- }
- if (cmHasLiteralPrefix(prop, "HEADER_DIRS_")) {
- std::string fileSetName = prop.substr(cmStrLen("HEADER_DIRS_"));
- if (fileSetName.empty()) {
- return nullptr;
- }
- auto const* fileSet = this->GetFileSet(fileSetName);
- if (!fileSet) {
- return nullptr;
- }
- static std::string output;
- output = cmJoin(fileSet->GetDirectoryEntries(), ";"_s);
- return cmValue(output);
}
- if (cmHasLiteralPrefix(prop, "HEADER_SET_")) {
- std::string fileSetName = prop.substr(cmStrLen("HEADER_SET_"));
- if (fileSetName.empty()) {
- return nullptr;
- }
- auto const* fileSet = this->GetFileSet(fileSetName);
- if (!fileSet) {
- return nullptr;
+
+ // Check fileset properties.
+ {
+ auto headers =
+ this->impl->HeadersFileSets.ReadProperties(this, this->impl.get(), prop);
+ if (headers.first) {
+ return headers.second;
}
- static std::string output;
- output = cmJoin(fileSet->GetFileEntries(), ";"_s);
- return cmValue(output);
}
cmValue retVal = this->impl->Properties.GetPropertyValue(prop);
@@ -2324,13 +2523,9 @@ std::pair<cmFileSet*, bool> cmTarget::GetOrCreateFileSet(
auto result = this->impl->FileSets.emplace(
std::make_pair(name, cmFileSet(name, type, vis)));
if (result.second) {
- if (cmFileSetVisibilityIsForSelf(vis)) {
- this->impl->HeaderSetsEntries.emplace_back(
- name, this->impl->Makefile->GetBacktrace());
- }
- if (cmFileSetVisibilityIsForInterface(vis)) {
- this->impl->InterfaceHeaderSetsEntries.emplace_back(
- name, this->impl->Makefile->GetBacktrace());
+ auto bt = this->impl->Makefile->GetBacktrace();
+ if (type == this->impl->HeadersFileSets.TypeName) {
+ this->impl->HeadersFileSets.AddFileSet(name, vis, std::move(bt));
}
}
return std::make_pair(&result.first->second, result.second);
@@ -2352,6 +2547,17 @@ std::string cmTarget::GetInterfaceFileSetsPropertyName(const std::string& type)
return "";
}
+std::vector<std::string> cmTarget::GetAllFileSetNames() const
+{
+ std::vector<std::string> result;
+
+ for (auto const& it : this->impl->FileSets) {
+ result.push_back(it.first);
+ }
+
+ return result;
+}
+
std::vector<std::string> cmTarget::GetAllInterfaceFileSets() const
{
std::vector<std::string> result;
@@ -2364,7 +2570,7 @@ std::vector<std::string> cmTarget::GetAllInterfaceFileSets() const
}
};
- appendEntries(this->impl->InterfaceHeaderSetsEntries);
+ appendEntries(this->impl->HeadersFileSets.InterfaceEntries.Entries);
return result;
}
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 3623854..5ed018e 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -220,6 +220,8 @@ public:
//! Return whether this target is a GUI executable on Android.
bool IsAndroidGuiExecutable() const;
+ bool HasKnownObjectFileLocation(std::string* reason = nullptr) const;
+
//! Get a backtrace from the creation of the target.
cmListFileBacktrace const& GetBacktrace() const;
@@ -269,6 +271,8 @@ public:
cmBTStringRange GetLinkImplementationEntries() const;
cmBTStringRange GetLinkInterfaceEntries() const;
+ cmBTStringRange GetLinkInterfaceDirectEntries() const;
+ cmBTStringRange GetLinkInterfaceDirectExcludeEntries() const;
cmBTStringRange GetHeaderSetsEntries() const;
@@ -288,6 +292,7 @@ public:
const std::string& type,
cmFileSetVisibility vis);
+ std::vector<std::string> GetAllFileSetNames() const;
std::vector<std::string> GetAllInterfaceFileSets() const;
static std::string GetFileSetsPropertyName(const std::string& type);
diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx
index e10d0b5..e1a6c78 100644
--- a/Source/cmTargetLinkLibrariesCommand.cxx
+++ b/Source/cmTargetLinkLibrariesCommand.cxx
@@ -379,6 +379,9 @@ bool cmTargetLinkLibrariesCommand(std::vector<std::string> const& args,
target->SetProperty("LINK_INTERFACE_LIBRARIES", "");
}
+ target->CheckProperty("LINK_LIBRARIES", &mf);
+ target->CheckProperty("INTERFACE_LINK_LIBRARIES", &mf);
+
return true;
}
diff --git a/Source/cmTryCompileCommand.cxx b/Source/cmTryCompileCommand.cxx
index 05b3f05..130c228 100644
--- a/Source/cmTryCompileCommand.cxx
+++ b/Source/cmTryCompileCommand.cxx
@@ -20,7 +20,7 @@ bool cmTryCompileCommand::InitialPass(std::vector<std::string> const& argv,
cmake::FIND_PACKAGE_MODE) {
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
- "The TRY_COMPILE() command is not supported in --find-package mode.");
+ "The try_compile() command is not supported in --find-package mode.");
return false;
}
diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx
index cd468b9..c82ac64 100644
--- a/Source/cmTryRunCommand.cxx
+++ b/Source/cmTryRunCommand.cxx
@@ -31,7 +31,7 @@ bool cmTryRunCommand::InitialPass(std::vector<std::string> const& argv,
cmake::FIND_PACKAGE_MODE) {
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
- "The TRY_RUN() command is not supported in --find-package mode.");
+ "The try_run() command is not supported in --find-package mode.");
return false;
}
@@ -217,7 +217,7 @@ void cmTryRunCommand::RunExecutable(const std::string& runArgs,
retStr = "FAILED_TO_RUN";
}
this->Makefile->AddCacheDefinition(this->RunResultVariable, retStr,
- "Result of TRY_RUN",
+ "Result of try_run()",
cmStateEnums::INTERNAL);
}
@@ -230,7 +230,7 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
std::string* out)
{
// copy the executable out of the CMakeFiles/ directory, so it is not
- // removed at the end of TRY_RUN and the user can run it manually
+ // removed at the end of try_run() and the user can run it manually
// on the target platform.
std::string copyDest =
cmStrCat(this->Makefile->GetHomeOutputDirectory(), "/CMakeFiles/",
@@ -252,7 +252,7 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
// if the variables doesn't exist, create it with a helpful error text
// and mark it as advanced
std::string comment =
- cmStrCat("Run result of TRY_RUN(), indicates whether the executable "
+ cmStrCat("Run result of try_run(), indicates whether the executable "
"would have been able to run on its target platform.\n",
detailsString);
this->Makefile->AddCacheDefinition(this->RunResultVariable,
@@ -274,7 +274,7 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
// if the variables doesn't exist, create it with a helpful error text
// and mark it as advanced
std::string comment = cmStrCat(
- "Output of TRY_RUN(), contains the text, which the executable "
+ "Output of try_run(), contains the text, which the executable "
"would have printed on stdout and stderr on its target platform.\n",
detailsString);
@@ -299,7 +299,7 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
if (firstTryRun) {
/* clang-format off */
file << "# This file was generated by CMake because it detected "
- "TRY_RUN() commands\n"
+ "try_run() commands\n"
"# in crosscompiling mode. It will be overwritten by the next "
"CMake run.\n"
"# Copy it to a safe location, set the variables to "
@@ -332,7 +332,7 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
}
comment += "The ";
comment += this->CompileResultVariable;
- comment += " variable holds the build result for this TRY_RUN().\n\n"
+ comment += " variable holds the build result for this try_run().\n\n"
"Source file : ";
comment += srcFile + "\n";
comment += "Executable : ";
@@ -346,19 +346,19 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
file << "set( " << this->RunResultVariable << " \n \""
<< this->Makefile->GetSafeDefinition(this->RunResultVariable)
- << "\"\n CACHE STRING \"Result from TRY_RUN\" FORCE)\n\n";
+ << "\"\n CACHE STRING \"Result from try_run\" FORCE)\n\n";
if (out) {
file << "set( " << internalRunOutputName << " \n \""
<< this->Makefile->GetSafeDefinition(internalRunOutputName)
- << "\"\n CACHE STRING \"Output from TRY_RUN\" FORCE)\n\n";
+ << "\"\n CACHE STRING \"Output from try_run\" FORCE)\n\n";
}
file.close();
}
firstTryRun = false;
std::string errorMessage =
- cmStrCat("TRY_RUN() invoked in cross-compiling mode, "
+ cmStrCat("try_run() invoked in cross-compiling mode, "
"please set the following cache variables "
"appropriately:\n ",
this->RunResultVariable, " (advanced)\n");
diff --git a/Source/cmVSSetupHelper.cxx b/Source/cmVSSetupHelper.cxx
index cbd241b..1a3e72e 100644
--- a/Source/cmVSSetupHelper.cxx
+++ b/Source/cmVSSetupHelper.cxx
@@ -4,6 +4,11 @@
#include <utility>
+#if !defined(CMAKE_BOOTSTRAP)
+# include <cm3p/json/reader.h>
+# include <cm3p/json/value.h>
+#endif
+
#include "cmsys/Encoding.hxx"
#include "cmsys/FStream.hxx"
@@ -295,6 +300,87 @@ bool cmVSSetupAPIHelper::IsEWDKEnabled()
return false;
}
+bool cmVSSetupAPIHelper::EnumerateVSInstancesWithVswhere(
+ std::vector<VSInstanceInfo>& VSInstances)
+{
+#if !defined(CMAKE_BOOTSTRAP)
+ // Construct vswhere command to get installed VS instances in JSON format
+ std::string vswhereExe = getenv("ProgramFiles(x86)") +
+ std::string(R"(\Microsoft Visual Studio\Installer\vswhere.exe)");
+ std::vector<std::string> vswhereCmd = { vswhereExe, "-format", "json" };
+
+ // Execute vswhere command and capture JSON output
+ std::string json_output;
+ int retVal = 1;
+ if (!cmSystemTools::RunSingleCommand(vswhereCmd, &json_output, &json_output,
+ &retVal, nullptr,
+ cmSystemTools::OUTPUT_NONE)) {
+ return false;
+ }
+
+ // Parse JSON output and iterate over elements
+ Json::CharReaderBuilder builder;
+ auto jsonReader = std::unique_ptr<Json::CharReader>(builder.newCharReader());
+ Json::Value json;
+ std::string error;
+
+ if (!jsonReader->parse(json_output.data(),
+ json_output.data() + json_output.size(), &json,
+ &error)) {
+ return false;
+ }
+
+ for (const auto& item : json) {
+ VSInstanceInfo instance;
+ instance.Version = item["installationVersion"].asString();
+ instance.VSInstallLocation = item["installationPath"].asString();
+ instance.IsWin10SDKInstalled = true;
+ instance.IsWin81SDKInstalled = false;
+ cmSystemTools::ConvertToUnixSlashes(instance.VSInstallLocation);
+ if (LoadVSInstanceVCToolsetVersion(instance)) {
+ VSInstances.push_back(instance);
+ }
+ }
+ return true;
+#else
+ static_cast<void>(VSInstances);
+ return false;
+#endif
+}
+
+bool cmVSSetupAPIHelper::EnumerateVSInstancesWithCOM(
+ std::vector<VSInstanceInfo>& VSInstances)
+{
+ if (initializationFailure || setupConfig == NULL || setupConfig2 == NULL ||
+ setupHelper == NULL)
+ return false;
+
+ SmartCOMPtr<IEnumSetupInstances> enumInstances = NULL;
+ if (FAILED(
+ setupConfig2->EnumInstances((IEnumSetupInstances**)&enumInstances)) ||
+ !enumInstances) {
+ return false;
+ }
+
+ SmartCOMPtr<ISetupInstance> instance;
+ while (SUCCEEDED(enumInstances->Next(1, &instance, NULL)) && instance) {
+ SmartCOMPtr<ISetupInstance2> instance2 = NULL;
+ if (FAILED(
+ instance->QueryInterface(IID_ISetupInstance2, (void**)&instance2)) ||
+ !instance2) {
+ instance = NULL;
+ continue;
+ }
+
+ VSInstanceInfo instanceInfo;
+ bool isInstalled = GetVSInstanceInfo(instance2, instanceInfo);
+ instance = instance2 = NULL;
+ if (isInstalled)
+ VSInstances.push_back(instanceInfo);
+ }
+ return true;
+}
+
bool cmVSSetupAPIHelper::EnumerateAndChooseVSInstance()
{
bool isVSInstanceExists = false;
@@ -321,10 +407,6 @@ bool cmVSSetupAPIHelper::EnumerateAndChooseVSInstance()
return true;
}
- if (initializationFailure || setupConfig == NULL || setupConfig2 == NULL ||
- setupHelper == NULL)
- return false;
-
std::string envVSCommonToolsDir;
std::string envVSCommonToolsDirEnvName =
"VS" + std::to_string(this->Version) + "0COMNTOOLS";
@@ -334,72 +416,60 @@ bool cmVSSetupAPIHelper::EnumerateAndChooseVSInstance()
cmSystemTools::ConvertToUnixSlashes(envVSCommonToolsDir);
}
- std::vector<VSInstanceInfo> vecVSInstances;
- SmartCOMPtr<IEnumSetupInstances> enumInstances = NULL;
- if (FAILED(
- setupConfig2->EnumInstances((IEnumSetupInstances**)&enumInstances)) ||
- !enumInstances) {
- return false;
- }
-
std::string const wantVersion = std::to_string(this->Version) + '.';
bool specifiedLocationNotSpecifiedVersion = false;
SmartCOMPtr<ISetupInstance> instance;
- while (SUCCEEDED(enumInstances->Next(1, &instance, NULL)) && instance) {
- SmartCOMPtr<ISetupInstance2> instance2 = NULL;
- if (FAILED(
- instance->QueryInterface(IID_ISetupInstance2, (void**)&instance2)) ||
- !instance2) {
- instance = NULL;
+
+ std::vector<VSInstanceInfo> vecVSInstancesAll;
+
+ // Enumerate VS instances with either COM interface or Vswhere
+ if (!EnumerateVSInstancesWithCOM(vecVSInstancesAll) &&
+ !EnumerateVSInstancesWithVswhere(vecVSInstancesAll)) {
+ return false;
+ }
+
+ std::vector<VSInstanceInfo> vecVSInstances;
+ for (const auto& instanceInfo : vecVSInstancesAll) {
+ // We are looking for a specific major version.
+ if (instanceInfo.Version.size() < wantVersion.size() ||
+ instanceInfo.Version.substr(0, wantVersion.size()) != wantVersion) {
continue;
}
- VSInstanceInfo instanceInfo;
- bool isInstalled = GetVSInstanceInfo(instance2, instanceInfo);
- instance = instance2 = NULL;
-
- if (isInstalled) {
- // We are looking for a specific major version.
- if (instanceInfo.Version.size() < wantVersion.size() ||
- instanceInfo.Version.substr(0, wantVersion.size()) != wantVersion) {
- continue;
+ if (!this->SpecifiedVSInstallLocation.empty()) {
+ // We are looking for a specific instance.
+ std::string currentVSLocation = instanceInfo.GetInstallLocation();
+ if (cmSystemTools::ComparePath(currentVSLocation,
+ this->SpecifiedVSInstallLocation)) {
+ if (this->SpecifiedVSInstallVersion.empty() ||
+ instanceInfo.Version == this->SpecifiedVSInstallVersion) {
+ chosenInstanceInfo = instanceInfo;
+ return true;
+ }
+ specifiedLocationNotSpecifiedVersion = true;
}
-
- if (!this->SpecifiedVSInstallLocation.empty()) {
- // We are looking for a specific instance.
- std::string currentVSLocation = instanceInfo.GetInstallLocation();
+ } else if (!this->SpecifiedVSInstallVersion.empty()) {
+ // We are looking for a specific version.
+ if (instanceInfo.Version == this->SpecifiedVSInstallVersion) {
+ chosenInstanceInfo = instanceInfo;
+ return true;
+ }
+ } else {
+ // We are not looking for a specific instance.
+ // If we've been given a hint then use it.
+ if (!envVSCommonToolsDir.empty()) {
+ std::string currentVSLocation =
+ cmStrCat(instanceInfo.GetInstallLocation(), "/Common7/Tools");
if (cmSystemTools::ComparePath(currentVSLocation,
- this->SpecifiedVSInstallLocation)) {
- if (this->SpecifiedVSInstallVersion.empty() ||
- instanceInfo.Version == this->SpecifiedVSInstallVersion) {
- chosenInstanceInfo = instanceInfo;
- return true;
- }
- specifiedLocationNotSpecifiedVersion = true;
- }
- } else if (!this->SpecifiedVSInstallVersion.empty()) {
- // We are looking for a specific version.
- if (instanceInfo.Version == this->SpecifiedVSInstallVersion) {
+ envVSCommonToolsDir)) {
chosenInstanceInfo = instanceInfo;
return true;
}
- } else {
- // We are not looking for a specific instance.
- // If we've been given a hint then use it.
- if (!envVSCommonToolsDir.empty()) {
- std::string currentVSLocation =
- cmStrCat(instanceInfo.GetInstallLocation(), "/Common7/Tools");
- if (cmSystemTools::ComparePath(currentVSLocation,
- envVSCommonToolsDir)) {
- chosenInstanceInfo = instanceInfo;
- return true;
- }
- }
- // Otherwise, add this to the list of candidates.
- vecVSInstances.push_back(instanceInfo);
}
+ // Otherwise, add this to the list of candidates.
+ vecVSInstances.push_back(instanceInfo);
}
}
diff --git a/Source/cmVSSetupHelper.h b/Source/cmVSSetupHelper.h
index 44c883b..a16f00b 100644
--- a/Source/cmVSSetupHelper.h
+++ b/Source/cmVSSetupHelper.h
@@ -118,6 +118,9 @@ private:
int ChooseVSInstance(const std::vector<VSInstanceInfo>& vecVSInstances);
bool EnumerateAndChooseVSInstance();
bool LoadSpecifiedVSInstanceFromDisk();
+ bool EnumerateVSInstancesWithVswhere(
+ std::vector<VSInstanceInfo>& VSInstances);
+ bool EnumerateVSInstancesWithCOM(std::vector<VSInstanceInfo>& VSInstances);
unsigned int Version;
diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx
index fd5402c..24394d9 100644
--- a/Source/cmVariableWatchCommand.cxx
+++ b/Source/cmVariableWatchCommand.cxx
@@ -58,7 +58,7 @@ void cmVariableWatchCommandVariableAccessed(const std::string& variable,
{ stack, cmListFileArgument::Quoted, fakeLineNo }
};
- cmListFileFunction newLFF{ data->Command, fakeLineNo,
+ cmListFileFunction newLFF{ data->Command, fakeLineNo, fakeLineNo,
std::move(newLFFArgs) };
cmExecutionStatus status(*makefile);
if (!makefile->ExecuteCommand(newLFF, status)) {
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 8ffb664..1739b5a 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -50,6 +50,24 @@
#include "cmValue.h"
#include "cmVisualStudioGeneratorOptions.h"
+namespace {
+std::string getProjectFileExtension(VsProjectType projectType)
+{
+ switch (projectType) {
+ case VsProjectType::csproj:
+ return ".csproj";
+ case VsProjectType::proj:
+ return ".proj";
+ case VsProjectType::vcxproj:
+ return ".vcxproj";
+ // Valid inputs shouldn't reach here. This default is needed so that all
+ // paths return value (C4715).
+ default:
+ return "";
+ }
+}
+}
+
struct cmIDEFlagTable;
static void ConvertToWindowsSlash(std::string& s);
@@ -235,29 +253,6 @@ static bool cmVS10IsTargetsFile(std::string const& path)
return cmSystemTools::Strucmp(ext.c_str(), ".targets") == 0;
}
-static VsProjectType computeProjectType(cmGeneratorTarget const* t)
-{
- if (t->IsCSharpOnly()) {
- return VsProjectType::csproj;
- }
- return VsProjectType::vcxproj;
-}
-
-static std::string computeProjectFileExtension(VsProjectType projectType)
-{
- switch (projectType) {
- case VsProjectType::csproj:
- return ".csproj";
- default:
- return ".vcxproj";
- }
-}
-
-static std::string computeProjectFileExtension(cmGeneratorTarget const* t)
-{
- return computeProjectFileExtension(computeProjectType(t));
-}
-
cmVisualStudio10TargetGenerator::cmVisualStudio10TargetGenerator(
cmGeneratorTarget* target, cmGlobalVisualStudio10Generator* gg)
: GeneratorTarget(target)
@@ -352,10 +347,10 @@ std::ostream& cmVisualStudio10TargetGenerator::Elem::WriteString(
void cmVisualStudio10TargetGenerator::Generate()
{
- this->ProjectType = computeProjectType(this->GeneratorTarget);
+ this->ProjectType = this->ComputeProjectType(this->GeneratorTarget);
this->Managed = this->ProjectType == VsProjectType::csproj;
const std::string ProjectFileExtension =
- computeProjectFileExtension(this->ProjectType);
+ getProjectFileExtension(this->ProjectType);
if (this->ProjectType == VsProjectType::csproj &&
this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY) {
@@ -416,10 +411,12 @@ void cmVisualStudio10TargetGenerator::Generate()
char magic[] = { char(0xEF), char(0xBB), char(0xBF) };
BuildFileStream.write(magic, 3);
- if (this->ProjectType == VsProjectType::csproj &&
- this->GeneratorTarget->IsDotNetSdkTarget() &&
- this->GlobalGenerator->GetVersion() >=
- cmGlobalVisualStudioGenerator::VSVersion::VS16) {
+ if (this->ProjectType == VsProjectType::proj) {
+ this->WriteZeroCheckProj(BuildFileStream);
+ } else if (this->ProjectType == VsProjectType::csproj &&
+ this->GeneratorTarget->IsDotNetSdkTarget() &&
+ this->GlobalGenerator->GetVersion() >=
+ cmGlobalVisualStudioGenerator::VSVersion::VS16) {
this->WriteSdkStyleProjectFile(BuildFileStream);
} else {
this->WriteClassicMsBuildProjectFile(BuildFileStream);
@@ -667,6 +664,14 @@ void cmVisualStudio10TargetGenerator::WriteClassicMsBuildProjectFile(
}
}
+ cmValue startupObject =
+ this->GeneratorTarget->GetProperty("VS_DOTNET_STARTUP_OBJECT");
+
+ if (startupObject && this->Managed) {
+ Elem e1(e0, "PropertyGroup");
+ e1.Element("StartupObject", *startupObject);
+ }
+
switch (this->ProjectType) {
case VsProjectType::vcxproj: {
std::string const& props =
@@ -681,6 +686,8 @@ void cmVisualStudio10TargetGenerator::WriteClassicMsBuildProjectFile(
.Attribute("Project", VS10_CSharp_DEFAULT_PROPS)
.Attribute("Condition", "Exists('" VS10_CSharp_DEFAULT_PROPS "')");
break;
+ default:
+ break;
}
this->WriteProjectConfigurationValues(e0);
@@ -737,6 +744,8 @@ void cmVisualStudio10TargetGenerator::WriteClassicMsBuildProjectFile(
case VsProjectType::csproj:
props = VS10_CSharp_USER_PROPS;
break;
+ default:
+ break;
}
if (cmValue p = this->GeneratorTarget->GetProperty("VS_USER_PROPS")) {
props = *p;
@@ -779,6 +788,8 @@ void cmVisualStudio10TargetGenerator::WriteClassicMsBuildProjectFile(
Elem(e0, "Import").Attribute("Project", VS10_CSharp_TARGETS);
}
break;
+ default:
+ break;
}
this->WriteTargetSpecificReferences(e0);
@@ -924,6 +935,12 @@ void cmVisualStudio10TargetGenerator::WriteSdkStyleProjectFile(
break;
}
e1.Element("OutputType", outputType);
+
+ cmValue startupObject =
+ this->GeneratorTarget->GetProperty("VS_DOTNET_STARTUP_OBJECT");
+ if (startupObject) {
+ e1.Element("StartupObject", *startupObject);
+ }
}
for (const std::string& config : this->Configurations) {
@@ -944,6 +961,45 @@ void cmVisualStudio10TargetGenerator::WriteSdkStyleProjectFile(
this->WriteProjectReferences(e0);
}
+void cmVisualStudio10TargetGenerator::WriteZeroCheckProj(
+ cmGeneratedFileStream& BuildFileStream)
+{
+ // ZERO_CHECK.proj is an XML file without any imports or targets. This is a
+ // ProjectReference for other targets and therefore, it needs to follow the
+ // ProjectReference protocol as documented here:
+ // https://github.com/dotnet/msbuild/blob/main/documentation/ProjectReference-Protocol.md
+ //
+ // We implement MSBuild target Build from WriteCustomCommand which calls
+ // WriteZeroCheckBuildTarget after setting up the command generator. MSBuild
+ // target Clean is a no-op as we do all the work for ZERO_CHECK on Build.
+ // MSBuild target GetTargetPath is needed and is no-op.
+ // MSBuild targets GetNativeManifest and GetCopyToOutputDirectoryItems are
+ // needed for MSBuild versions below 15.7 and are no-op. MSBuild target
+ // BeforeBuild is needed for supporting GLOBs.
+ BuildFileStream << "<?xml version=\"1.0\" encoding=\""
+ << this->GlobalGenerator->Encoding() << "\"?>";
+ {
+ Elem e0(BuildFileStream, "Project");
+ e0.Attribute("DefaultTargets", "Build");
+ e0.Attribute("ToolsVersion", this->GlobalGenerator->GetToolsVersion());
+ e0.Attribute("xmlns",
+ "http://schemas.microsoft.com/developer/msbuild/2003");
+
+ this->WriteCustomCommands(e0);
+
+ for (const char* targetName :
+ { "Clean", "GetTargetPath", "GetNativeManifest",
+ "GetCopyToOutputDirectoryItems" }) {
+ {
+ Elem e1(e0, "Target");
+ e1.Attribute("Name", targetName);
+ }
+ }
+
+ this->WriteZeroCheckBeforeBuildTarget(e0);
+ }
+}
+
void cmVisualStudio10TargetGenerator::WriteCommonPropertyGroupGlobals(Elem& e1)
{
e1.Attribute("Label", "Globals");
@@ -1659,11 +1715,16 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule(
}
}
}
+ if (this->ProjectType == VsProjectType::proj) {
+ this->WriteZeroCheckBuildTarget(e0, command, source);
+ return;
+ }
+
cmLocalVisualStudio7Generator* lg = this->LocalGenerator;
std::unique_ptr<Elem> spe1;
std::unique_ptr<Elem> spe2;
- if (this->ProjectType != VsProjectType::csproj) {
+ if (this->ProjectType == VsProjectType::vcxproj) {
spe1 = cm::make_unique<Elem>(e0, "ItemGroup");
spe2 = cm::make_unique<Elem>(*spe1, "CustomBuild");
this->WriteSource(*spe2, source);
@@ -1861,7 +1922,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
// Write out group file
std::string path = cmStrCat(
this->LocalGenerator->GetCurrentBinaryDirectory(), '/', this->Name,
- computeProjectFileExtension(this->GeneratorTarget), ".filters");
+ this->ComputeProjectFileExtension(this->GeneratorTarget), ".filters");
cmGeneratedFileStream fout(path);
fout.SetCopyIfDifferent(true);
char magic[] = { char(0xEF), char(0xBB), char(0xBF) };
@@ -3016,6 +3077,134 @@ void cmVisualStudio10TargetGenerator::OutputLinkIncremental(
}
}
+void cmVisualStudio10TargetGenerator::WriteZeroCheckBuildTarget(
+ cmVisualStudio10TargetGenerator::Elem& e0, const cmCustomCommand& command,
+ const cmSourceFile* source)
+{
+ cmLocalVisualStudio7Generator* lg = this->LocalGenerator;
+
+ Elem e1(e0, "Target");
+ e1.Attribute("Name", "Build");
+
+ std::string noConfig{};
+ cmCustomCommandGenerator ccg{ command, noConfig, lg, true };
+ std::string comment = lg->ConstructComment(ccg);
+ comment = cmVS10EscapeComment(comment);
+ std::string script = lg->ConstructScript(ccg);
+ bool symbolic = false;
+ // input files for custom command
+ std::stringstream additional_inputs;
+ {
+ const char* sep = "";
+ if (this->ProjectType == VsProjectType::proj) {
+ // List explicitly the path to primary input.
+ std::string sourceFullPath = source->GetFullPath();
+ ConvertToWindowsSlash(sourceFullPath);
+ additional_inputs << sourceFullPath;
+ sep = ";";
+ }
+
+ // Avoid listing an input more than once.
+ std::set<std::string> unique_inputs;
+ // The source is either implicitly an input or has been added above.
+ unique_inputs.insert(source->GetFullPath());
+
+ for (std::string const& d : ccg.GetDepends()) {
+ std::string dep;
+ if (lg->GetRealDependency(d, noConfig, dep)) {
+ if (!unique_inputs.insert(dep).second) {
+ // already listed
+ continue;
+ }
+ ConvertToWindowsSlash(dep);
+ additional_inputs << sep << dep;
+ sep = ";";
+ if (!symbolic) {
+ if (cmSourceFile* sf = this->Makefile->GetSource(
+ dep, cmSourceFileLocationKind::Known)) {
+ symbolic = sf->GetPropertyAsBool("SYMBOLIC");
+ }
+ }
+ }
+ }
+ }
+ // output files for custom command
+ std::stringstream outputs;
+ {
+ const char* sep = "";
+ for (std::string const& o : ccg.GetOutputs()) {
+ std::string out = o;
+ ConvertToWindowsSlash(out);
+ outputs << sep << out;
+ sep = ";";
+ if (!symbolic) {
+ if (cmSourceFile* sf =
+ this->Makefile->GetSource(o, cmSourceFileLocationKind::Known)) {
+ symbolic = sf->GetPropertyAsBool("SYMBOLIC");
+ }
+ }
+ }
+ }
+ script += lg->FinishConstructScript(this->ProjectType);
+
+ e1.Attribute("Inputs", cmVS10EscapeAttr(additional_inputs.str()));
+ e1.Attribute("Outputs", cmVS10EscapeAttr(outputs.str()));
+
+ e1.SetHasElements();
+
+ if (!comment.empty()) {
+ Elem(e1, "Message").Attribute("Text", comment);
+ }
+ Elem(e1, "Exec").Attribute("Command", script);
+}
+
+void cmVisualStudio10TargetGenerator::WriteZeroCheckBeforeBuildTarget(
+ cmVisualStudio10TargetGenerator::Elem& e0)
+{
+ const auto& commands = this->GeneratorTarget->GetPreBuildCommands();
+ if (commands.empty()) {
+ return;
+ }
+
+ {
+ Elem e1(e0, "Target");
+ e1.Attribute("Name", "BeforeBuild");
+ e1.Attribute("BeforeTargets", "Build");
+
+ cmLocalVisualStudio7Generator* lg = this->LocalGenerator;
+ std::string script;
+ const char* pre = "";
+ std::string comment;
+ for (cmCustomCommand const& cc : commands) {
+ cmCustomCommandGenerator ccg(cc, std::string{}, lg);
+ if (!ccg.HasOnlyEmptyCommandLines()) {
+ comment += pre;
+ comment += lg->ConstructComment(ccg);
+ script += pre;
+ pre = "\n";
+ script += lg->ConstructScript(ccg);
+ }
+ }
+
+ if (script.empty()) {
+ return;
+ }
+
+ script += lg->FinishConstructScript(this->ProjectType);
+ comment = cmVS10EscapeComment(comment);
+ std::string strippedComment = comment;
+ strippedComment.erase(
+ std::remove(strippedComment.begin(), strippedComment.end(), '\t'),
+ strippedComment.end());
+
+ e1.SetHasElements();
+ if (!comment.empty() && !strippedComment.empty()) {
+ Elem(e1, "Message").Attribute("Text", comment);
+ }
+ Elem(e1, "Exec").Attribute("Command", script);
+ }
+}
+
std::vector<std::string> cmVisualStudio10TargetGenerator::GetIncludes(
std::string const& config, std::string const& lang) const
{
@@ -3057,6 +3246,8 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
cm::make_unique<Options>(this->LocalGenerator, Options::CSharpCompiler,
gg->GetCSharpFlagTable());
break;
+ default:
+ break;
}
Options& clOptions = *pOptions;
@@ -3182,6 +3373,8 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
return def.find('=') != std::string::npos;
});
break;
+ default:
+ break;
}
clOptions.AddDefines(targetDefines);
@@ -3309,7 +3502,9 @@ void cmVisualStudio10TargetGenerator::WriteClOptions(
} else if (this->MSTools) {
cmsys::RegularExpression clangToolset("v[0-9]+_clang_.*");
const char* toolset = this->GlobalGenerator->GetPlatformToolset();
- if (toolset && clangToolset.find(toolset)) {
+ cmValue noCompileBatching =
+ this->GeneratorTarget->GetProperty("VS_NO_COMPILE_BATCHING");
+ if (noCompileBatching.IsOn() || (toolset && clangToolset.find(toolset))) {
e2.Element("ObjectFileName", "$(IntDir)%(filename).obj");
} else {
e2.Element("ObjectFileName", "$(IntDir)");
@@ -3637,62 +3832,15 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaLinkOptions(
return false;
}
- // Would like to use:
- // cmLinkLineDeviceComputer computer(this->LocalGenerator,
- // this->LocalGenerator->GetStateSnapshot().GetDirectory());
- // std::string computed_libs = computer.ComputeLinkLibraries(cli,
- // std::string{}); but it outputs in "<libA> <libB>" format instead of
- // "<libA>;<libB>"
- // Note:
- // Any modification of this algorithm should be reflected also in
- // cmLinkLineDeviceComputer
cmComputeLinkInformation& cli = *pcli;
+ cmLinkLineDeviceComputer computer(
+ this->LocalGenerator,
+ this->LocalGenerator->GetStateSnapshot().GetDirectory());
+ std::vector<BT<std::string>> btLibVec;
+ computer.ComputeLinkLibraries(cli, std::string{}, btLibVec);
std::vector<std::string> libVec;
- const auto& libs = cli.GetItems();
- for (cmComputeLinkInformation::Item const& l : libs) {
-
- if (l.Target) {
- auto managedType = l.Target->GetManagedType(configName);
- // Do not allow C# targets to be added to the LIB listing. LIB files
- // are used for linking C++ dependencies. C# libraries do not have lib
- // files. Instead, they compile down to C# reference libraries (DLL
- // files). The
- // `<ProjectReference>` elements added to the vcxproj are enough for
- // the IDE to deduce the DLL file required by other C# projects that
- // need its reference library.
- if (managedType == cmGeneratorTarget::ManagedType::Managed) {
- continue;
- }
- const auto type = l.Target->GetType();
-
- bool skip = false;
- switch (type) {
- case cmStateEnums::SHARED_LIBRARY:
- case cmStateEnums::MODULE_LIBRARY:
- case cmStateEnums::INTERFACE_LIBRARY:
- skip = true;
- break;
- case cmStateEnums::STATIC_LIBRARY:
- skip = l.Target->GetPropertyAsBool("CUDA_RESOLVE_DEVICE_SYMBOLS");
- break;
- default:
- break;
- }
- if (skip) {
- continue;
- }
- }
-
- if (l.IsPath == cmComputeLinkInformation::ItemIsPath::Yes) {
- std::string path =
- this->LocalGenerator->MaybeRelativeToCurBinDir(l.Value.Value);
- ConvertToWindowsSlash(path);
- if (!cmVS10IsTargetsFile(l.Value.Value)) {
- libVec.push_back(path);
- }
- } else {
- libVec.push_back(l.Value.Value);
- }
+ for (auto const& item : btLibVec) {
+ libVec.emplace_back(item.Value);
}
cudaLinkOptions.AddFlag("AdditionalDependencies", libVec);
@@ -4305,6 +4453,9 @@ void cmVisualStudio10TargetGenerator::AddLibraries(
this->AdditionalUsingDirectories[config].insert(
cmSystemTools::GetFilenamePath(location));
break;
+ default:
+ // In .proj files, we wouldn't be referencing libraries.
+ break;
}
}
}
@@ -4326,7 +4477,8 @@ void cmVisualStudio10TargetGenerator::AddLibraries(
if (cmVS10IsTargetsFile(l.Value.Value)) {
vsTargetVec.push_back(path);
} else {
- libVec.push_back(path);
+ libVec.push_back(l.HasFeature() ? l.GetFormattedItem(path).Value
+ : path);
}
} else if (!l.Target ||
l.Target->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
@@ -4533,7 +4685,7 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences(Elem& e0)
path = *p;
} else {
path = cmStrCat(lg->GetCurrentBinaryDirectory(), '/', dt->GetName(),
- computeProjectFileExtension(dt));
+ this->ComputeProjectFileExtension(dt));
}
ConvertToWindowsSlash(path);
Elem e2(e1, "ProjectReference");
@@ -5387,6 +5539,26 @@ std::string cmVisualStudio10TargetGenerator::GetCMakeFilePath(
return path;
}
+std::string cmVisualStudio10TargetGenerator::ComputeProjectFileExtension(
+ cmGeneratorTarget const* t) const
+{
+ return getProjectFileExtension(this->ComputeProjectType(t));
+}
+
+VsProjectType cmVisualStudio10TargetGenerator::ComputeProjectType(
+ cmGeneratorTarget const* t) const
+{
+ if (this->GlobalGenerator->GetVersion() >=
+ cmGlobalVisualStudioGenerator::VSVersion::VS16 &&
+ t->GetName() == CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
+ return VsProjectType::proj;
+ }
+ if (t->IsCSharpOnly()) {
+ return VsProjectType::csproj;
+ }
+ return VsProjectType::vcxproj;
+}
+
void cmVisualStudio10TargetGenerator::WriteStdOutEncodingUtf8(Elem& e1)
{
if (this->GlobalGenerator->IsUtf8EncodingSupported()) {
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index 8d777a3..7a0b8da 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -264,6 +264,13 @@ private:
void WriteClassicMsBuildProjectFile(cmGeneratedFileStream& BuildFileStream);
void WriteSdkStyleProjectFile(cmGeneratedFileStream& BuildFileStream);
+ void WriteZeroCheckProj(cmGeneratedFileStream& BuildFileStream);
+ void WriteZeroCheckBuildTarget(cmVisualStudio10TargetGenerator::Elem& e0,
+ const cmCustomCommand& command,
+ const cmSourceFile* source);
+ void WriteZeroCheckBeforeBuildTarget(
+ cmVisualStudio10TargetGenerator::Elem& e0);
+
void WriteCommonPropertyGroupGlobals(
cmVisualStudio10TargetGenerator::Elem& e1);
@@ -275,4 +282,7 @@ private:
void ParseSettingsProperty(const std::string& settingsPropertyValue,
ConfigToSettings& toolSettings);
std::string GetCMakeFilePath(const char* name) const;
+
+ std::string ComputeProjectFileExtension(cmGeneratorTarget const* t) const;
+ VsProjectType ComputeProjectType(cmGeneratorTarget const* t) const;
};
diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx
index 0b27dfb..00c65ed 100644
--- a/Source/cmVisualStudioGeneratorOptions.cxx
+++ b/Source/cmVisualStudioGeneratorOptions.cxx
@@ -183,7 +183,8 @@ void cmVisualStudioGeneratorOptions::FixCudaCodeGeneration()
// First entries for the -arch=<arch> [-code=<code>,...] pair.
if (!arch.empty()) {
std::string arch_name = arch[0];
- if (arch_name == "all" || arch_name == "all-major") {
+ if (arch_name == "all" || arch_name == "all-major" ||
+ arch_name == "native") {
AppendFlagString("AdditionalOptions", "-arch=" + arch_name);
return;
}
diff --git a/Source/cmVsProjectType.h b/Source/cmVsProjectType.h
index 8899267..04053a0 100644
--- a/Source/cmVsProjectType.h
+++ b/Source/cmVsProjectType.h
@@ -7,5 +7,6 @@
enum class VsProjectType
{
vcxproj,
- csproj
+ csproj,
+ proj,
};
diff --git a/Source/cmWhileCommand.cxx b/Source/cmWhileCommand.cxx
index a93a81f..68d5a9a 100644
--- a/Source/cmWhileCommand.cxx
+++ b/Source/cmWhileCommand.cxx
@@ -17,6 +17,8 @@
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmOutputConverter.h"
+#include "cmPolicies.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
@@ -79,9 +81,8 @@ bool cmWhileFunctionBlocker::Replay(std::vector<cmListFileFunction> functions,
return out;
};
- // FIXME(#23296): For compatibility with older versions of CMake, we
- // tolerate condition errors that evaluate to false. We should add
- // a policy to enforce such errors.
+ // For compatibility with projects that do not set CMP0130 to NEW,
+ // we tolerate condition errors that evaluate to false.
bool enforceError = true;
std::string errorString;
MessageType messageType;
@@ -110,14 +111,38 @@ bool cmWhileFunctionBlocker::Replay(std::vector<cmListFileFunction> functions,
}
}
+ if (!errorString.empty() && !enforceError) {
+ // This error should only be enforced if CMP0130 is NEW.
+ switch (mf.GetPolicyStatus(cmPolicies::CMP0130)) {
+ case cmPolicies::WARN:
+ // Convert the error to a warning and enforce it.
+ messageType = MessageType::AUTHOR_WARNING;
+ enforceError = true;
+ break;
+ case cmPolicies::OLD:
+ // OLD behavior is to silently ignore the error.
+ break;
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::NEW:
+ // NEW behavior is to enforce the error.
+ enforceError = true;
+ break;
+ }
+ }
+
if (!errorString.empty() && enforceError) {
- std::string err = "had incorrect arguments:\n ";
+ std::string err = "while() given incorrect arguments:\n ";
for (auto const& i : expandedArguments) {
err += " ";
err += cmOutputConverter::EscapeForCMake(i.GetValue());
}
err += "\n";
err += errorString;
+ if (mf.GetPolicyStatus(cmPolicies::CMP0130) == cmPolicies::WARN) {
+ err =
+ cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0130), '\n', err);
+ }
mf.GetCMakeInstance()->IssueMessage(messageType, err, whileBT);
if (messageType == MessageType::FATAL_ERROR) {
cmSystemTools::SetFatalErrorOccured();
diff --git a/Source/cmWindowsRegistry.cxx b/Source/cmWindowsRegistry.cxx
new file mode 100644
index 0000000..6dba863
--- /dev/null
+++ b/Source/cmWindowsRegistry.cxx
@@ -0,0 +1,770 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include "cmWindowsRegistry.h"
+
+#include <cctype>
+#include <cstddef>
+#include <functional>
+#include <type_traits>
+#include <unordered_map>
+#include <utility>
+
+#include <cmext/string_view>
+
+#include "cmsys/RegularExpression.hxx"
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+# include <algorithm>
+# include <cstring>
+# include <exception>
+# include <iterator>
+# include <vector>
+
+# include <cm/memory>
+
+# include <windows.h>
+
+# include "cmMakefile.h"
+# include "cmStringAlgorithms.h"
+# include "cmValue.h"
+#endif
+
+namespace {
+// Case-independent string comparison
+int Strucmp(cm::string_view l, cm::string_view r)
+{
+ if (l.empty() && r.empty()) {
+ return 0;
+ }
+ if (l.empty() || r.empty()) {
+ return static_cast<int>(l.size() - r.size());
+ }
+
+ int lc;
+ int rc;
+ cm::string_view::size_type li = 0;
+ cm::string_view::size_type ri = 0;
+
+ do {
+ lc = std::tolower(l[li++]);
+ rc = std::tolower(r[ri++]);
+ } while (lc == rc && li < l.size() && ri < r.size());
+
+ return lc == rc ? static_cast<int>(l.size() - r.size()) : lc - rc;
+}
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+bool Is64BitWindows()
+{
+# if defined(_WIN64)
+ // 64-bit programs run only on Win64
+ return true;
+# else
+ // 32-bit programs run on both 32-bit and 64-bit Windows, so we must check.
+ BOOL isWow64 = false;
+ return IsWow64Process(GetCurrentProcess(), &isWow64) && isWow64;
+# endif
+}
+
+// Helper to translate Windows registry value type to enum ValueType
+cm::optional<cmWindowsRegistry::ValueType> ToValueType(DWORD type)
+{
+ using ValueType = cmWindowsRegistry::ValueType;
+
+ static std::unordered_map<DWORD, ValueType> ValueTypes{
+ { REG_SZ, ValueType::Reg_SZ },
+ { REG_EXPAND_SZ, ValueType::Reg_EXPAND_SZ },
+ { REG_MULTI_SZ, ValueType::Reg_MULTI_SZ },
+ { REG_DWORD, ValueType::Reg_DWORD },
+ { REG_QWORD, ValueType::Reg_QWORD }
+ };
+
+ auto it = ValueTypes.find(type);
+
+ return it == ValueTypes.end()
+ ? cm::nullopt
+ : cm::optional<cmWindowsRegistry::ValueType>{ it->second };
+}
+
+// class registry_exception
+class registry_error : public std::exception
+{
+public:
+ registry_error(std::string msg)
+ : What(std::move(msg))
+ {
+ }
+ ~registry_error() override = default;
+
+ const char* what() const noexcept override { return What.c_str(); }
+
+private:
+ std::string What;
+};
+
+// Class KeyHandler
+class KeyHandler
+{
+public:
+ using View = cmWindowsRegistry::View;
+ using ValueTypeSet = cmWindowsRegistry::ValueTypeSet;
+
+ KeyHandler(HKEY hkey)
+ : Handler(hkey)
+ {
+ }
+ ~KeyHandler() { RegCloseKey(this->Handler); }
+
+ static KeyHandler OpenKey(cm::string_view rootKey, cm::string_view subKey,
+ View view);
+ static KeyHandler OpenKey(cm::string_view key, View view);
+
+ std::string ReadValue(
+ cm::string_view name,
+ ValueTypeSet supportedTypes = cmWindowsRegistry::AllTypes,
+ cm::string_view separator = "\0"_s);
+
+ std::vector<std::string> GetValueNames();
+ std::vector<std::string> GetSubKeys();
+
+private:
+ static std::string FormatSystemError(LSTATUS status);
+ static std::wstring ToWide(cm::string_view str);
+ static std::string ToNarrow(const wchar_t* str, int size = -1);
+
+ HKEY Handler;
+};
+
+KeyHandler KeyHandler::OpenKey(cm::string_view rootKey, cm::string_view subKey,
+ View view)
+{
+ if (view == View::Reg64 && !Is64BitWindows()) {
+ throw registry_error("No 64bit registry on Windows32.");
+ }
+
+ HKEY hRootKey;
+ if (rootKey == "HKCU"_s || rootKey == "HKEY_CURRENT_USER"_s) {
+ hRootKey = HKEY_CURRENT_USER;
+ } else if (rootKey == "HKLM"_s || rootKey == "HKEY_LOCAL_MACHINE"_s) {
+ hRootKey = HKEY_LOCAL_MACHINE;
+ } else if (rootKey == "HKCR"_s || rootKey == "HKEY_CLASSES_ROOT"_s) {
+ hRootKey = HKEY_CLASSES_ROOT;
+ } else if (rootKey == "HKCC"_s || rootKey == "HKEY_CURRENT_CONFIG"_s) {
+ hRootKey = HKEY_CURRENT_CONFIG;
+ } else if (rootKey == "HKU"_s || rootKey == "HKEY_USERS"_s) {
+ hRootKey = HKEY_USERS;
+ } else {
+ throw registry_error(cmStrCat(rootKey, ": invalid root key."));
+ }
+ // Update path format
+ auto key = ToWide(subKey);
+ std::replace(key.begin(), key.end(), L'/', L'\\');
+
+ REGSAM options = KEY_READ;
+ if (Is64BitWindows()) {
+ options |= view == View::Reg64 ? KEY_WOW64_64KEY : KEY_WOW64_32KEY;
+ }
+
+ HKEY hKey;
+ LSTATUS status;
+ if ((status = RegOpenKeyExW(hRootKey, key.c_str(), 0, options, &hKey)) !=
+ ERROR_SUCCESS) {
+ throw registry_error(FormatSystemError(status));
+ }
+
+ return KeyHandler(hKey);
+}
+
+KeyHandler KeyHandler::OpenKey(cm::string_view key, View view)
+{
+ auto start = key.find_first_of("\\/"_s);
+
+ return OpenKey(key.substr(0, start),
+ start == cm::string_view::npos ? cm::string_view{ ""_s }
+ : key.substr(start + 1),
+ view);
+}
+
+std::string KeyHandler::FormatSystemError(LSTATUS status)
+{
+ std::string formattedMessage{ "Windows Registry: unexpected error." };
+ LPWSTR message = nullptr;
+ DWORD size = 1024;
+ if (FormatMessageW(
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, nullptr,
+ status, 0, reinterpret_cast<LPWSTR>(&message), size, nullptr) != 0) {
+ try {
+ formattedMessage = cmTrimWhitespace(ToNarrow(message));
+ } catch (...) {
+ // ignore any exception because this method can be called
+ // as part of the raise of an exception
+ }
+ }
+ LocalFree(message);
+
+ return formattedMessage;
+}
+
+std::wstring KeyHandler::ToWide(cm::string_view str)
+{
+ std::wstring wstr;
+
+ if (str.empty()) {
+ return wstr;
+ }
+
+ const auto wlength =
+ MultiByteToWideChar(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str.data(),
+ int(str.size()), nullptr, 0);
+ if (wlength > 0) {
+ auto wdata = cm::make_unique<wchar_t[]>(wlength);
+ const auto r =
+ MultiByteToWideChar(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str.data(),
+ int(str.size()), wdata.get(), wlength);
+ if (r > 0) {
+ wstr = std::wstring(wdata.get(), wlength);
+ } else {
+ throw registry_error(FormatSystemError(GetLastError()));
+ }
+ } else {
+ throw registry_error(FormatSystemError(GetLastError()));
+ }
+
+ return wstr;
+}
+
+std::string KeyHandler::ToNarrow(const wchar_t* wstr, int size)
+{
+ std::string str;
+
+ if (size == 0 || (size == -1 && wstr[0] == L'\0')) {
+ return str;
+ }
+
+ const auto length =
+ WideCharToMultiByte(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, wstr, size,
+ nullptr, 0, nullptr, nullptr);
+ if (length > 0) {
+ auto data = cm::make_unique<char[]>(length);
+ const auto r =
+ WideCharToMultiByte(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, wstr, size,
+ data.get(), length, nullptr, nullptr);
+ if (r > 0) {
+ if (size == -1) {
+ str = std::string(data.get());
+ } else {
+ str = std::string(data.get(), length);
+ }
+ } else {
+ throw registry_error(FormatSystemError(GetLastError()));
+ }
+ } else {
+ throw registry_error(FormatSystemError(GetLastError()));
+ }
+
+ return str;
+}
+
+std::string KeyHandler::ReadValue(cm::string_view name,
+ ValueTypeSet supportedTypes,
+ cm::string_view separator)
+{
+ LSTATUS status;
+ DWORD size;
+ // pick-up maximum size for value
+ if ((status = RegQueryInfoKeyW(this->Handler, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr,
+ &size, nullptr, nullptr)) != ERROR_SUCCESS) {
+ throw registry_error(this->FormatSystemError(status));
+ }
+ auto data = cm::make_unique<BYTE[]>(size);
+ DWORD type;
+ auto valueName = this->ToWide(name);
+ if ((status = RegQueryValueExW(this->Handler, valueName.c_str(), nullptr,
+ &type, data.get(), &size)) != ERROR_SUCCESS) {
+ throw registry_error(this->FormatSystemError(status));
+ }
+
+ auto valueType = ToValueType(type);
+ if (!valueType || !supportedTypes.contains(*valueType)) {
+ throw registry_error(cmStrCat(type, ": unsupported type."));
+ }
+
+ switch (type) {
+ case REG_SZ:
+ return this->ToNarrow(reinterpret_cast<wchar_t*>(data.get()));
+ break;
+ case REG_EXPAND_SZ: {
+ auto expandSize = ExpandEnvironmentStringsW(
+ reinterpret_cast<wchar_t*>(data.get()), nullptr, 0);
+ auto expandData = cm::make_unique<wchar_t[]>(expandSize + 1);
+ if (ExpandEnvironmentStringsW(reinterpret_cast<wchar_t*>(data.get()),
+ expandData.get(), expandSize + 1) == 0) {
+ throw registry_error(this->FormatSystemError(GetLastError()));
+ } else {
+ return this->ToNarrow(expandData.get());
+ }
+ } break;
+ case REG_DWORD:
+ return std::to_string(*reinterpret_cast<std::uint32_t*>(data.get()));
+ break;
+ case REG_QWORD:
+ return std::to_string(*reinterpret_cast<std::uint64_t*>(data.get()));
+ break;
+ case REG_MULTI_SZ: {
+ // replace separator with semicolon
+ auto sep = this->ToWide(separator)[0];
+ std::replace(reinterpret_cast<wchar_t*>(data.get()),
+ reinterpret_cast<wchar_t*>(data.get()) +
+ (size / sizeof(wchar_t)) - 1,
+ sep, L';');
+ return this->ToNarrow(reinterpret_cast<wchar_t*>(data.get()));
+ } break;
+ default:
+ throw registry_error(cmStrCat(type, ": unsupported type."));
+ }
+}
+
+std::vector<std::string> KeyHandler::GetValueNames()
+{
+ LSTATUS status;
+ DWORD maxSize;
+ // pick-up maximum size for value names
+ if ((status = RegQueryInfoKeyW(
+ this->Handler, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, &maxSize, nullptr, nullptr, nullptr)) != ERROR_SUCCESS) {
+ throw registry_error(this->FormatSystemError(status));
+ }
+ // increment size for final null
+ auto data = cm::make_unique<wchar_t[]>(++maxSize);
+ DWORD index = 0;
+ DWORD size = maxSize;
+
+ std::vector<std::string> valueNames;
+
+ while ((status = RegEnumValueW(this->Handler, index, data.get(), &size,
+ nullptr, nullptr, nullptr, nullptr)) ==
+ ERROR_SUCCESS) {
+ auto name = this->ToNarrow(data.get());
+ valueNames.push_back(name.empty() ? "(default)" : name);
+ size = maxSize;
+ ++index;
+ }
+
+ if (status != ERROR_NO_MORE_ITEMS) {
+ throw registry_error(this->FormatSystemError(status));
+ }
+
+ return valueNames;
+}
+
+std::vector<std::string> KeyHandler::GetSubKeys()
+{
+ LSTATUS status;
+ DWORD size;
+ // pick-up maximum size for subkeys
+ if ((status = RegQueryInfoKeyW(
+ this->Handler, nullptr, nullptr, nullptr, nullptr, &size, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr)) != ERROR_SUCCESS) {
+ throw registry_error(this->FormatSystemError(status));
+ }
+ // increment size for final null
+ auto data = cm::make_unique<wchar_t[]>(++size);
+ DWORD index = 0;
+ std::vector<std::string> subKeys;
+
+ while ((status = RegEnumKeyW(this->Handler, index, data.get(), size)) ==
+ ERROR_SUCCESS) {
+ subKeys.push_back(this->ToNarrow(data.get()));
+ ++index;
+ }
+ if (status != ERROR_NO_MORE_ITEMS) {
+ throw registry_error(this->FormatSystemError(status));
+ }
+
+ return subKeys;
+}
+#endif
+
+// ExpressionParser: Helper to parse expression holding multiple
+// registry specifications
+class ExpressionParser
+{
+public:
+ ExpressionParser(cm::string_view expression)
+ : Expression(expression)
+ , Separator(";"_s)
+ , RegistryFormat{
+ "\\[({.+})?(HKCU|HKEY_CURRENT_USER|HKLM|HKEY_LOCAL_MACHINE|HKCR|HKEY_"
+ "CLASSES_"
+ "ROOT|HKCC|HKEY_CURRENT_CONFIG|HKU|HKEY_USERS)[/\\]?([^]]*)\\]"
+ }
+ {
+ }
+
+ bool Find()
+ {
+ // reset result members
+ this->RootKey = cm::string_view{};
+ this->SubKey = cm::string_view{};
+ this->ValueName = cm::string_view{};
+
+ auto result = this->RegistryFormat.find(this->Expression);
+
+ if (result) {
+ auto separator = cm::string_view{
+ this->Expression.data() + this->RegistryFormat.start(1),
+ this->RegistryFormat.end(1) - this->RegistryFormat.start(1)
+ };
+ if (separator.empty()) {
+ separator = this->Separator;
+ } else {
+ separator = separator.substr(1, separator.length() - 2);
+ }
+
+ this->RootKey = cm::string_view{
+ this->Expression.data() + this->RegistryFormat.start(2),
+ this->RegistryFormat.end(2) - this->RegistryFormat.start(2)
+ };
+ this->SubKey = cm::string_view{
+ this->Expression.data() + this->RegistryFormat.start(3),
+ this->RegistryFormat.end(3) - this->RegistryFormat.start(3)
+ };
+
+ auto pos = this->SubKey.find(separator);
+ if (pos != cm::string_view::npos) {
+ // split in ValueName and SubKey
+ this->ValueName = this->SubKey.substr(pos + separator.size());
+ if (Strucmp(this->ValueName, "(default)") == 0) {
+ // handle magic name for default value
+ this->ValueName = ""_s;
+ }
+ this->SubKey = this->SubKey.substr(0, pos);
+ } else {
+ this->ValueName = ""_s;
+ }
+ }
+ return result;
+ }
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ void Replace(const std::string& value)
+ {
+ this->Expression.replace(
+ this->RegistryFormat.start(),
+ this->RegistryFormat.end() - this->RegistryFormat.start(), value);
+ }
+
+ cm::string_view GetRootKey() const { return this->RootKey; }
+
+ cm::string_view GetSubKey() const { return this->SubKey; }
+ cm::string_view GetValueName() const { return this->ValueName; }
+
+ const std::string& GetExpression() const { return this->Expression; }
+#endif
+
+private:
+ std::string Expression;
+ cm::string_view Separator;
+ cmsys::RegularExpression RegistryFormat;
+ cm::string_view RootKey;
+ cm::string_view SubKey;
+ cm::string_view ValueName;
+};
+}
+
+// class cmWindowsRegistry
+const cmWindowsRegistry::ValueTypeSet cmWindowsRegistry::SimpleTypes =
+ cmWindowsRegistry::ValueTypeSet{ cmWindowsRegistry::ValueType::Reg_SZ,
+ cmWindowsRegistry::ValueType::Reg_EXPAND_SZ,
+ cmWindowsRegistry::ValueType::Reg_DWORD,
+ cmWindowsRegistry::ValueType::Reg_QWORD };
+const cmWindowsRegistry::ValueTypeSet cmWindowsRegistry::AllTypes =
+ cmWindowsRegistry::SimpleTypes + cmWindowsRegistry::ValueType::Reg_MULTI_SZ;
+
+cmWindowsRegistry::cmWindowsRegistry(cmMakefile& makefile,
+ const ValueTypeSet& supportedTypes)
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ : SupportedTypes(supportedTypes)
+#else
+ : LastError("No Registry on this platform.")
+#endif
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ if (cmValue targetSize = makefile.GetDefinition("CMAKE_SIZEOF_VOID_P")) {
+ this->TargetSize = targetSize == "8" ? 64 : 32;
+ }
+#else
+ (void)makefile;
+ (void)supportedTypes;
+#endif
+}
+
+cm::optional<cmWindowsRegistry::View> cmWindowsRegistry::ToView(
+ cm::string_view name)
+{
+ static std::unordered_map<cm::string_view, cmWindowsRegistry::View>
+ ViewDefinitions{
+ { "BOTH"_s, View::Both }, { "HOST"_s, View::Host },
+ { "TARGET"_s, View::Target }, { "32"_s, View::Reg32 },
+ { "64"_s, View::Reg64 }, { "32_64"_s, View::Reg32_64 },
+ { "64_32"_s, View::Reg64_32 }
+ };
+
+ auto it = ViewDefinitions.find(name);
+
+ return it == ViewDefinitions.end()
+ ? cm::nullopt
+ : cm::optional<cmWindowsRegistry::View>{ it->second };
+}
+
+// define hash structure required by std::unordered_map
+namespace std {
+template <>
+struct hash<cmWindowsRegistry::View>
+{
+ size_t operator()(cmWindowsRegistry::View const& v) const noexcept
+ {
+ return static_cast<
+ typename underlying_type<cmWindowsRegistry::View>::type>(v);
+ }
+};
+}
+
+cm::string_view cmWindowsRegistry::FromView(View view)
+{
+ static std::unordered_map<cmWindowsRegistry::View, cm::string_view>
+ ViewDefinitions{
+ { View::Both, "BOTH"_s }, { View::Host, "HOST"_s },
+ { View::Target, "TARGET"_s }, { View::Reg32, "32"_s },
+ { View::Reg64, "64"_s }, { View::Reg32_64, "32_64"_s },
+ { View::Reg64_32, "64_32"_s }
+ };
+
+ auto it = ViewDefinitions.find(view);
+
+ return it == ViewDefinitions.end() ? ""_s : it->second;
+}
+
+cm::string_view cmWindowsRegistry::GetLastError() const
+{
+ return this->LastError;
+}
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+std::vector<cmWindowsRegistry::View> cmWindowsRegistry::ComputeViews(View view)
+{
+ switch (view) {
+ case View::Both:
+ switch (this->TargetSize) {
+ case 64:
+ return std::vector<View>{ View::Reg64, View::Reg32 };
+ break;
+ case 32:
+ return Is64BitWindows()
+ ? std::vector<View>{ View::Reg32, View::Reg64 }
+ : std::vector<View>{ View::Reg32 };
+ break;
+ default:
+ // No language specified, fallback to host architecture
+ return Is64BitWindows()
+ ? std::vector<View>{ View::Reg64, View::Reg32 }
+ : std::vector<View>{ View::Reg32 };
+ break;
+ }
+ break;
+ case View::Target:
+ switch (this->TargetSize) {
+ case 64:
+ return std::vector<View>{ View::Reg64 };
+ break;
+ case 32:
+ return std::vector<View>{ View::Reg32 };
+ break;
+ default:
+ break;
+ }
+ CM_FALLTHROUGH;
+ case View::Host:
+ return std::vector<View>{ Is64BitWindows() ? View::Reg64 : View::Reg32 };
+ break;
+ case View::Reg64_32:
+ return Is64BitWindows() ? std::vector<View>{ View::Reg64, View::Reg32 }
+ : std::vector<View>{ View::Reg32 };
+ break;
+ case View::Reg32_64:
+ return Is64BitWindows() ? std::vector<View>{ View::Reg32, View::Reg64 }
+ : std::vector<View>{ View::Reg32 };
+ break;
+ default:
+ return std::vector<View>{ view };
+ break;
+ }
+}
+#endif
+
+cm::optional<std::string> cmWindowsRegistry::ReadValue(
+ cm::string_view key, cm::string_view name, View view,
+ cm::string_view separator)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ // compute list of registry views
+ auto views = this->ComputeViews(view);
+
+ if (Strucmp(name, "(default)") == 0) {
+ // handle magic name for default value
+ name = ""_s;
+ }
+ if (separator.empty()) {
+ separator = "\0"_s;
+ }
+
+ for (auto v : views) {
+ try {
+ this->LastError.clear();
+ auto handler = KeyHandler::OpenKey(key, v);
+ return handler.ReadValue(name, this->SupportedTypes, separator);
+ } catch (const registry_error& e) {
+ this->LastError = e.what();
+ continue;
+ }
+ }
+#else
+ (void)key;
+ (void)name;
+ (void)view;
+ (void)separator;
+#endif
+ return cm::nullopt;
+}
+
+cm::optional<std::vector<std::string>> cmWindowsRegistry::GetValueNames(
+ cm::string_view key, View view)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ this->LastError.clear();
+ // compute list of registry views
+ auto views = this->ComputeViews(view);
+ std::vector<std::string> valueNames;
+ bool querySuccessful = false;
+
+ for (auto v : views) {
+ try {
+ auto handler = KeyHandler::OpenKey(key, v);
+ auto list = handler.GetValueNames();
+ std::move(list.begin(), list.end(), std::back_inserter(valueNames));
+ querySuccessful = true;
+ } catch (const registry_error& e) {
+ this->LastError = e.what();
+ continue;
+ }
+ }
+ if (!valueNames.empty()) {
+ // value names must be unique and sorted
+ std::sort(valueNames.begin(), valueNames.end());
+ valueNames.erase(std::unique(valueNames.begin(), valueNames.end()),
+ valueNames.end());
+ }
+
+ if (querySuccessful) {
+ // At least one query was successful, so clean-up any error message
+ this->LastError.clear();
+ return valueNames;
+ }
+#else
+ (void)key;
+ (void)view;
+#endif
+ return cm::nullopt;
+}
+
+cm::optional<std::vector<std::string>> cmWindowsRegistry::GetSubKeys(
+ cm::string_view key, View view)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ this->LastError.clear();
+ // compute list of registry views
+ auto views = this->ComputeViews(view);
+ std::vector<std::string> subKeys;
+ bool querySuccessful = false;
+
+ for (auto v : views) {
+ try {
+ auto handler = KeyHandler::OpenKey(key, v);
+ auto list = handler.GetSubKeys();
+ std::move(list.begin(), list.end(), std::back_inserter(subKeys));
+ querySuccessful = true;
+ } catch (const registry_error& e) {
+ this->LastError = e.what();
+ continue;
+ }
+ }
+ if (!subKeys.empty()) {
+ // keys must be unique and sorted
+ std::sort(subKeys.begin(), subKeys.end());
+ subKeys.erase(std::unique(subKeys.begin(), subKeys.end()), subKeys.end());
+ }
+
+ if (querySuccessful) {
+ // At least one query was successful, so clean-up any error message
+ this->LastError.clear();
+ return subKeys;
+ }
+#else
+ (void)key;
+ (void)view;
+#endif
+ return cm::nullopt;
+}
+
+cm::optional<std::vector<std::string>> cmWindowsRegistry::ExpandExpression(
+ cm::string_view expression, View view, cm::string_view separator)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ static std::string NOTFOUND{ "/REGISTRY-NOTFOUND" };
+
+ this->LastError.clear();
+
+ // compute list of registry views
+ auto views = this->ComputeViews(view);
+ std::vector<std::string> result;
+
+ for (auto v : views) {
+ ExpressionParser parser(expression);
+
+ while (parser.Find()) {
+ try {
+ auto handler =
+ KeyHandler::OpenKey(parser.GetRootKey(), parser.GetSubKey(), v);
+ auto data = handler.ReadValue(parser.GetValueName(),
+ this->SupportedTypes, separator);
+ parser.Replace(data);
+ } catch (const registry_error& e) {
+ this->LastError = e.what();
+ parser.Replace(NOTFOUND);
+ continue;
+ }
+ }
+ result.emplace_back(parser.GetExpression());
+ if (expression == parser.GetExpression()) {
+ // there no substitutions, so can ignore other views
+ break;
+ }
+ }
+
+ return result;
+#else
+ (void)view;
+ (void)separator;
+
+ ExpressionParser parser(expression);
+ if (parser.Find()) {
+ // expression holds unsupported registry access
+ // so the expression cannot be used on this platform
+ return cm::nullopt;
+ }
+ return std::vector<std::string>{ std::string{ expression } };
+#endif
+}
diff --git a/Source/cmWindowsRegistry.h b/Source/cmWindowsRegistry.h
new file mode 100644
index 0000000..bb9090e
--- /dev/null
+++ b/Source/cmWindowsRegistry.h
@@ -0,0 +1,85 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include <cm/optional>
+#include <cm/string_view>
+#include <cmext/enum_set>
+#include <cmext/string_view>
+
+class cmMakefile;
+
+class cmWindowsRegistry
+{
+public:
+ enum class View
+ {
+ Both,
+ Target,
+ Host,
+ Reg64_32,
+ Reg32_64,
+ Reg32,
+ Reg64
+ };
+
+ // Registry supported types
+ enum class ValueType : std::uint8_t
+ {
+ Reg_SZ,
+ Reg_EXPAND_SZ,
+ Reg_MULTI_SZ,
+ Reg_DWORD,
+ Reg_QWORD
+ };
+ using ValueTypeSet = cm::enum_set<ValueType>;
+
+ // All types as defined by enum ValueType
+ static const ValueTypeSet AllTypes;
+ // same as AllTYpes but without type REG_MULTI_SZ
+ static const ValueTypeSet SimpleTypes;
+
+ cmWindowsRegistry(cmMakefile&,
+ const ValueTypeSet& supportedTypes = AllTypes);
+
+ // Helper routine to convert string to enum value
+ static cm::optional<View> ToView(cm::string_view name);
+ // Helper routine to convert enum to string
+ static cm::string_view FromView(View view);
+
+ cm::optional<std::string> ReadValue(cm::string_view key,
+ View view = View::Both,
+ cm::string_view separator = "\0"_s)
+ {
+ return this->ReadValue(key, ""_s, view, separator);
+ }
+ cm::optional<std::string> ReadValue(cm::string_view key,
+ cm::string_view name,
+ View view = View::Both,
+ cm::string_view separator = "\0"_s);
+
+ cm::optional<std::vector<std::string>> GetValueNames(cm::string_view key,
+ View view = View::Both);
+ cm::optional<std::vector<std::string>> GetSubKeys(cm::string_view key,
+ View view = View::Both);
+
+ // Expand an expression which may contains multiple references
+ // to registry keys.
+ // Depending of the view specified, one or two expansions can be done.
+ cm::optional<std::vector<std::string>> ExpandExpression(
+ cm::string_view expression, View view, cm::string_view separator = "\0"_s);
+
+ cm::string_view GetLastError() const;
+
+private:
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ std::vector<View> ComputeViews(View view);
+
+ int TargetSize = 0;
+ ValueTypeSet SupportedTypes = AllTypes;
+#endif
+ std::string LastError;
+};
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 7de488b..a8dc963 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -565,10 +565,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
"No install directory specified for --install-prefix",
CommandArgument::Values::One, PrefixLambda },
CommandArgument{ "--find-package", CommandArgument::Values::Zero,
- [&](std::string const&, cmake*) -> bool {
- findPackageMode = true;
- return true;
- } },
+ CommandArgument::setToTrue(findPackageMode) },
};
for (decltype(args.size()) i = 1; i < args.size(); ++i) {
std::string const& arg = args[i];
@@ -868,13 +865,15 @@ void cmake::SetArgs(const std::vector<std::string>& args)
CommandArgument{ "-B", "No build directory specified for -B",
CommandArgument::Values::One,
CommandArgument::RequiresSeparator::No, BuildArgLambda },
+ CommandArgument{ "--fresh", CommandArgument::Values::Zero,
+ [](std::string const&, cmake* cm) -> bool {
+ cm->FreshCache = true;
+ return true;
+ } },
CommandArgument{ "-P", "-P must be followed by a file name.",
CommandArgument::Values::One,
CommandArgument::RequiresSeparator::No,
- [&](std::string const&, cmake*) -> bool {
- scriptMode = true;
- return true;
- } },
+ CommandArgument::setToTrue(scriptMode) },
CommandArgument{ "-D", "-D must be followed with VAR=VALUE.",
CommandArgument::Values::One,
CommandArgument::RequiresSeparator::No,
@@ -1158,6 +1157,12 @@ void cmake::SetArgs(const std::vector<std::string>& args)
// iterate each argument
std::string const& arg = args[i];
+ if (scriptMode && arg == "--") {
+ // Stop processing CMake args and avoid possible errors
+ // when arbitrary args are given to CMake script.
+ break;
+ }
+
// Generator flag has special handling for when to print help
// so it becomes the exception
if (generatorCommand.matches(arg)) {
@@ -1455,7 +1460,7 @@ void cmake::PrintTraceFormatVersion()
Json::StreamWriterBuilder builder;
builder["indentation"] = "";
version["major"] = 1;
- version["minor"] = 1;
+ version["minor"] = 2;
val["version"] = version;
msg = Json::writeString(builder, val);
#endif
@@ -2098,6 +2103,21 @@ int cmake::ActualConfigure()
cmStateEnums::INTERNAL);
}
+ // We want to create the package redirects directory as early as possible,
+ // but not before pre-configure checks have passed. This ensures we get
+ // errors about inappropriate source/binary directories first.
+ const auto redirectsDir =
+ cmStrCat(this->GetHomeOutputDirectory(), "/CMakeFiles/pkgRedirects");
+ cmSystemTools::RemoveADirectory(redirectsDir);
+ if (!cmSystemTools::MakeDirectory(redirectsDir)) {
+ cmSystemTools::Error(
+ "Unable to (re)create the private pkgRedirects directory:\n" +
+ redirectsDir);
+ return -1;
+ }
+ this->AddCacheEntry("CMAKE_FIND_PACKAGE_REDIRECTS_DIR", redirectsDir,
+ "Value Computed by CMake.", cmStateEnums::STATIC);
+
// no generator specified on the command line
if (!this->GlobalGenerator) {
cmValue genName = this->State->GetInitializedCacheValue("CMAKE_GENERATOR");
@@ -2398,12 +2418,19 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure)
}
if (this->GetWorkingMode() == NORMAL_MODE) {
+ if (this->FreshCache) {
+ this->DeleteCache(this->GetHomeOutputDirectory());
+ }
// load the cache
if (this->LoadCache() < 0) {
cmSystemTools::Error("Error executing cmake::LoadCache(). Aborting.\n");
return -1;
}
} else {
+ if (this->FreshCache) {
+ cmSystemTools::Error("--fresh allowed only when configuring a project");
+ return -1;
+ }
this->AddCMakePaths();
}
diff --git a/Source/cmake.h b/Source/cmake.h
index 3c2a36c..c2bbff7 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -703,6 +703,7 @@ private:
FileExtensions HipFileExtensions;
bool ClearBuildSystem = false;
bool DebugTryCompile = false;
+ bool FreshCache = false;
bool RegenerateDuringBuild = false;
std::unique_ptr<cmFileTimeCache> FileTimeCache;
std::string GraphVizFile;
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index 76055b4..41c6c12 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -9,6 +9,7 @@
#include <climits>
#include <cstdio>
#include <cstring>
+#include <functional>
#include <iostream>
#include <sstream>
#include <string>
@@ -73,6 +74,8 @@ const char* cmDocumentationOptions[][2] = {
{ "--list-presets", "List available presets." },
{ "-E", "CMake command mode." },
{ "-L[A][H]", "List non-advanced cached variables." },
+ { "--fresh",
+ "Configure a fresh build tree, removing any existing cache file." },
{ "--build <dir>", "Build a CMake-generated project binary tree." },
{ "--install <dir>", "Install a CMake-generated project binary tree." },
{ "--open <dir>", "Open generated project in the associated application." },
@@ -260,37 +263,17 @@ int do_cmake(int ac, char const* const* av)
return true;
} },
CommandArgument{ "--system-information", CommandArgument::Values::Zero,
- [&](std::string const&) -> bool {
- sysinfo = true;
- return true;
- } },
+ CommandArgument::setToTrue(sysinfo) },
CommandArgument{ "-N", CommandArgument::Values::Zero,
- [&](std::string const&) -> bool {
- view_only = true;
- return true;
- } },
+ CommandArgument::setToTrue(view_only) },
CommandArgument{ "-LAH", CommandArgument::Values::Zero,
- [&](std::string const&) -> bool {
- list_all_cached = true;
- list_help = true;
- return true;
- } },
+ CommandArgument::setToTrue(list_all_cached, list_help) },
CommandArgument{ "-LA", CommandArgument::Values::Zero,
- [&](std::string const&) -> bool {
- list_all_cached = true;
- return true;
- } },
+ CommandArgument::setToTrue(list_all_cached) },
CommandArgument{ "-LH", CommandArgument::Values::Zero,
- [&](std::string const&) -> bool {
- list_cached = true;
- list_help = true;
- return true;
- } },
+ CommandArgument::setToTrue(list_cached, list_help) },
CommandArgument{ "-L", CommandArgument::Values::Zero,
- [&](std::string const&) -> bool {
- list_cached = true;
- return true;
- } },
+ CommandArgument::setToTrue(list_cached) },
CommandArgument{ "-P", "No script specified for argument -P",
CommandArgument::Values::One,
CommandArgument::RequiresSeparator::No,
@@ -508,15 +491,9 @@ int do_build(int ac, char const* const* av)
std::vector<CommandArgument> arguments = {
CommandArgument{ "--preset", CommandArgument::Values::One,
- [&](std::string const& value) -> bool {
- presetName = value;
- return true;
- } },
+ CommandArgument::setToValue(presetName) },
CommandArgument{ "--list-presets", CommandArgument::Values::Zero,
- [&](std::string const&) -> bool {
- listPresets = true;
- return true;
- } },
+ CommandArgument::setToTrue(listPresets) },
CommandArgument{ "-j", CommandArgument::Values::ZeroOrOne,
CommandArgument::RequiresSeparator::No, jLambda },
CommandArgument{ "--parallel", CommandArgument::Values::ZeroOrOne,
@@ -525,15 +502,9 @@ int do_build(int ac, char const* const* av)
CommandArgument{ "--target", CommandArgument::Values::OneOrMore,
targetLambda },
CommandArgument{ "--config", CommandArgument::Values::One,
- [&](std::string const& value) -> bool {
- config = value;
- return true;
- } },
+ CommandArgument::setToValue(config) },
CommandArgument{ "--clean-first", CommandArgument::Values::Zero,
- [&](std::string const&) -> bool {
- cleanFirst = true;
- return true;
- } },
+ CommandArgument::setToTrue(cleanFirst) },
CommandArgument{ "--resolve-package-references",
CommandArgument::Values::One, resolvePackagesLambda },
CommandArgument{ "-v", CommandArgument::Values::Zero, verboseLambda },
@@ -543,10 +514,7 @@ int do_build(int ac, char const* const* av)
CommandArgument{ "--use-stderr", CommandArgument::Values::Zero,
[](std::string const&) -> bool { return true; } },
CommandArgument{ "--", CommandArgument::Values::Zero,
- [&](std::string const&) -> bool {
- nativeOptionsPassed = true;
- return true;
- } },
+ CommandArgument::setToTrue(nativeOptionsPassed) },
};
if (ac >= 3) {
@@ -829,31 +797,16 @@ int do_install(int ac, char const* const* av)
std::vector<CommandArgument> arguments = {
CommandArgument{ "--config", CommandArgument::Values::One,
- [&](std::string const& value) -> bool {
- config = value;
- return true;
- } },
+ CommandArgument::setToValue(config) },
CommandArgument{ "--component", CommandArgument::Values::One,
- [&](std::string const& value) -> bool {
- component = value;
- return true;
- } },
- CommandArgument{ "--default-directory-permissions",
- CommandArgument::Values::One,
- [&](std::string const& value) -> bool {
- defaultDirectoryPermissions = value;
- return true;
- } },
+ CommandArgument::setToValue(component) },
+ CommandArgument{
+ "--default-directory-permissions", CommandArgument::Values::One,
+ CommandArgument::setToValue(defaultDirectoryPermissions) },
CommandArgument{ "--prefix", CommandArgument::Values::One,
- [&](std::string const& value) -> bool {
- prefix = value;
- return true;
- } },
+ CommandArgument::setToValue(prefix) },
CommandArgument{ "--strip", CommandArgument::Values::Zero,
- [&](std::string const&) -> bool {
- strip = true;
- return true;
- } },
+ CommandArgument::setToTrue(strip) },
CommandArgument{ "-v", CommandArgument::Values::Zero, verboseLambda },
CommandArgument{ "--verbose", CommandArgument::Values::Zero,
verboseLambda }
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 32c01e5..df740c9 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -97,7 +97,8 @@ void CMakeCommandUsage(std::string const& program)
<< "Available commands: \n"
<< " capabilities - Report capabilities built into cmake "
"in JSON format\n"
- << " cat <files>... - concat the files and print them to the standard output\n"
+ << " cat [--] <files>... - concat the files and print them to the "
+ "standard output\n"
<< " chdir dir cmd [args...] - run command in a given directory\n"
<< " compare_files [--ignore-eol] file1 file2\n"
<< " - check if file1 is same as file2\n"
@@ -110,7 +111,7 @@ void CMakeCommandUsage(std::string const& program)
<< " echo [<string>...] - displays arguments as text\n"
<< " echo_append [<string>...] - displays arguments as text but no new "
"line\n"
- << " env [--unset=NAME]... [NAME=VALUE]... COMMAND [ARG]...\n"
+ << " env [--unset=NAME ...] [NAME=VALUE ...] [--] <command> [<arg>...]\n"
<< " - run command in a modified environment\n"
<< " environment - display the current environment\n"
<< " make_directory <dir>... - create parent and <dir> directories\n"
@@ -125,8 +126,9 @@ void CMakeCommandUsage(std::string const& program)
<< " remove_directory <dir>... - remove directories and their contents (deprecated: use rm instead)\n"
<< " rename oldname newname - rename a file or directory "
"(on one volume)\n"
- << " rm [-rRf] <file/dir>... - remove files or directories, use -f to "
- "force it, r or R to remove directories and their contents recursively\n"
+ << " rm [-rRf] [--] <file/dir>... - remove files or directories, use -f "
+ "to force it, r or R to remove directories and their contents "
+ "recursively\n"
<< " sleep <number>... - sleep for given number of seconds\n"
<< " tar [cxt][vf][zjJ] file.tar [file/dir1 file/dir2 ...]\n"
<< " - create or extract a tar or zip archive\n"
@@ -793,6 +795,12 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
auto ae = args.cend();
for (; ai != ae; ++ai) {
std::string const& a = *ai;
+ if (a == "--") {
+ // Stop parsing options/environment variables; the next argument
+ // should be the command.
+ ++ai;
+ break;
+ }
if (cmHasLiteralPrefix(a, "--unset=")) {
// Unset environment variable.
cmSystemTools::UnPutEnv(a.substr(8));
@@ -1051,9 +1059,12 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
// Command to concat files into one
if (args[1] == "cat" && args.size() >= 3) {
int return_value = 0;
+ bool doing_options = true;
for (auto const& arg : cmMakeRange(args).advance(2)) {
- if (cmHasLiteralPrefix(arg, "-")) {
- if (arg != "--") {
+ if (doing_options && cmHasLiteralPrefix(arg, "-")) {
+ if (arg == "--") {
+ doing_options = false;
+ } else {
cmSystemTools::Error(arg + ": option not handled");
return_value = 1;
}
@@ -1275,8 +1286,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
// FIXME: With advanced add_subdirectory usage, these are
// not necessarily the same as the generator originally used.
// We should pass all these directories through an info file.
- lgd->SetRelativePathTopSource(homeDir);
- lgd->SetRelativePathTopBinary(homeOutDir);
+ lgd->SetRelativePathTop(homeDir, homeOutDir);
// Actually scan dependencies.
return lgd->UpdateDependencies(depInfo, verbose, color) ? 0 : 2;
@@ -1358,6 +1368,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
std::vector<std::string> files;
std::string mtime;
std::string format;
+ cmSystemTools::cmTarExtractTimestamps extractTimestamps =
+ cmSystemTools::cmTarExtractTimestamps::Yes;
cmSystemTools::cmTarCompression compress =
cmSystemTools::TarCompressNone;
int nCompress = 0;
@@ -1383,6 +1395,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
format);
return 1;
}
+ } else if (arg == "--touch") {
+ extractTimestamps = cmSystemTools::cmTarExtractTimestamps::No;
} else {
cmSystemTools::Error("Unknown option to -E tar: " + arg);
return 1;
@@ -1454,7 +1468,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
return 1;
}
} else if (action == cmSystemTools::TarActionExtract) {
- if (!cmSystemTools::ExtractTar(outFile, files, verbose)) {
+ if (!cmSystemTools::ExtractTar(outFile, files, extractTimestamps,
+ verbose)) {
cmSystemTools::Error("Problem extracting tar: " + outFile);
return 1;
}
@@ -1558,8 +1573,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
// FIXME: With advanced add_subdirectory usage, these are
// not necessarily the same as the generator originally used.
// We should pass all these directories through an info file.
- lgd->SetRelativePathTopSource(homeDir);
- lgd->SetRelativePathTopBinary(homeOutDir);
+ lgd->SetRelativePathTop(homeDir, homeOutDir);
return cmTransformDepfile(format, *lgd, args[8], args[9]) ? 0 : 2;
}
diff --git a/Source/ctest.cxx b/Source/ctest.cxx
index cad27fa..363f473 100644
--- a/Source/ctest.cxx
+++ b/Source/ctest.cxx
@@ -44,6 +44,9 @@ static const char* cmDocumentationOptions[][2] = {
{ "--test-output-size-failed <size>",
"Limit the output for failed tests "
"to <size> bytes" },
+ { "--test-output-truncation <mode>",
+ "Truncate 'tail' (default), 'middle' or 'head' of test output once "
+ "maximum output size is reached" },
{ "-F", "Enable failover." },
{ "-j <jobs>, --parallel <jobs>",
"Run the tests in parallel using the "
diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c
index 19bf982..22cbf06 100644
--- a/Source/kwsys/ProcessUNIX.c
+++ b/Source/kwsys/ProcessUNIX.c
@@ -1906,7 +1906,7 @@ static void kwsysProcessDestroy(kwsysProcess* cp)
(errno == EINTR)) {
}
if (result > 0) {
- /* This child has termianted. */
+ /* This child has terminated. */
cp->ForkPIDs[i] = 0;
if (--cp->CommandsLeft == 0) {
/* All children have terminated. Close the signal pipe
diff --git a/Source/kwsys/ProcessWin32.c b/Source/kwsys/ProcessWin32.c
index e97973e..17e1507 100644
--- a/Source/kwsys/ProcessWin32.c
+++ b/Source/kwsys/ProcessWin32.c
@@ -2119,7 +2119,7 @@ static void kwsysProcessSetExitExceptionByIndex(kwsysProcess* cp, int code,
KWSYSPE_CASE(Fault, "In-page error");
break;
case STATUS_INVALID_HANDLE:
- KWSYSPE_CASE(Fault, "Invalid hanlde");
+ KWSYSPE_CASE(Fault, "Invalid handle");
break;
case STATUS_NONCONTINUABLE_EXCEPTION:
KWSYSPE_CASE(Fault, "Noncontinuable exception");