summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--CMakeLists.txt2
-rw-r--r--CONTRIBUTING.rst1
-rw-r--r--Help/command/file.rst13
-rw-r--r--Help/command/install.rst9
-rw-r--r--Help/command/list.rst73
-rw-r--r--Help/manual/cmake-properties.7.rst2
-rw-r--r--Help/manual/cmake-variables.7.rst1
-rw-r--r--Help/prop_tgt/COMMON_LANGUAGE_RUNTIME.rst19
-rw-r--r--Help/prop_tgt/IMPORTED_COMMON_LANGUAGE_RUNTIME.rst8
-rw-r--r--Help/release/3.11.rst25
-rw-r--r--Help/release/dev/UseSWIG-Multiple-Behaviors.rst6
-rw-r--r--Help/release/dev/glob_configure_depends.rst6
-rw-r--r--Help/release/dev/list-transform.rst5
-rw-r--r--Help/release/dev/managed-target-property.rst8
-rw-r--r--Help/release/dev/msvc-toolset-version-variable.rst6
-rw-r--r--Help/release/dev/wcdh-raw-features.rst6
-rw-r--r--Help/variable/MSVC_TOOLSET_VERSION.rst21
-rw-r--r--Help/variable/MSVC_VERSION.rst3
-rw-r--r--Modules/CMakeCUDACompiler.cmake.in1
-rw-r--r--Modules/CMakeCUDAInformation.cmake18
-rw-r--r--Modules/CMakeParseImplicitLinkInfo.cmake2
-rw-r--r--Modules/CheckIncludeFile.cmake3
-rw-r--r--Modules/CheckIncludeFileCXX.cmake3
-rw-r--r--Modules/CheckIncludeFiles.cmake3
-rw-r--r--Modules/Compiler/Clang-CXX.cmake47
-rw-r--r--Modules/Compiler/MSVC-CXX-FeatureTests.cmake36
-rw-r--r--Modules/FindBoost.cmake33
-rw-r--r--Modules/FindCUDA.cmake5
-rw-r--r--Modules/FindGTK2.cmake10
-rw-r--r--Modules/FindIce.cmake20
-rw-r--r--Modules/FindImageMagick.cmake3
-rw-r--r--Modules/FindOpenAL.cmake2
-rw-r--r--Modules/FindOpenMP.cmake17
-rw-r--r--Modules/FindPython.cmake15
-rw-r--r--Modules/FindPython/Support.cmake9
-rw-r--r--Modules/FindwxWidgets.cmake44
-rw-r--r--Modules/InstallRequiredSystemLibraries.cmake105
-rw-r--r--Modules/MatlabTestsRedirect.cmake5
-rw-r--r--Modules/Platform/Android-Clang-CXX.cmake7
-rw-r--r--Modules/Platform/Android-GNU-CXX.cmake3
-rw-r--r--Modules/Platform/Android/ndk-stl-c++.cmake1
-rw-r--r--Modules/Platform/Android/ndk-stl-gabi++.cmake1
-rw-r--r--Modules/Platform/Android/ndk-stl-gnustl.cmake1
-rw-r--r--Modules/Platform/Android/ndk-stl-none.cmake1
-rw-r--r--Modules/Platform/Android/ndk-stl-stlport.cmake1
-rw-r--r--Modules/Platform/Android/ndk-stl-system.cmake1
-rw-r--r--Modules/Platform/Windows-MSVC.cmake25
-rw-r--r--Modules/Platform/Windows-NVIDIA-CUDA.cmake19
-rw-r--r--Modules/UseSWIG.cmake167
-rw-r--r--Modules/WriteCompilerDetectionHeader.cmake116
-rw-r--r--Source/CMakeLists.txt3
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CPack/cpack.cxx8
-rw-r--r--Source/CTest/cmCTestCurl.h2
-rw-r--r--Source/cmAlgorithms.h2
-rw-r--r--Source/cmCacheManager.cxx18
-rw-r--r--Source/cmCommandArgumentParserHelper.cxx9
-rw-r--r--Source/cmConfigureFileCommand.h6
-rw-r--r--Source/cmCoreTryCompile.h2
-rw-r--r--Source/cmExportBuildFileGenerator.cxx5
-rw-r--r--Source/cmExportFileGenerator.cxx14
-rw-r--r--Source/cmExportLibraryDependenciesCommand.h2
-rw-r--r--Source/cmExternalMakefileProjectGenerator.h2
-rw-r--r--Source/cmFileCommand.cxx38
-rw-r--r--Source/cmGeneratorExpressionNode.cxx3
-rw-r--r--Source/cmGeneratorTarget.cxx84
-rw-r--r--Source/cmGeneratorTarget.h31
-rw-r--r--Source/cmGlobVerificationManager.cxx172
-rw-r--r--Source/cmGlobVerificationManager.h89
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx77
-rw-r--r--Source/cmGlobalNinjaGenerator.h3
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx7
-rw-r--r--Source/cmGlobalVisualStudio8Generator.cxx38
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx47
-rw-r--r--Source/cmGlobalXCodeGenerator.h2
-rw-r--r--Source/cmInstallFilesCommand.h2
-rw-r--r--Source/cmInstallTargetGenerator.cxx8
-rw-r--r--Source/cmLinkLineDeviceComputer.cxx54
-rw-r--r--Source/cmListCommand.cxx556
-rw-r--r--Source/cmListCommand.h1
-rw-r--r--Source/cmLocalNinjaGenerator.cxx10
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx16
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx51
-rw-r--r--Source/cmMacroCommand.cxx2
-rw-r--r--Source/cmMakefile.cxx28
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx4
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx4
-rw-r--r--Source/cmMakefileTargetGenerator.cxx2
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx6
-rw-r--r--Source/cmNinjaTargetGenerator.cxx158
-rw-r--r--Source/cmQtAutoGenerator.cxx111
-rw-r--r--Source/cmQtAutoGenerator.h38
-rw-r--r--Source/cmQtAutoGeneratorMocUic.cxx52
-rw-r--r--Source/cmQtAutoGeneratorMocUic.h2
-rw-r--r--Source/cmQtAutoGeneratorRcc.cxx8
-rw-r--r--Source/cmState.cxx36
-rw-r--r--Source/cmState.h14
-rw-r--r--Source/cmStateSnapshot.cxx19
-rw-r--r--Source/cmStringCommand.cxx100
-rw-r--r--Source/cmStringCommand.h23
-rw-r--r--Source/cmStringReplaceHelper.cxx117
-rw-r--r--Source/cmStringReplaceHelper.h69
-rw-r--r--Source/cmTargetLinkLibrariesCommand.h4
-rw-r--r--Source/cmTargetPropCommandBase.h2
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx316
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h5
-rw-r--r--Source/cmXMLWriter.cxx29
-rw-r--r--Source/cmXMLWriter.h3
-rw-r--r--Source/cmake.cxx96
-rw-r--r--Source/cmake.h10
-rw-r--r--Source/kwsys/SystemInformation.cxx2
-rw-r--r--Tests/CMakeLists.txt5
-rw-r--r--Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in6
-rw-r--r--Tests/CompileFeatures/CMakeLists.txt218
-rw-r--r--Tests/CudaOnly/CMakeLists.txt5
-rw-r--r--Tests/CudaOnly/LinkSystemDeviceLibraries/CMakeLists.txt15
-rw-r--r--Tests/CudaOnly/LinkSystemDeviceLibraries/main.cu77
-rw-r--r--Tests/CudaOnly/PDB/CMakeLists.txt19
-rw-r--r--Tests/CudaOnly/PDB/check_pdbs.cmake10
-rw-r--r--Tests/CudaOnly/PDB/main.cu4
-rw-r--r--Tests/FindMatlab/basic_checks/CMakeLists.txt7
-rw-r--r--Tests/FindMatlab/failure_reports/CMakeLists.txt39
-rw-r--r--Tests/Module/ExternalData/Data5/CMakeLists.txt6
-rw-r--r--Tests/Module/ExternalData/Data5/Data5.dat.md51
-rw-r--r--Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt15
-rw-r--r--Tests/Module/WriteCompilerDetectionHeader/main_bare.cpp23
-rw-r--r--Tests/RunCMake/Android/android_lib.cxx4
-rw-r--r--Tests/RunCMake/Android/check_binary.cmake8
-rw-r--r--Tests/RunCMake/Android/common.cmake17
-rw-r--r--Tests/RunCMake/CMakeLists.txt9
-rw-r--r--Tests/RunCMake/CPackCommandLine/NotAGenerator-result.txt1
-rw-r--r--Tests/RunCMake/CPackCommandLine/NotAGenerator-stderr.txt1
-rw-r--r--Tests/RunCMake/CPackCommandLine/RunCMakeTest.cmake10
-rw-r--r--Tests/RunCMake/CommandLine/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/CommandLine/trace-expand-warn-uninitialized-stderr.txt2
-rw-r--r--Tests/RunCMake/CommandLine/trace-expand-warn-uninitialized.cmake4
-rw-r--r--Tests/RunCMake/Ninja/RspFileC.cmake2
-rw-r--r--Tests/RunCMake/Ninja/RspFileCXX.cmake2
-rw-r--r--Tests/RunCMake/Ninja/RspFileFortran.cmake2
-rw-r--r--Tests/RunCMake/Ninja/RunCMakeTest.cmake6
-rw-r--r--Tests/RunCMake/UseSWIG/BasicPerl.cmake18
-rw-r--r--Tests/RunCMake/UseSWIG/BasicPython.cmake9
-rw-r--r--Tests/RunCMake/UseSWIG/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/UseSWIG/LegacyPerl.cmake18
-rw-r--r--Tests/RunCMake/UseSWIG/LegacyPython.cmake9
-rw-r--r--Tests/RunCMake/UseSWIG/MultipleModules.cmake30
-rw-r--r--Tests/RunCMake/UseSWIG/MultiplePython.cmake26
-rw-r--r--Tests/RunCMake/UseSWIG/RunCMakeTest.cmake27
-rw-r--r--Tests/RunCMake/VS10Project/ExplicitCMakeLists-check.cmake25
-rw-r--r--Tests/RunCMake/VS10Project/ExplicitCMakeLists.cmake3
-rw-r--r--Tests/RunCMake/VS10Project/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/WriteCompilerDetectionHeader/InvalidFeature-stderr.txt1
-rw-r--r--Tests/RunCMake/XcodeProject/ExplicitCMakeLists-check.cmake20
-rw-r--r--Tests/RunCMake/XcodeProject/ExplicitCMakeLists.cmake2
-rw-r--r--Tests/RunCMake/XcodeProject/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/file/GLOB-CONFIGURE_DEPENDS-RerunCMake-build-stdout.txt1
-rw-r--r--Tests/RunCMake/file/GLOB-CONFIGURE_DEPENDS-RerunCMake-rebuild_first-stdout.txt2
-rw-r--r--Tests/RunCMake/file/GLOB-CONFIGURE_DEPENDS-RerunCMake-rebuild_second-stdout.txt2
-rw-r--r--Tests/RunCMake/file/GLOB-CONFIGURE_DEPENDS-RerunCMake-stdout.txt1
-rw-r--r--Tests/RunCMake/file/GLOB-CONFIGURE_DEPENDS-RerunCMake.cmake10
-rw-r--r--Tests/RunCMake/file/GLOB-error-CONFIGURE_DEPENDS-SCRIPT_MODE-result.txt1
-rw-r--r--Tests/RunCMake/file/GLOB-error-CONFIGURE_DEPENDS-SCRIPT_MODE-stderr.txt1
-rw-r--r--Tests/RunCMake/file/GLOB-error-CONFIGURE_DEPENDS-SCRIPT_MODE.cmake1
-rw-r--r--Tests/RunCMake/file/GLOB-error-CONFIGURE_DEPENDS-modified-result.txt1
-rw-r--r--Tests/RunCMake/file/GLOB-error-CONFIGURE_DEPENDS-modified-stderr.txt7
-rw-r--r--Tests/RunCMake/file/GLOB-error-CONFIGURE_DEPENDS-modified.cmake21
-rw-r--r--Tests/RunCMake/file/GLOB-noexp-CONFIGURE_DEPENDS-result.txt1
-rw-r--r--Tests/RunCMake/file/GLOB-noexp-CONFIGURE_DEPENDS-stderr.txt4
-rw-r--r--Tests/RunCMake/file/GLOB-noexp-CONFIGURE_DEPENDS.cmake1
-rw-r--r--Tests/RunCMake/file/GLOB-warn-CONFIGURE_DEPENDS-late-stderr.txt6
-rw-r--r--Tests/RunCMake/file/GLOB-warn-CONFIGURE_DEPENDS-late.cmake11
-rw-r--r--Tests/RunCMake/file/GLOB_RECURSE-warn-CONFIGURE_DEPENDS-ninja-version-stderr.txt13
-rw-r--r--Tests/RunCMake/file/GLOB_RECURSE-warn-CONFIGURE_DEPENDS-ninja-version.cmake6
-rw-r--r--Tests/RunCMake/file/RunCMakeTest.cmake69
-rw-r--r--Tests/RunCMake/list/RunCMakeTest.cmake41
-rw-r--r--Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-APPEND.cmake48
-rw-r--r--Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-GENEX_STRIP.cmake49
-rw-r--r--Tests/RunCMake/list/TRANSFORM-InvalidAction-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-InvalidAction-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-InvalidAction.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-NoAction-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-NoAction-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-NoAction.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-PREPEND.cmake48
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex-stderr.txt5
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1-stderr.txt5
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2-stderr.txt5
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE.cmake48
-rw-r--r--Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-STRIP.cmake49
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument-stderr.txt5
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex-stderr.txt5
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments-stderr.txt5
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-TOLOWER.cmake48
-rw-r--r--Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-TOUPPER.cmake48
-rw-r--r--Tests/RunCMake/variable_watch/RaiseInParentScope-stderr.txt2
-rw-r--r--Tests/RunCMake/variable_watch/RaiseInParentScope.cmake15
-rw-r--r--Tests/RunCMake/variable_watch/RunCMakeTest.cmake1
-rw-r--r--Tests/UseSWIG/BasicConfiguration.cmake (renamed from Tests/RunCMake/UseSWIG/BasicConfiguration.cmake)24
-rw-r--r--Tests/UseSWIG/BasicPerl/CMakeLists.txt14
-rw-r--r--Tests/UseSWIG/BasicPython/CMakeLists.txt13
-rw-r--r--Tests/UseSWIG/CMakeLists.txt76
-rw-r--r--Tests/UseSWIG/LegacyConfiguration.cmake (renamed from Tests/RunCMake/UseSWIG/LegacyConfiguration.cmake)14
-rw-r--r--Tests/UseSWIG/LegacyPerl/CMakeLists.txt14
-rw-r--r--Tests/UseSWIG/LegacyPython/CMakeLists.txt13
-rw-r--r--Tests/UseSWIG/ModuleVersion2/CMakeLists.txt56
-rw-r--r--Tests/UseSWIG/MultipleModules/CMakeLists.txt68
-rw-r--r--Tests/UseSWIG/MultiplePython/CMakeLists.txt59
-rw-r--r--Tests/UseSWIG/example.cxx (renamed from Tests/RunCMake/UseSWIG/example.cxx)0
-rw-r--r--Tests/UseSWIG/example.h (renamed from Tests/RunCMake/UseSWIG/example.h)0
-rw-r--r--Tests/UseSWIG/example.i (renamed from Tests/RunCMake/UseSWIG/example.i)0
-rw-r--r--Tests/UseSWIG/runme.php4 (renamed from Tests/RunCMake/UseSWIG/runme.php4)0
-rw-r--r--Tests/UseSWIG/runme.pike (renamed from Tests/RunCMake/UseSWIG/runme.pike)0
-rw-r--r--Tests/UseSWIG/runme.pl (renamed from Tests/RunCMake/UseSWIG/runme.pl)0
-rw-r--r--Tests/UseSWIG/runme.py (renamed from Tests/RunCMake/UseSWIG/runme.py)0
-rw-r--r--Tests/UseSWIG/runme.rb (renamed from Tests/RunCMake/UseSWIG/runme.rb)0
-rw-r--r--Tests/UseSWIG/runme.tcl (renamed from Tests/RunCMake/UseSWIG/runme.tcl)0
-rw-r--r--Tests/UseSWIG/runme2.tcl (renamed from Tests/RunCMake/UseSWIG/runme2.tcl)0
-rw-r--r--Utilities/Release/linux64_release.cmake2
-rw-r--r--Utilities/Release/win32_release.cmake2
-rw-r--r--Utilities/Release/win64_release.cmake2
-rwxr-xr-xbootstrap8
298 files changed, 4237 insertions, 1177 deletions
diff --git a/.gitignore b/.gitignore
index 5d1732d..22e9800 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,6 @@
*.pyc
Testing
+
+# Visual Studio work directory
+.vs/
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a27c662..3ee67cb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -546,7 +546,7 @@ macro (CMAKE_BUILD_UTILITIES)
#---------------------------------------------------------------------
# Build libuv library.
if(CMAKE_USE_SYSTEM_LIBUV)
- find_package(LibUV 1.0.0)
+ find_package(LibUV 1.10.0)
if(NOT LIBUV_FOUND)
message(FATAL_ERROR
"CMAKE_USE_SYSTEM_LIBUV is ON but a libuv is not found!")
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index fa2c23d..01987be 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -36,6 +36,7 @@ To contribute patches:
#. Push a topic branch to a personal repository fork on GitLab.
#. Create a GitLab Merge Request targeting the upstream ``master`` branch
(even if the change is intended for merge to the ``release`` branch).
+ Check the box to allow edits from maintainers.
The merge request will enter the `CMake Review Process`_ for consideration.
diff --git a/Help/command/file.rst b/Help/command/file.rst
index 5e18077..43ce3d9 100644
--- a/Help/command/file.rst
+++ b/Help/command/file.rst
@@ -98,10 +98,10 @@ command.
::
file(GLOB <variable>
- [LIST_DIRECTORIES true|false] [RELATIVE <path>]
+ [LIST_DIRECTORIES true|false] [RELATIVE <path>] [CONFIGURE_DEPENDS]
[<globbing-expressions>...])
file(GLOB_RECURSE <variable> [FOLLOW_SYMLINKS]
- [LIST_DIRECTORIES true|false] [RELATIVE <path>]
+ [LIST_DIRECTORIES true|false] [RELATIVE <path>] [CONFIGURE_DEPENDS]
[<globbing-expressions>...])
Generate a list of files that match the ``<globbing-expressions>`` and
@@ -110,6 +110,11 @@ regular expressions, but much simpler. If ``RELATIVE`` flag is
specified, the results will be returned as relative paths to the given
path. The results will be ordered lexicographically.
+If the ``CONFIGURE_DEPENDS`` flag is specified, CMake will add logic
+to the main build system check target to rerun the flagged ``GLOB`` commands
+at build time. If any of the outputs change, CMake will regenerate the build
+system.
+
By default ``GLOB`` lists directories - directories are omitted in result if
``LIST_DIRECTORIES`` is set to false.
@@ -118,6 +123,10 @@ By default ``GLOB`` lists directories - directories are omitted in result if
your source tree. If no CMakeLists.txt file changes when a source is
added or removed then the generated build system cannot know when to
ask CMake to regenerate.
+ The ``CONFIGURE_DEPENDS`` flag may not work reliably on all generators, or if
+ a new generator is added in the future that cannot support it, projects using
+ it will be stuck. Even if ``CONFIGURE_DEPENDS`` works reliably, there is
+ still a cost to perform the check on every rebuild.
Examples of globbing expressions include::
diff --git a/Help/command/install.rst b/Help/command/install.rst
index eb7b07c..e9c185c 100644
--- a/Help/command/install.rst
+++ b/Help/command/install.rst
@@ -339,12 +339,12 @@ Installing Exports
install(EXPORT <export-name> DESTINATION <dir>
[NAMESPACE <namespace>] [[FILE <name>.cmake]|
- [EXPORT_ANDROID_MK <name>.mk]]
[PERMISSIONS permissions...]
[CONFIGURATIONS [Debug|Release|...]]
[EXPORT_LINK_INTERFACE_LIBRARIES]
[COMPONENT <component>]
[EXCLUDE_FROM_ALL])
+ install(EXPORT_ANDROID_MK <export-name> DESTINATION <dir> [...])
The ``EXPORT`` form generates and installs a CMake file containing code to
import targets from the installation tree into another project.
@@ -367,8 +367,9 @@ specified that does not match that given to the targets associated with
included in the export but a target to which it links is not included
the behavior is unspecified.
-In addition to cmake language files, the ``EXPORT_ANDROID_MK`` option maybe
-used to specify an export to the android ndk build system. The Android
+In addition to cmake language files, the ``EXPORT_ANDROID_MK`` mode maybe
+used to specify an export to the android ndk build system. This mode
+accepts the same options as the normal export mode. The Android
NDK supports the use of prebuilt libraries, both static and shared. This
allows cmake to build the libraries of a project and make them available
to an ndk build system complete with transitive dependencies, include flags
@@ -385,7 +386,7 @@ and installed by the current project. For example, the code
will install the executable myexe to ``<prefix>/bin`` and code to import
it in the file ``<prefix>/lib/myproj/myproj.cmake`` and
-``<prefix>/lib/share/ndk-modules/Android.mk``. An outside project
+``<prefix>/share/ndk-modules/Android.mk``. An outside project
may load this file with the include command and reference the ``myexe``
executable from the installation tree using the imported target name
``mp_myexe`` as if the target were built in its own tree.
diff --git a/Help/command/list.rst b/Help/command/list.rst
index 6218a2a..e240b65 100644
--- a/Help/command/list.rst
+++ b/Help/command/list.rst
@@ -151,6 +151,79 @@ REMOVE_DUPLICATES
Removes duplicated items in the list.
+TRANSFORM
+"""""""""
+
+::
+
+ list(TRANSFORM <list> <ACTION> [<SELECTOR>]
+ [OUTPUT_VARIABLE <output variable>])
+
+Transforms the list by applying an action to all or, by specifying a
+``<SELECTOR>``, to the selected elements of the list, storing result in-place
+or in the specified output variable.
+
+.. note::
+
+ ``TRANSFORM`` sub-command does not change the number of elements of the
+ list. If a ``<SELECTOR>`` is specified, only some elements will be changed,
+ the other ones will remain same as before the transformation.
+
+``<ACTION>`` specify the action to apply to the elements of list.
+The actions have exactly the same semantics as sub-commands of
+:command:`string` command.
+
+The ``<ACTION>`` may be one of:
+
+``APPEND``, ``PREPEND``: Append, prepend specified value to each element of
+the list. ::
+
+ list(TRANSFORM <list> <APPEND|PREPEND> <value> ...)
+
+``TOUPPER``, ``TOLOWER``: Convert each element of the list to upper, lower
+characters. ::
+
+ list(TRANSFORM <list> <TOLOWER|TOUPPER> ...)
+
+``STRIP``: Remove leading and trailing spaces from each element of the
+list. ::
+
+ list(TRANSFORM <list> STRIP ...)
+
+``GENEX_STRIP``: Strip any
+:manual:`generator expressions <cmake-generator-expressions(7)>` from each
+element of the list. ::
+
+ list(TRANSFORM <list> GENEX_STRIP ...)
+
+``REPLACE``: Match the regular expression as many times as possible and
+substitute the replacement expression for the match for each element
+of the list
+(Same semantic as ``REGEX REPLACE`` from :command:`string` command). ::
+
+ list(TRANSFORM <list> REPLACE <regular_expression>
+ <replace_expression> ...)
+
+``<SELECTOR>`` select which elements of the list will be transformed. Only one
+type of selector can be specified at a time.
+
+The ``<SELECTOR>`` may be one of:
+
+``AT``: Specify a list of indexes. ::
+
+ list(TRANSFORM <list> <ACTION> AT <index> [<index> ...] ...)
+
+``FOR``: Specify a range with, optionaly, an increment used to iterate over
+the range. ::
+
+ list(TRANSFORM <list> <ACTION> FOR <start> <stop> [<step>] ...)
+
+``REGEX``: Specify a regular expression. Only elements matching the regular
+expression will be transformed. ::
+
+ list(TRANSFORM <list> <ACTION> REGEX <regular_expression> ...)
+
+
Sorting
^^^^^^^
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 7ace270..d141479 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -143,6 +143,7 @@ Properties on Targets
/prop_tgt/C_EXTENSIONS
/prop_tgt/C_STANDARD
/prop_tgt/C_STANDARD_REQUIRED
+ /prop_tgt/COMMON_LANGUAGE_RUNTIME
/prop_tgt/COMPATIBLE_INTERFACE_BOOL
/prop_tgt/COMPATIBLE_INTERFACE_NUMBER_MAX
/prop_tgt/COMPATIBLE_INTERFACE_NUMBER_MIN
@@ -186,6 +187,7 @@ Properties on Targets
/prop_tgt/GNUtoMS
/prop_tgt/HAS_CXX
/prop_tgt/IMPLICIT_DEPENDS_INCLUDE_TRANSFORM
+ /prop_tgt/IMPORTED_COMMON_LANGUAGE_RUNTIME
/prop_tgt/IMPORTED_CONFIGURATIONS
/prop_tgt/IMPORTED_GLOBAL
/prop_tgt/IMPORTED_IMPLIB_CONFIG
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 652dab8..c1b0316 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -239,6 +239,7 @@ Variables that Describe the System
/variable/MSVC80
/variable/MSVC90
/variable/MSVC_IDE
+ /variable/MSVC_TOOLSET_VERSION
/variable/MSVC_VERSION
/variable/UNIX
/variable/WIN32
diff --git a/Help/prop_tgt/COMMON_LANGUAGE_RUNTIME.rst b/Help/prop_tgt/COMMON_LANGUAGE_RUNTIME.rst
new file mode 100644
index 0000000..28517e6
--- /dev/null
+++ b/Help/prop_tgt/COMMON_LANGUAGE_RUNTIME.rst
@@ -0,0 +1,19 @@
+COMMON_LANGUAGE_RUNTIME
+-----------------------
+
+By setting this target property, the target is configured to build with
+``C++/CLI`` support.
+
+The Visual Studio generator defines the ``clr`` parameter depending on
+the value of ``COMMON_LANGUAGE_RUNTIME``:
+
+* property not set: native C++ (i.e. default)
+* property set but empty: mixed unmanaged/managed C++
+* property set to any non empty value: managed C++
+
+Supported values: ``""``, ``"pure"``, ``"safe"``
+
+This property is only evaluated :ref:`Visual Studio Generators` for
+VS 2010 and above.
+
+See also :prop_tgt:`IMPORTED_COMMON_LANGUAGE_RUNTIME`
diff --git a/Help/prop_tgt/IMPORTED_COMMON_LANGUAGE_RUNTIME.rst b/Help/prop_tgt/IMPORTED_COMMON_LANGUAGE_RUNTIME.rst
new file mode 100644
index 0000000..99e3bc4
--- /dev/null
+++ b/Help/prop_tgt/IMPORTED_COMMON_LANGUAGE_RUNTIME.rst
@@ -0,0 +1,8 @@
+IMPORTED_COMMON_LANGUAGE_RUNTIME
+--------------------------------
+
+Property to define if the target uses ``C++/CLI``.
+
+Ignored for non-imported targets.
+
+See also the :prop_tgt:`COMMON_LANGUAGE_RUNTIME` target property.
diff --git a/Help/release/3.11.rst b/Help/release/3.11.rst
index b57ac29..dbaa8af 100644
--- a/Help/release/3.11.rst
+++ b/Help/release/3.11.rst
@@ -127,15 +127,6 @@ Properties
Modules
-------
-* The :module:`CheckIncludeFile` module ``check_include_file`` macro
- learned to honor the ``CMAKE_REQUIRED_LIBRARIES`` variable.
-
-* The :module:`CheckIncludeFileCXX` module ``check_include_file_cxx`` macro
- learned to honor the ``CMAKE_REQUIRED_LIBRARIES`` variable.
-
-* The :module:`CheckIncludeFiles` module ``check_include_files`` macro
- learned to honor the ``CMAKE_REQUIRED_LIBRARIES`` variable.
-
* The :module:`CheckIncludeFiles` module :command:`CHECK_INCLUDE_FILES`
command gained a ``LANGUAGE`` option to specify whether to check using the
``C`` or ``CXX`` compiler.
@@ -276,3 +267,19 @@ Other Changes
values containing newlines are now truncated before writing to the file.
In addition, a warning comment is written to the cache file, and a warning
message is displayed to the user on the console.
+
+Updates
+=======
+
+Changes made since CMake 3.11.0 include the following.
+
+3.11.1
+------
+
+* The :module:`CheckIncludeFile` module ``check_include_file`` macro,
+ :module:`CheckIncludeFileCXX` module ``check_include_file_cxx`` macro,
+ and :module:`CheckIncludeFiles` module ``check_include_files`` macro
+ were taught to honor the ``CMAKE_REQUIRED_LIBRARIES`` variable in
+ CMake 3.11.0. This has been reverted due to changing behavior of
+ checks for existing projects. It may be restored in the future
+ with a policy for compatibility.
diff --git a/Help/release/dev/UseSWIG-Multiple-Behaviors.rst b/Help/release/dev/UseSWIG-Multiple-Behaviors.rst
new file mode 100644
index 0000000..043ba50
--- /dev/null
+++ b/Help/release/dev/UseSWIG-Multiple-Behaviors.rst
@@ -0,0 +1,6 @@
+UseSWIG-multiple-behaviors
+--------------------------
+
+* The :module:`UseSWIG` module learned to manage multiple behaviors through
+ ``UseSWIG_MODULE_VERSION`` variable to ensure legacy support as well as more
+ robust handling of ``SWIG`` advanced features (like ``%template``).
diff --git a/Help/release/dev/glob_configure_depends.rst b/Help/release/dev/glob_configure_depends.rst
new file mode 100644
index 0000000..147e44a
--- /dev/null
+++ b/Help/release/dev/glob_configure_depends.rst
@@ -0,0 +1,6 @@
+glob_configure_depends
+----------------------
+
+* The :command:`file(GLOB)` and :command:`file(GLOB_RECURSE)` commands
+ learned a new flag ``CONFIGURE_DEPENDS`` which enables expression of
+ build system dependency on globbed directory's contents.
diff --git a/Help/release/dev/list-transform.rst b/Help/release/dev/list-transform.rst
new file mode 100644
index 0000000..4a6dacc
--- /dev/null
+++ b/Help/release/dev/list-transform.rst
@@ -0,0 +1,5 @@
+list-transform
+--------------
+
+* The :command:`list` command learned a ``TRANSFORM`` sub-command
+ to apply various string transformation to list's elements.
diff --git a/Help/release/dev/managed-target-property.rst b/Help/release/dev/managed-target-property.rst
new file mode 100644
index 0000000..b961512
--- /dev/null
+++ b/Help/release/dev/managed-target-property.rst
@@ -0,0 +1,8 @@
+target property COMMON_LANGUAGE_RUNTIME
+---------------------------------------
+
+* The :prop_tgt:`COMMON_LANGUAGE_RUNTIME` target property was introduced
+ to configure the use of managed C++ for :ref:`Visual Studio Generators`
+ for VS 2010 and above.
+* To support ``C++/CLI`` for imported targets, the
+ :prop_tgt:`IMPORTED_COMMON_LANGUAGE_RUNTIME` was added.
diff --git a/Help/release/dev/msvc-toolset-version-variable.rst b/Help/release/dev/msvc-toolset-version-variable.rst
new file mode 100644
index 0000000..28ba0b9
--- /dev/null
+++ b/Help/release/dev/msvc-toolset-version-variable.rst
@@ -0,0 +1,6 @@
+msvc-toolset-version-variable
+-----------------------------
+
+* A :variable:`MSVC_TOOLSET_VERSION` variable was added to provide the
+ MSVC toolset version associated with the current MSVC compiler version
+ in :variable:`MSVC_VERSION`.
diff --git a/Help/release/dev/wcdh-raw-features.rst b/Help/release/dev/wcdh-raw-features.rst
new file mode 100644
index 0000000..bdc7b62
--- /dev/null
+++ b/Help/release/dev/wcdh-raw-features.rst
@@ -0,0 +1,6 @@
+wcdh-raw-features
+-----------------
+
+* The :module:`WriteCompilerDetectionHeader` module now supports the
+ ``BARE_FEATURES`` argument which allows to add a compatibility define for
+ the exact keyword of a new language feature.
diff --git a/Help/variable/MSVC_TOOLSET_VERSION.rst b/Help/variable/MSVC_TOOLSET_VERSION.rst
new file mode 100644
index 0000000..77e1ea9
--- /dev/null
+++ b/Help/variable/MSVC_TOOLSET_VERSION.rst
@@ -0,0 +1,21 @@
+MSVC_TOOLSET_VERSION
+--------------------
+
+The toolset version of Microsoft Visual C/C++ being used if any.
+If MSVC-like is being used, this variable is set based on the version
+of the compiler as given by the :variable:`MSVC_VERSION` variable.
+
+Known toolset version numbers are::
+
+ 80 = VS 2005 (8.0)
+ 90 = VS 2008 (9.0)
+ 100 = VS 2010 (10.0)
+ 110 = VS 2012 (11.0)
+ 120 = VS 2013 (12.0)
+ 140 = VS 2015 (14.0)
+ 141 = VS 2017 (15.0)
+
+Compiler versions newer than those known to CMake will be reported
+as the latest known toolset version.
+
+See also the :variable:`MSVC_VERSION` variable.
diff --git a/Help/variable/MSVC_VERSION.rst b/Help/variable/MSVC_VERSION.rst
index 5f70c02..4ef43d8 100644
--- a/Help/variable/MSVC_VERSION.rst
+++ b/Help/variable/MSVC_VERSION.rst
@@ -19,4 +19,5 @@ Known version numbers are::
1900 = VS 14.0 (v140 toolset)
1910-1919 = VS 15.0 (v141 toolset)
-See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable.
+See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` and
+:variable:`MSVC_TOOLSET_VERSION` variable.
diff --git a/Modules/CMakeCUDACompiler.cmake.in b/Modules/CMakeCUDACompiler.cmake.in
index f524e5f..9761d8c 100644
--- a/Modules/CMakeCUDACompiler.cmake.in
+++ b/Modules/CMakeCUDACompiler.cmake.in
@@ -11,6 +11,7 @@ set(CMAKE_CUDA_SIMULATE_VERSION "@CMAKE_CUDA_SIMULATE_VERSION@")
set(CMAKE_CUDA_COMPILER_ENV_VAR "CUDACXX")
set(CMAKE_CUDA_HOST_COMPILER_ENV_VAR "CUDAHOSTCXX")
+set(CMAKE_CUDA_COMPILER_LOADED 1)
set(CMAKE_CUDA_COMPILER_ID_RUN 1)
set(CMAKE_CUDA_SOURCE_FILE_EXTENSIONS cu)
set(CMAKE_CUDA_LINKER_PREFERENCE 15)
diff --git a/Modules/CMakeCUDAInformation.cmake b/Modules/CMakeCUDAInformation.cmake
index 167e177..4788cbf 100644
--- a/Modules/CMakeCUDAInformation.cmake
+++ b/Modules/CMakeCUDAInformation.cmake
@@ -177,17 +177,31 @@ else()
set(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS "")
endif()
+# Add implicit host link directories that contain device libraries
+# to the device link line.
+set(__IMPLICT_DLINK_DIRS ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES})
+if(__IMPLICT_DLINK_DIRS)
+ list(REMOVE_ITEM __IMPLICT_DLINK_DIRS ${CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES})
+endif()
+set(__IMPLICT_DLINK_FLAGS )
+foreach(dir ${__IMPLICT_DLINK_DIRS})
+ if(EXISTS "${dir}/libcublas_device.a")
+ string(APPEND __IMPLICT_DLINK_FLAGS " -L\"${dir}\"")
+ endif()
+endforeach()
+unset(__IMPLICT_DLINK_DIRS)
#These are used when linking relocatable (dc) cuda code
if(NOT CMAKE_CUDA_DEVICE_LINK_LIBRARY)
set(CMAKE_CUDA_DEVICE_LINK_LIBRARY
- "<CMAKE_CUDA_COMPILER> ${CMAKE_CUDA_HOST_FLAGS} <CMAKE_CUDA_LINK_FLAGS> <LANGUAGE_COMPILE_FLAGS> ${CMAKE_CUDA_COMPILE_OPTIONS_PIC} ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
+ "<CMAKE_CUDA_COMPILER> ${CMAKE_CUDA_HOST_FLAGS} <CMAKE_CUDA_LINK_FLAGS> <LANGUAGE_COMPILE_FLAGS> ${CMAKE_CUDA_COMPILE_OPTIONS_PIC} ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICT_DLINK_FLAGS}")
endif()
if(NOT CMAKE_CUDA_DEVICE_LINK_EXECUTABLE)
set(CMAKE_CUDA_DEVICE_LINK_EXECUTABLE
- "<CMAKE_CUDA_COMPILER> ${CMAKE_CUDA_HOST_FLAGS} <FLAGS> <CMAKE_CUDA_LINK_FLAGS> ${CMAKE_CUDA_COMPILE_OPTIONS_PIC} ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
+ "<CMAKE_CUDA_COMPILER> ${CMAKE_CUDA_HOST_FLAGS} <FLAGS> <CMAKE_CUDA_LINK_FLAGS> ${CMAKE_CUDA_COMPILE_OPTIONS_PIC} ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICT_DLINK_FLAGS}")
endif()
unset(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS)
+unset(__IMPLICT_DLINK_FLAGS)
set(CMAKE_CUDA_INFORMATION_LOADED 1)
diff --git a/Modules/CMakeParseImplicitLinkInfo.cmake b/Modules/CMakeParseImplicitLinkInfo.cmake
index 63d18ab..935f92d 100644
--- a/Modules/CMakeParseImplicitLinkInfo.cmake
+++ b/Modules/CMakeParseImplicitLinkInfo.cmake
@@ -142,7 +142,7 @@ function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var fwk_var log_var obj
# We remove items that are not language-specific.
set(implicit_libs "")
foreach(lib IN LISTS implicit_libs_tmp)
- if("x${lib}" MATCHES "^x(crt.*\\.o|gcc_eh.*|System.*|.*libclang_rt.*|msvcrt.*|libvcruntime.*|libucrt.*|libcmt.*)$")
+ if("x${lib}" MATCHES "^x(crt.*\\.o|gcc_eh.*|.*libgcc_eh.*|System.*|.*libclang_rt.*|msvcrt.*|libvcruntime.*|libucrt.*|libcmt.*)$")
string(APPEND log " remove lib [${lib}]\n")
elseif(IS_ABSOLUTE "${lib}")
get_filename_component(abs "${lib}" ABSOLUTE)
diff --git a/Modules/CheckIncludeFile.cmake b/Modules/CheckIncludeFile.cmake
index 501fc9a..e5554c4 100644
--- a/Modules/CheckIncludeFile.cmake
+++ b/Modules/CheckIncludeFile.cmake
@@ -27,8 +27,6 @@
# list of macros to define (-DFOO=bar)
# ``CMAKE_REQUIRED_INCLUDES``
# list of include directories
-# ``CMAKE_REQUIRED_LIBRARIES``
-# list of libraries to link
# ``CMAKE_REQUIRED_QUIET``
# execute quietly without messages
#
@@ -61,7 +59,6 @@ macro(CHECK_INCLUDE_FILE INCLUDE VARIABLE)
${CMAKE_BINARY_DIR}
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.c
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
- LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}
CMAKE_FLAGS
-DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_INCLUDE_FILE_FLAGS}
"${CHECK_INCLUDE_FILE_C_INCLUDE_DIRS}"
diff --git a/Modules/CheckIncludeFileCXX.cmake b/Modules/CheckIncludeFileCXX.cmake
index cdb25fb..7948bab 100644
--- a/Modules/CheckIncludeFileCXX.cmake
+++ b/Modules/CheckIncludeFileCXX.cmake
@@ -27,8 +27,6 @@
# list of macros to define (-DFOO=bar)
# ``CMAKE_REQUIRED_INCLUDES``
# list of include directories
-# ``CMAKE_REQUIRED_LIBRARIES``
-# list of libraries to link
# ``CMAKE_REQUIRED_QUIET``
# execute quietly without messages
#
@@ -60,7 +58,6 @@ macro(CHECK_INCLUDE_FILE_CXX INCLUDE VARIABLE)
${CMAKE_BINARY_DIR}
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.cxx
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
- LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}
CMAKE_FLAGS
-DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_INCLUDE_FILE_FLAGS}
"${CHECK_INCLUDE_FILE_CXX_INCLUDE_DIRS}"
diff --git a/Modules/CheckIncludeFiles.cmake b/Modules/CheckIncludeFiles.cmake
index 14db68c..59afdab 100644
--- a/Modules/CheckIncludeFiles.cmake
+++ b/Modules/CheckIncludeFiles.cmake
@@ -33,8 +33,6 @@
# list of macros to define (-DFOO=bar)
# ``CMAKE_REQUIRED_INCLUDES``
# list of include directories
-# ``CMAKE_REQUIRED_LIBRARIES``
-# list of libraries to link
# ``CMAKE_REQUIRED_QUIET``
# execute quietly without messages
#
@@ -104,7 +102,6 @@ macro(CHECK_INCLUDE_FILES INCLUDE VARIABLE)
${CMAKE_BINARY_DIR}
${src}
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
- LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}
CMAKE_FLAGS
-DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_INCLUDE_FILES_FLAGS}
"${CHECK_INCLUDE_FILES_INCLUDE_DIRS}"
diff --git a/Modules/Compiler/Clang-CXX.cmake b/Modules/Compiler/Clang-CXX.cmake
index 77866e9..e99011b 100644
--- a/Modules/Compiler/Clang-CXX.cmake
+++ b/Modules/Compiler/Clang-CXX.cmake
@@ -51,8 +51,33 @@ if(NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
endif()
unset(_clang_version_std17)
+
+ __compiler_check_default_language_standard(CXX 2.1 98)
+elseif(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 3.9
+ AND CMAKE_CXX_SIMULATE_VERSION VERSION_GREATER_EQUAL 19.0)
+ # This version of clang-cl and the MSVC version it simulates have
+ # support for -std: flags.
+ set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "")
+ set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "")
+ set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "")
+ set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "")
+ set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std:c++14")
+ set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std:c++14")
+ if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 6.0)
+ set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std:c++17")
+ set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std:c++17")
+ set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std:c++latest")
+ set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std:c++latest")
+ else()
+ set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std:c++latest")
+ set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std:c++latest")
+ endif()
+
+ __compiler_check_default_language_standard(CXX 3.9 14)
else()
- # clang-cl does not know these options because it behaves like cl.exe
+ # This version of clang-cl, or the MSVC version it simulates, does not have
+ # language standards. Set these options as empty strings so the feature
+ # test infrastructure can at least check to see if they are defined.
set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "")
set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "")
set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "")
@@ -63,10 +88,22 @@ else()
set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "")
set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "")
set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "")
-endif()
-if(NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
- __compiler_check_default_language_standard(CXX 2.1 98)
-else()
+ # There is no meaningful default for this
set(CMAKE_CXX_STANDARD_DEFAULT "")
+
+ # There are no compiler modes so we only need to test features once.
+ # Override the default macro for this special case. Pretend that
+ # all language standards are available so that at least compilation
+ # can be attempted.
+ macro(cmake_record_cxx_compile_features)
+ list(APPEND CMAKE_CXX_COMPILE_FEATURES
+ cxx_std_98
+ cxx_std_11
+ cxx_std_14
+ cxx_std_17
+ cxx_std_20
+ )
+ _record_compiler_features(CXX "" CMAKE_CXX_COMPILE_FEATURES)
+ endmacro()
endif()
diff --git a/Modules/Compiler/MSVC-CXX-FeatureTests.cmake b/Modules/Compiler/MSVC-CXX-FeatureTests.cmake
index 5969586..9c604f2 100644
--- a/Modules/Compiler/MSVC-CXX-FeatureTests.cmake
+++ b/Modules/Compiler/MSVC-CXX-FeatureTests.cmake
@@ -1,15 +1,20 @@
+# Reference: https://docs.microsoft.com/en-us/cpp/visual-cpp-language-conformance
+# https://blogs.msdn.microsoft.com/vcblog/2015/06/19/c111417-features-in-vs-2015-rtm/
+# https://blogs.msdn.microsoft.com/vcblog/2013/12/02/c1114-core-language-features-in-vs-2013-and-the-nov-2013-ctp/
+# https://blogs.msdn.microsoft.com/vcblog/2011/09/12/c11-features-in-visual-c-11/
-# Reference: http://msdn.microsoft.com/en-us/library/vstudio/hh567368.aspx
-# http://blogs.msdn.com/b/vcblog/archive/2013/06/28/c-11-14-stl-features-fixes-and-breaking-changes-in-vs-2013.aspx
-# http://blogs.msdn.com/b/vcblog/archive/2014/11/17/c-11-14-17-features-in-vs-2015-preview.aspx
-# http://www.visualstudio.com/en-us/news/vs2015-preview-vs.aspx
-# http://blogs.msdn.com/b/vcblog/archive/2015/04/29/c-11-14-17-features-in-vs-2015-rc.aspx
-# http://blogs.msdn.com/b/vcblog/archive/2015/06/19/c-11-14-17-features-in-vs-2015-rtm.aspx
+set(_cmake_oldestSupported "_MSC_VER >= 1600")
+# VS 2017 v15.3 fixes support for incomplete decltypes
+# https://docs.microsoft.com/en-us/cpp/cpp-conformance-improvements-2017#update_153
+set(_cmake_feature_test_cxx_decltype_incomplete_return_types "_MSC_VER >= 1911")
-set(_cmake_oldestSupported "_MSC_VER >= 1600")
+set(MSVC_2017 "_MSC_VER >= 1910")
+# VS 2017 introduces support for "N3652 Extended constexpr"
+# but as of v15.6 there are still bugs in the implementation
+#set(_cmake_feature_test_cxx_relaxed_constexpr "${MSVC_2017}")
-# VS version 15 (not 2015) introduces support for aggregate initializers.
+# VS 2017 Preview introduces support for aggregate initializers.
set(_cmake_feature_test_cxx_aggregate_default_initializers "_MSC_FULL_VER >= 190024406")
# VS 2015 Update 2 introduces support for variable templates.
@@ -48,7 +53,6 @@ set(_cmake_feature_test_cxx_reference_qualified_functions "${MSVC_2015}")
# lists this as 'partial' in 2013
set(_cmake_feature_test_cxx_deleted_functions "${MSVC_2015}")
-set(MSVC_2013_v30723 "_MSC_FULL_VER >= 180030723")
# http://blogs.msdn.com/b/vcblog/archive/2014/11/17/c-11-14-17-features-in-vs-2015-preview.aspx
# Note 1. While previous version of VisualStudio said they supported these
# they silently produced bad code, and are now marked as having partial
@@ -56,7 +60,7 @@ set(MSVC_2013_v30723 "_MSC_FULL_VER >= 180030723")
# in MSVC 2015, so support the feature for that version, assuming that is true.
# The blog post also says that VS 2013 Update 3 generates an error in cases
# that previously produced bad code.
-set(_cmake_feature_test_cxx_generalized_initializers "${MSVC_2013_v30723}")
+set(_cmake_feature_test_cxx_generalized_initializers "_MSC_FULL_VER >= 180030723")
set(MSVC_2013 "_MSC_VER >= 1800")
set(_cmake_feature_test_cxx_alias_templates "${MSVC_2013}")
@@ -98,20 +102,10 @@ set(_cmake_feature_test_cxx_template_template_parameters "${MSVC_2010}")
set(_cmake_feature_test_cxx_trailing_return_types "${MSVC_2010}")
set(_cmake_feature_test_cxx_variadic_macros "${MSVC_2010}")
-# Currently unsupported:
-# set(_cmake_feature_test_cxx_relaxed_constexpr )
-# 'NSDMIs for aggregates'
-# set(_cmake_feature_test_cxx_aggregate_default_initializers )
-
-# In theory decltype incomplete return types was added in 2012
-# but without support for decltype_auto and return type deduction this
-# feature is unusable. This remains so as of VS 2015 Preview.
-# set(_cmake_feature_test_cxx_decltype_incomplete_return_types )
-
# Unset all the variables that we don't need exposed.
# _cmake_oldestSupported is required by WriteCompilerDetectionHeader
+set(MSVC_2017)
set(MSVC_2015)
-set(MSVC_2013_v30723)
set(MSVC_2013)
set(MSVC_2012)
set(MSVC_2010)
diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake
index 8d44aee..5b5002a 100644
--- a/Modules/FindBoost.cmake
+++ b/Modules/FindBoost.cmake
@@ -458,20 +458,10 @@ function(_Boost_GUESS_COMPILER_PREFIX _ret)
elseif (GHSMULTI)
set(_boost_COMPILER "-ghs")
elseif("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC")
- if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.10)
+ if(MSVC_TOOLSET_VERSION GREATER_EQUAL 141)
set(_boost_COMPILER "-vc141;-vc140")
- elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19)
- set(_boost_COMPILER "-vc140")
- elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 18)
- set(_boost_COMPILER "-vc120")
- elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 17)
- set(_boost_COMPILER "-vc110")
- elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 16)
- set(_boost_COMPILER "-vc100")
- elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 15)
- set(_boost_COMPILER "-vc90")
- elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 14)
- set(_boost_COMPILER "-vc80")
+ elseif(MSVC_TOOLSET_VERSION GREATER_EQUAL 80)
+ set(_boost_COMPILER "-vc${MSVC_TOOLSET_VERSION}")
elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13.10)
set(_boost_COMPILER "-vc71")
elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13) # Good luck!
@@ -1009,21 +999,12 @@ function(_Boost_UPDATE_WINDOWS_LIBRARY_SEARCH_DIRS_WITH_PREBUILT_PATHS component
else()
set(_arch_suffix 32)
endif()
- if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.10)
+ if(MSVC_TOOLSET_VERSION GREATER_EQUAL 141)
list(APPEND ${componentlibvar} ${basedir}/lib${_arch_suffix}-msvc-14.1)
list(APPEND ${componentlibvar} ${basedir}/lib${_arch_suffix}-msvc-14.0)
- elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19)
- list(APPEND ${componentlibvar} ${basedir}/lib${_arch_suffix}-msvc-14.0)
- elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 18)
- list(APPEND ${componentlibvar} ${basedir}/lib${_arch_suffix}-msvc-12.0)
- elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 17)
- list(APPEND ${componentlibvar} ${basedir}/lib${_arch_suffix}-msvc-11.0)
- elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 16)
- list(APPEND ${componentlibvar} ${basedir}/lib${_arch_suffix}-msvc-10.0)
- elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 15)
- list(APPEND ${componentlibvar} ${basedir}/lib${_arch_suffix}-msvc-9.0)
- elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 14)
- list(APPEND ${componentlibvar} ${basedir}/lib${_arch_suffix}-msvc-8.0)
+ elseif(MSVC_TOOLSET_VERSION GREATER_EQUAL 80)
+ math(EXPR _toolset_major_version "${MSVC_TOOLSET_VERSION} / 10")
+ list(APPEND ${componentlibvar} ${basedir}/lib${_arch_suffix}-msvc-${_toolset_major_version}.0)
endif()
set(${componentlibvar} ${${componentlibvar}} PARENT_SCOPE)
endif()
diff --git a/Modules/FindCUDA.cmake b/Modules/FindCUDA.cmake
index 6f6f349..a0e4aa9 100644
--- a/Modules/FindCUDA.cmake
+++ b/Modules/FindCUDA.cmake
@@ -557,6 +557,11 @@ else()
set(c_compiler_realpath "")
endif()
set(CUDA_HOST_COMPILER "${c_compiler_realpath}" CACHE FILEPATH "Host side compiler used by NVCC")
+ elseif(MSVC AND "${CMAKE_C_COMPILER}" MATCHES "clcache")
+ # NVCC does not think it will work if it is passed clcache.exe as the host
+ # compiler, which means that builds with CC=cl.exe won't work. Best to just
+ # feed it whatever the actual cl.exe is as the host compiler.
+ set(CUDA_HOST_COMPILER "cl.exe" CACHE FILEPATH "Host side compiler used by NVCC")
else()
set(CUDA_HOST_COMPILER "${CMAKE_C_COMPILER}"
CACHE FILEPATH "Host side compiler used by NVCC")
diff --git a/Modules/FindGTK2.cmake b/Modules/FindGTK2.cmake
index 8d0da51..15d1230 100644
--- a/Modules/FindGTK2.cmake
+++ b/Modules/FindGTK2.cmake
@@ -352,13 +352,9 @@ function(_GTK2_FIND_LIBRARY _var _lib _expand_vc _append_version)
if(_expand_vc AND MSVC)
# Add vc80/vc90/vc100 midfixes
- if(MSVC_VERSION EQUAL 1400)
- set(_library ${_library}-vc80)
- elseif(MSVC_VERSION EQUAL 1500)
- set(_library ${_library}-vc90)
- elseif(MSVC_VERSION EQUAL 1600)
- set(_library ${_library}-vc100)
- elseif(MSVC_VERSION EQUAL 1700)
+ if(MSVC_TOOLSET_VERSION LESS 110)
+ set(_library ${_library}-vc${MSVC_TOOLSET_VERSION})
+ else()
# Up to gtkmm-win 2.22.0-2 there are no vc110 libraries but vc100 can be used
set(_library ${_library}-vc100)
endif()
diff --git a/Modules/FindIce.cmake b/Modules/FindIce.cmake
index b37f796..df76e5a 100644
--- a/Modules/FindIce.cmake
+++ b/Modules/FindIce.cmake
@@ -255,21 +255,15 @@ function(_Ice_FIND)
unset(vcvers)
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
- if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.10)
+ if(MSVC_TOOLSET_VERSION GREATER_EQUAL 141)
set(vcvers "141;140")
- elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19)
- set(vcvers "140")
- elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 18)
- set(vcvers "120")
- elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 17)
- set(vcvers "110")
- elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 16)
- set(vcvers "100")
- elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 15)
- set(vcvers "90")
+ elseif(MSVC_TOOLSET_VERSION GREATER_EQUAL 100)
+ set(vcvers "${MSVC_TOOLSET_VERSION}")
+ elseif(MSVC_TOOLSET_VERSION GREATER_EQUAL 90)
+ set(vcvers "${MSVC_TOOLSET_VERSION}")
set(vcyear "2008")
- elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 14)
- set(vcvers "80")
+ elseif(MSVC_TOOLSET_VERSION GREATER_EQUAL 80)
+ set(vcvers "${MSVC_TOOLSET_VERSION}")
set(vcyear "2005")
else() # Unknown version
set(vcvers Unknown)
diff --git a/Modules/FindImageMagick.cmake b/Modules/FindImageMagick.cmake
index 881bff1..6d94d3b 100644
--- a/Modules/FindImageMagick.cmake
+++ b/Modules/FindImageMagick.cmake
@@ -104,6 +104,7 @@ function(FIND_IMAGEMAGICK_API component header)
PATH_SUFFIXES
ImageMagick ImageMagick-6 ImageMagick-7
DOC "Path to the ImageMagick arch-independent include dir."
+ NO_DEFAULT_PATH
)
find_path(ImageMagick_${component}_ARCH_INCLUDE_DIR
NAMES magick/magick-baseconfig.h
@@ -116,6 +117,7 @@ function(FIND_IMAGEMAGICK_API component header)
PATH_SUFFIXES
ImageMagick ImageMagick-6 ImageMagick-7
DOC "Path to the ImageMagick arch-specific include dir."
+ NO_DEFAULT_PATH
)
find_library(ImageMagick_${component}_LIBRARY
NAMES ${ARGN}
@@ -125,6 +127,7 @@ function(FIND_IMAGEMAGICK_API component header)
PATHS
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\ImageMagick\\Current;BinPath]/lib"
DOC "Path to the ImageMagick Magick++ library."
+ NO_DEFAULT_PATH
)
# old version have only indep dir
diff --git a/Modules/FindOpenAL.cmake b/Modules/FindOpenAL.cmake
index c3d202e..7521d51 100644
--- a/Modules/FindOpenAL.cmake
+++ b/Modules/FindOpenAL.cmake
@@ -58,7 +58,7 @@
find_path(OPENAL_INCLUDE_DIR al.h
HINTS
ENV OPENALDIR
- PATH_SUFFIXES include/AL include/OpenAL include
+ PATH_SUFFIXES include/AL include/OpenAL include AL OpenAL
PATHS
~/Library/Frameworks
/Library/Frameworks
diff --git a/Modules/FindOpenMP.cmake b/Modules/FindOpenMP.cmake
index e252ba5..329ace1 100644
--- a/Modules/FindOpenMP.cmake
+++ b/Modules/FindOpenMP.cmake
@@ -242,19 +242,10 @@ function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR)
endforeach()
set("${OPENMP_LIB_NAMES_VAR}" "${_OPENMP_LIB_NAMES}" PARENT_SCOPE)
else()
- # The Intel compiler on windows has no verbose mode, so we need to treat it explicitly
- if("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "Intel" AND "${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
- set("${OPENMP_LIB_NAMES_VAR}" "libiomp5md" PARENT_SCOPE)
- find_library(OpenMP_libiomp5md_LIBRARY
- NAMES "libiomp5md"
- HINTS ${CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES}
- CMAKE_FIND_ROOT_PATH_BOTH
- NO_DEFAULT_PATH
- )
- mark_as_advanced(OpenMP_libiomp5md_LIBRARY)
- else()
- set("${OPENMP_LIB_NAMES_VAR}" "" PARENT_SCOPE)
- endif()
+ # We do not know how to extract implicit OpenMP libraries for this compiler.
+ # Assume that it handles them automatically, e.g. the Intel Compiler on
+ # Windows should put the dependency in its object files.
+ set("${OPENMP_LIB_NAMES_VAR}" "" PARENT_SCOPE)
endif()
break()
elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "AppleClang"
diff --git a/Modules/FindPython.cmake b/Modules/FindPython.cmake
index c87f784..8139e53 100644
--- a/Modules/FindPython.cmake
+++ b/Modules/FindPython.cmake
@@ -144,18 +144,19 @@ else()
set (Python_FIND_QUIETLY TRUE)
set (Python_FIND_REQUIRED FALSE)
- foreach (_Python_REQUIRED_VERSION_MAJOR IN ITEMS 3 2)
+ set (_Python_REQUIRED_VERSIONS 3 2)
+ set (_Python_REQUIRED_VERSION_LAST 2)
+
+ foreach (_Python_REQUIRED_VERSION_MAJOR IN LISTS _Python_REQUIRED_VERSIONS)
set (Python_FIND_VERSION ${_Python_REQUIRED_VERSION_MAJOR})
include (${CMAKE_CURRENT_LIST_DIR}/FindPython/Support.cmake)
- if (Python_FOUND)
+ if (Python_FOUND OR
+ _Python_REQUIRED_VERSION_MAJOR EQUAL _Python_REQUIRED_VERSION_LAST)
break()
endif()
# clean-up some CACHE variables to ensure look-up restart from scratch
- foreach (_Python_ITEM IN ITEMS EXECUTABLE COMPILER
- LIBRARY_RELEASE RUNTIME_LIBRARY_RELEASE
- LIBRARY_DEBUG RUNTIME_LIBRARY_DEBUG
- INCLUDE_DIR)
- unset (Python_${_Python_ITEM} CACHE)
+ foreach (_Python_ITEM IN LISTS _Python_CACHED_VARS)
+ unset (${_Python_ITEM} CACHE)
endforeach()
endforeach()
diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake
index be34624..179b394 100644
--- a/Modules/FindPython/Support.cmake
+++ b/Modules/FindPython/Support.cmake
@@ -162,12 +162,14 @@ unset (${_PYTHON_PREFIX}_VERSION_MINOR)
unset (${_PYTHON_PREFIX}_VERSION_PATCH)
unset (_${_PYTHON_PREFIX}_REQUIRED_VARS)
+unset (_${_PYTHON_PREFIX}_CACHED_VARS)
# first step, search for the interpreter
if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
if (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter)
list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_EXECUTABLE)
+ list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS ${_PYTHON_PREFIX}_EXECUTABLE)
endif()
set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR)
@@ -305,6 +307,7 @@ endif()
if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
if (${_PYTHON_PREFIX}_FIND_REQUIRED_Compiler)
list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_COMPILER)
+ list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS ${_PYTHON_PREFIX}_COMPILER)
endif()
# IronPython specific artifacts
@@ -393,6 +396,12 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development)
list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_LIBRARY
${_PYTHON_PREFIX}_INCLUDE_DIR)
+ list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS ${_PYTHON_PREFIX}_LIBRARY
+ ${_PYTHON_PREFIX}_LIBRARY_RELEASE
+ ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE
+ ${_PYTHON_PREFIX}_LIBRARY_DEBUG
+ ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG
+ ${_PYTHON_PREFIX}_INCLUDE_DIR)
endif()
# Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES
diff --git a/Modules/FindwxWidgets.cmake b/Modules/FindwxWidgets.cmake
index 202d481..f2d6285 100644
--- a/Modules/FindwxWidgets.cmake
+++ b/Modules/FindwxWidgets.cmake
@@ -498,19 +498,7 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
set(_WX_TOOL gcc)
elseif(MSVC)
set(_WX_TOOL vc)
- if(NOT MSVC_VERSION LESS 1910)
- set(_WX_TOOLVER 141)
- elseif(NOT MSVC_VERSION LESS 1900)
- set(_WX_TOOLVER 140)
- elseif(NOT MSVC_VERSION LESS 1800)
- set(_WX_TOOLVER 120)
- elseif(NOT MSVC_VERSION LESS 1700)
- set(_WX_TOOLVER 110)
- elseif(NOT MSVC_VERSION LESS 1600)
- set(_WX_TOOLVER 100)
- elseif(NOT MSVC_VERSION LESS 1500)
- set(_WX_TOOLVER 90)
- endif()
+ set(_WX_TOOLVER ${MSVC_TOOLSET_VERSION})
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(_WX_ARCH _x64)
endif()
@@ -875,6 +863,26 @@ else()
set(wxWidgets_INCLUDE_DIRS ${_tmp_path})
separate_arguments(wxWidgets_INCLUDE_DIRS)
list(REMOVE_ITEM wxWidgets_INCLUDE_DIRS "")
+
+ set(_tmp_path "")
+ foreach(_path ${wxWidgets_LIBRARY_DIRS})
+ execute_process(
+ COMMAND cygpath -w ${_path}
+ OUTPUT_VARIABLE _native_path
+ RESULT_VARIABLE _retv
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET
+ )
+ if(_retv EQUAL 0)
+ file(TO_CMAKE_PATH ${_native_path} _native_path)
+ DBG_MSG_V("Path ${_path} converted to ${_native_path}")
+ string(APPEND _tmp_path " ${_native_path}")
+ endif()
+ endforeach()
+ DBG_MSG("Setting wxWidgets_LIBRARY_DIRS = ${_tmp_path}")
+ set(wxWidgets_LIBRARY_DIRS ${_tmp_path})
+ separate_arguments(wxWidgets_LIBRARY_DIRS)
+ list(REMOVE_ITEM wxWidgets_LIBRARY_DIRS "")
endif()
unset(_cygpath_exe CACHE)
endif()
@@ -917,14 +925,16 @@ unset(_wx_lib_missing)
# Check if a specific version was requested by find_package().
if(wxWidgets_FOUND)
- find_file(_filename wx/version.h PATHS ${wxWidgets_INCLUDE_DIRS} NO_DEFAULT_PATH)
- dbg_msg("_filename: ${_filename}")
+ unset(_wx_filename)
+ find_file(_wx_filename wx/version.h PATHS ${wxWidgets_INCLUDE_DIRS} NO_DEFAULT_PATH)
+ dbg_msg("_wx_filename: ${_wx_filename}")
- if(NOT _filename)
+ if(NOT _wx_filename)
message(FATAL_ERROR "wxWidgets wx/version.h file not found in ${wxWidgets_INCLUDE_DIRS}.")
endif()
- file(READ ${_filename} _wx_version_h)
+ file(READ "${_wx_filename}" _wx_version_h)
+ unset(_wx_filename CACHE)
string(REGEX REPLACE "^(.*\n)?#define +wxMAJOR_VERSION +([0-9]+).*"
"\\2" wxWidgets_VERSION_MAJOR "${_wx_version_h}" )
diff --git a/Modules/InstallRequiredSystemLibraries.cmake b/Modules/InstallRequiredSystemLibraries.cmake
index 797f9e4..50e9361 100644
--- a/Modules/InstallRequiredSystemLibraries.cmake
+++ b/Modules/InstallRequiredSystemLibraries.cmake
@@ -121,9 +121,7 @@ if(MSVC)
)
endif()
- if(MSVC_VERSION EQUAL 1400)
- set(MSVC_REDIST_NAME VC80)
-
+ if(MSVC_TOOLSET_VERSION EQUAL 80)
# Find the runtime library redistribution directory.
get_filename_component(msvc_install_dir
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\8.0;InstallDir]" ABSOLUTE)
@@ -163,9 +161,7 @@ if(MSVC)
endif()
endif()
- if(MSVC_VERSION EQUAL 1500)
- set(MSVC_REDIST_NAME VC90)
-
+ if(MSVC_TOOLSET_VERSION EQUAL 90)
# Find the runtime library redistribution directory.
get_filename_component(msvc_install_dir
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\9.0;InstallDir]" ABSOLUTE)
@@ -209,34 +205,31 @@ if(MSVC)
endif()
set(MSVC_REDIST_NAME "")
- set(_MSVCRT_DLL_VERSION "")
- set(_MSVCRT_IDE_VERSION "")
+ set(_MSVC_DLL_VERSION "")
+ set(_MSVC_IDE_VERSION "")
if(MSVC_VERSION GREATER_EQUAL 2000)
message(WARNING "MSVC ${MSVC_VERSION} not yet supported.")
- elseif(MSVC_VERSION GREATER_EQUAL 1911)
- set(MSVC_REDIST_NAME VC141)
- set(_MSVCRT_DLL_VERSION 140)
- set(_MSVCRT_IDE_VERSION 15)
- elseif(MSVC_VERSION EQUAL 1910)
- set(MSVC_REDIST_NAME VC150)
- set(_MSVCRT_DLL_VERSION 140)
- set(_MSVCRT_IDE_VERSION 15)
- elseif(MSVC_VERSION EQUAL 1900)
- set(MSVC_REDIST_NAME VC140)
- set(_MSVCRT_DLL_VERSION 140)
- set(_MSVCRT_IDE_VERSION 14)
- elseif(MSVC_VERSION EQUAL 1800)
- set(MSVC_REDIST_NAME VC120)
- set(_MSVCRT_DLL_VERSION 120)
- set(_MSVCRT_IDE_VERSION 12)
- elseif(MSVC_VERSION EQUAL 1700)
- set(MSVC_REDIST_NAME VC110)
- set(_MSVCRT_DLL_VERSION 110)
- set(_MSVCRT_IDE_VERSION 11)
- elseif(MSVC_VERSION EQUAL 1600)
- set(MSVC_REDIST_NAME VC100)
- set(_MSVCRT_DLL_VERSION 100)
- set(_MSVCRT_IDE_VERSION 10)
+ elseif(MSVC_TOOLSET_VERSION)
+ set(MSVC_REDIST_NAME VC${MSVC_TOOLSET_VERSION})
+ if(MSVC_VERSION EQUAL 1910)
+ # VS2017 named this differently prior to update 3.
+ set(MSVC_REDIST_NAME VC150)
+ endif()
+
+ math(EXPR _MSVC_DLL_VERSION "${MSVC_TOOLSET_VERSION} / 10 * 10")
+
+ if(MSVC_TOOLSET_VERSION EQUAL 141)
+ set(_MSVC_IDE_VERSION 15)
+ else()
+ math(EXPR _MSVC_IDE_VERSION "${MSVC_TOOLSET_VERSION} / 10")
+ endif()
+ endif()
+
+ set(_MSVCRT_DLL_VERSION "")
+ set(_MSVCRT_IDE_VERSION "")
+ if(_MSVC_IDE_VERSION GREATER_EQUAL 10)
+ set(_MSVCRT_DLL_VERSION "${_MSVC_DLL_VERSION}")
+ set(_MSVCRT_IDE_VERSION "${_MSVC_IDE_VERSION}")
endif()
if(_MSVCRT_DLL_VERSION)
@@ -433,23 +426,9 @@ if(MSVC)
set(_MFC_DLL_VERSION "")
set(_MFC_IDE_VERSION "")
- if(MSVC_VERSION GREATER_EQUAL 2000)
- # Version not yet supported.
- elseif(MSVC_VERSION GREATER_EQUAL 1910)
- set(_MFC_DLL_VERSION 140)
- set(_MFC_IDE_VERSION 15)
- elseif(MSVC_VERSION EQUAL 1900)
- set(_MFC_DLL_VERSION 140)
- set(_MFC_IDE_VERSION 14)
- elseif(MSVC_VERSION EQUAL 1800)
- set(_MFC_DLL_VERSION 120)
- set(_MFC_IDE_VERSION 12)
- elseif(MSVC_VERSION EQUAL 1700)
- set(_MFC_DLL_VERSION 110)
- set(_MFC_IDE_VERSION 11)
- elseif(MSVC_VERSION EQUAL 1600)
- set(_MFC_DLL_VERSION 100)
- set(_MFC_IDE_VERSION 10)
+ if(_MSVC_IDE_VERSION GREATER_EQUAL 10)
+ set(_MFC_DLL_VERSION ${_MSVC_DLL_VERSION})
+ set(_MFC_IDE_VERSION ${_MSVC_IDE_VERSION})
endif()
if(_MFC_DLL_VERSION)
@@ -520,32 +499,8 @@ if(MSVC)
# MSVC 8 was the first version with OpenMP
# Furthermore, there is no debug version of this
if(CMAKE_INSTALL_OPENMP_LIBRARIES AND _IRSL_HAVE_MSVC)
- set(_MSOMP_DLL_VERSION "")
- set(_MSOMP_IDE_VERSION "")
- if(MSVC_VERSION GREATER_EQUAL 2000)
- # Version not yet supported.
- elseif(MSVC_VERSION GREATER_EQUAL 1910)
- set(_MSOMP_DLL_VERSION 140)
- set(_MSOMP_IDE_VERSION 15)
- elseif(MSVC_VERSION EQUAL 1900)
- set(_MSOMP_DLL_VERSION 140)
- set(_MSOMP_IDE_VERSION 14)
- elseif(MSVC_VERSION EQUAL 1800)
- set(_MSOMP_DLL_VERSION 120)
- set(_MSOMP_IDE_VERSION 12)
- elseif(MSVC_VERSION EQUAL 1700)
- set(_MSOMP_DLL_VERSION 110)
- set(_MSOMP_IDE_VERSION 11)
- elseif(MSVC_VERSION EQUAL 1600)
- set(_MSOMP_DLL_VERSION 100)
- set(_MSOMP_IDE_VERSION 10)
- elseif(MSVC_VERSION EQUAL 1500)
- set(_MSOMP_DLL_VERSION 90)
- set(_MSOMP_IDE_VERSION 9)
- elseif(MSVC_VERSION EQUAL 1400)
- set(_MSOMP_DLL_VERSION 80)
- set(_MSOMP_IDE_VERSION 8)
- endif()
+ set(_MSOMP_DLL_VERSION ${_MSVC_DLL_VERSION})
+ set(_MSOMP_IDE_VERSION ${_MSVC_IDE_VERSION})
if(_MSOMP_DLL_VERSION)
set(v "${_MSOMP_DLL_VERSION}")
diff --git a/Modules/MatlabTestsRedirect.cmake b/Modules/MatlabTestsRedirect.cmake
index 64d580d..fc36fc3 100644
--- a/Modules/MatlabTestsRedirect.cmake
+++ b/Modules/MatlabTestsRedirect.cmake
@@ -55,11 +55,12 @@ endif()
if(no_unittest_framework)
- set(unittest_to_run "try, ${unittest_file_to_run_name}, catch err, disp('An exception has been thrown during the execution'), disp(err), disp(err.stack), exit(1), end, exit(0)")
+ set(unittest_to_run "${unittest_file_to_run_name}")
endif()
+set(command_to_run "try, ${unittest_to_run}, catch err, disp('An exception has been thrown during the execution'), disp(err), disp(err.stack), exit(1), end, exit(0)")
set(Matlab_SCRIPT_TO_RUN
- "addpath(${concat_string}); ${cmd_to_run_before_test}; ${unittest_to_run}"
+ "addpath(${concat_string}); ${cmd_to_run_before_test}; ${command_to_run}"
)
# if the working directory is not specified then default
# to the output_directory because the log file will go there
diff --git a/Modules/Platform/Android-Clang-CXX.cmake b/Modules/Platform/Android-Clang-CXX.cmake
index 7111836..85d5088 100644
--- a/Modules/Platform/Android-Clang-CXX.cmake
+++ b/Modules/Platform/Android-Clang-CXX.cmake
@@ -1,2 +1,9 @@
include(Platform/Android-Clang)
__android_compiler_clang(CXX)
+if(_ANDROID_STL_NOSTDLIBXX)
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 6)
+ string(APPEND CMAKE_CXX_STANDARD_LIBRARIES " -nostdlib++")
+ else()
+ string(APPEND CMAKE_CXX_STANDARD_LIBRARIES " -nodefaultlibs -lgcc -lc -lm -ldl")
+ endif()
+endif()
diff --git a/Modules/Platform/Android-GNU-CXX.cmake b/Modules/Platform/Android-GNU-CXX.cmake
index 41279d1..d30d0ff 100644
--- a/Modules/Platform/Android-GNU-CXX.cmake
+++ b/Modules/Platform/Android-GNU-CXX.cmake
@@ -1,2 +1,5 @@
include(Platform/Android-GNU)
__android_compiler_gnu(CXX)
+if(_ANDROID_STL_NOSTDLIBXX)
+ string(APPEND CMAKE_CXX_STANDARD_LIBRARIES " -nodefaultlibs -lgcc -lc -lm -ldl")
+endif()
diff --git a/Modules/Platform/Android/ndk-stl-c++.cmake b/Modules/Platform/Android/ndk-stl-c++.cmake
index a12411c..1cafd1f 100644
--- a/Modules/Platform/Android/ndk-stl-c++.cmake
+++ b/Modules/Platform/Android/ndk-stl-c++.cmake
@@ -1,6 +1,7 @@
# <ndk>/sources/cxx-stl/llvm-libc++/Android.mk
set(_ANDROID_STL_RTTI 1)
set(_ANDROID_STL_EXCEPTIONS 1)
+set(_ANDROID_STL_NOSTDLIBXX 1)
macro(__android_stl_cxx lang filename)
# Add the include directory.
if(EXISTS "${CMAKE_ANDROID_NDK}/sources/cxx-stl/llvm-libc++/libcxx/include/cstddef")
diff --git a/Modules/Platform/Android/ndk-stl-gabi++.cmake b/Modules/Platform/Android/ndk-stl-gabi++.cmake
index 850a47a..d3b9e45 100644
--- a/Modules/Platform/Android/ndk-stl-gabi++.cmake
+++ b/Modules/Platform/Android/ndk-stl-gabi++.cmake
@@ -1,6 +1,7 @@
# <ndk>/sources/cxx-stl/gabi++/Android.mk
set(_ANDROID_STL_RTTI 1)
set(_ANDROID_STL_EXCEPTIONS 1)
+set(_ANDROID_STL_NOSTDLIBXX 1)
macro(__android_stl_gabixx lang filename)
__android_stl_inc(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/gabi++/include" 1)
__android_stl_lib(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/gabi++/libs/${CMAKE_ANDROID_ARCH_ABI}/${filename}" 1)
diff --git a/Modules/Platform/Android/ndk-stl-gnustl.cmake b/Modules/Platform/Android/ndk-stl-gnustl.cmake
index b3226ee..46cedc6 100644
--- a/Modules/Platform/Android/ndk-stl-gnustl.cmake
+++ b/Modules/Platform/Android/ndk-stl-gnustl.cmake
@@ -1,6 +1,7 @@
# <ndk>/sources/cxx-stl/gnu-libstdc++/Android.mk
set(_ANDROID_STL_RTTI 1)
set(_ANDROID_STL_EXCEPTIONS 1)
+set(_ANDROID_STL_NOSTDLIBXX 1)
macro(__android_stl_gnustl lang filename)
__android_stl_inc(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${CMAKE_${lang}_ANDROID_TOOLCHAIN_VERSION}/include" 1)
__android_stl_inc(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${CMAKE_${lang}_ANDROID_TOOLCHAIN_VERSION}/libs/${CMAKE_ANDROID_ARCH_ABI}/include" 1)
diff --git a/Modules/Platform/Android/ndk-stl-none.cmake b/Modules/Platform/Android/ndk-stl-none.cmake
index 9049c91..45122f7 100644
--- a/Modules/Platform/Android/ndk-stl-none.cmake
+++ b/Modules/Platform/Android/ndk-stl-none.cmake
@@ -1,2 +1,3 @@
+set(_ANDROID_STL_NOSTDLIBXX 1)
macro(__android_stl lang)
endmacro()
diff --git a/Modules/Platform/Android/ndk-stl-stlport.cmake b/Modules/Platform/Android/ndk-stl-stlport.cmake
index eab6b94..efad33b 100644
--- a/Modules/Platform/Android/ndk-stl-stlport.cmake
+++ b/Modules/Platform/Android/ndk-stl-stlport.cmake
@@ -1,6 +1,7 @@
# <ndk>/sources/cxx-stl/stlport/Android.mk
set(_ANDROID_STL_RTTI 1)
set(_ANDROID_STL_EXCEPTIONS 1)
+set(_ANDROID_STL_NOSTDLIBXX 0)
macro(__android_stl_stlport lang filename)
__android_stl_inc(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/stlport/stlport" 1)
__android_stl_lib(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/stlport/libs/${CMAKE_ANDROID_ARCH_ABI}/${filename}" 1)
diff --git a/Modules/Platform/Android/ndk-stl-system.cmake b/Modules/Platform/Android/ndk-stl-system.cmake
index dd554fe..7d86a40 100644
--- a/Modules/Platform/Android/ndk-stl-system.cmake
+++ b/Modules/Platform/Android/ndk-stl-system.cmake
@@ -1,6 +1,7 @@
# <ndk>/android-ndk-r11c/sources/cxx-stl/system/Android.mk
set(_ANDROID_STL_RTTI 0)
set(_ANDROID_STL_EXCEPTIONS 0)
+set(_ANDROID_STL_NOSTDLIBXX 0)
macro(__android_stl lang)
__android_stl_inc(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/system/include" 1)
endmacro()
diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake
index a1f54c0..ae180ed 100644
--- a/Modules/Platform/Windows-MSVC.cmake
+++ b/Modules/Platform/Windows-MSVC.cmake
@@ -71,6 +71,31 @@ if(NOT MSVC_VERSION)
message(FATAL_ERROR "MSVC compiler version not detected properly: ${_compiler_version}")
endif()
+ if(MSVC_VERSION GREATER_EQUAL 1910)
+ # VS 2017 or greater
+ set(MSVC_TOOLSET_VERSION 141)
+ elseif(MSVC_VERSION EQUAL 1900)
+ # VS 2015
+ set(MSVC_TOOLSET_VERSION 140)
+ elseif(MSVC_VERSION EQUAL 1800)
+ # VS 2013
+ set(MSVC_TOOLSET_VERSION 120)
+ elseif(MSVC_VERSION EQUAL 1700)
+ # VS 2012
+ set(MSVC_TOOLSET_VERSION 110)
+ elseif(MSVC_VERSION EQUAL 1600)
+ # VS 2010
+ set(MSVC_TOOLSET_VERSION 100)
+ elseif(MSVC_VERSION EQUAL 1500)
+ # VS 2008
+ set(MSVC_TOOLSET_VERSION 90)
+ elseif(MSVC_VERSION EQUAL 1400)
+ # VS 2005
+ set(MSVC_TOOLSET_VERSION 80)
+ else()
+ # We don't support MSVC_TOOLSET_VERSION for earlier compiler.
+ endif()
+
set(MSVC10)
set(MSVC11)
set(MSVC12)
diff --git a/Modules/Platform/Windows-NVIDIA-CUDA.cmake b/Modules/Platform/Windows-NVIDIA-CUDA.cmake
index 970c2c6..0c11e55 100644
--- a/Modules/Platform/Windows-NVIDIA-CUDA.cmake
+++ b/Modules/Platform/Windows-NVIDIA-CUDA.cmake
@@ -36,12 +36,27 @@ else()
set(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS "")
endif()
+# Add implicit host link directories that contain device libraries
+# to the device link line.
+set(__IMPLICT_DLINK_DIRS ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES})
+if(__IMPLICT_DLINK_DIRS)
+ list(REMOVE_ITEM __IMPLICT_DLINK_DIRS ${CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES})
+endif()
+set(__IMPLICT_DLINK_FLAGS )
+foreach(dir ${__IMPLICT_DLINK_DIRS})
+ if(EXISTS "${dir}/cublas_device.lib")
+ string(APPEND __IMPLICT_DLINK_FLAGS " -L\"${dir}\"")
+ endif()
+endforeach()
+unset(__IMPLICT_DLINK_DIRS)
+
set(CMAKE_CUDA_DEVICE_LINK_LIBRARY
- "<CMAKE_CUDA_COMPILER> <CMAKE_CUDA_LINK_FLAGS> <LANGUAGE_COMPILE_FLAGS> ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS")
+ "<CMAKE_CUDA_COMPILER> <CMAKE_CUDA_LINK_FLAGS> <LANGUAGE_COMPILE_FLAGS> ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS${__IMPLICT_DLINK_FLAGS}")
set(CMAKE_CUDA_DEVICE_LINK_EXECUTABLE
- "<CMAKE_CUDA_COMPILER> <FLAGS> <CMAKE_CUDA_LINK_FLAGS> ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS")
+ "<CMAKE_CUDA_COMPILER> <FLAGS> <CMAKE_CUDA_LINK_FLAGS> ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS${__IMPLICT_DLINK_FLAGS}")
unset(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS)
+unset(__IMPLICT_DLINK_FLAGS)
string(REPLACE "/D" "-D" _PLATFORM_DEFINES_CUDA "${_PLATFORM_DEFINES}${_PLATFORM_DEFINES_CXX}")
diff --git a/Modules/UseSWIG.cmake b/Modules/UseSWIG.cmake
index 8e7ca41..8713cd8 100644
--- a/Modules/UseSWIG.cmake
+++ b/Modules/UseSWIG.cmake
@@ -5,7 +5,10 @@
UseSWIG
-------
-Defines the following command for use with SWIG:
+This file provides support for ``SWIG``. It is assumed that :module:`FindSWIG`
+module has already been loaded.
+
+Defines the following command for use with ``SWIG``:
.. command:: swig_add_library
@@ -20,17 +23,23 @@ Defines the following command for use with SWIG:
SOURCES <file>...
)
- Targets created with command ``swig_add_library`` have the same capabilities as targets
- created with command :command:`add_library`, so can be used with any command accepting a target
- especially command :command:`target_link_libraries`.
+ Targets created with the ``swig_add_library`` command have the same
+ capabilities as targets created with the :command:`add_library` command, so
+ those targets can be used with any command expecting a target (e.g.
+ :command:`target_link_libraries`).
+
+ .. note::
- The arguments are:
+ For multi-config generators, this module does not support
+ configuration-specific files generated by ``SWIG``. All build
+ configurations must result in the same generated source file.
``TYPE``
- ``SHARED``, ``MODULE`` and ``STATIC`` have same semantic as command :command:`add_library`.
- if ``USE_BUILD_SHARED_LIBS`` is specified, library type will be ``STATIC`` or ``SHARED``
- based on whether the current value of the variable :variable:`BUILD_SHARED_LIBS` is ``ON``.
- If none is specified, ``MODULE`` will be used.
+ ``SHARED``, ``MODULE`` and ``STATIC`` have the same semantic as for the
+ :command:`add_library` command. If ``USE_BUILD_SHARED_LIBS`` is specified,
+ the library type will be ``STATIC`` or ``SHARED`` based on whether the
+ current value of the :variable:`BUILD_SHARED_LIBS` variable is ``ON``. If
+ no type is specified, ``MODULE`` will be used.
``LANGUAGE``
Specify the target language.
@@ -39,22 +48,40 @@ Defines the following command for use with SWIG:
Prevent the generation of the wrapper layer (swig ``-noproxy`` option).
``OUTPUT_DIR``
- Specify where to write the language specific files (swig ``-outdir`` option).
- If not specified, variable ``CMAKE_SWIG_OUTDIR`` will be used. If none is specified,
- :variable:`CMAKE_CURRENT_BINARY_DIR` is used.
+ Specify where to write the language specific files (swig ``-outdir``
+ option). If not given, the ``CMAKE_SWIG_OUTDIR`` variable will be used.
+ If neither is specified, the default depends on the value of the
+ ``UseSWIG_MODULE_VERSION`` variable as follows:
+
+ * If ``UseSWIG_MODULE_VERSION`` is 1 or is undefined, output is written to
+ the :variable:`CMAKE_CURRENT_BINARY_DIR` directory.
+ * If ``UseSWIG_MODULE_VERSION`` is 2, a dedicated directory will be used.
+ The path of this directory can be retrieved from the
+ ``SWIG_SUPPORT_FILES_DIRECTORY`` target property.
``OUTFILE_DIR``
- Specify an output directory name where the generated source file will be placed
- (swig -o option). If not specified, variable ``SWIG_OUTFILE_DIR`` will be used.
- If none is specified, option ``OUTPUT_DIR`` or variable ``CMAKE_SWIG_OUTDIR`` is used.
+ Specify an output directory name where the generated source file will be
+ placed (swig -o option). If not specified, the ``SWIG_OUTFILE_DIR`` variable
+ will be used. If neither is specified, ``OUTPUT_DIR`` or
+ ``CMAKE_SWIG_OUTDIR`` is used instead.
``SOURCES``
- List of sources for the library. Files with extension ``.i`` will be identified as sources
- for ``SWIG`` tool. Other files will be handled in the standard way.
+ List of sources for the library. Files with extension ``.i`` will be
+ identified as sources for the ``SWIG`` tool. Other files will be handled in
+ the standard way.
-Source files properties on module files **must** be set before the invocation
-of the ``swig_add_library`` command to specify special behavior of SWIG and ensure
-generated files will receive required settings.
+.. note::
+
+ If ``UseSWIG_MODULE_VERSION`` is set to 2, it is **strongly** recommended
+ to use a dedicated directory unique to the target when either the
+ ``OUTPUT_DIR`` option or the ``CMAKE_SWIG_OUTDIR`` variable are specified.
+ The output directory contents are erased as part of the target build, so
+ to prevent interference between targets or losing other important files, each
+ target should have its own dedicated output directory.
+
+Source file properties on module files **must** be set before the invocation
+of the ``swig_add_library`` command to specify special behavior of SWIG and
+ensure generated files will receive the required settings.
``CPLUSPLUS``
Call SWIG in c++ mode. For example:
@@ -66,7 +93,8 @@ generated files will receive required settings.
``INCLUDE_DIRECTORIES``, ``COMPILE_DEFINITIONS`` and ``COMPILE_OPTIONS``
Add custom flags to SWIG compiler and have same semantic as properties
- :prop_sf:`INCLUDE_DIRECTORIES`, :prop_sf:`COMPILE_DEFINITIONS` and :prop_sf:`COMPILE_OPTIONS`.
+ :prop_sf:`INCLUDE_DIRECTORIES`, :prop_sf:`COMPILE_DEFINITIONS` and
+ :prop_sf:`COMPILE_OPTIONS`.
``GENERATED_INCLUDE_DIRECTORIES``, ``GENERATED_COMPILE_DEFINITIONS`` and ``GENERATED_COMPILE_OPTIONS``
Add custom flags to the C/C++ generated source. They will fill, respectively,
@@ -85,12 +113,13 @@ generated files will receive required settings.
set_property(SOURCE mymod.i PROPERTY SWIG_MODULE_NAME mymod_realname)
-Target library properties can be set to apply same configuration to all SWIG input files.
+Target library properties can be set to apply same configuration to all SWIG
+input files.
``SWIG_INCLUDE_DIRECTORIES``, ``SWIG_COMPILE_DEFINITIONS`` and ``SWIG_COMPILE_OPTIONS``
- These properties will be applied to all SWIG input files and have same semantic as
- target properties :prop_tgt:`INCLUDE_DIRECTORIES`, :prop_tgt:`COMPILE_DEFINITIONS` and
- :prop_tgt:`COMPILE_OPTIONS`.
+ These properties will be applied to all SWIG input files and have same
+ semantic as target properties :prop_tgt:`INCLUDE_DIRECTORIES`,
+ :prop_tgt:`COMPILE_DEFINITIONS` and :prop_tgt:`COMPILE_OPTIONS`.
.. code-block:: cmake
@@ -99,12 +128,16 @@ Target library properties can be set to apply same configuration to all SWIG inp
set_property(TARGET mymod PROPERTY SWIG_COMPILE_OPTIONS -bla -blb)
``SWIG_GENERATED_INCLUDE_DIRECTORIES``, ``SWIG_GENERATED_COMPILE_DEFINITIONS`` and ``SWIG_GENERATED_COMPILE_OPTIONS``
- These properties will populate, respectively, properties :prop_sf:`INCLUDE_DIRECTORIES`,
- :prop_sf:`COMPILE_DEFINITIONS` and :prop_sf:`COMPILE_FLAGS` of all generated C/C++ files.
+ These properties will populate, respectively, properties
+ :prop_sf:`INCLUDE_DIRECTORIES`, :prop_sf:`COMPILE_DEFINITIONS` and
+ :prop_sf:`COMPILE_FLAGS` of all generated C/C++ files.
``SWIG_DEPENDS``
Add dependencies to all SWIG input files.
+The following target properties are output properties and can be used to get
+information about support files generated by ``SWIG`` interface compilation.
+
``SWIG_SUPPORT_FILES``
This output property list of wrapper files generated during SWIG compilation.
@@ -113,7 +146,26 @@ Target library properties can be set to apply same configuration to all SWIG inp
swig_add_library(mymod LANGUAGE python SOURCES mymod.i)
get_property(support_files TARGET mymod PROPERTY SWIG_SUPPORT_FILES)
-Some variables can be set to specify special behavior of SWIG:
+ .. note::
+
+ Only most principal support files are listed. In case some advanced
+ features of ``SWIG`` are used (for example ``%template``), associated
+ support files may not be listed. Prefer to use the
+ ``SWIG_SUPPORT_FILES_DIRECTORY`` property to handle support files.
+
+``SWIG_SUPPORT_FILES_DIRECTORY``
+ This output property specifies the directory where support files will be
+ generated.
+
+Some variables can be set to customize the behavior of ``swig_add_library``
+as well as ``SWIG``:
+
+``UseSWIG_MODULE_VERSION``
+ Specify different behaviors for ``UseSWIG`` module.
+
+ * Set to 1 or undefined: Legacy behavior is applied.
+ * Set to 2: A new strategy is applied regarding support files: the output
+ directory of support files is erased before ``SWIG`` interface compilation.
``CMAKE_SWIG_FLAGS``
Add flags to all swig calls.
@@ -158,7 +210,6 @@ macro(SWIG_MODULE_INITIALIZE name language)
string(TOUPPER "${language}" SWIG_MODULE_${name}_LANGUAGE)
string(TOLOWER "${language}" SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG)
- set(SWIG_MODULE_${name}_NAME "${name}")
set(SWIG_MODULE_${name}_EXTRA_FLAGS)
if (NOT DEFINED SWIG_MODULE_${name}_NOPROXY)
set (SWIG_MODULE_${name}_NOPROXY FALSE)
@@ -172,11 +223,6 @@ macro(SWIG_MODULE_INITIALIZE name language)
endif()
if(SWIG_MODULE_${name}_LANGUAGE STREQUAL "UNKNOWN")
message(FATAL_ERROR "SWIG Error: Language \"${language}\" not found")
- elseif(SWIG_MODULE_${name}_LANGUAGE STREQUAL "PYTHON" AND NOT SWIG_MODULE_${name}_NOPROXY)
- # swig will produce a module.py containing an 'import _modulename' statement,
- # which implies having a corresponding _modulename.so (*NIX), _modulename.pyd (Win32),
- # unless the -noproxy flag is used
- set(SWIG_MODULE_${name}_NAME "_${name}")
elseif(SWIG_MODULE_${name}_LANGUAGE STREQUAL "PERL")
list(APPEND SWIG_MODULE_${name}_EXTRA_FLAGS "-shadow")
endif()
@@ -255,7 +301,7 @@ function(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile)
# handle various swig compile flags properties
get_source_file_property (include_directories "${infile}" INCLUDE_DIRECTORIES)
if (include_directories)
- list (APPEND swig_source_file_flags "-I$<JOIN:${include_directories},$<SEMICOLON>-I>")
+ list (APPEND swig_source_file_flags "$<$<BOOL:${include_directories}>:-I$<JOIN:${include_directories},$<SEMICOLON>-I>>")
endif()
set (property "$<TARGET_PROPERTY:${name},SWIG_INCLUDE_DIRECTORIES>")
list (APPEND swig_source_file_flags "$<$<BOOL:${property}>:-I$<JOIN:${property},$<SEMICOLON>-I>>")
@@ -264,7 +310,7 @@ function(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile)
list (APPEND swig_source_file_flags "$<$<BOOL:${property}>:-D$<JOIN:${property},$<SEMICOLON>-D>>")
get_source_file_property (compile_definitions "${infile}" COMPILE_DEFINITIONS)
if (compile_definitions)
- list (APPEND swig_source_file_flags "-D$<JOIN:${compile_definitions},$<SEMICOLON>-D>")
+ list (APPEND swig_source_file_flags "$<$<BOOL:${compile_definitions}>:-D$<JOIN:${compile_definitions},$<SEMICOLON>-D>>")
endif()
list (APPEND swig_source_file_flags "$<TARGET_PROPERTY:${name},SWIG_COMPILE_OPTIONS>")
@@ -306,7 +352,7 @@ function(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile)
list (REMOVE_DUPLICATES cmake_include_directories)
set (swig_include_dirs)
if (cmake_include_directories)
- set (swig_include_dirs "-I$<JOIN:${cmake_include_directories},$<SEMICOLON>-I>")
+ set (swig_include_dirs "$<$<BOOL:${cmake_include_directories}>:-I$<JOIN:${cmake_include_directories},$<SEMICOLON>-I>>")
endif()
set(swig_special_flags)
@@ -332,6 +378,14 @@ function(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile)
list (APPEND swig_dependencies ${file_depends})
endif()
+ if (UseSWIG_MODULE_VERSION VERSION_GREATER 1)
+ # as part of custom command, start by removing old generated files
+ # to ensure obsolete files do not stay
+ set (swig_cleanup_command COMMAND "${CMAKE_COMMAND}" -E remove_directory "${outdir}")
+ else()
+ unset (swig_cleanup_command)
+ endif()
+
# IMPLICIT_DEPENDS below can not handle situations where a dependent file is
# removed. We need an extra step with timestamp and custom target, see #16830
# As this is needed only for Makefile generator do it conditionally
@@ -352,10 +406,11 @@ function(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile)
add_custom_command(
OUTPUT ${swig_custom_output}
${swig_custom_products}
+ ${swig_cleanup_command}
# Let's create the ${outdir} at execution time, in case dir contains $(OutDir)
COMMAND "${CMAKE_COMMAND}" -E make_directory ${outdir} ${outfiledir}
${swig_timestamp_command}
- COMMAND "${SWIG_EXECUTABLE}"
+ COMMAND "${CMAKE_COMMAND}" -E env "SWIG_LIB=${SWIG_DIR}" "${SWIG_EXECUTABLE}"
"-${SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG}"
"${swig_source_file_flags}"
-outdir "${outdir}"
@@ -434,6 +489,12 @@ function(SWIG_ADD_LIBRARY name)
unset(_SAM_TYPE)
endif()
+ if (NOT DEFINED UseSWIG_MODULE_VERSION)
+ set (UseSWIG_MODULE_VERSION 1)
+ elseif (NOT UseSWIG_MODULE_VERSION MATCHES "^(1|2)$")
+ message (FATAL_ERROR "UseSWIG_MODULE_VERSION: ${UseSWIG_MODULE_VERSION}: invalid value. 1 or 2 is expected.")
+ endif()
+
set (workingdir "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${name}.dir")
# set special variable to pass extra information to command SWIG_ADD_SOURCE_TO_MODULE
# which cannot be changed due to legacy compatibility
@@ -444,7 +505,11 @@ function(SWIG_ADD_LIBRARY name)
if (CMAKE_SWIG_OUTDIR)
set (outputdir "${CMAKE_SWIG_OUTDIR}")
else()
- set (outputdir "${CMAKE_CURRENT_BINARY_DIR}")
+ if (UseSWIG_MODULE_VERSION VERSION_GREATER 1)
+ set (outputdir "${workingdir}/${_SAM_LANGUAGE}.files")
+ else()
+ set (outputdir "${CMAKE_CURRENT_BINARY_DIR}")
+ endif()
endif()
endif()
@@ -470,6 +535,9 @@ function(SWIG_ADD_LIBRARY name)
set(swig_dot_i_sources ${_SAM_SOURCES})
list(FILTER swig_dot_i_sources INCLUDE REGEX "\\.i$")
+ if (NOT swig_dot_i_sources)
+ message(FATAL_ERROR "SWIG_ADD_LIBRARY: no SWIG interface files specified")
+ endif()
set(swig_other_sources ${_SAM_SOURCES})
list(REMOVE_ITEM swig_other_sources ${swig_dot_i_sources})
@@ -486,12 +554,14 @@ function(SWIG_ADD_LIBRARY name)
endforeach()
set_property (DIRECTORY APPEND PROPERTY
ADDITIONAL_MAKE_CLEAN_FILES ${swig_generated_sources} ${swig_generated_timestamps})
+ if (UseSWIG_MODULE_VERSION VERSION_GREATER 1)
+ set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${outputdir}")
+ endif()
add_library(${name}
${_SAM_TYPE}
${swig_generated_sources}
${swig_other_sources})
- set_target_properties(${name} PROPERTIES OUTPUT_NAME "${SWIG_MODULE_${name}_NAME}")
if(CMAKE_GENERATOR MATCHES "Make")
# see IMPLICIT_DEPENDS above
add_custom_target(${name}_swig_compilation DEPENDS ${swig_generated_timestamps})
@@ -524,8 +594,14 @@ function(SWIG_ADD_LIBRARY name)
set_target_properties(${name} PROPERTIES PREFIX "")
endif()
elseif (swig_lowercase_language STREQUAL "python")
- # this is only needed for the python case where a _modulename.so is generated
- set_target_properties(${name} PROPERTIES PREFIX "")
+ if (SWIG_MODULE_${name}_NOPROXY)
+ set_target_properties(${name} PROPERTIES PREFIX "")
+ else()
+ # swig will produce a module.py containing an 'import _modulename' statement,
+ # which implies having a corresponding _modulename.so (*NIX), _modulename.pyd (Win32),
+ # unless the -noproxy flag is used
+ set_target_properties(${name} PROPERTIES PREFIX "_")
+ endif()
# Python extension modules on Windows must have the extension ".pyd"
# instead of ".dll" as of Python 2.5. Older python versions do support
# this suffix.
@@ -560,7 +636,10 @@ function(SWIG_ADD_LIBRARY name)
# assume empty prefix because we expect the module to be dynamically loaded
set_target_properties (${name} PROPERTIES PREFIX "")
endif ()
- # target property SWIG_SUPPORT_FILES lists proxy support files
+
+ # target property SWIG_SUPPORT_FILES_DIRECTORY specify output directory of support files
+ set_property (TARGET ${name} PROPERTY SWIG_SUPPORT_FILES_DIRECTORY "${outputdir}")
+ # target property SWIG_SUPPORT_FILES lists principal proxy support files
if (NOT SWIG_MODULE_${name}_NOPROXY)
string(TOUPPER "${_SAM_LANGUAGE}" swig_uppercase_language)
set(swig_all_support_files)
@@ -572,7 +651,7 @@ function(SWIG_ADD_LIBRARY name)
if (swig_all_support_files)
list(REMOVE_DUPLICATES swig_all_support_files)
endif()
- set_property (TARGET ${name} APPEND PROPERTY SWIG_SUPPORT_FILES ${swig_all_support_files})
+ set_property (TARGET ${name} PROPERTY SWIG_SUPPORT_FILES ${swig_all_support_files})
endif()
# to ensure legacy behavior, export some variables
diff --git a/Modules/WriteCompilerDetectionHeader.cmake b/Modules/WriteCompilerDetectionHeader.cmake
index 675df84..3718e9d 100644
--- a/Modules/WriteCompilerDetectionHeader.cmake
+++ b/Modules/WriteCompilerDetectionHeader.cmake
@@ -17,6 +17,7 @@
# [OUTPUT_FILES_VAR <output_files_var> OUTPUT_DIR <output_dir>]
# COMPILERS <compiler> [...]
# FEATURES <feature> [...]
+# [BARE_FEATURES <feature> [...]]
# [VERSION <version>]
# [PROLOG <prolog>]
# [EPILOG <epilog>]
@@ -83,10 +84,14 @@
# See the :manual:`cmake-compile-features(7)` manual for information on
# compile features.
#
+# ``BARE_FEATURES`` will define the compatibility macros with the name used in
+# newer versions of the language standard, so the code can use the new feature
+# name unconditionally.
+#
# ``ALLOW_UNKNOWN_COMPILERS`` and ``ALLOW_UNKNOWN_COMPILER_VERSIONS`` cause
# the module to generate conditions that treat unknown compilers as simply
# lacking all features. Without these options the default behavior is to
-# generate a ``#error`` for unknown compilers.
+# generate a ``#error`` for unknown compilers and versions.
#
# Feature Test Macros
# ===================
@@ -148,20 +153,24 @@
# ``ClimbingStats_CONSTEXPR`` macro will expand to ``constexpr``
# if ``cxx_constexpr`` is supported.
#
-# The following features generate corresponding symbol defines:
+# If ``BARE_FEATURES cxx_final`` was given as argument the ``final`` keyword
+# will be defined for old compilers, too.
+#
+# The following features generate corresponding symbol defines and if they
+# are available as ``BARE_FEATURES``:
#
-# ========================== =================================== =================
-# Feature Define Symbol
-# ========================== =================================== =================
-# ``c_restrict`` ``<PREFIX>_RESTRICT`` ``restrict``
-# ``cxx_constexpr`` ``<PREFIX>_CONSTEXPR`` ``constexpr``
+# ========================== =================================== ================= ======
+# Feature Define Symbol bare
+# ========================== =================================== ================= ======
+# ``c_restrict`` ``<PREFIX>_RESTRICT`` ``restrict`` yes
+# ``cxx_constexpr`` ``<PREFIX>_CONSTEXPR`` ``constexpr`` yes
# ``cxx_deleted_functions`` ``<PREFIX>_DELETED_FUNCTION`` ``= delete``
# ``cxx_extern_templates`` ``<PREFIX>_EXTERN_TEMPLATE`` ``extern``
-# ``cxx_final`` ``<PREFIX>_FINAL`` ``final``
-# ``cxx_noexcept`` ``<PREFIX>_NOEXCEPT`` ``noexcept``
+# ``cxx_final`` ``<PREFIX>_FINAL`` ``final`` yes
+# ``cxx_noexcept`` ``<PREFIX>_NOEXCEPT`` ``noexcept`` yes
# ``cxx_noexcept`` ``<PREFIX>_NOEXCEPT_EXPR(X)`` ``noexcept(X)``
-# ``cxx_override`` ``<PREFIX>_OVERRIDE`` ``override``
-# ========================== =================================== =================
+# ``cxx_override`` ``<PREFIX>_OVERRIDE`` ``override`` yes
+# ========================== =================================== ================= ======
#
# Compatibility Implementation Macros
# ===================================
@@ -195,18 +204,18 @@
# decorator or a compiler-specific decorator such as ``__alignof__``
# used by GNU compilers.
#
-# ============================= ================================ =====================
-# Feature Define Symbol
-# ============================= ================================ =====================
+# ============================= ================================ ===================== ======
+# Feature Define Symbol bare
+# ============================= ================================ ===================== ======
# ``cxx_alignas`` ``<PREFIX>_ALIGNAS`` ``alignas``
# ``cxx_alignof`` ``<PREFIX>_ALIGNOF`` ``alignof``
-# ``cxx_nullptr`` ``<PREFIX>_NULLPTR`` ``nullptr``
+# ``cxx_nullptr`` ``<PREFIX>_NULLPTR`` ``nullptr`` yes
# ``cxx_static_assert`` ``<PREFIX>_STATIC_ASSERT`` ``static_assert``
# ``cxx_static_assert`` ``<PREFIX>_STATIC_ASSERT_MSG`` ``static_assert``
# ``cxx_attribute_deprecated`` ``<PREFIX>_DEPRECATED`` ``[[deprecated]]``
# ``cxx_attribute_deprecated`` ``<PREFIX>_DEPRECATED_MSG`` ``[[deprecated]]``
# ``cxx_thread_local`` ``<PREFIX>_THREAD_LOCAL`` ``thread_local``
-# ============================= ================================ =====================
+# ============================= ================================ ===================== ======
#
# A use-case which arises with such deprecation macros is the deprecation
# of an entire library. In that case, all public API in the library may
@@ -252,6 +261,37 @@ macro(_simpledefine FEATURE_NAME FEATURE_TESTNAME FEATURE_STRING FEATURE_DEFAULT
endif()
endmacro()
+macro(_simplebaredefine FEATURE_NAME FEATURE_STRING FEATURE_DEFAULT_STRING)
+ if (feature STREQUAL "${FEATURE_NAME}")
+ string(APPEND file_content "
+# if !(defined(${def_name}) && ${def_name})
+# define ${FEATURE_STRING} ${FEATURE_DEFAULT_STRING}
+# endif
+\n")
+ endif()
+endmacro()
+
+function(_check_feature_lists C_FEATURE_VAR CXX_FEATURE_VAR)
+ foreach(feature ${ARGN})
+ if (feature MATCHES "^c_std_")
+ # ignored
+ elseif (feature MATCHES "^cxx_std_")
+ # ignored
+ elseif (feature MATCHES "^cxx_")
+ list(APPEND _langs CXX)
+ list(APPEND ${CXX_FEATURE_VAR} ${feature})
+ elseif (feature MATCHES "^c_")
+ list(APPEND _langs C)
+ list(APPEND ${C_FEATURE_VAR} ${feature})
+ else()
+ message(FATAL_ERROR "Unsupported feature ${feature}.")
+ endif()
+ endforeach()
+ set(${C_FEATURE_VAR} ${${C_FEATURE_VAR}} PARENT_SCOPE)
+ set(${CXX_FEATURE_VAR} ${${CXX_FEATURE_VAR}} PARENT_SCOPE)
+ set(_langs ${_langs} PARENT_SCOPE)
+endfunction()
+
function(write_compiler_detection_header
file_keyword file_arg
prefix_keyword prefix_arg
@@ -264,13 +304,13 @@ function(write_compiler_detection_header
endif()
set(options ALLOW_UNKNOWN_COMPILERS ALLOW_UNKNOWN_COMPILER_VERSIONS)
set(oneValueArgs VERSION EPILOG PROLOG OUTPUT_FILES_VAR OUTPUT_DIR)
- set(multiValueArgs COMPILERS FEATURES)
+ set(multiValueArgs COMPILERS FEATURES BARE_FEATURES)
cmake_parse_arguments(_WCD "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if (NOT _WCD_COMPILERS)
message(FATAL_ERROR "Invalid arguments. write_compiler_detection_header requires at least one compiler.")
endif()
- if (NOT _WCD_FEATURES)
+ if (NOT _WCD_FEATURES AND NOT _WCD_BARE_FEATURES)
message(FATAL_ERROR "Invalid arguments. write_compiler_detection_header requires at least one feature.")
endif()
@@ -377,21 +417,8 @@ function(write_compiler_detection_header
)\n")
endif()
- foreach(feature ${_WCD_FEATURES})
- if (feature MATCHES "^c_std_")
- # ignored
- elseif (feature MATCHES "^cxx_std_")
- # ignored
- elseif (feature MATCHES "^cxx_")
- list(APPEND _langs CXX)
- list(APPEND CXX_features ${feature})
- elseif (feature MATCHES "^c_")
- list(APPEND _langs C)
- list(APPEND C_features ${feature})
- else()
- message(FATAL_ERROR "Unsupported feature ${feature}.")
- endif()
- endforeach()
+ _check_feature_lists(C_features CXX_features ${_WCD_FEATURES})
+ _check_feature_lists(C_bare_features CXX_bare_features ${_WCD_BARE_FEATURES})
list(REMOVE_DUPLICATES _langs)
if(_WCD_OUTPUT_FILES_VAR)
@@ -606,6 +633,29 @@ template<> struct ${prefix_arg}StaticAssert<true>{};
endif()
endforeach()
+ foreach(feature ${${_lang}_bare_features})
+ string(TOUPPER ${feature} feature_upper)
+ set(feature_PP "COMPILER_${feature_upper}")
+ set(def_name ${prefix_arg}_${feature_PP})
+ _simplebaredefine(c_restrict restrict "")
+ _simplebaredefine(cxx_constexpr constexpr "")
+ _simplebaredefine(cxx_final final "")
+ _simplebaredefine(cxx_override override "")
+ if (feature STREQUAL cxx_nullptr)
+ set(def_value "nullptr")
+ string(APPEND file_content "
+# if !(defined(${def_name}) && ${def_name})
+# if ${prefix_arg}_COMPILER_IS_GNU
+# define ${def_value} __null
+# else
+# define ${def_value} 0
+# endif
+# endif
+\n")
+ endif()
+ _simplebaredefine(cxx_noexcept noexcept "")
+ endforeach()
+
string(APPEND file_content "#endif\n")
endforeach()
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index e547356..a007098 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -246,6 +246,8 @@ set(SRCS
cmGlobalGeneratorFactory.h
cmGlobalUnixMakefileGenerator3.cxx
cmGlobalUnixMakefileGenerator3.h
+ cmGlobVerificationManager.cxx
+ cmGlobVerificationManager.h
cmGraphAdjacencyList.h
cmGraphVizWriter.cxx
cmGraphVizWriter.h
@@ -555,6 +557,7 @@ set(SRCS
cmSiteNameCommand.h
cmSourceGroupCommand.cxx
cmSourceGroupCommand.h
+ cmStringReplaceHelper.cxx
cmStringCommand.cxx
cmStringCommand.h
cmSubdirCommand.cxx
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 0f1a352..e7dc51e 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,5 +1,5 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 11)
-set(CMake_VERSION_PATCH 20180404)
+set(CMake_VERSION_PATCH 20180417)
#set(CMake_VERSION_RC 1)
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index 507a10c..b6ff38b 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -350,16 +350,16 @@ int main(int argc, char const* const* argv)
}
if (parsed) {
cpackGenerator = generators.NewGenerator(gen);
- if (!cpackGenerator) {
+ if (cpackGenerator) {
+ cpackGenerator->SetTrace(trace);
+ cpackGenerator->SetTraceExpand(traceExpand);
+ } else {
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
"Cannot initialize CPack generator: " << gen
<< std::endl);
parsed = 0;
}
- cpackGenerator->SetTrace(trace);
- cpackGenerator->SetTraceExpand(traceExpand);
-
if (parsed && !cpackGenerator->Initialize(gen, mf)) {
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
"Cannot initialize the generator " << gen
diff --git a/Source/CTest/cmCTestCurl.h b/Source/CTest/cmCTestCurl.h
index 427a392..86d9489 100644
--- a/Source/CTest/cmCTestCurl.h
+++ b/Source/CTest/cmCTestCurl.h
@@ -16,7 +16,7 @@ class cmCTestCurl
public:
cmCTestCurl(cmCTest*);
~cmCTestCurl();
- bool UploadFile(std::string const& url, std::string const& file,
+ bool UploadFile(std::string const& local_file, std::string const& url,
std::string const& fields, std::string& response);
bool HttpRequest(std::string const& url, std::string const& fields,
std::string& response);
diff --git a/Source/cmAlgorithms.h b/Source/cmAlgorithms.h
index 3380b78..244dc1c 100644
--- a/Source/cmAlgorithms.h
+++ b/Source/cmAlgorithms.h
@@ -311,7 +311,7 @@ struct RemoveDuplicatesAPI<Range, T*>
template <typename Range>
typename Range::const_iterator cmRemoveDuplicates(Range& r)
{
- typedef typename ContainerAlgorithms::RemoveDuplicatesAPI<Range> API;
+ typedef ContainerAlgorithms::RemoveDuplicatesAPI<Range> API;
typedef typename API::value_type T;
std::vector<T> unique;
unique.reserve(r.size());
diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx
index 85ac985..13407e5 100644
--- a/Source/cmCacheManager.cxx
+++ b/Source/cmCacheManager.cxx
@@ -8,6 +8,7 @@
#include <sstream>
#include <stdio.h>
#include <string.h>
+#include <string>
#include "cmGeneratedFileStream.h"
#include "cmMessenger.h"
@@ -243,19 +244,18 @@ bool cmCacheManager::SaveCache(const std::string& path, cmMessenger* messenger)
}
// before writing the cache, update the version numbers
// to the
- char temp[1024];
- sprintf(temp, "%d", cmVersion::GetMinorVersion());
- this->AddCacheEntry("CMAKE_CACHE_MINOR_VERSION", temp,
- "Minor version of cmake used to create the "
+ this->AddCacheEntry("CMAKE_CACHE_MAJOR_VERSION",
+ std::to_string(cmVersion::GetMajorVersion()).c_str(),
+ "Major version of cmake used to create the "
"current loaded cache",
cmStateEnums::INTERNAL);
- sprintf(temp, "%d", cmVersion::GetMajorVersion());
- this->AddCacheEntry("CMAKE_CACHE_MAJOR_VERSION", temp,
- "Major version of cmake used to create the "
+ this->AddCacheEntry("CMAKE_CACHE_MINOR_VERSION",
+ std::to_string(cmVersion::GetMinorVersion()).c_str(),
+ "Minor version of cmake used to create the "
"current loaded cache",
cmStateEnums::INTERNAL);
- sprintf(temp, "%d", cmVersion::GetPatchVersion());
- this->AddCacheEntry("CMAKE_CACHE_PATCH_VERSION", temp,
+ this->AddCacheEntry("CMAKE_CACHE_PATCH_VERSION",
+ std::to_string(cmVersion::GetPatchVersion()).c_str(),
"Patch version of cmake used to create the "
"current loaded cache",
cmStateEnums::INTERNAL);
diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx
index bf314bd..ccb4f88 100644
--- a/Source/cmCommandArgumentParserHelper.cxx
+++ b/Source/cmCommandArgumentParserHelper.cxx
@@ -101,10 +101,11 @@ const char* cmCommandArgumentParserHelper::ExpandVariable(const char* var)
// not been "cleared"/initialized with a set(foo ) call
if (this->WarnUninitialized && !this->Makefile->VariableInitialized(var)) {
if (this->CheckSystemVars ||
- cmSystemTools::IsSubDirectory(this->FileName,
- this->Makefile->GetHomeDirectory()) ||
- cmSystemTools::IsSubDirectory(
- this->FileName, this->Makefile->GetHomeOutputDirectory())) {
+ (this->FileName &&
+ (cmSystemTools::IsSubDirectory(
+ this->FileName, this->Makefile->GetHomeDirectory()) ||
+ cmSystemTools::IsSubDirectory(
+ this->FileName, this->Makefile->GetHomeOutputDirectory())))) {
std::ostringstream msg;
msg << "uninitialized variable \'" << var << "\'";
this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, msg.str());
diff --git a/Source/cmConfigureFileCommand.h b/Source/cmConfigureFileCommand.h
index cff934b..5603c50 100644
--- a/Source/cmConfigureFileCommand.h
+++ b/Source/cmConfigureFileCommand.h
@@ -32,9 +32,9 @@ private:
std::string InputFile;
std::string OutputFile;
- bool CopyOnly;
- bool EscapeQuotes;
- bool AtOnly;
+ bool CopyOnly = false;
+ bool EscapeQuotes = false;
+ bool AtOnly = false;
};
#endif
diff --git a/Source/cmCoreTryCompile.h b/Source/cmCoreTryCompile.h
index 6f35a54..ae714a6 100644
--- a/Source/cmCoreTryCompile.h
+++ b/Source/cmCoreTryCompile.h
@@ -46,7 +46,7 @@ protected:
std::string BinaryDirectory;
std::string OutputFile;
std::string FindErrorMessage;
- bool SrcFileSignature;
+ bool SrcFileSignature = false;
private:
std::vector<std::string> WarnCMP0067;
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index bbbc998..72489bf 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -224,13 +224,14 @@ void cmExportBuildFileGenerator::SetImportLocationProperty(
}
// Add the import library for windows DLLs.
- if (target->HasImportLibrary() &&
+ if (target->HasImportLibrary(config) &&
mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")) {
std::string prop = "IMPORTED_IMPLIB";
prop += suffix;
std::string value =
target->GetFullPath(config, cmStateEnums::ImportLibraryArtifact);
- target->GetImplibGNUtoMS(value, value, "${CMAKE_IMPORT_LIBRARY_SUFFIX}");
+ target->GetImplibGNUtoMS(config, value, value,
+ "${CMAKE_IMPORT_LIBRARY_SUFFIX}");
properties[prop] = value;
}
}
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 2dcbfa0..8894d44 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -777,6 +777,20 @@ void cmExportFileGenerator::SetImportDetailProperties(
properties[prop] = m.str();
}
}
+
+ // Add information if this target is a managed target
+ if (target->GetManagedType(config) !=
+ cmGeneratorTarget::ManagedType::Native) {
+ std::string prop = "IMPORTED_COMMON_LANGUAGE_RUNTIME";
+ prop += suffix;
+ std::string propval;
+ if (auto* p = target->GetProperty("COMMON_LANGUAGE_RUNTIME")) {
+ propval = p;
+ }
+ // TODO: make sure propval is set to non-empty string for
+ // CSharp targets (i.e. force ManagedType::Managed).
+ properties[prop] = propval;
+ }
}
template <typename T>
diff --git a/Source/cmExportLibraryDependenciesCommand.h b/Source/cmExportLibraryDependenciesCommand.h
index bf5e9bc..8414866 100644
--- a/Source/cmExportLibraryDependenciesCommand.h
+++ b/Source/cmExportLibraryDependenciesCommand.h
@@ -27,7 +27,7 @@ public:
private:
std::string Filename;
- bool Append;
+ bool Append = false;
void ConstFinalPass() const;
};
diff --git a/Source/cmExternalMakefileProjectGenerator.h b/Source/cmExternalMakefileProjectGenerator.h
index 5cc6442..d48abca 100644
--- a/Source/cmExternalMakefileProjectGenerator.h
+++ b/Source/cmExternalMakefileProjectGenerator.h
@@ -62,7 +62,7 @@ protected:
///! Contains the names of the global generators support by this generator.
std::vector<std::string> SupportedGlobalGenerators;
///! the global generator which creates the makefiles
- const cmGlobalGenerator* GlobalGenerator;
+ const cmGlobalGenerator* GlobalGenerator = nullptr;
std::string Name;
};
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 90b943b..0d31070 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -758,7 +758,11 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
}
std::vector<std::string> files;
+ bool configureDepends = false;
+ bool warnConfigureLate = false;
bool warnFollowedSymlinks = false;
+ const cmake::WorkingMode workingMode =
+ this->Makefile->GetCMakeInstance()->GetWorkingMode();
while (i != args.end()) {
if (*i == "LIST_DIRECTORIES") {
++i;
@@ -807,6 +811,27 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
this->SetError("GLOB requires a glob expression after the directory.");
return false;
}
+ } else if (*i == "CONFIGURE_DEPENDS") {
+ // Generated build system depends on glob results
+ if (!configureDepends && warnConfigureLate) {
+ this->Makefile->IssueMessage(
+ cmake::AUTHOR_WARNING,
+ "CONFIGURE_DEPENDS flag was given after a glob expression was "
+ "already evaluated.");
+ }
+ if (workingMode != cmake::NORMAL_MODE) {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ "CONFIGURE_DEPENDS is invalid for script and find package modes.");
+ return false;
+ }
+ configureDepends = true;
+ ++i;
+ if (i == args.end()) {
+ this->SetError(
+ "GLOB requires a glob expression after CONFIGURE_DEPENDS.");
+ return false;
+ }
} else {
std::string expr = *i;
if (!cmsys::SystemTools::FileIsFullPath(*i)) {
@@ -849,6 +874,19 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
std::vector<std::string>& foundFiles = g.GetFiles();
files.insert(files.end(), foundFiles.begin(), foundFiles.end());
+
+ if (configureDepends) {
+ std::sort(foundFiles.begin(), foundFiles.end());
+ foundFiles.erase(std::unique(foundFiles.begin(), foundFiles.end()),
+ foundFiles.end());
+ this->Makefile->GetCMakeInstance()->AddGlobCacheEntry(
+ recurse, (recurse ? g.GetRecurseListDirs() : g.GetListDirs()),
+ (recurse ? g.GetRecurseThroughSymlinks() : false),
+ (g.GetRelative() ? g.GetRelative() : ""), expr, foundFiles, variable,
+ this->Makefile->GetBacktrace());
+ } else {
+ warnConfigureLate = true;
+ }
++i;
}
}
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 09b7faf..89ed4f0 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -1675,7 +1675,8 @@ struct TargetFilesystemArtifactResultCreator<ArtifactLinkerTag>
"executables with ENABLE_EXPORTS.");
return std::string();
}
- cmStateEnums::ArtifactType artifact = target->HasImportLibrary()
+ cmStateEnums::ArtifactType artifact =
+ target->HasImportLibrary(context->Config)
? cmStateEnums::ImportLibraryArtifact
: cmStateEnums::RuntimeBinaryArtifact;
return target->GetFullPath(context->Config, artifact);
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 63bfbc6..0cb299c 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -4978,6 +4978,16 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
}
}
+ // Get information if target is managed assembly.
+ {
+ std::string linkProp = "IMPORTED_COMMON_LANGUAGE_RUNTIME";
+ if (auto pc = this->GetProperty(linkProp + suffix)) {
+ info.Managed = this->CheckManagedType(pc);
+ } else if (auto p = this->GetProperty(linkProp)) {
+ info.Managed = this->CheckManagedType(p);
+ }
+ }
+
// Get the cyclic repetition count.
if (this->GetType() == cmStateEnums::STATIC_LIBRARY) {
std::string linkProp = "IMPORTED_LINK_INTERFACE_MULTIPLICITY";
@@ -5195,6 +5205,18 @@ void cmGeneratorTarget::GetLanguages(std::set<std::string>& languages,
}
}
+bool cmGeneratorTarget::HasLanguage(std::string const& language,
+ std::string const& config,
+ bool exclusive) const
+{
+ std::set<std::string> languages;
+ this->GetLanguages(languages, config);
+ // add linker language (if it is different from compiler languages)
+ languages.insert(this->GetLinkerLanguage(config));
+ return (languages.size() == 1 || !exclusive) &&
+ languages.count(language) > 0;
+}
+
void cmGeneratorTarget::ComputeLinkImplementationLanguages(
const std::string& config, cmOptionalLinkImplementation& impl) const
{
@@ -5381,16 +5403,17 @@ std::string cmGeneratorTarget::GetPDBDirectory(const std::string& config) const
return "";
}
-bool cmGeneratorTarget::HasImplibGNUtoMS() const
+bool cmGeneratorTarget::HasImplibGNUtoMS(std::string const& config) const
{
- return this->HasImportLibrary() && this->GetPropertyAsBool("GNUtoMS");
+ return this->HasImportLibrary(config) && this->GetPropertyAsBool("GNUtoMS");
}
-bool cmGeneratorTarget::GetImplibGNUtoMS(std::string const& gnuName,
+bool cmGeneratorTarget::GetImplibGNUtoMS(std::string const& config,
+ std::string const& gnuName,
std::string& out,
const char* newExt) const
{
- if (this->HasImplibGNUtoMS() && gnuName.size() > 6 &&
+ if (this->HasImplibGNUtoMS(config) && gnuName.size() > 6 &&
gnuName.substr(gnuName.size() - 6) == ".dll.a") {
out = gnuName.substr(0, gnuName.size() - 6);
out += newExt ? newExt : ".lib";
@@ -5405,11 +5428,14 @@ bool cmGeneratorTarget::IsExecutableWithExports() const
this->GetPropertyAsBool("ENABLE_EXPORTS"));
}
-bool cmGeneratorTarget::HasImportLibrary() const
+bool cmGeneratorTarget::HasImportLibrary(std::string const& config) const
{
return (this->IsDLLPlatform() &&
(this->GetType() == cmStateEnums::SHARED_LIBRARY ||
- this->IsExecutableWithExports()));
+ this->IsExecutableWithExports()) &&
+ // Assemblies which have only managed code do not have
+ // import libraries.
+ this->GetManagedType(config) != ManagedType::Managed);
}
std::string cmGeneratorTarget::GetSupportDirectory() const
@@ -5462,3 +5488,49 @@ bool cmGeneratorTarget::IsCFBundleOnApple() const
return (this->GetType() == cmStateEnums::MODULE_LIBRARY &&
this->Makefile->IsOn("APPLE") && this->GetPropertyAsBool("BUNDLE"));
}
+
+cmGeneratorTarget::ManagedType cmGeneratorTarget::CheckManagedType(
+ std::string const& propval) const
+{
+ // The type of the managed assembly (mixed unmanaged C++ and C++/CLI,
+ // or only C++/CLI) does only depend on whether the property is an empty
+ // string or contains any value at all. In Visual Studio generators
+ // this propval is prepended with /clr[:] which results in:
+ //
+ // 1. propval does not exist: no /clr flag, unmanaged target, has import
+ // lib
+ // 2. empty propval: add /clr as flag, mixed unmanaged/managed
+ // target, has import lib
+ // 3. any value (safe,pure): add /clr:[propval] as flag, target with
+ // managed code only, no import lib
+ return propval.empty() ? ManagedType::Mixed : ManagedType::Managed;
+}
+
+cmGeneratorTarget::ManagedType cmGeneratorTarget::GetManagedType(
+ const std::string& config) const
+{
+ // Only libraries and executables can be managed targets.
+ if (this->GetType() != cmStateEnums::SHARED_LIBRARY &&
+ this->GetType() != cmStateEnums::STATIC_LIBRARY &&
+ this->GetType() != cmStateEnums::EXECUTABLE) {
+ return ManagedType::Undefined;
+ }
+
+ // Check imported target.
+ if (this->IsImported()) {
+ if (cmGeneratorTarget::ImportInfo const* info =
+ this->GetImportInfo(config)) {
+ return info->Managed;
+ }
+ return ManagedType::Undefined;
+ }
+
+ // Check for explicitly set clr target property.
+ if (auto* clr = this->GetProperty("COMMON_LANGUAGE_RUNTIME")) {
+ return this->CheckManagedType(clr);
+ }
+
+ // TODO: need to check if target is a CSharp target here.
+ // If yes: return ManagedType::Managed.
+ return ManagedType::Native;
+}
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 2f6ce33..d4a553a 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -364,6 +364,12 @@ public:
void GetLanguages(std::set<std::string>& languages,
std::string const& config) const;
+ // Evaluate if the target uses the given language for compilation
+ // and/or linking. If 'exclusive' is true, 'language' is expected
+ // to be the only language used for the target.
+ bool HasLanguage(std::string const& language, std::string const& config,
+ bool exclusive = true) const;
+
void GetObjectLibrariesCMP0026(
std::vector<cmGeneratorTarget*>& objlibs) const;
@@ -566,17 +572,17 @@ public:
std::string GetLinkerLanguage(const std::string& config) const;
/** Does this target have a GNU implib to convert to MS format? */
- bool HasImplibGNUtoMS() const;
+ bool HasImplibGNUtoMS(std::string const& config) const;
/** Convert the given GNU import library name (.dll.a) to a name with a new
extension (.lib or ${CMAKE_IMPORT_LIBRARY_SUFFIX}). */
- bool GetImplibGNUtoMS(std::string const& gnuName, std::string& out,
- const char* newExt = nullptr) const;
+ bool GetImplibGNUtoMS(std::string const& config, std::string const& gnuName,
+ std::string& out, const char* newExt = nullptr) const;
bool IsExecutableWithExports() const;
/** Return whether or not the target has a DLL import library. */
- bool HasImportLibrary() const;
+ bool HasImportLibrary(std::string const& config) const;
/** Get a build-tree directory in which to place target support files. */
std::string GetSupportDirectory() const;
@@ -597,6 +603,19 @@ public:
/** Return whether this target is a CFBundle (plugin) on Apple. */
bool IsCFBundleOnApple() const;
+ /** Assembly types. The order of the values of this enum is relevant
+ because of smaller/larger comparison operations! */
+ enum ManagedType
+ {
+ Undefined = 0, // target is no lib or executable
+ Native, // target compiles to unmanaged binary.
+ Mixed, // target compiles to mixed (managed and unmanaged) binary.
+ Managed // target compiles to managed binary.
+ };
+
+ /** Return the type of assembly this target compiles to. */
+ ManagedType GetManagedType(const std::string& config) const;
+
struct SourceFileFlags GetTargetSourceFileFlags(
const cmSourceFile* sf) const;
@@ -741,10 +760,12 @@ private:
{
ImportInfo()
: NoSOName(false)
+ , Managed(Native)
, Multiplicity(0)
{
}
bool NoSOName;
+ ManagedType Managed;
unsigned int Multiplicity;
std::string Location;
std::string SOName;
@@ -838,6 +859,8 @@ private:
bool ComputePDBOutputDir(const std::string& kind, const std::string& config,
std::string& out) const;
+ ManagedType CheckManagedType(std::string const& propval) const;
+
public:
const std::vector<const cmGeneratorTarget*>& GetLinkImplementationClosure(
const std::string& config) const;
diff --git a/Source/cmGlobVerificationManager.cxx b/Source/cmGlobVerificationManager.cxx
new file mode 100644
index 0000000..e23b6ea
--- /dev/null
+++ b/Source/cmGlobVerificationManager.cxx
@@ -0,0 +1,172 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmGlobVerificationManager.h"
+
+#include "cmsys/FStream.hxx"
+#include <sstream>
+
+#include "cmGeneratedFileStream.h"
+#include "cmListFileCache.h"
+#include "cmSystemTools.h"
+#include "cmVersion.h"
+#include "cmake.h"
+
+bool cmGlobVerificationManager::SaveVerificationScript(const std::string& path)
+{
+ if (this->Cache.empty()) {
+ return true;
+ }
+
+ std::string scriptFile = path;
+ scriptFile += cmake::GetCMakeFilesDirectory();
+ std::string stampFile = scriptFile;
+ cmSystemTools::MakeDirectory(scriptFile);
+ scriptFile += "/VerifyGlobs.cmake";
+ stampFile += "/cmake.verify_globs";
+ cmGeneratedFileStream verifyScriptFile(scriptFile.c_str());
+ verifyScriptFile.SetCopyIfDifferent(true);
+ if (!verifyScriptFile) {
+ cmSystemTools::Error("Unable to open verification script file for save. ",
+ scriptFile.c_str());
+ cmSystemTools::ReportLastSystemError("");
+ return false;
+ }
+
+ verifyScriptFile << std::boolalpha;
+ verifyScriptFile << "# CMAKE generated file: DO NOT EDIT!\n"
+ << "# Generated by CMake Version "
+ << cmVersion::GetMajorVersion() << "."
+ << cmVersion::GetMinorVersion() << "\n";
+
+ for (auto const& i : this->Cache) {
+ CacheEntryKey k = std::get<0>(i);
+ CacheEntryValue v = std::get<1>(i);
+
+ if (!v.Initialized) {
+ continue;
+ }
+
+ verifyScriptFile << "\n";
+
+ for (auto const& bt : v.Backtraces) {
+ verifyScriptFile << "# " << std::get<0>(bt);
+ std::get<1>(bt).PrintTitle(verifyScriptFile);
+ verifyScriptFile << "\n";
+ }
+
+ k.PrintGlobCommand(verifyScriptFile, "NEW_GLOB");
+ verifyScriptFile << "\n";
+
+ verifyScriptFile << "set(OLD_GLOB\n";
+ for (const std::string& file : v.Files) {
+ verifyScriptFile << " \"" << file << "\"\n";
+ }
+ verifyScriptFile << " )\n";
+
+ verifyScriptFile << "if(NOT \"${NEW_GLOB}\" STREQUAL \"${OLD_GLOB}\")\n"
+ << " message(\"-- GLOB mismatch!\")\n"
+ << " file(TOUCH_NOCREATE \"" << stampFile << "\")\n"
+ << "endif()\n";
+ }
+ verifyScriptFile.Close();
+
+ cmsys::ofstream verifyStampFile(stampFile.c_str());
+ if (!verifyStampFile) {
+ cmSystemTools::Error("Unable to open verification stamp file for write. ",
+ stampFile.c_str());
+ return false;
+ }
+ verifyStampFile << "# This file is generated by CMake for checking of the "
+ "VerifyGlobs.cmake file\n";
+ this->VerifyScript = scriptFile;
+ this->VerifyStamp = stampFile;
+ return true;
+}
+
+bool cmGlobVerificationManager::DoWriteVerifyTarget() const
+{
+ return !this->VerifyScript.empty() && !this->VerifyStamp.empty();
+}
+
+bool cmGlobVerificationManager::CacheEntryKey::operator<(
+ const CacheEntryKey& r) const
+{
+ if (this->Recurse < r.Recurse) {
+ return true;
+ }
+ if (this->Recurse > r.Recurse) {
+ return false;
+ }
+ if (this->ListDirectories < r.ListDirectories) {
+ return true;
+ }
+ if (this->ListDirectories > r.ListDirectories) {
+ return false;
+ }
+ if (this->FollowSymlinks < r.FollowSymlinks) {
+ return true;
+ }
+ if (this->FollowSymlinks > r.FollowSymlinks) {
+ return false;
+ }
+ if (this->Relative < r.Relative) {
+ return true;
+ }
+ if (this->Relative > r.Relative) {
+ return false;
+ }
+ if (this->Expression < r.Expression) {
+ return true;
+ }
+ if (this->Expression > r.Expression) {
+ return false;
+ }
+ return false;
+}
+
+void cmGlobVerificationManager::CacheEntryKey::PrintGlobCommand(
+ std::ostream& out, const std::string& cmdVar)
+{
+ out << "file(GLOB" << (this->Recurse ? "_RECURSE " : " ");
+ out << cmdVar << " ";
+ if (this->Recurse && this->FollowSymlinks) {
+ out << "FOLLOW_SYMLINKS ";
+ }
+ out << "LIST_DIRECTORIES " << this->ListDirectories << " ";
+ if (!this->Relative.empty()) {
+ out << "RELATIVE \"" << this->Relative << "\" ";
+ }
+ out << "\"" << this->Expression << "\")";
+}
+
+void cmGlobVerificationManager::AddCacheEntry(
+ const bool recurse, const bool listDirectories, const bool followSymlinks,
+ const std::string& relative, const std::string& expression,
+ const std::vector<std::string>& files, const std::string& variable,
+ const cmListFileBacktrace& backtrace)
+{
+ CacheEntryKey key = CacheEntryKey(recurse, listDirectories, followSymlinks,
+ relative, expression);
+ CacheEntryValue& value = this->Cache[key];
+ if (!value.Initialized) {
+ value.Files = files;
+ value.Initialized = true;
+ value.Backtraces.emplace_back(variable, backtrace);
+ } else if (value.Initialized && value.Files != files) {
+ std::ostringstream message;
+ message << std::boolalpha;
+ message << "The glob expression\n";
+ key.PrintGlobCommand(message, variable);
+ backtrace.PrintTitle(message);
+ message << "\nwas already present in the glob cache but the directory\n"
+ "contents have changed during the configuration run.\n";
+ message << "Matching glob expressions:";
+ for (auto const& bt : value.Backtraces) {
+ message << "\n " << std::get<0>(bt);
+ std::get<1>(bt).PrintTitle(message);
+ }
+ cmSystemTools::Error(message.str().c_str());
+ } else {
+ value.Backtraces.emplace_back(variable, backtrace);
+ }
+}
diff --git a/Source/cmGlobVerificationManager.h b/Source/cmGlobVerificationManager.h
new file mode 100644
index 0000000..4508602
--- /dev/null
+++ b/Source/cmGlobVerificationManager.h
@@ -0,0 +1,89 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmGlobVerificationManager_h
+#define cmGlobVerificationManager_h
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include "cmListFileCache.h"
+
+#include <iosfwd>
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+/** \class cmGlobVerificationManager
+ * \brief Class for expressing build-time dependencies on glob expressions.
+ *
+ * Generates a CMake script which verifies glob outputs during prebuild.
+ *
+ */
+class cmGlobVerificationManager
+{
+public:
+ cmGlobVerificationManager() {}
+
+protected:
+ ///! Save verification script for given makefile.
+ ///! Saves to output <path>/<CMakeFilesDirectory>/VerifyGlobs.cmake
+ bool SaveVerificationScript(const std::string& path);
+
+ ///! Add an entry into the glob cache
+ void AddCacheEntry(bool recurse, bool listDirectories, bool followSymlinks,
+ const std::string& relative,
+ const std::string& expression,
+ const std::vector<std::string>& files,
+ const std::string& variable,
+ const cmListFileBacktrace& bt);
+
+ ///! Check targets should be written in generated build system.
+ bool DoWriteVerifyTarget() const;
+
+ ///! Get the paths to the generated script and stamp files
+ std::string const& GetVerifyScript() const { return this->VerifyScript; }
+ std::string const& GetVerifyStamp() const { return this->VerifyStamp; }
+
+private:
+ struct CacheEntryKey
+ {
+ const bool Recurse;
+ const bool ListDirectories;
+ const bool FollowSymlinks;
+ const std::string Relative;
+ const std::string Expression;
+ CacheEntryKey(const bool rec, const bool l, const bool s,
+ const std::string& rel, const std::string& e)
+ : Recurse(rec)
+ , ListDirectories(l)
+ , FollowSymlinks(s)
+ , Relative(rel)
+ , Expression(e)
+ {
+ }
+ bool operator<(const CacheEntryKey& r) const;
+ void PrintGlobCommand(std::ostream& out, const std::string& cmdVar);
+ };
+
+ struct CacheEntryValue
+ {
+ bool Initialized;
+ std::vector<std::string> Files;
+ std::vector<std::pair<std::string, cmListFileBacktrace>> Backtraces;
+ CacheEntryValue()
+ : Initialized(false)
+ {
+ }
+ };
+
+ typedef std::map<CacheEntryKey, CacheEntryValue> CacheEntryMap;
+ CacheEntryMap Cache;
+ std::string VerifyScript;
+ std::string VerifyStamp;
+
+ // Only cmState should be able to add cache values.
+ // cmGlobVerificationManager should never be used directly.
+ friend class cmState; // allow access to add cache values
+};
+
+#endif
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 55a403e..d562df7 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -475,6 +475,7 @@ cmGlobalNinjaGenerator::cmGlobalNinjaGenerator(cmake* cm)
, PolicyCMP0058(cmPolicies::WARN)
, NinjaSupportsConsolePool(false)
, NinjaSupportsImplicitOuts(false)
+ , NinjaSupportsManifestRestat(false)
, NinjaSupportsDyndeps(0)
{
#ifdef _WIN32
@@ -597,6 +598,9 @@ void cmGlobalNinjaGenerator::CheckNinjaFeatures()
this->NinjaSupportsImplicitOuts = !cmSystemTools::VersionCompare(
cmSystemTools::OP_LESS, this->NinjaVersion.c_str(),
this->RequiredNinjaVersionForImplicitOuts().c_str());
+ this->NinjaSupportsManifestRestat = !cmSystemTools::VersionCompare(
+ cmSystemTools::OP_LESS, this->NinjaVersion.c_str(),
+ RequiredNinjaVersionForManifestRestat().c_str());
{
// Our ninja branch adds ".dyndep-#" to its version number,
// where '#' is a feature-specific version number. Extract it.
@@ -1361,6 +1365,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
/*generator=*/true);
cmNinjaDeps implicitDeps;
+ cmNinjaDeps explicitDeps;
for (cmLocalGenerator* localGen : this->LocalGenerators) {
std::vector<std::string> const& lf =
localGen->GetMakefile()->GetListFiles();
@@ -1370,10 +1375,6 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
}
implicitDeps.push_back(this->CMakeCacheFile);
- std::sort(implicitDeps.begin(), implicitDeps.end());
- implicitDeps.erase(std::unique(implicitDeps.begin(), implicitDeps.end()),
- implicitDeps.end());
-
cmNinjaVars variables;
// Use 'console' pool to get non buffered output of the CMake re-run call
// Available since Ninja 1.5
@@ -1381,12 +1382,71 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
variables["pool"] = "console";
}
+ cmake* cm = this->GetCMakeInstance();
+ if (this->SupportsManifestRestat() && cm->DoWriteGlobVerifyTarget()) {
+ std::ostringstream verify_cmd;
+ verify_cmd << lg->ConvertToOutputFormat(cmSystemTools::GetCMakeCommand(),
+ cmOutputConverter::SHELL)
+ << " -P "
+ << lg->ConvertToOutputFormat(cm->GetGlobVerifyScript(),
+ cmOutputConverter::SHELL);
+
+ WriteRule(*this->RulesFileStream, "VERIFY_GLOBS", verify_cmd.str(),
+ "Re-checking globbed directories...",
+ "Rule for re-checking globbed directories.",
+ /*depfile=*/"",
+ /*deptype=*/"",
+ /*rspfile=*/"",
+ /*rspcontent*/ "",
+ /*restat=*/"",
+ /*generator=*/true);
+
+ std::string verifyForce = cm->GetGlobVerifyScript() + "_force";
+ cmNinjaDeps verifyForceDeps(1, this->NinjaOutputPath(verifyForce));
+
+ this->WritePhonyBuild(os, "Phony target to force glob verification run.",
+ verifyForceDeps, cmNinjaDeps());
+
+ variables["restat"] = "1";
+ std::string const verifyScriptFile =
+ this->NinjaOutputPath(cm->GetGlobVerifyScript());
+ std::string const verifyStampFile =
+ this->NinjaOutputPath(cm->GetGlobVerifyStamp());
+ this->WriteBuild(os,
+ "Re-run CMake to check if globbed directories changed.",
+ "VERIFY_GLOBS",
+ /*outputs=*/cmNinjaDeps(1, verifyStampFile),
+ /*implicitOuts=*/cmNinjaDeps(),
+ /*explicitDeps=*/cmNinjaDeps(),
+ /*implicitDeps=*/verifyForceDeps,
+ /*orderOnlyDeps=*/cmNinjaDeps(), variables);
+
+ variables.erase("restat");
+ implicitDeps.push_back(verifyScriptFile);
+ explicitDeps.push_back(verifyStampFile);
+ } else if (!this->SupportsManifestRestat() &&
+ cm->DoWriteGlobVerifyTarget()) {
+ std::ostringstream msg;
+ msg << "The detected version of Ninja:\n"
+ << " " << this->NinjaVersion << "\n"
+ << "is less than the version of Ninja required by CMake for adding "
+ "restat dependencies to the build.ninja manifest regeneration "
+ "target:\n"
+ << " " << this->RequiredNinjaVersionForManifestRestat() << "\n";
+ msg << "Any pre-check scripts, such as those generated for file(GLOB "
+ "CONFIGURE_DEPENDS), will not be run by Ninja.";
+ this->GetCMakeInstance()->IssueMessage(cmake::AUTHOR_WARNING, msg.str());
+ }
+
+ std::sort(implicitDeps.begin(), implicitDeps.end());
+ implicitDeps.erase(std::unique(implicitDeps.begin(), implicitDeps.end()),
+ implicitDeps.end());
+
std::string const ninjaBuildFile = this->NinjaOutputPath(NINJA_BUILD_FILE);
this->WriteBuild(os, "Re-run CMake if any of its inputs changed.",
"RERUN_CMAKE",
/*outputs=*/cmNinjaDeps(1, ninjaBuildFile),
- /*implicitOuts=*/cmNinjaDeps(),
- /*explicitDeps=*/cmNinjaDeps(), implicitDeps,
+ /*implicitOuts=*/cmNinjaDeps(), explicitDeps, implicitDeps,
/*orderOnlyDeps=*/cmNinjaDeps(), variables);
cmNinjaDeps missingInputs;
@@ -1419,6 +1479,11 @@ bool cmGlobalNinjaGenerator::SupportsImplicitOuts() const
return this->NinjaSupportsImplicitOuts;
}
+bool cmGlobalNinjaGenerator::SupportsManifestRestat() const
+{
+ return this->NinjaSupportsManifestRestat;
+}
+
void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
{
WriteRule(*this->RulesFileStream, "CLEAN", ninjaCmd() + " -t clean",
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index 7f80d08..a779919 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -346,8 +346,10 @@ public:
static std::string RequiredNinjaVersion() { return "1.3"; }
static std::string RequiredNinjaVersionForConsolePool() { return "1.5"; }
static std::string RequiredNinjaVersionForImplicitOuts() { return "1.7"; }
+ static std::string RequiredNinjaVersionForManifestRestat() { return "1.8"; }
bool SupportsConsolePool() const;
bool SupportsImplicitOuts() const;
+ bool SupportsManifestRestat() const;
std::string NinjaOutputPath(std::string const& path) const;
bool HasOutputPathPrefix() const { return !this->OutputPathPrefix.empty(); }
@@ -460,6 +462,7 @@ private:
std::string NinjaVersion;
bool NinjaSupportsConsolePool;
bool NinjaSupportsImplicitOuts;
+ bool NinjaSupportsManifestRestat;
unsigned long NinjaSupportsDyndeps;
private:
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index c92df55..a005885 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -301,6 +301,13 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
lfiles.insert(lfiles.end(), lg->GetMakefile()->GetListFiles().begin(),
lg->GetMakefile()->GetListFiles().end());
}
+
+ cmake* cm = this->GetCMakeInstance();
+ if (cm->DoWriteGlobVerifyTarget()) {
+ lfiles.push_back(cm->GetGlobVerifyScript());
+ lfiles.push_back(cm->GetGlobVerifyStamp());
+ }
+
// Sort the list and remove duplicates.
std::sort(lfiles.begin(), lfiles.end(), std::less<std::string>());
#if !defined(__VMS) // The Compaq STL on VMS crashes, so accept duplicates.
diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx
index ad72f5e..117d051 100644
--- a/Source/cmGlobalVisualStudio8Generator.cxx
+++ b/Source/cmGlobalVisualStudio8Generator.cxx
@@ -87,18 +87,18 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
{
// Add a special target on which all other targets depend that
// checks the build system and optionally re-runs CMake.
- const char* no_working_directory = 0;
+ // Skip the target if no regeneration is to be done.
+ if (this->GlobalSettingIsOn("CMAKE_SUPPRESS_REGENERATION")) {
+ return false;
+ }
+
+ const char* no_working_directory = nullptr;
std::vector<std::string> no_depends;
std::vector<cmLocalGenerator*> const& generators = this->LocalGenerators;
cmLocalVisualStudio7Generator* lg =
static_cast<cmLocalVisualStudio7Generator*>(generators[0]);
cmMakefile* mf = lg->GetMakefile();
- // Skip the target if no regeneration is to be done.
- if (this->GlobalSettingIsOn("CMAKE_SUPPRESS_REGENERATION")) {
- return false;
- }
-
cmCustomCommandLines noCommandLines;
cmTarget* tgt = mf->AddUtilityCommand(
CMAKE_CHECK_BUILD_SYSTEM_TARGET, cmMakefile::TargetOrigin::Generator,
@@ -144,6 +144,30 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
listFiles.insert(listFiles.end(), lmf->GetListFiles().begin(),
lmf->GetListFiles().end());
}
+
+ // Add a custom prebuild target to run the VerifyGlobs script.
+ cmake* cm = this->GetCMakeInstance();
+ if (cm->DoWriteGlobVerifyTarget()) {
+ cmCustomCommandLine verifyCommandLine;
+ verifyCommandLine.push_back(cmSystemTools::GetCMakeCommand());
+ verifyCommandLine.push_back("-P");
+ verifyCommandLine.push_back(cm->GetGlobVerifyScript());
+ cmCustomCommandLines verifyCommandLines;
+ verifyCommandLines.push_back(verifyCommandLine);
+ std::vector<std::string> byproducts;
+ byproducts.push_back(cm->GetGlobVerifyStamp());
+
+ mf->AddCustomCommandToTarget(CMAKE_CHECK_BUILD_SYSTEM_TARGET, byproducts,
+ no_depends, verifyCommandLines,
+ cmTarget::PRE_BUILD, "Checking File Globs",
+ no_working_directory, false);
+
+ // Ensure ZERO_CHECK always runs in Visual Studio using MSBuild,
+ // otherwise the prebuild command will not be run.
+ tgt->SetProperty("VS_GLOBAL_DisableFastUpToDateCheck", "true");
+ listFiles.push_back(cm->GetGlobVerifyStamp());
+ }
+
// Sort the list of input files and remove duplicates.
std::sort(listFiles.begin(), listFiles.end(), std::less<std::string>());
std::vector<std::string>::iterator new_end =
@@ -151,8 +175,6 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
listFiles.erase(new_end, listFiles.end());
// Create a rule to re-run CMake.
- std::string stampName = cmake::GetCMakeFilesDirectoryPostSlash();
- stampName += "generate.stamp";
cmCustomCommandLine commandLine;
commandLine.push_back(cmSystemTools::GetCMakeCommand());
std::string argH = "-H";
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index f8597af..4481bdc 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -537,6 +537,12 @@ void cmGlobalXCodeGenerator::CreateReRunCMakeFile(
std::vector<std::string>::iterator new_end =
std::unique(lfiles.begin(), lfiles.end());
lfiles.erase(new_end, lfiles.end());
+
+ cmake* cm = this->GetCMakeInstance();
+ if (cm->DoWriteGlobVerifyTarget()) {
+ lfiles.emplace_back(cm->GetGlobVerifyStamp());
+ }
+
this->CurrentReRunCMakeMakefile = root->GetCurrentBinaryDirectory();
this->CurrentReRunCMakeMakefile += "/CMakeScripts";
cmSystemTools::MakeDirectory(this->CurrentReRunCMakeMakefile.c_str());
@@ -555,14 +561,28 @@ void cmGlobalXCodeGenerator::CreateReRunCMakeFile(
makefileStream << "TARGETS += $(subst $(space),$(spaceplus),$(wildcard "
<< this->ConvertToRelativeForMake(lfile) << "))\n";
}
+ makefileStream << "\n";
std::string checkCache = root->GetBinaryDirectory();
checkCache += "/";
checkCache += cmake::GetCMakeFilesDirectoryPostSlash();
checkCache += "cmake.check_cache";
- makefileStream << "\n"
- << this->ConvertToRelativeForMake(checkCache)
+ if (cm->DoWriteGlobVerifyTarget()) {
+ makefileStream << ".NOTPARALLEL:\n\n";
+ makefileStream << ".PHONY: all VERIFY_GLOBS\n\n";
+ makefileStream << "all: VERIFY_GLOBS "
+ << this->ConvertToRelativeForMake(checkCache) << "\n\n";
+ makefileStream << "VERIFY_GLOBS:\n";
+ makefileStream << "\t"
+ << this->ConvertToRelativeForMake(
+ cmSystemTools::GetCMakeCommand())
+ << " -P "
+ << this->ConvertToRelativeForMake(cm->GetGlobVerifyScript())
+ << "\n\n";
+ }
+
+ makefileStream << this->ConvertToRelativeForMake(checkCache)
<< ": $(TARGETS)\n";
makefileStream << "\t"
<< this->ConvertToRelativeForMake(
@@ -821,6 +841,19 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
return buildFile;
}
+void cmGlobalXCodeGenerator::AddXCodeProjBuildRule(
+ cmGeneratorTarget* target, std::vector<cmSourceFile*>& sources) const
+{
+ std::string listfile =
+ target->GetLocalGenerator()->GetCurrentSourceDirectory();
+ listfile += "/CMakeLists.txt";
+ cmSourceFile* srcCMakeLists = target->Makefile->GetOrCreateSource(listfile);
+ if (std::find(sources.begin(), sources.end(), srcCMakeLists) ==
+ sources.end()) {
+ sources.push_back(srcCMakeLists);
+ }
+}
+
std::string GetSourcecodeValueFromFileExtension(const std::string& _ext,
const std::string& lang,
bool& keepLastKnownFileType)
@@ -1043,10 +1076,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeTargets(
}
// Add CMakeLists.txt file for user convenience.
- std::string listfile =
- gtgt->GetLocalGenerator()->GetCurrentSourceDirectory();
- listfile += "/CMakeLists.txt";
- classes.push_back(gtgt->Makefile->GetOrCreateSource(listfile));
+ this->AddXCodeProjBuildRule(gtgt, classes);
std::sort(classes.begin(), classes.end(), cmSourceFilePathCompare());
@@ -2339,10 +2369,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateUtilityTarget(
}
// Add CMakeLists.txt file for user convenience.
- std::string listfile =
- gtgt->GetLocalGenerator()->GetCurrentSourceDirectory();
- listfile += "/CMakeLists.txt";
- sources.push_back(gtgt->Makefile->GetOrCreateSource(listfile));
+ this->AddXCodeProjBuildRule(gtgt, sources);
for (auto sourceFile : sources) {
if (!sourceFile->GetPropertyAsBool("GENERATED")) {
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index b45887e..7c51177 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -198,6 +198,8 @@ private:
cmGeneratorTarget* target);
cmXCodeObject* CreateXCodeSourceFile(cmLocalGenerator* gen, cmSourceFile* sf,
cmGeneratorTarget* gtgt);
+ void AddXCodeProjBuildRule(cmGeneratorTarget* target,
+ std::vector<cmSourceFile*>& sources) const;
bool CreateXCodeTargets(cmLocalGenerator* gen, std::vector<cmXCodeObject*>&);
bool IsHeaderFile(cmSourceFile*);
void AddDependTarget(cmXCodeObject* target, cmXCodeObject* dependTarget);
diff --git a/Source/cmInstallFilesCommand.h b/Source/cmInstallFilesCommand.h
index 19f2559..a52f45e 100644
--- a/Source/cmInstallFilesCommand.h
+++ b/Source/cmInstallFilesCommand.h
@@ -48,7 +48,7 @@ protected:
private:
std::vector<std::string> FinalArgs;
- bool IsFilesForm;
+ bool IsFilesForm = false;
std::string Destination;
std::vector<std::string> Files;
};
diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
index a9b4908..e0afa2d 100644
--- a/Source/cmInstallTargetGenerator.cxx
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -135,7 +135,7 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(
filesFrom.push_back(std::move(from1));
filesTo.push_back(std::move(to1));
std::string targetNameImportLib;
- if (this->Target->GetImplibGNUtoMS(targetNameImport,
+ if (this->Target->GetImplibGNUtoMS(config, targetNameImport,
targetNameImportLib)) {
filesFrom.push_back(fromDirConfig + targetNameImportLib);
filesTo.push_back(toDir + targetNameImportLib);
@@ -201,7 +201,7 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(
filesFrom.push_back(std::move(from1));
filesTo.push_back(std::move(to1));
std::string targetNameImportLib;
- if (this->Target->GetImplibGNUtoMS(targetNameImport,
+ if (this->Target->GetImplibGNUtoMS(config, targetNameImport,
targetNameImportLib)) {
filesFrom.push_back(fromDirConfig + targetNameImportLib);
filesTo.push_back(toDir + targetNameImportLib);
@@ -398,7 +398,7 @@ std::string cmInstallTargetGenerator::GetInstallFilename(
targetNamePDB, config);
if (nameType == NameImplib) {
// Use the import library name.
- if (!target->GetImplibGNUtoMS(targetNameImport, fname,
+ if (!target->GetImplibGNUtoMS(config, targetNameImport, fname,
"${CMAKE_IMPORT_LIBRARY_SUFFIX}")) {
fname = targetNameImport;
}
@@ -419,7 +419,7 @@ std::string cmInstallTargetGenerator::GetInstallFilename(
targetNameImport, targetNamePDB, config);
if (nameType == NameImplib) {
// Use the import library name.
- if (!target->GetImplibGNUtoMS(targetNameImport, fname,
+ if (!target->GetImplibGNUtoMS(config, targetNameImport, fname,
"${CMAKE_IMPORT_LIBRARY_SUFFIX}")) {
fname = targetNameImport;
}
diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx
index 3beeae3..557fa41 100644
--- a/Source/cmLinkLineDeviceComputer.cxx
+++ b/Source/cmLinkLineDeviceComputer.cxx
@@ -3,9 +3,9 @@
#include "cmLinkLineDeviceComputer.h"
-#include <set>
#include <sstream>
+#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalNinjaGenerator.h"
@@ -32,38 +32,32 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries(
ItemVector const& items = cli.GetItems();
std::string config = cli.GetConfig();
for (auto const& item : items) {
- if (!item.Target) {
- continue;
- }
-
- bool skippable = false;
- switch (item.Target->GetType()) {
- case cmStateEnums::SHARED_LIBRARY:
- case cmStateEnums::MODULE_LIBRARY:
- case cmStateEnums::INTERFACE_LIBRARY:
- skippable = true;
- break;
- case cmStateEnums::STATIC_LIBRARY:
- // If a static library is resolving its device linking, it should
- // be removed for other device linking
- skippable =
- item.Target->GetPropertyAsBool("CUDA_RESOLVE_DEVICE_SYMBOLS");
- break;
- default:
- break;
- }
-
- if (skippable) {
- continue;
- }
-
- std::set<std::string> langs;
- item.Target->GetLanguages(langs, config);
- if (langs.count("CUDA") == 0) {
- continue;
+ if (item.Target) {
+ bool skip = false;
+ switch (item.Target->GetType()) {
+ case cmStateEnums::MODULE_LIBRARY:
+ case cmStateEnums::INTERFACE_LIBRARY:
+ skip = true;
+ break;
+ case cmStateEnums::STATIC_LIBRARY:
+ skip = item.Target->GetPropertyAsBool("CUDA_RESOLVE_DEVICE_SYMBOLS");
+ break;
+ default:
+ break;
+ }
+ if (skip) {
+ continue;
+ }
}
if (item.IsPath) {
+ // nvcc understands absolute paths to libraries ending in '.a' should
+ // be passed to nvlink. Other extensions like '.so' or '.dylib' are
+ // rejected by the nvcc front-end even though nvlink knows to ignore
+ // them. Bypass the front-end via '-Xnvlink'.
+ if (!cmHasLiteralSuffix(item.Value, ".a")) {
+ fout << "-Xnvlink ";
+ }
fout << this->ConvertToOutputFormat(
this->ConvertToLinkReference(item.Value));
} else {
diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx
index 821e6d1..31bc1c0 100644
--- a/Source/cmListCommand.cxx
+++ b/Source/cmListCommand.cxx
@@ -5,14 +5,19 @@
#include "cmsys/RegularExpression.hxx"
#include <algorithm>
#include <assert.h>
+#include <functional>
#include <iterator>
+#include <set>
#include <sstream>
+#include <stdexcept>
#include <stdio.h>
#include <stdlib.h> // required for atoi
#include "cmAlgorithms.h"
+#include "cmGeneratorExpression.h"
#include "cmMakefile.h"
#include "cmPolicies.h"
+#include "cmStringReplaceHelper.h"
#include "cmSystemTools.h"
#include "cmake.h"
@@ -54,6 +59,9 @@ bool cmListCommand::InitialPass(std::vector<std::string> const& args,
if (subCommand == "REMOVE_DUPLICATES") {
return this->HandleRemoveDuplicatesCommand(args);
}
+ if (subCommand == "TRANSFORM") {
+ return this->HandleTransformCommand(args);
+ }
if (subCommand == "SORT") {
return this->HandleSortCommand(args);
}
@@ -407,6 +415,554 @@ bool cmListCommand::HandleRemoveDuplicatesCommand(
return true;
}
+// Helpers for list(TRANSFORM <list> ...)
+namespace {
+using transform_type = std::function<std::string(const std::string&)>;
+
+class transform_error : public std::runtime_error
+{
+public:
+ transform_error(const std::string& error)
+ : std::runtime_error(error)
+ {
+ }
+};
+
+class TransformSelector
+{
+public:
+ virtual ~TransformSelector() {}
+
+ std::string Tag;
+
+ virtual bool Validate(std::size_t count = 0) = 0;
+
+ virtual bool InSelection(const std::string&) = 0;
+
+ virtual void Transform(std::vector<std::string>& list,
+ const transform_type& transform)
+ {
+ std::transform(list.begin(), list.end(), list.begin(), transform);
+ }
+
+protected:
+ TransformSelector(std::string&& tag)
+ : Tag(std::move(tag))
+ {
+ }
+};
+class TransformNoSelector : public TransformSelector
+{
+public:
+ TransformNoSelector()
+ : TransformSelector("NO SELECTOR")
+ {
+ }
+
+ bool Validate(std::size_t) override { return true; }
+
+ bool InSelection(const std::string&) override { return true; }
+};
+class TransformSelectorRegex : public TransformSelector
+{
+public:
+ TransformSelectorRegex(const std::string& regex)
+ : TransformSelector("REGEX")
+ , Regex(regex)
+ {
+ }
+
+ bool Validate(std::size_t) override { return this->Regex.is_valid(); }
+
+ bool InSelection(const std::string& value) override
+ {
+ return this->Regex.find(value);
+ }
+
+ cmsys::RegularExpression Regex;
+};
+class TransformSelectorIndexes : public TransformSelector
+{
+public:
+ std::vector<int> Indexes;
+
+ bool InSelection(const std::string&) override { return true; }
+
+ void Transform(std::vector<std::string>& list,
+ const transform_type& transform) override
+ {
+ this->Validate(list.size());
+
+ for (auto index : this->Indexes) {
+ list[index] = transform(list[index]);
+ }
+ }
+
+protected:
+ TransformSelectorIndexes(std::string&& tag)
+ : TransformSelector(std::move(tag))
+ {
+ }
+ TransformSelectorIndexes(std::string&& tag, std::vector<int>&& indexes)
+ : TransformSelector(std::move(tag))
+ , Indexes(indexes)
+ {
+ }
+
+ int NormalizeIndex(int index, std::size_t count)
+ {
+ if (index < 0) {
+ index = static_cast<int>(count) + index;
+ }
+ if (index < 0 || count <= static_cast<std::size_t>(index)) {
+ std::ostringstream str;
+ str << "sub-command TRANSFORM, selector " << this->Tag
+ << ", index: " << index << " out of range (-" << count << ", "
+ << count - 1 << ").";
+ throw transform_error(str.str());
+ }
+ return index;
+ }
+};
+class TransformSelectorAt : public TransformSelectorIndexes
+{
+public:
+ TransformSelectorAt(std::vector<int>&& indexes)
+ : TransformSelectorIndexes("AT", std::move(indexes))
+ {
+ }
+
+ bool Validate(std::size_t count) override
+ {
+ decltype(Indexes) indexes;
+
+ for (auto index : Indexes) {
+ indexes.push_back(this->NormalizeIndex(index, count));
+ }
+ this->Indexes = std::move(indexes);
+
+ return true;
+ }
+};
+class TransformSelectorFor : public TransformSelectorIndexes
+{
+public:
+ TransformSelectorFor(int start, int stop, int step)
+ : TransformSelectorIndexes("FOR")
+ , Start(start)
+ , Stop(stop)
+ , Step(step)
+ {
+ }
+
+ bool Validate(std::size_t count) override
+ {
+ this->Start = this->NormalizeIndex(this->Start, count);
+ this->Stop = this->NormalizeIndex(this->Stop, count);
+
+ // compute indexes
+ auto size = (this->Stop - this->Start + 1) / this->Step;
+ if ((this->Stop - this->Start + 1) % this->Step != 0) {
+ size += 1;
+ }
+
+ this->Indexes.resize(size);
+ auto start = this->Start, step = this->Step;
+ std::generate(this->Indexes.begin(), this->Indexes.end(),
+ [&start, step]() -> int {
+ auto r = start;
+ start += step;
+ return r;
+ });
+
+ return true;
+ }
+
+private:
+ int Start, Stop, Step;
+};
+
+class TransformAction
+{
+public:
+ virtual ~TransformAction() {}
+
+ virtual std::string Transform(const std::string& input) = 0;
+};
+class TransformReplace : public TransformAction
+{
+public:
+ TransformReplace(const std::vector<std::string>& arguments,
+ cmMakefile* makefile)
+ : ReplaceHelper(arguments[0], arguments[1], makefile)
+ {
+ makefile->ClearMatches();
+
+ if (!this->ReplaceHelper.IsRegularExpressionValid()) {
+ std::ostringstream error;
+ error
+ << "sub-command TRANSFORM, action REPLACE: Failed to compile regex \""
+ << arguments[0] << "\".";
+ throw transform_error(error.str());
+ }
+ if (!this->ReplaceHelper.IsReplaceExpressionValid()) {
+ std::ostringstream error;
+ error << "sub-command TRANSFORM, action REPLACE: "
+ << this->ReplaceHelper.GetError() << ".";
+ throw transform_error(error.str());
+ }
+ }
+
+ std::string Transform(const std::string& input) override
+ {
+ // Scan through the input for all matches.
+ std::string output;
+
+ if (!this->ReplaceHelper.Replace(input, output)) {
+ std::ostringstream error;
+ error << "sub-command TRANSFORM, action REPLACE: "
+ << this->ReplaceHelper.GetError() << ".";
+ throw transform_error(error.str());
+ }
+
+ return output;
+ }
+
+private:
+ cmStringReplaceHelper ReplaceHelper;
+};
+}
+
+bool cmListCommand::HandleTransformCommand(
+ std::vector<std::string> const& args)
+{
+ if (args.size() < 3) {
+ this->SetError(
+ "sub-command TRANSFORM requires an action to be specified.");
+ return false;
+ }
+
+ // Structure collecting all elements of the command
+ struct Command
+ {
+ Command(const std::string& listName)
+ : ListName(listName)
+ , OutputName(listName)
+ {
+ }
+
+ std::string Name;
+ std::string ListName;
+ std::vector<std::string> Arguments;
+ std::unique_ptr<TransformAction> Action;
+ std::unique_ptr<TransformSelector> Selector;
+ std::string OutputName;
+ } command(args[1]);
+
+ // Descriptor of action
+ // Arity: number of arguments required for the action
+ // Transform: lambda function implementing the action
+ struct ActionDescriptor
+ {
+ ActionDescriptor(const std::string& name)
+ : Name(name)
+ {
+ }
+ ActionDescriptor(const std::string& name, int arity,
+ const transform_type& transform)
+ : Name(name)
+ , Arity(arity)
+ , Transform(transform)
+ {
+ }
+
+ operator const std::string&() const { return Name; }
+
+ std::string Name;
+ int Arity = 0;
+ transform_type Transform;
+ };
+
+ // Build a set of supported actions.
+ std::set<ActionDescriptor,
+ std::function<bool(const std::string&, const std::string&)>>
+ descriptors(
+ [](const std::string& x, const std::string& y) { return x < y; });
+ descriptors = { { "APPEND", 1,
+ [&command](const std::string& s) -> std::string {
+ if (command.Selector->InSelection(s)) {
+ return s + command.Arguments[0];
+ }
+
+ return s;
+ } },
+ { "PREPEND", 1,
+ [&command](const std::string& s) -> std::string {
+ if (command.Selector->InSelection(s)) {
+ return command.Arguments[0] + s;
+ }
+
+ return s;
+ } },
+ { "TOUPPER", 0,
+ [&command](const std::string& s) -> std::string {
+ if (command.Selector->InSelection(s)) {
+ return cmSystemTools::UpperCase(s);
+ }
+
+ return s;
+ } },
+ { "TOLOWER", 0,
+ [&command](const std::string& s) -> std::string {
+ if (command.Selector->InSelection(s)) {
+ return cmSystemTools::LowerCase(s);
+ }
+
+ return s;
+ } },
+ { "STRIP", 0,
+ [&command](const std::string& s) -> std::string {
+ if (command.Selector->InSelection(s)) {
+ return cmSystemTools::TrimWhitespace(s);
+ }
+
+ return s;
+ } },
+ { "GENEX_STRIP", 0,
+ [&command](const std::string& s) -> std::string {
+ if (command.Selector->InSelection(s)) {
+ return cmGeneratorExpression::Preprocess(
+ s,
+ cmGeneratorExpression::StripAllGeneratorExpressions);
+ }
+
+ return s;
+ } },
+ { "REPLACE", 2,
+ [&command](const std::string& s) -> std::string {
+ if (command.Selector->InSelection(s)) {
+ return command.Action->Transform(s);
+ }
+
+ return s;
+ } } };
+
+ using size_type = std::vector<std::string>::size_type;
+ size_type index = 2;
+
+ // Parse all possible function parameters
+ auto descriptor = descriptors.find(args[index]);
+
+ if (descriptor == descriptors.end()) {
+ std::ostringstream error;
+ error << " sub-command TRANSFORM, " << args[index] << " invalid action.";
+ this->SetError(error.str());
+ return false;
+ }
+
+ // Action arguments
+ index += 1;
+ if (args.size() < index + descriptor->Arity) {
+ std::ostringstream error;
+ error << "sub-command TRANSFORM, action " << descriptor->Name
+ << " expects " << descriptor->Arity << " argument(s).";
+ this->SetError(error.str());
+ return false;
+ }
+
+ command.Name = descriptor->Name;
+ index += descriptor->Arity;
+ if (descriptor->Arity > 0) {
+ command.Arguments =
+ std::vector<std::string>(args.begin() + 3, args.begin() + index);
+ }
+
+ if (command.Name == "REPLACE") {
+ try {
+ command.Action =
+ cm::make_unique<TransformReplace>(command.Arguments, this->Makefile);
+ } catch (const transform_error& e) {
+ this->SetError(e.what());
+ return false;
+ }
+ }
+
+ const std::string REGEX{ "REGEX" }, AT{ "AT" }, FOR{ "FOR" },
+ OUTPUT_VARIABLE{ "OUTPUT_VARIABLE" };
+
+ // handle optional arguments
+ while (args.size() > index) {
+ if ((args[index] == REGEX || args[index] == AT || args[index] == FOR) &&
+ command.Selector) {
+ std::ostringstream error;
+ error << "sub-command TRANSFORM, selector already specified ("
+ << command.Selector->Tag << ").";
+ this->SetError(error.str());
+ return false;
+ }
+
+ // REGEX selector
+ if (args[index] == REGEX) {
+ if (args.size() == ++index) {
+ this->SetError("sub-command TRANSFORM, selector REGEX expects "
+ "'regular expression' argument.");
+ return false;
+ }
+
+ command.Selector = cm::make_unique<TransformSelectorRegex>(args[index]);
+ if (!command.Selector->Validate()) {
+ std::ostringstream error;
+ error << "sub-command TRANSFORM, selector REGEX failed to compile "
+ "regex \"";
+ error << args[index] << "\".";
+ this->SetError(error.str());
+ return false;
+ }
+
+ index += 1;
+ continue;
+ }
+
+ // AT selector
+ if (args[index] == AT) {
+ // get all specified indexes
+ std::vector<int> indexes;
+ while (args.size() > ++index) {
+ std::size_t pos;
+ int value;
+
+ try {
+ value = std::stoi(args[index], &pos);
+ if (pos != args[index].length()) {
+ // this is not a number, stop processing
+ break;
+ }
+ indexes.push_back(value);
+ } catch (const std::invalid_argument&) {
+ // this is not a number, stop processing
+ break;
+ }
+ }
+
+ if (indexes.empty()) {
+ this->SetError(
+ "sub-command TRANSFORM, selector AT expects at least one "
+ "numeric value.");
+ return false;
+ }
+
+ command.Selector =
+ cm::make_unique<TransformSelectorAt>(std::move(indexes));
+
+ continue;
+ }
+
+ // FOR selector
+ if (args[index] == FOR) {
+ if (args.size() <= ++index + 1) {
+ this->SetError("sub-command TRANSFORM, selector FOR expects, at least,"
+ " two arguments.");
+ return false;
+ }
+
+ int start = 0, stop = 0, step = 1;
+ bool valid = true;
+ try {
+ std::size_t pos;
+
+ start = std::stoi(args[index], &pos);
+ if (pos != args[index].length()) {
+ // this is not a number
+ valid = false;
+ } else {
+ stop = std::stoi(args[++index], &pos);
+ if (pos != args[index].length()) {
+ // this is not a number
+ valid = false;
+ }
+ }
+ } catch (const std::invalid_argument&) {
+ // this is not numbers
+ valid = false;
+ }
+ if (!valid) {
+ this->SetError("sub-command TRANSFORM, selector FOR expects, "
+ "at least, two numeric values.");
+ return false;
+ }
+ // try to read a third numeric value for step
+ if (args.size() > ++index) {
+ try {
+ std::size_t pos;
+
+ step = std::stoi(args[index], &pos);
+ if (pos != args[index].length()) {
+ // this is not a number
+ step = 1;
+ } else {
+ index += 1;
+ }
+ } catch (const std::invalid_argument&) {
+ // this is not number, ignore exception
+ }
+ }
+
+ if (step < 0) {
+ this->SetError("sub-command TRANSFORM, selector FOR expects "
+ "non negative numeric value for <step>.");
+ }
+
+ command.Selector =
+ cm::make_unique<TransformSelectorFor>(start, stop, step);
+
+ continue;
+ }
+
+ // output variable
+ if (args[index] == OUTPUT_VARIABLE) {
+ if (args.size() == ++index) {
+ this->SetError("sub-command TRANSFORM, OUTPUT_VARIABLE "
+ "expects variable name argument.");
+ return false;
+ }
+
+ command.OutputName = args[index++];
+ continue;
+ }
+
+ std::ostringstream error;
+ error << "sub-command TRANSFORM, '"
+ << cmJoin(cmMakeRange(args).advance(index), " ")
+ << "': unexpected argument(s).";
+ this->SetError(error.str());
+ return false;
+ }
+
+ // expand the list variable
+ std::vector<std::string> varArgsExpanded;
+ if (!this->GetList(varArgsExpanded, command.ListName)) {
+ this->Makefile->AddDefinition(command.OutputName, "");
+ return true;
+ }
+
+ if (!command.Selector) {
+ // no selector specified, apply transformation to all elements
+ command.Selector = cm::make_unique<TransformNoSelector>();
+ }
+
+ try {
+ command.Selector->Transform(varArgsExpanded, descriptor->Transform);
+ } catch (const transform_error& e) {
+ this->SetError(e.what());
+ return false;
+ }
+
+ this->Makefile->AddDefinition(command.OutputName,
+ cmJoin(varArgsExpanded, ";").c_str());
+
+ return true;
+}
+
bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args)
{
assert(args.size() >= 2);
diff --git a/Source/cmListCommand.h b/Source/cmListCommand.h
index d69d8f9..76a9856 100644
--- a/Source/cmListCommand.h
+++ b/Source/cmListCommand.h
@@ -41,6 +41,7 @@ protected:
bool HandleRemoveAtCommand(std::vector<std::string> const& args);
bool HandleRemoveItemCommand(std::vector<std::string> const& args);
bool HandleRemoveDuplicatesCommand(std::vector<std::string> const& args);
+ bool HandleTransformCommand(std::vector<std::string> const& args);
bool HandleSortCommand(std::vector<std::string> const& args);
bool HandleSublistCommand(std::vector<std::string> const& args);
bool HandleReverseCommand(std::vector<std::string> const& args);
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index c1af92f..c714299 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -197,6 +197,16 @@ void cmLocalNinjaGenerator::WriteNinjaRequiredVersion(std::ostream& os)
this->GetGlobalNinjaGenerator()->RequiredNinjaVersionForConsolePool();
}
+ // The Ninja generator writes rules which require support for restat
+ // when rebuilding build.ninja manifest (>= 1.8)
+ if (this->GetGlobalNinjaGenerator()->SupportsManifestRestat() &&
+ this->GetCMakeInstance()->DoWriteGlobVerifyTarget() &&
+ !this->GetGlobalNinjaGenerator()->GlobalSettingIsOn(
+ "CMAKE_SUPPRESS_REGENERATION")) {
+ requiredVersion =
+ this->GetGlobalNinjaGenerator()->RequiredNinjaVersionForManifestRestat();
+ }
+
cmGlobalNinjaGenerator::WriteComment(
os, "Minimal version of Ninja required by this file");
os << "ninja_required_version = " << requiredVersion << std::endl
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index c9237a8..cf2a7b9 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -763,6 +763,14 @@ void cmLocalUnixMakefileGenerator3::WriteSpecialTargetsBottom(
if (!this->GlobalGenerator->GlobalSettingIsOn(
"CMAKE_SUPPRESS_REGENERATION")) {
// Build command to run CMake to check if anything needs regenerating.
+ std::vector<std::string> commands;
+ cmake* cm = this->GlobalGenerator->GetCMakeInstance();
+ if (cm->DoWriteGlobVerifyTarget()) {
+ std::string rescanRule = "$(CMAKE_COMMAND) -P ";
+ rescanRule += this->ConvertToOutputFormat(cm->GetGlobVerifyScript(),
+ cmOutputConverter::SHELL);
+ commands.push_back(rescanRule);
+ }
std::string cmakefileName = cmake::GetCMakeFilesDirectoryPostSlash();
cmakefileName += "Makefile.cmake";
std::string runRule =
@@ -773,7 +781,6 @@ void cmLocalUnixMakefileGenerator3::WriteSpecialTargetsBottom(
runRule += " 0";
std::vector<std::string> no_depends;
- std::vector<std::string> commands;
commands.push_back(std::move(runRule));
if (!this->IsRootMakefile()) {
this->CreateCDCommand(commands, this->GetBinaryDirectory(),
@@ -1666,6 +1673,13 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules(
// write the depend rule, really a recompute depends rule
depends.clear();
commands.clear();
+ cmake* cm = this->GlobalGenerator->GetCMakeInstance();
+ if (cm->DoWriteGlobVerifyTarget()) {
+ std::string rescanRule = "$(CMAKE_COMMAND) -P ";
+ rescanRule += this->ConvertToOutputFormat(cm->GetGlobVerifyScript(),
+ cmOutputConverter::SHELL);
+ commands.push_back(rescanRule);
+ }
std::string cmakefileName = cmake::GetCMakeFilesDirectoryPostSlash();
cmakefileName += "Makefile.cmake";
{
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 91ee09f..fcdcdc5 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -160,10 +160,21 @@ void cmLocalVisualStudio7Generator::WriteStampFiles()
depName += ".depend";
cmsys::ofstream depFile(depName.c_str());
depFile << "# CMake generation dependency list for this directory.\n";
- std::vector<std::string> const& listFiles = this->Makefile->GetListFiles();
- for (std::vector<std::string>::const_iterator lf = listFiles.begin();
- lf != listFiles.end(); ++lf) {
- depFile << *lf << std::endl;
+
+ std::vector<std::string> listFiles(this->Makefile->GetListFiles());
+ cmake* cm = this->GlobalGenerator->GetCMakeInstance();
+ if (cm->DoWriteGlobVerifyTarget()) {
+ listFiles.push_back(cm->GetGlobVerifyStamp());
+ }
+
+ // Sort the list of input files and remove duplicates.
+ std::sort(listFiles.begin(), listFiles.end(), std::less<std::string>());
+ std::vector<std::string>::iterator new_end =
+ std::unique(listFiles.begin(), listFiles.end());
+ listFiles.erase(new_end, listFiles.end());
+
+ for (const std::string& lf : listFiles) {
+ depFile << lf << "\n";
}
}
@@ -228,6 +239,18 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule()
return nullptr;
}
+ std::vector<std::string> listFiles = this->Makefile->GetListFiles();
+ cmake* cm = this->GlobalGenerator->GetCMakeInstance();
+ if (cm->DoWriteGlobVerifyTarget()) {
+ listFiles.push_back(cm->GetGlobVerifyStamp());
+ }
+
+ // Sort the list of input files and remove duplicates.
+ std::sort(listFiles.begin(), listFiles.end(), std::less<std::string>());
+ std::vector<std::string>::iterator new_end =
+ std::unique(listFiles.begin(), listFiles.end());
+ listFiles.erase(new_end, listFiles.end());
+
std::string stampName = this->GetCurrentBinaryDirectory();
stampName += "/";
stampName += cmake::GetCMakeFilesDirectoryPostSlash();
@@ -245,17 +268,14 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule()
commandLine.push_back(args);
commandLine.push_back("--check-stamp-file");
commandLine.push_back(stampName);
-
- std::vector<std::string> const& listFiles = this->Makefile->GetListFiles();
-
cmCustomCommandLines commandLines;
commandLines.push_back(commandLine);
const char* no_working_directory = 0;
std::string fullpathStampName =
cmSystemTools::CollapseFullPath(stampName.c_str());
this->Makefile->AddCustomCommandToOutput(
- fullpathStampName.c_str(), listFiles, makefileIn.c_str(), commandLines,
- comment.c_str(), no_working_directory, true, false);
+ fullpathStampName, listFiles, makefileIn, commandLines, comment.c_str(),
+ no_working_directory, true, false);
if (cmSourceFile* file = this->Makefile->GetSource(makefileIn.c_str())) {
// Finalize the source file path now since we're adding this after
// the generator validated all project-named sources.
@@ -1344,7 +1364,18 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
for (size_t ci = 0; ci < configs.size(); ++ci) {
acs.Configs.push_back(ci);
}
- sources.Sources.emplace_back(std::move(acs));
+ bool haveCMakeLists = false;
+ for (cmGeneratorTarget::AllConfigSource& si : sources.Sources) {
+ if (si.Source == sf) {
+ haveCMakeLists = true;
+ // Replace the explicit source reference with our generated one.
+ si = acs;
+ break;
+ }
+ }
+ if (!haveCMakeLists) {
+ sources.Sources.emplace_back(std::move(acs));
+ }
}
}
diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx
index 07943e3..6f4b930 100644
--- a/Source/cmMacroCommand.cxx
+++ b/Source/cmMacroCommand.cxx
@@ -93,7 +93,7 @@ bool cmMacroHelperCommand::InvokeInitialPass(
argVs.reserve(expandedArgs.size());
char argvName[60];
for (unsigned int j = 0; j < expandedArgs.size(); ++j) {
- sprintf(argvName, "${ARGV%i}", j);
+ sprintf(argvName, "${ARGV%u}", j);
argVs.push_back(argvName);
}
// Invoke all the functions that were collected in the block.
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 3ecd7eb..9aeeb5c 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -1836,12 +1836,10 @@ void cmMakefile::AddGlobalLinkInformation(cmTarget& target)
std::vector<std::string> linkDirs;
cmSystemTools::ExpandListArgument(linkDirsProp, linkDirs);
- for (std::string const& linkDir : linkDirs) {
- std::string newdir = linkDir;
- // remove trailing slashes
- if (*linkDir.rbegin() == '/') {
- newdir = linkDir.substr(0, linkDir.size() - 1);
- }
+ for (std::string& linkDir : linkDirs) {
+ // Sanitize the path the same way the link_directories command does
+ // in case projects set the LINK_DIRECTORIES property directly.
+ cmSystemTools::ConvertToUnixSlashes(linkDir);
target.AddLinkDirectory(linkDir);
}
}
@@ -2705,10 +2703,11 @@ cmake::MessageType cmMakefile::ExpandVariablesInStringNew(
if (this->GetCMakeInstance()->GetWarnUninitialized() &&
!this->VariableInitialized(lookup)) {
if (this->CheckSystemVars ||
- cmSystemTools::IsSubDirectory(filename,
- this->GetHomeDirectory()) ||
- cmSystemTools::IsSubDirectory(
- filename, this->GetHomeOutputDirectory())) {
+ (filename &&
+ (cmSystemTools::IsSubDirectory(filename,
+ this->GetHomeDirectory()) ||
+ cmSystemTools::IsSubDirectory(
+ filename, this->GetHomeOutputDirectory())))) {
std::ostringstream msg;
msg << "uninitialized variable \'" << lookup << "\'";
this->IssueMessage(cmake::AUTHOR_WARNING, msg.str());
@@ -3840,7 +3839,16 @@ void cmMakefile::RaiseScope(const std::string& var, const char* varDef)
std::ostringstream m;
m << "Cannot set \"" << var << "\": current scope has no parent.";
this->IssueMessage(cmake::AUTHOR_WARNING, m.str());
+ return;
+ }
+
+#ifdef CMAKE_BUILD_WITH_CMAKE
+ cmVariableWatch* vv = this->GetVariableWatch();
+ if (vv) {
+ vv->VariableAccessed(var, cmVariableWatch::VARIABLE_MODIFIED_ACCESS,
+ varDef, this);
}
+#endif
}
cmTarget* cmMakefile::AddImportedTarget(const std::string& name,
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 9bbc043..1e59f44 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -477,8 +477,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
this->LocalGenerator->GetCurrentBinaryDirectory(),
targetFullPathImport));
std::string implib;
- if (this->GeneratorTarget->GetImplibGNUtoMS(targetFullPathImport,
- implib)) {
+ if (this->GeneratorTarget->GetImplibGNUtoMS(
+ this->ConfigName, targetFullPathImport, implib)) {
exeCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), implib));
}
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index 9299ffe..27fae04 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -641,8 +641,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
this->LocalGenerator->GetCurrentBinaryDirectory(),
targetFullPathImport));
std::string implib;
- if (this->GeneratorTarget->GetImplibGNUtoMS(targetFullPathImport,
- implib)) {
+ if (this->GeneratorTarget->GetImplibGNUtoMS(
+ this->ConfigName, targetFullPathImport, implib)) {
libCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), implib));
}
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index abe5ff3..3998823 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -1402,7 +1402,7 @@ std::string cmMakefileTargetGenerator::GetLinkRule(
const std::string& linkRuleVar)
{
std::string linkRule = this->Makefile->GetRequiredDefinition(linkRuleVar);
- if (this->GeneratorTarget->HasImplibGNUtoMS()) {
+ if (this->GeneratorTarget->HasImplibGNUtoMS(this->ConfigName)) {
std::string ruleVar = "CMAKE_";
ruleVar += this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
ruleVar += "_GNUtoMS_RULE";
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index f1fb2d2..542bb0a 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -187,7 +187,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(bool useResponseFile)
std::string responseFlag;
if (!useResponseFile) {
vars.Objects = "$in";
- vars.LinkLibraries = "$LINK_LIBRARIES";
+ vars.LinkLibraries = "$LINK_PATH $LINK_LIBRARIES";
} else {
std::string cmakeVarLang = "CMAKE_";
cmakeVarLang += this->TargetLinkLanguage;
@@ -482,7 +482,7 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd()
const char* linkCmd = mf->GetDefinition(linkCmdVar);
if (linkCmd) {
std::string linkCmdStr = linkCmd;
- if (this->GetGeneratorTarget()->HasImplibGNUtoMS()) {
+ if (this->GetGeneratorTarget()->HasImplibGNUtoMS(this->ConfigName)) {
std::string ruleVar = "CMAKE_";
ruleVar += this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
ruleVar += "_GNUtoMS_RULE";
@@ -881,7 +881,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
targetOutputImplib, cmOutputConverter::SHELL);
vars["TARGET_IMPLIB"] = impLibPath;
EnsureParentDirectoryExists(impLibPath);
- if (genTarget.HasImportLibrary()) {
+ if (genTarget.HasImportLibrary(cfgName)) {
byproducts.push_back(targetOutputImplib);
}
}
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index fa7d95a..ddb1d54 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -445,72 +445,18 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
cmMakefile* mf = this->GetMakefile();
std::string flags = "$FLAGS";
- std::string rspfile;
- std::string rspcontent;
+ std::string responseFlag;
bool const lang_supports_response = !(lang == "RC" || lang == "CUDA");
if (lang_supports_response && this->ForceResponseFile()) {
std::string const responseFlagVar =
"CMAKE_" + lang + "_RESPONSE_FILE_FLAG";
- std::string responseFlag =
- this->Makefile->GetSafeDefinition(responseFlagVar);
+ responseFlag = this->Makefile->GetSafeDefinition(responseFlagVar);
if (responseFlag.empty()) {
responseFlag = "@";
}
- rspfile = "$RSP_FILE";
- responseFlag += rspfile;
- rspcontent = " $DEFINES $INCLUDES $FLAGS";
- flags = std::move(responseFlag);
- vars.Defines = "";
- vars.Includes = "";
- }
-
- // Tell ninja dependency format so all deps can be loaded into a database
- std::string deptype;
- std::string depfile;
- std::string cldeps;
- if (explicitPP) {
- // The explicit preprocessing step will handle dependency scanning.
- } else if (this->NeedDepTypeMSVC(lang)) {
- deptype = "msvc";
- depfile.clear();
- flags += " /showIncludes";
- } else if (mf->IsOn("CMAKE_NINJA_CMCLDEPS_" + lang)) {
- // For the MS resource compiler we need cmcldeps, but skip dependencies
- // for source-file try_compile cases because they are always fresh.
- if (!mf->GetIsSourceFileTryCompile()) {
- deptype = "gcc";
- depfile = "$DEP_FILE";
- const std::string cl = mf->GetDefinition("CMAKE_C_COMPILER")
- ? mf->GetSafeDefinition("CMAKE_C_COMPILER")
- : mf->GetSafeDefinition("CMAKE_CXX_COMPILER");
- cldeps = "\"";
- cldeps += cmSystemTools::GetCMClDepsCommand();
- cldeps += "\" " + lang + " " + vars.Source + " $DEP_FILE $out \"";
- cldeps += mf->GetSafeDefinition("CMAKE_CL_SHOWINCLUDES_PREFIX");
- cldeps += "\" \"" + cl + "\" ";
- }
- } else {
- deptype = "gcc";
- const char* langdeptype = mf->GetDefinition("CMAKE_NINJA_DEPTYPE_" + lang);
- if (langdeptype) {
- deptype = langdeptype;
- }
- depfile = "$DEP_FILE";
- const std::string flagsName = "CMAKE_DEPFILE_FLAGS_" + lang;
- std::string depfileFlags = mf->GetSafeDefinition(flagsName);
- if (!depfileFlags.empty()) {
- cmSystemTools::ReplaceString(depfileFlags, "<DEPFILE>", "$DEP_FILE");
- cmSystemTools::ReplaceString(depfileFlags, "<OBJECT>", "$out");
- cmSystemTools::ReplaceString(depfileFlags, "<CMAKE_C_COMPILER>",
- mf->GetDefinition("CMAKE_C_COMPILER"));
- flags += " " + depfileFlags;
- }
}
- vars.Flags = flags.c_str();
- vars.DependencyFile = depfile.c_str();
-
std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
this->GetLocalGenerator()->CreateRulePlaceholderExpander());
@@ -550,7 +496,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
vars.Source = "$in";
// Preprocessing and compilation use the same flags.
- ppVars.Flags = vars.Flags;
+ std::string ppFlags = flags;
// Move preprocessor definitions to the preprocessor rule.
ppVars.Defines = vars.Defines;
@@ -560,6 +506,20 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
// compilation rule still needs them for the INCLUDE directive.
ppVars.Includes = vars.Includes;
+ // If using a response file, move defines, includes, and flags into it.
+ std::string ppRspFile;
+ std::string ppRspContent;
+ if (!responseFlag.empty()) {
+ ppRspFile = "$RSP_FILE";
+ ppRspContent = std::string(" ") + ppVars.Defines + " " +
+ ppVars.Includes + " " + ppFlags;
+ ppFlags = responseFlag + ppRspFile;
+ ppVars.Defines = "";
+ ppVars.Includes = "";
+ }
+
+ ppVars.Flags = ppFlags.c_str();
+
// Rule for preprocessing source file.
std::vector<std::string> ppCmds;
cmSystemTools::ExpandListArgument(ppCmd, ppCmds);
@@ -588,13 +548,11 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
ppComment << "Rule for preprocessing " << lang << " files.";
std::ostringstream ppDesc;
ppDesc << "Building " << lang << " preprocessed $out";
- this->GetGlobalGenerator()->AddRule(this->LanguagePreprocessRule(lang),
- ppCmdLine, ppDesc.str(),
- ppComment.str(), ppDepfile, ppDeptype,
- /*rspfile*/ "",
- /*rspcontent*/ "",
- /*restat*/ "",
- /*generator*/ false);
+ this->GetGlobalGenerator()->AddRule(
+ this->LanguagePreprocessRule(lang), ppCmdLine, ppDesc.str(),
+ ppComment.str(), ppDepfile, ppDeptype, ppRspFile, ppRspContent,
+ /*restat*/ "",
+ /*generator*/ false);
}
if (needDyndep) {
@@ -631,6 +589,64 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
/*generator*/ false);
}
+ // If using a response file, move defines, includes, and flags into it.
+ std::string rspfile;
+ std::string rspcontent;
+ if (!responseFlag.empty()) {
+ rspfile = "$RSP_FILE";
+ rspcontent =
+ std::string(" ") + vars.Defines + " " + vars.Includes + " " + flags;
+ flags = responseFlag + rspfile;
+ vars.Defines = "";
+ vars.Includes = "";
+ }
+
+ // Tell ninja dependency format so all deps can be loaded into a database
+ std::string deptype;
+ std::string depfile;
+ std::string cldeps;
+ if (explicitPP) {
+ // The explicit preprocessing step will handle dependency scanning.
+ } else if (this->NeedDepTypeMSVC(lang)) {
+ deptype = "msvc";
+ depfile.clear();
+ flags += " /showIncludes";
+ } else if (mf->IsOn("CMAKE_NINJA_CMCLDEPS_" + lang)) {
+ // For the MS resource compiler we need cmcldeps, but skip dependencies
+ // for source-file try_compile cases because they are always fresh.
+ if (!mf->GetIsSourceFileTryCompile()) {
+ deptype = "gcc";
+ depfile = "$DEP_FILE";
+ const std::string cl = mf->GetDefinition("CMAKE_C_COMPILER")
+ ? mf->GetSafeDefinition("CMAKE_C_COMPILER")
+ : mf->GetSafeDefinition("CMAKE_CXX_COMPILER");
+ cldeps = "\"";
+ cldeps += cmSystemTools::GetCMClDepsCommand();
+ cldeps += "\" " + lang + " " + vars.Source + " $DEP_FILE $out \"";
+ cldeps += mf->GetSafeDefinition("CMAKE_CL_SHOWINCLUDES_PREFIX");
+ cldeps += "\" \"" + cl + "\" ";
+ }
+ } else {
+ deptype = "gcc";
+ const char* langdeptype = mf->GetDefinition("CMAKE_NINJA_DEPTYPE_" + lang);
+ if (langdeptype) {
+ deptype = langdeptype;
+ }
+ depfile = "$DEP_FILE";
+ const std::string flagsName = "CMAKE_DEPFILE_FLAGS_" + lang;
+ std::string depfileFlags = mf->GetSafeDefinition(flagsName);
+ if (!depfileFlags.empty()) {
+ cmSystemTools::ReplaceString(depfileFlags, "<DEPFILE>", "$DEP_FILE");
+ cmSystemTools::ReplaceString(depfileFlags, "<OBJECT>", "$out");
+ cmSystemTools::ReplaceString(depfileFlags, "<CMAKE_C_COMPILER>",
+ mf->GetDefinition("CMAKE_C_COMPILER"));
+ flags += " " + depfileFlags;
+ }
+ }
+
+ vars.Flags = flags.c_str();
+ vars.DependencyFile = depfile.c_str();
+
// Rule for compiling object file.
std::vector<std::string> compileCmds;
if (lang == "CUDA") {
@@ -865,6 +881,11 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
std::string const objectFileDir =
cmSystemTools::GetFilenamePath(objectFileName);
+ bool const lang_supports_response =
+ !(language == "RC" || language == "CUDA");
+ int const commandLineLengthLimit =
+ ((lang_supports_response && this->ForceResponseFile())) ? -1 : 0;
+
cmNinjaVars vars;
vars["FLAGS"] = this->ComputeFlagsForObject(source, language);
vars["DEFINES"] = this->ComputeDefines(source, language);
@@ -1012,9 +1033,12 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetGeneratorTarget(),
ppVars);
+ std::string const ppRspFile = ppFileName + ".rsp";
+
this->GetGlobalGenerator()->WriteBuild(
this->GetBuildFileStream(), ppComment, ppRule, ppOutputs, ppImplicitOuts,
- ppExplicitDeps, ppImplicitDeps, ppOrderOnlyDeps, ppVars);
+ ppExplicitDeps, ppImplicitDeps, ppOrderOnlyDeps, ppVars, ppRspFile,
+ commandLineLengthLimit);
}
if (needDyndep) {
std::string const dyndep = this->GetDyndepFilePath(language);
@@ -1034,10 +1058,6 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
this->SetMsvcTargetPdbVariable(vars);
- bool const lang_supports_response =
- !(language == "RC" || language == "CUDA");
- int const commandLineLengthLimit =
- ((lang_supports_response && this->ForceResponseFile())) ? -1 : 0;
std::string const rspfile = objectFileName + ".rsp";
this->GetGlobalGenerator()->WriteBuild(
diff --git a/Source/cmQtAutoGenerator.cxx b/Source/cmQtAutoGenerator.cxx
index 5c35d76..bf184d8 100644
--- a/Source/cmQtAutoGenerator.cxx
+++ b/Source/cmQtAutoGenerator.cxx
@@ -146,19 +146,93 @@ void cmQtAutoGenerator::Logger::ErrorCommand(
}
}
-std::string cmQtAutoGenerator::FileSystem::RealPath(
+std::string cmQtAutoGenerator::FileSystem::GetRealPath(
std::string const& filename)
{
std::lock_guard<std::mutex> lock(Mutex_);
return cmSystemTools::GetRealPath(filename);
}
+std::string cmQtAutoGenerator::FileSystem::CollapseCombinedPath(
+ std::string const& dir, std::string const& file)
+{
+ std::lock_guard<std::mutex> lock(Mutex_);
+ return cmSystemTools::CollapseCombinedPath(dir, file);
+}
+
+void cmQtAutoGenerator::FileSystem::SplitPath(
+ const std::string& p, std::vector<std::string>& components,
+ bool expand_home_dir)
+{
+ std::lock_guard<std::mutex> lock(Mutex_);
+ cmSystemTools::SplitPath(p, components, expand_home_dir);
+}
+
+std::string cmQtAutoGenerator::FileSystem::JoinPath(
+ const std::vector<std::string>& components)
+{
+ std::lock_guard<std::mutex> lock(Mutex_);
+ return cmSystemTools::JoinPath(components);
+}
+
+std::string cmQtAutoGenerator::FileSystem::JoinPath(
+ std::vector<std::string>::const_iterator first,
+ std::vector<std::string>::const_iterator last)
+{
+ std::lock_guard<std::mutex> lock(Mutex_);
+ return cmSystemTools::JoinPath(first, last);
+}
+
+std::string cmQtAutoGenerator::FileSystem::GetFilenameWithoutLastExtension(
+ const std::string& filename)
+{
+ std::lock_guard<std::mutex> lock(Mutex_);
+ return cmSystemTools::GetFilenameWithoutLastExtension(filename);
+}
+
+std::string cmQtAutoGenerator::FileSystem::SubDirPrefix(
+ std::string const& filename)
+{
+ std::lock_guard<std::mutex> lock(Mutex_);
+ return cmQtAutoGen::SubDirPrefix(filename);
+}
+
+void cmQtAutoGenerator::FileSystem::setupFilePathChecksum(
+ std::string const& currentSrcDir, std::string const& currentBinDir,
+ std::string const& projectSrcDir, std::string const& projectBinDir)
+{
+ std::lock_guard<std::mutex> lock(Mutex_);
+ FilePathChecksum_.setupParentDirs(currentSrcDir, currentBinDir,
+ projectSrcDir, projectBinDir);
+}
+
+std::string cmQtAutoGenerator::FileSystem::GetFilePathChecksum(
+ std::string const& filename)
+{
+ std::lock_guard<std::mutex> lock(Mutex_);
+ return FilePathChecksum_.getPart(filename);
+}
+
bool cmQtAutoGenerator::FileSystem::FileExists(std::string const& filename)
{
std::lock_guard<std::mutex> lock(Mutex_);
return cmSystemTools::FileExists(filename);
}
+bool cmQtAutoGenerator::FileSystem::FileExists(std::string const& filename,
+ bool isFile)
+{
+ std::lock_guard<std::mutex> lock(Mutex_);
+ return cmSystemTools::FileExists(filename, isFile);
+}
+
+unsigned long cmQtAutoGenerator::FileSystem::FileLength(
+ std::string const& filename)
+{
+ std::lock_guard<std::mutex> lock(Mutex_);
+ return cmSystemTools::FileLength(filename);
+}
+
bool cmQtAutoGenerator::FileSystem::FileIsOlderThan(
std::string const& buildFile, std::string const& sourceFile,
std::string* error)
@@ -188,35 +262,30 @@ bool cmQtAutoGenerator::FileSystem::FileRead(std::string& content,
std::string* error)
{
bool success = false;
- {
- std::lock_guard<std::mutex> lock(Mutex_);
- if (cmSystemTools::FileExists(filename, true)) {
- std::size_t const length = cmSystemTools::FileLength(filename);
+ if (FileExists(filename, true)) {
+ unsigned long const length = FileLength(filename);
+ {
+ std::lock_guard<std::mutex> lock(Mutex_);
cmsys::ifstream ifs(filename.c_str(), (std::ios::in | std::ios::binary));
if (ifs) {
- if (length > 0) {
- content.resize(length);
- ifs.read(&content.front(), content.size());
- if (ifs) {
- success = true;
- } else {
- content.clear();
- if (error != nullptr) {
- error->append("Reading from the file failed.");
- }
- }
+ content.reserve(length);
+ content.assign(std::istreambuf_iterator<char>{ ifs },
+ std::istreambuf_iterator<char>{});
+ if (ifs) {
+ success = true;
} else {
- // Readable but empty file
content.clear();
- success = true;
+ if (error != nullptr) {
+ error->append("Reading from the file failed.");
+ }
}
} else if (error != nullptr) {
error->append("Opening the file for reading failed.");
}
- } else if (error != nullptr) {
- error->append(
- "The file does not exist, is not readable or is a directory.");
}
+ } else if (error != nullptr) {
+ error->append(
+ "The file does not exist, is not readable or is a directory.");
}
return success;
}
diff --git a/Source/cmQtAutoGenerator.h b/Source/cmQtAutoGenerator.h
index e029d8d..299e4c2 100644
--- a/Source/cmQtAutoGenerator.h
+++ b/Source/cmQtAutoGenerator.h
@@ -5,6 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include "cmFilePathChecksum.h"
#include "cmQtAutoGen.h"
#include "cmUVHandlePtr.h"
#include "cmUVSignalHackRAII.h" // IWYU pragma: keep
@@ -68,9 +69,42 @@ public:
{
}
+ /// @brief Logger
Logger* Log() const { return Log_; }
- std::string RealPath(std::string const& filename);
+
+ // -- Paths
+ /// @brief Wrapper for cmSystemTools::GetRealPath
+ std::string GetRealPath(std::string const& filename);
+ /// @brief Wrapper for cmSystemTools::CollapseCombinedPath
+ std::string CollapseCombinedPath(std::string const& dir,
+ std::string const& file);
+ /// @brief Wrapper for cmSystemTools::SplitPath
+ void SplitPath(const std::string& p, std::vector<std::string>& components,
+ bool expand_home_dir = true);
+ /// @brief Wrapper for cmSystemTools::JoinPath
+ std::string JoinPath(const std::vector<std::string>& components);
+ /// @brief Wrapper for cmSystemTools::JoinPath
+ std::string JoinPath(std::vector<std::string>::const_iterator first,
+ std::vector<std::string>::const_iterator last);
+ /// @brief Wrapper for cmSystemTools::GetFilenameWithoutLastExtension
+ std::string GetFilenameWithoutLastExtension(const std::string& filename);
+ /// @brief Wrapper for cmQtAutoGen::SubDirPrefix
+ std::string SubDirPrefix(std::string const& filename);
+ /// @brief Wrapper for cmFilePathChecksum::setupParentDirs
+ void setupFilePathChecksum(std::string const& currentSrcDir,
+ std::string const& currentBinDir,
+ std::string const& projectSrcDir,
+ std::string const& projectBinDir);
+ /// @brief Wrapper for cmFilePathChecksum::getPart
+ std::string GetFilePathChecksum(std::string const& filename);
+
+ // -- File access
+ /// @brief Wrapper for cmSystemTools::FileExists
bool FileExists(std::string const& filename);
+ /// @brief Wrapper for cmSystemTools::FileExists
+ bool FileExists(std::string const& filename, bool isFile);
+ /// @brief Wrapper for cmSystemTools::FileLength
+ unsigned long FileLength(std::string const& filename);
bool FileIsOlderThan(std::string const& buildFile,
std::string const& sourceFile,
std::string* error = nullptr);
@@ -92,6 +126,7 @@ public:
bool FileRemove(std::string const& filename);
bool Touch(std::string const& filename);
+ // -- Directory access
bool MakeDirectory(std::string const& dirname);
/// @brief Error logging version
bool MakeDirectory(GeneratorT genType, std::string const& dirname);
@@ -102,6 +137,7 @@ public:
private:
std::mutex Mutex_;
+ cmFilePathChecksum FilePathChecksum_;
Logger* Log_;
};
diff --git a/Source/cmQtAutoGeneratorMocUic.cxx b/Source/cmQtAutoGeneratorMocUic.cxx
index 37cf0f8..b1be967 100644
--- a/Source/cmQtAutoGeneratorMocUic.cxx
+++ b/Source/cmQtAutoGeneratorMocUic.cxx
@@ -26,7 +26,7 @@
std::string cmQtAutoGeneratorMocUic::BaseSettingsT::AbsoluteBuildPath(
std::string const& relativePath) const
{
- return cmSystemTools::CollapseCombinedPath(AutogenBuildDir, relativePath);
+ return FileSys->CollapseCombinedPath(AutogenBuildDir, relativePath);
}
/**
@@ -106,7 +106,7 @@ std::string cmQtAutoGeneratorMocUic::MocSettingsT::FindIncludedFile(
std::string testPath = sourcePath;
testPath += includeString;
if (FileSys->FileExists(testPath)) {
- return FileSys->RealPath(testPath);
+ return FileSys->GetRealPath(testPath);
}
}
// Search in include directories
@@ -115,7 +115,7 @@ std::string cmQtAutoGeneratorMocUic::MocSettingsT::FindIncludedFile(
fullPath.push_back('/');
fullPath += includeString;
if (FileSys->FileExists(fullPath)) {
- return FileSys->RealPath(fullPath);
+ return FileSys->GetRealPath(fullPath);
}
}
// Return empty string
@@ -166,9 +166,9 @@ void cmQtAutoGeneratorMocUic::JobParseT::Process(WorkerT& wrk)
MetaT meta;
if (wrk.FileSys().FileRead(meta.Content, FileName, &error)) {
if (!meta.Content.empty()) {
- meta.FileDir = SubDirPrefix(FileName);
+ meta.FileDir = wrk.FileSys().SubDirPrefix(FileName);
meta.FileBase =
- cmSystemTools::GetFilenameWithoutLastExtension(FileName);
+ wrk.FileSys().GetFilenameWithoutLastExtension(FileName);
bool success = true;
if (AutoMoc) {
@@ -222,9 +222,9 @@ bool cmQtAutoGeneratorMocUic::JobParseT::ParseMocSource(WorkerT& wrk,
cmsys::RegularExpressionMatch match;
while (wrk.Moc().RegExpInclude.find(contentChars, match)) {
std::string incString = match.match(2);
- std::string incDir(SubDirPrefix(incString));
+ std::string incDir(wrk.FileSys().SubDirPrefix(incString));
std::string incBase =
- cmSystemTools::GetFilenameWithoutLastExtension(incString);
+ wrk.FileSys().GetFilenameWithoutLastExtension(incString);
if (cmHasLiteralPrefix(incBase, "moc_")) {
// moc_<BASE>.cxx
// Remove the moc_ part from the base name
@@ -487,7 +487,7 @@ std::string cmQtAutoGeneratorMocUic::JobParseT::MocFindIncludedHeader(
}
// Sanitize
if (!header.empty()) {
- header = wrk.FileSys().RealPath(header);
+ header = wrk.FileSys().GetRealPath(header);
}
return header;
}
@@ -533,12 +533,12 @@ std::string cmQtAutoGeneratorMocUic::JobParseT::UicFindIncludedFile(
{
std::string res;
std::string searchFile =
- cmSystemTools::GetFilenameWithoutLastExtension(includeString).substr(3);
+ wrk.FileSys().GetFilenameWithoutLastExtension(includeString).substr(3);
searchFile += ".ui";
// Collect search paths list
std::deque<std::string> testFiles;
{
- std::string const searchPath = SubDirPrefix(includeString);
+ std::string const searchPath = wrk.FileSys().SubDirPrefix(includeString);
std::string searchFileFull;
if (!searchPath.empty()) {
@@ -569,7 +569,7 @@ std::string cmQtAutoGeneratorMocUic::JobParseT::UicFindIncludedFile(
// Search for the .ui file!
for (std::string const& testFile : testFiles) {
if (wrk.FileSys().FileExists(testFile)) {
- res = wrk.FileSys().RealPath(testFile);
+ res = wrk.FileSys().GetRealPath(testFile);
break;
}
}
@@ -676,9 +676,9 @@ void cmQtAutoGeneratorMocUic::JobMocT::Process(WorkerT& wrk)
BuildFile += '/';
BuildFile += IncludeString;
} else {
- std::string rel = wrk.Base().FilePathChecksum.getPart(SourceFile);
+ std::string rel = wrk.FileSys().GetFilePathChecksum(SourceFile);
rel += "/moc_";
- rel += cmSystemTools::GetFilenameWithoutLastExtension(SourceFile);
+ rel += wrk.FileSys().GetFilenameWithoutLastExtension(SourceFile);
rel += ".cpp";
// Register relative file path
wrk.Gen().ParallelMocAutoRegister(rel);
@@ -798,7 +798,7 @@ bool cmQtAutoGeneratorMocUic::JobMocT::UpdateRequired(WorkerT& wrk)
}
// Check dependency timestamps
std::string error;
- std::string sourceDir = SubDirPrefix(SourceFile);
+ std::string sourceDir = wrk.FileSys().SubDirPrefix(SourceFile);
for (std::string const& depFileRel : Depends) {
std::string depFileAbs =
wrk.Moc().FindIncludedFile(sourceDir, depFileRel);
@@ -853,8 +853,12 @@ void cmQtAutoGeneratorMocUic::JobMocT::GenerateMoc(WorkerT& wrk)
ProcessResultT result;
if (wrk.RunProcess(GeneratorT::MOC, result, cmd)) {
// Moc command success
+ // Print moc output
+ if (!result.StdOut.empty()) {
+ wrk.LogInfo(GeneratorT::MOC, result.StdOut);
+ }
+ // Notify the generator that a not included file changed (on demand)
if (IncludeString.empty()) {
- // Notify the generator that a not included file changed
wrk.Gen().ParallelMocAutoUpdated();
}
} else {
@@ -963,9 +967,13 @@ void cmQtAutoGeneratorMocUic::JobUicT::GenerateUic(WorkerT& wrk)
ProcessResultT result;
if (wrk.RunProcess(GeneratorT::UIC, result, cmd)) {
- // Success
+ // Uic command success
+ // Print uic output
+ if (!result.StdOut.empty()) {
+ wrk.LogInfo(GeneratorT::UIC, result.StdOut);
+ }
} else {
- // Command failed
+ // Uic command failed
{
std::string emsg = "The uic process failed to compile\n ";
emsg += Quoted(SourceFile);
@@ -1416,8 +1424,8 @@ bool cmQtAutoGeneratorMocUic::Init(cmMakefile* makefile)
// Search for the default header file and a private header
{
std::array<std::string, 2> bases;
- bases[0] = SubDirPrefix(src);
- bases[0] += cmSystemTools::GetFilenameWithoutLastExtension(src);
+ bases[0] = FileSys().SubDirPrefix(src);
+ bases[0] += FileSys().GetFilenameWithoutLastExtension(src);
bases[1] = bases[0];
bases[1] += "_p";
for (std::string const& headerBase : bases) {
@@ -1444,7 +1452,7 @@ bool cmQtAutoGeneratorMocUic::Init(cmMakefile* makefile)
// ------------------------
// Init file path checksum generator
- Base_.FilePathChecksum.setupParentDirs(
+ FileSys().setupFilePathChecksum(
Base().CurrentSourceDir, Base().CurrentBinaryDir, Base().ProjectSourceDir,
Base().ProjectBinaryDir);
@@ -1503,8 +1511,8 @@ bool cmQtAutoGeneratorMocUic::Init(cmMakefile* makefile)
if (cmHasLiteralSuffix(path, ".framework/Headers")) {
// Go up twice to get to the framework root
std::vector<std::string> pathComponents;
- cmSystemTools::SplitPath(path, pathComponents);
- std::string frameworkPath = cmSystemTools::JoinPath(
+ FileSys().SplitPath(path, pathComponents);
+ std::string frameworkPath = FileSys().JoinPath(
pathComponents.begin(), pathComponents.end() - 2);
frameworkPaths.insert(frameworkPath);
}
diff --git a/Source/cmQtAutoGeneratorMocUic.h b/Source/cmQtAutoGeneratorMocUic.h
index 696d5bd..2226954 100644
--- a/Source/cmQtAutoGeneratorMocUic.h
+++ b/Source/cmQtAutoGeneratorMocUic.h
@@ -5,7 +5,6 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cmFilePathChecksum.h"
#include "cmQtAutoGen.h"
#include "cmQtAutoGenerator.h"
#include "cmUVHandlePtr.h"
@@ -95,7 +94,6 @@ public:
std::string AutogenBuildDir;
std::string AutogenIncludeDir;
// - Files
- cmFilePathChecksum FilePathChecksum;
std::vector<std::string> HeaderExtensions;
// - File system
FileSystem* FileSys;
diff --git a/Source/cmQtAutoGeneratorRcc.cxx b/Source/cmQtAutoGeneratorRcc.cxx
index 2bf00f7..84ec5e2 100644
--- a/Source/cmQtAutoGeneratorRcc.cxx
+++ b/Source/cmQtAutoGeneratorRcc.cxx
@@ -533,10 +533,14 @@ bool cmQtAutoGeneratorRcc::GenerateRcc()
if (Process_->IsFinished()) {
// Process is finished
if (!ProcessResult_.error()) {
- // Process success
+ // Rcc process success
+ // Print rcc output
+ if (!ProcessResult_.StdOut.empty()) {
+ Log().Info(GeneratorT::RCC, ProcessResult_.StdOut);
+ }
BuildFileChanged_ = true;
} else {
- // Process failed
+ // Rcc process failed
{
std::string emsg = "The rcc process failed to compile\n ";
emsg += Quoted(QrcFile_);
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index bb891b5..a93fb11 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -13,6 +13,7 @@
#include "cmCommand.h"
#include "cmDefinitions.h"
#include "cmDisallowedCommand.h"
+#include "cmGlobVerificationManager.h"
#include "cmListFileCache.h"
#include "cmStatePrivate.h"
#include "cmStateSnapshot.h"
@@ -31,11 +32,13 @@ cmState::cmState()
, MSYSShell(false)
{
this->CacheManager = new cmCacheManager;
+ this->GlobVerificationManager = new cmGlobVerificationManager;
}
cmState::~cmState()
{
delete this->CacheManager;
+ delete this->GlobVerificationManager;
cmDeleteAll(this->BuiltinCommands);
cmDeleteAll(this->ScriptedCommands);
}
@@ -207,6 +210,39 @@ void cmState::AddCacheEntry(const std::string& key, const char* value,
this->CacheManager->AddCacheEntry(key, value, helpString, type);
}
+bool cmState::DoWriteGlobVerifyTarget() const
+{
+ return this->GlobVerificationManager->DoWriteVerifyTarget();
+}
+
+std::string const& cmState::GetGlobVerifyScript() const
+{
+ return this->GlobVerificationManager->GetVerifyScript();
+}
+
+std::string const& cmState::GetGlobVerifyStamp() const
+{
+ return this->GlobVerificationManager->GetVerifyStamp();
+}
+
+bool cmState::SaveVerificationScript(const std::string& path)
+{
+ return this->GlobVerificationManager->SaveVerificationScript(path);
+}
+
+void cmState::AddGlobCacheEntry(bool recurse, bool listDirectories,
+ bool followSymlinks,
+ const std::string& relative,
+ const std::string& expression,
+ const std::vector<std::string>& files,
+ const std::string& variable,
+ cmListFileBacktrace const& backtrace)
+{
+ this->GlobVerificationManager->AddCacheEntry(
+ recurse, listDirectories, followSymlinks, relative, expression, files,
+ variable, backtrace);
+}
+
void cmState::RemoveCacheEntry(std::string const& key)
{
this->CacheManager->RemoveCacheEntry(key);
diff --git a/Source/cmState.h b/Source/cmState.h
index 6cbf82d..4c6fc69 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -12,6 +12,7 @@
#include "cmDefinitions.h"
#include "cmLinkedTree.h"
+#include "cmListFileCache.h"
#include "cmPolicies.h"
#include "cmProperty.h"
#include "cmPropertyDefinitionMap.h"
@@ -21,6 +22,7 @@
class cmCacheManager;
class cmCommand;
+class cmGlobVerificationManager;
class cmPropertyDefinition;
class cmStateSnapshot;
class cmMessenger;
@@ -165,12 +167,24 @@ private:
const char* helpString,
cmStateEnums::CacheEntryType type);
+ bool DoWriteGlobVerifyTarget() const;
+ std::string const& GetGlobVerifyScript() const;
+ std::string const& GetGlobVerifyStamp() const;
+ bool SaveVerificationScript(const std::string& path);
+ void AddGlobCacheEntry(bool recurse, bool listDirectories,
+ bool followSymlinks, const std::string& relative,
+ const std::string& expression,
+ const std::vector<std::string>& files,
+ const std::string& variable,
+ cmListFileBacktrace const& bt);
+
std::map<cmProperty::ScopeType, cmPropertyDefinitionMap> PropertyDefinitions;
std::vector<std::string> EnabledLanguages;
std::map<std::string, cmCommand*> BuiltinCommands;
std::map<std::string, cmCommand*> ScriptedCommands;
cmPropertyMap GlobalProperties;
cmCacheManager* CacheManager;
+ cmGlobVerificationManager* GlobVerificationManager;
cmLinkedTree<cmStateDetail::BuildsystemDirectoryStateType>
BuildsystemDirectory;
diff --git a/Source/cmStateSnapshot.cxx b/Source/cmStateSnapshot.cxx
index 479ecd2..0d97c33 100644
--- a/Source/cmStateSnapshot.cxx
+++ b/Source/cmStateSnapshot.cxx
@@ -6,7 +6,7 @@
#include <algorithm>
#include <assert.h>
#include <iterator>
-#include <stdio.h>
+#include <string>
#include "cmAlgorithms.h"
#include "cmDefinitions.h"
@@ -328,15 +328,14 @@ void cmStateSnapshot::SetDefaultDefinitions()
this->SetDefinition("CMAKE_HOST_SOLARIS", "1");
#endif
- char temp[1024];
- sprintf(temp, "%d", cmVersion::GetMinorVersion());
- this->SetDefinition("CMAKE_MINOR_VERSION", temp);
- sprintf(temp, "%d", cmVersion::GetMajorVersion());
- this->SetDefinition("CMAKE_MAJOR_VERSION", temp);
- sprintf(temp, "%d", cmVersion::GetPatchVersion());
- this->SetDefinition("CMAKE_PATCH_VERSION", temp);
- sprintf(temp, "%d", cmVersion::GetTweakVersion());
- this->SetDefinition("CMAKE_TWEAK_VERSION", temp);
+ this->SetDefinition("CMAKE_MAJOR_VERSION",
+ std::to_string(cmVersion::GetMajorVersion()));
+ this->SetDefinition("CMAKE_MINOR_VERSION",
+ std::to_string(cmVersion::GetMinorVersion()));
+ this->SetDefinition("CMAKE_PATCH_VERSION",
+ std::to_string(cmVersion::GetPatchVersion()));
+ this->SetDefinition("CMAKE_TWEAK_VERSION",
+ std::to_string(cmVersion::GetTweakVersion()));
this->SetDefinition("CMAKE_VERSION", cmVersion::GetCMakeVersion());
this->SetDefinition("CMAKE_FILES_DIRECTORY",
diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx
index 9631912..dabec47 100644
--- a/Source/cmStringCommand.cxx
+++ b/Source/cmStringCommand.cxx
@@ -13,6 +13,7 @@
#include "cmCryptoHash.h"
#include "cmGeneratorExpression.h"
#include "cmMakefile.h"
+#include "cmStringReplaceHelper.h"
#include "cmSystemTools.h"
#include "cmTimestamp.h"
#include "cmUuid.h"
@@ -344,46 +345,17 @@ bool cmStringCommand::RegexReplace(std::vector<std::string> const& args)
std::string const& regex = args[2];
std::string const& replace = args[3];
std::string const& outvar = args[4];
+ cmStringReplaceHelper replaceHelper(regex, replace, this->Makefile);
- // Pull apart the replace expression to find the escaped [0-9] values.
- std::vector<RegexReplacement> replacement;
- std::string::size_type l = 0;
- while (l < replace.length()) {
- std::string::size_type r = replace.find('\\', l);
- if (r == std::string::npos) {
- r = replace.length();
- replacement.push_back(replace.substr(l, r - l));
- } else {
- if (r - l > 0) {
- replacement.push_back(replace.substr(l, r - l));
- }
- if (r == (replace.length() - 1)) {
- this->SetError("sub-command REGEX, mode REPLACE: "
- "replace-expression ends in a backslash.");
- return false;
- }
- if ((replace[r + 1] >= '0') && (replace[r + 1] <= '9')) {
- replacement.push_back(replace[r + 1] - '0');
- } else if (replace[r + 1] == 'n') {
- replacement.push_back("\n");
- } else if (replace[r + 1] == '\\') {
- replacement.push_back("\\");
- } else {
- std::string e = "sub-command REGEX, mode REPLACE: Unknown escape \"";
- e += replace.substr(r, 2);
- e += "\" in replace-expression.";
- this->SetError(e);
- return false;
- }
- r += 2;
- }
- l = r;
+ if (!replaceHelper.IsReplaceExpressionValid()) {
+ this->SetError("sub-command REGEX, mode REPLACE: " +
+ replaceHelper.GetError() + ".");
+ return false;
}
this->Makefile->ClearMatches();
- // Compile the regular expression.
- cmsys::RegularExpression re;
- if (!re.compile(regex.c_str())) {
+
+ if (!replaceHelper.IsRegularExpressionValid()) {
std::string e =
"sub-command REGEX, mode REPLACE failed to compile regex \"" + regex +
"\".";
@@ -392,60 +364,16 @@ bool cmStringCommand::RegexReplace(std::vector<std::string> const& args)
}
// Concatenate all the last arguments together.
- std::string input = cmJoin(cmMakeRange(args).advance(5), std::string());
-
- // Scan through the input for all matches.
+ const std::string input =
+ cmJoin(cmMakeRange(args).advance(5), std::string());
std::string output;
- std::string::size_type base = 0;
- while (re.find(input.c_str() + base)) {
- this->Makefile->ClearMatches();
- this->Makefile->StoreMatches(re);
- std::string::size_type l2 = re.start();
- std::string::size_type r = re.end();
-
- // Concatenate the part of the input that was not matched.
- output += input.substr(base, l2);
-
- // Make sure the match had some text.
- if (r - l2 == 0) {
- std::string e = "sub-command REGEX, mode REPLACE regex \"" + regex +
- "\" matched an empty string.";
- this->SetError(e);
- return false;
- }
- // Concatenate the replacement for the match.
- for (RegexReplacement const& i : replacement) {
- if (i.number < 0) {
- // This is just a plain-text part of the replacement.
- output += i.value;
- } else {
- // Replace with part of the match.
- int n = i.number;
- std::string::size_type start = re.start(n);
- std::string::size_type end = re.end(n);
- std::string::size_type len = input.length() - base;
- if ((start != std::string::npos) && (end != std::string::npos) &&
- (start <= len) && (end <= len)) {
- output += input.substr(base + start, end - start);
- } else {
- std::string e =
- "sub-command REGEX, mode REPLACE: replace expression \"" +
- replace + "\" contains an out-of-range escape for regex \"" +
- regex + "\".";
- this->SetError(e);
- return false;
- }
- }
- }
-
- // Move past the match.
- base += r;
+ if (!replaceHelper.Replace(input, output)) {
+ this->SetError("sub-command REGEX, mode REPLACE: " +
+ replaceHelper.GetError() + ".");
+ return false;
}
- // Concatenate the text after the last match.
- output += input.substr(base, input.length() - base);
-
// Store the output in the provided variable.
this->Makefile->AddDefinition(outvar, output.c_str());
return true;
diff --git a/Source/cmStringCommand.h b/Source/cmStringCommand.h
index 569ed83..cbff73e 100644
--- a/Source/cmStringCommand.h
+++ b/Source/cmStringCommand.h
@@ -60,29 +60,6 @@ protected:
bool joinImpl(std::vector<std::string> const& args, std::string const& glue,
size_t varIdx);
-
- class RegexReplacement
- {
- public:
- RegexReplacement(const char* s)
- : number(-1)
- , value(s)
- {
- }
- RegexReplacement(const std::string& s)
- : number(-1)
- , value(s)
- {
- }
- RegexReplacement(int n)
- : number(n)
- , value()
- {
- }
- RegexReplacement() {}
- int number;
- std::string value;
- };
};
#endif
diff --git a/Source/cmStringReplaceHelper.cxx b/Source/cmStringReplaceHelper.cxx
new file mode 100644
index 0000000..69b7ced
--- /dev/null
+++ b/Source/cmStringReplaceHelper.cxx
@@ -0,0 +1,117 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmStringReplaceHelper.h"
+
+#include "cmMakefile.h"
+#include <sstream>
+
+cmStringReplaceHelper::cmStringReplaceHelper(const std::string& regex,
+ const std::string& replace_expr,
+ cmMakefile* makefile)
+ : RegExString(regex)
+ , RegularExpression(regex)
+ , ReplaceExpression(replace_expr)
+ , Makefile(makefile)
+{
+ this->ParseReplaceExpression();
+}
+
+bool cmStringReplaceHelper::Replace(const std::string& input,
+ std::string& output)
+{
+ output.clear();
+
+ // Scan through the input for all matches.
+ std::string::size_type base = 0;
+ while (this->RegularExpression.find(input.c_str() + base)) {
+ if (this->Makefile != nullptr) {
+ this->Makefile->ClearMatches();
+ this->Makefile->StoreMatches(this->RegularExpression);
+ }
+ auto l2 = this->RegularExpression.start();
+ auto r = this->RegularExpression.end();
+
+ // Concatenate the part of the input that was not matched.
+ output += input.substr(base, l2);
+
+ // Make sure the match had some text.
+ if (r - l2 == 0) {
+ std::ostringstream error;
+ error << "regex \"" << this->RegExString << "\" matched an empty string";
+ this->ErrorString = error.str();
+ return false;
+ }
+
+ // Concatenate the replacement for the match.
+ for (const auto& replacement : this->Replacements) {
+ if (replacement.Number < 0) {
+ // This is just a plain-text part of the replacement.
+ output += replacement.Value;
+ } else {
+ // Replace with part of the match.
+ auto n = replacement.Number;
+ auto start = this->RegularExpression.start(n);
+ auto end = this->RegularExpression.end(n);
+ auto len = input.length() - base;
+ if ((start != std::string::npos) && (end != std::string::npos) &&
+ (start <= len) && (end <= len)) {
+ output += input.substr(base + start, end - start);
+ } else {
+ std::ostringstream error;
+ error << "replace expression \"" << this->ReplaceExpression
+ << "\" contains an out-of-range escape for regex \""
+ << this->RegExString << "\"";
+ this->ErrorString = error.str();
+ return false;
+ }
+ }
+ }
+
+ // Move past the match.
+ base += r;
+ }
+
+ // Concatenate the text after the last match.
+ output += input.substr(base, input.length() - base);
+
+ return true;
+}
+
+void cmStringReplaceHelper::ParseReplaceExpression()
+{
+ std::string::size_type l = 0;
+ while (l < this->ReplaceExpression.length()) {
+ auto r = this->ReplaceExpression.find('\\', l);
+ if (r == std::string::npos) {
+ r = this->ReplaceExpression.length();
+ this->Replacements.push_back(this->ReplaceExpression.substr(l, r - l));
+ } else {
+ if (r - l > 0) {
+ this->Replacements.push_back(this->ReplaceExpression.substr(l, r - l));
+ }
+ if (r == (this->ReplaceExpression.length() - 1)) {
+ this->ValidReplaceExpression = false;
+ this->ErrorString = "replace-expression ends in a backslash";
+ return;
+ }
+ if ((this->ReplaceExpression[r + 1] >= '0') &&
+ (this->ReplaceExpression[r + 1] <= '9')) {
+ this->Replacements.push_back(this->ReplaceExpression[r + 1] - '0');
+ } else if (this->ReplaceExpression[r + 1] == 'n') {
+ this->Replacements.push_back("\n");
+ } else if (this->ReplaceExpression[r + 1] == '\\') {
+ this->Replacements.push_back("\\");
+ } else {
+ this->ValidReplaceExpression = false;
+ std::ostringstream error;
+ error << "Unknown escape \"" << this->ReplaceExpression.substr(r, 2)
+ << "\" in replace-expression";
+ this->ErrorString = error.str();
+ return;
+ }
+ r += 2;
+ }
+ l = r;
+ }
+}
diff --git a/Source/cmStringReplaceHelper.h b/Source/cmStringReplaceHelper.h
new file mode 100644
index 0000000..938325a
--- /dev/null
+++ b/Source/cmStringReplaceHelper.h
@@ -0,0 +1,69 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmStringReplaceHelper_h
+#define cmStringReplaceHelper_h
+
+#include "cmsys/RegularExpression.hxx"
+
+#include <string>
+#include <vector>
+
+class cmMakefile;
+
+class cmStringReplaceHelper
+{
+public:
+ cmStringReplaceHelper(const std::string& regex,
+ const std::string& replace_expr,
+ cmMakefile* makefile = nullptr);
+
+ bool IsRegularExpressionValid() const
+ {
+ return this->RegularExpression.is_valid();
+ }
+ bool IsReplaceExpressionValid() const
+ {
+ return this->ValidReplaceExpression;
+ }
+
+ bool Replace(const std::string& input, std::string& output);
+
+ const std::string& GetError() { return this->ErrorString; }
+
+private:
+ class RegexReplacement
+ {
+ public:
+ RegexReplacement(const char* s)
+ : Number(-1)
+ , Value(s)
+ {
+ }
+ RegexReplacement(const std::string& s)
+ : Number(-1)
+ , Value(s)
+ {
+ }
+ RegexReplacement(int n)
+ : Number(n)
+ , Value()
+ {
+ }
+ RegexReplacement() {}
+
+ int Number;
+ std::string Value;
+ };
+
+ void ParseReplaceExpression();
+
+ std::string ErrorString;
+ std::string RegExString;
+ cmsys::RegularExpression RegularExpression;
+ bool ValidReplaceExpression = true;
+ std::string ReplaceExpression;
+ std::vector<RegexReplacement> Replacements;
+ cmMakefile* Makefile = nullptr;
+};
+
+#endif
diff --git a/Source/cmTargetLinkLibrariesCommand.h b/Source/cmTargetLinkLibrariesCommand.h
index a2f3ecd..54f8cf4 100644
--- a/Source/cmTargetLinkLibrariesCommand.h
+++ b/Source/cmTargetLinkLibrariesCommand.h
@@ -43,7 +43,7 @@ private:
void LinkLibraryTypeSpecifierWarning(int left, int right);
static const char* LinkLibraryTypeNames[3];
- cmTarget* Target;
+ cmTarget* Target = nullptr;
enum ProcessingState
{
ProcessingLinkLibraries,
@@ -55,7 +55,7 @@ private:
ProcessingKeywordPrivateInterface
};
- ProcessingState CurrentProcessingState;
+ ProcessingState CurrentProcessingState = ProcessingLinkLibraries;
bool HandleLibrary(const std::string& lib, cmTargetLinkLibraryType llt);
};
diff --git a/Source/cmTargetPropCommandBase.h b/Source/cmTargetPropCommandBase.h
index 3c736fc..943285d 100644
--- a/Source/cmTargetPropCommandBase.h
+++ b/Source/cmTargetPropCommandBase.h
@@ -28,7 +28,7 @@ public:
protected:
std::string Property;
- cmTarget* Target;
+ cmTarget* Target = nullptr;
virtual void HandleInterfaceContent(cmTarget* tgt,
const std::vector<std::string>& content,
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 4bd07ef..19cb50b 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -33,6 +33,7 @@ struct cmVisualStudio10TargetGenerator::Elem
cmGeneratedFileStream& S;
int Indent;
bool HasElements = false;
+ const char* Tag = nullptr;
Elem(cmGeneratedFileStream& s, int i)
: S(s)
@@ -46,25 +47,45 @@ struct cmVisualStudio10TargetGenerator::Elem
{
par.SetHasElements();
}
+ Elem(Elem& par, const char* tag)
+ : S(par.S)
+ , Indent(par.Indent + 1)
+ {
+ par.SetHasElements();
+ this->StartElement(tag);
+ }
void SetHasElements()
{
if (!HasElements) {
- S << ">\n";
+ this->S << ">\n";
HasElements = true;
}
}
+ cmGeneratedFileStream& WriteString(const char* line);
+ void StartElement(const char* tag)
+ {
+ this->Tag = tag;
+ this->WriteString("<") << tag;
+ }
+ template <typename T>
+ void WriteElem(const char* tag, const T& val)
+ {
+ this->WriteString("<") << tag << ">" << val << "</" << tag << ">\n";
+ }
+ template <typename T>
+ void Attr(const char* an, const T& av)
+ {
+ this->S << " " << an << "=\"" << av << "\"";
+ }
void WriteEndTag(const char* tag)
{
if (HasElements) {
- S.fill(' ');
- S.width(Indent * 2);
- // write an empty string to get the fill level indent to print
- S << "";
- S << "</" << tag << ">\n";
+ this->WriteString("</") << tag << ">\n";
} else {
- S << " />\n";
+ this->S << " />\n";
}
}
+ void EndElement() { this->WriteEndTag(this->Tag); }
};
class cmVS10GeneratorOptions : public cmVisualStudioGeneratorOptions
@@ -102,16 +123,14 @@ inline void cmVisualStudio10TargetGenerator::WriteElem(const char* tag,
const char* val,
int indentLevel)
{
- this->WriteString("<", indentLevel);
- (*this->BuildFileStream) << tag << ">" << val << "</" << tag << ">\n";
+ Elem(*this->BuildFileStream, indentLevel).WriteElem(tag, val);
}
inline void cmVisualStudio10TargetGenerator::WriteElem(const char* tag,
std::string const& val,
int indentLevel)
{
- this->WriteString("<", indentLevel);
- (*this->BuildFileStream) << tag << ">" << val << "</" << tag << ">\n";
+ Elem(*this->BuildFileStream, indentLevel).WriteElem(tag, val);
}
inline void cmVisualStudio10TargetGenerator::WriteElemEscapeXML(
@@ -120,8 +139,11 @@ inline void cmVisualStudio10TargetGenerator::WriteElemEscapeXML(
this->WriteElem(tag, cmVS10EscapeXML(val), indentLevel);
}
-static std::string cmVS10EscapeQuotes(std::string arg)
+static std::string cmVS10EscapeAttr(std::string arg)
{
+ cmSystemTools::ReplaceString(arg, "&", "&amp;");
+ cmSystemTools::ReplaceString(arg, "<", "&lt;");
+ cmSystemTools::ReplaceString(arg, ">", "&gt;");
cmSystemTools::ReplaceString(arg, "\"", "&quot;");
return arg;
}
@@ -247,14 +269,21 @@ void cmVisualStudio10TargetGenerator::WritePlatformConfigTag(
}
}
+cmGeneratedFileStream& cmVisualStudio10TargetGenerator::Elem::WriteString(
+ const char* line)
+{
+ this->S.fill(' ');
+ this->S.width(this->Indent * 2);
+ // write an empty string to get the fill level indent to print
+ this->S << "";
+ this->S << line;
+ return this->S;
+}
+
void cmVisualStudio10TargetGenerator::WriteString(const char* line,
int indentLevel)
{
- this->BuildFileStream->fill(' ');
- this->BuildFileStream->width(indentLevel * 2);
- // write an empty string to get the fill level indent to print
- (*this->BuildFileStream) << "";
- (*this->BuildFileStream) << line;
+ Elem(*this->BuildFileStream, indentLevel).WriteString(line);
}
#define VS10_CXX_DEFAULT_PROPS "$(VCTargetsPath)\\Microsoft.Cpp.Default.props"
@@ -342,8 +371,8 @@ void cmVisualStudio10TargetGenerator::Generate()
if (this->NsightTegra) {
this->WriteString("<PropertyGroup Label=\"NsightTegraProject\">\n", 1);
- const int nsightTegraMajorVersion = this->NsightTegraVersion[0];
- const int nsightTegraMinorVersion = this->NsightTegraVersion[1];
+ const unsigned int nsightTegraMajorVersion = this->NsightTegraVersion[0];
+ const unsigned int nsightTegraMinorVersion = this->NsightTegraVersion[1];
if (nsightTegraMajorVersion >= 2) {
this->WriteString("<NsightTegraProjectRevisionNumber>", 2);
if (nsightTegraMajorVersion > 3 ||
@@ -529,7 +558,8 @@ void cmVisualStudio10TargetGenerator::Generate()
"BuildCustomizations\\CUDA ",
2);
(*this->BuildFileStream)
- << cmVS10EscapeXML(this->GlobalGenerator->GetPlatformToolsetCudaString())
+ << cmVS10EscapeAttr(
+ this->GlobalGenerator->GetPlatformToolsetCudaString())
<< ".props\" />\n";
}
if (this->GlobalGenerator->IsMasmEnabled()) {
@@ -549,7 +579,7 @@ void cmVisualStudio10TargetGenerator::Generate()
this->Makefile->ConfigureFile(propsTemplate.c_str(), propsLocal.c_str(),
false, true, true);
std::string import = std::string("<Import Project=\"") +
- cmVS10EscapeXML(propsLocal) + "\" />\n";
+ cmVS10EscapeAttr(propsLocal) + "\" />\n";
this->WriteString(import.c_str(), 2);
}
this->WriteString("</ImportGroup>\n", 1);
@@ -571,8 +601,8 @@ void cmVisualStudio10TargetGenerator::Generate()
ConvertToWindowsSlash(props);
this->WriteString("", 2);
(*this->BuildFileStream)
- << "<Import Project=\"" << cmVS10EscapeXML(props) << "\""
- << " Condition=\"exists('" << cmVS10EscapeXML(props) << "')\""
+ << "<Import Project=\"" << cmVS10EscapeAttr(props) << "\""
+ << " Condition=\"exists('" << cmVS10EscapeAttr(props) << "')\""
<< " Label=\"LocalAppDataPlatform\" />\n";
}
}
@@ -607,7 +637,8 @@ void cmVisualStudio10TargetGenerator::Generate()
"BuildCustomizations\\CUDA ",
2);
(*this->BuildFileStream)
- << cmVS10EscapeXML(this->GlobalGenerator->GetPlatformToolsetCudaString())
+ << cmVS10EscapeAttr(
+ this->GlobalGenerator->GetPlatformToolsetCudaString())
<< ".targets\" />\n";
}
if (this->GlobalGenerator->IsMasmEnabled()) {
@@ -619,7 +650,7 @@ void cmVisualStudio10TargetGenerator::Generate()
std::string nasmTargets =
GetCMakeFilePath("Templates/MSBuild/nasm.targets");
std::string import = "<Import Project=\"";
- import += cmVS10EscapeXML(nasmTargets) + "\" />\n";
+ import += cmVS10EscapeAttr(nasmTargets) + "\" />\n";
this->WriteString(import.c_str(), 2);
}
this->WriteString("</ImportGroup>\n", 1);
@@ -696,7 +727,7 @@ void cmVisualStudio10TargetGenerator::WriteDotNetReference(
std::string const& ref, std::string const& hint)
{
this->WriteString("<Reference Include=\"", 2);
- (*this->BuildFileStream) << cmVS10EscapeXML(ref) << "\">\n";
+ (*this->BuildFileStream) << cmVS10EscapeAttr(ref) << "\">\n";
this->WriteElem("CopyLocalSatelliteAssemblies", "true", 3);
this->WriteElem("ReferenceOutputAssembly", "true", 3);
if (!hint.empty()) {
@@ -943,7 +974,7 @@ void cmVisualStudio10TargetGenerator::WriteWinRTReferences()
this->WriteString("<ItemGroup>\n", 1);
for (std::string const& ri : references) {
this->WriteString("<Reference Include=\"", 2);
- (*this->BuildFileStream) << cmVS10EscapeXML(ri) << "\">\n";
+ (*this->BuildFileStream) << cmVS10EscapeAttr(ri) << "\">\n";
this->WriteElem("IsWinMDFile", "true", 3);
this->WriteString("</Reference>\n", 2);
}
@@ -1237,15 +1268,15 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule(
cmCustomCommandGenerator ccg(command, c, lg);
std::string comment = lg->ConstructComment(ccg);
comment = cmVS10EscapeComment(comment);
- std::string script = cmVS10EscapeXML(lg->ConstructScript(ccg));
+ std::string script = lg->ConstructScript(ccg);
// input files for custom command
std::stringstream inputs;
- inputs << cmVS10EscapeXML(source->GetFullPath());
+ inputs << source->GetFullPath();
for (std::string const& d : ccg.GetDepends()) {
std::string dep;
if (lg->GetRealDependency(d, c, dep)) {
ConvertToWindowsSlash(dep);
- inputs << ";" << cmVS10EscapeXML(dep);
+ inputs << ";" << dep;
}
}
// output files for custom command
@@ -1254,19 +1285,13 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule(
for (std::string const& o : ccg.GetOutputs()) {
std::string out = o;
ConvertToWindowsSlash(out);
- outputs << sep << cmVS10EscapeXML(out);
+ outputs << sep << out;
sep = ";";
}
if (this->ProjectType == csproj) {
std::string name = "CustomCommand_" + c + "_" +
cmSystemTools::ComputeStringMD5(sourcePath);
- std::string inputs_s = inputs.str();
- std::string outputs_s = outputs.str();
- comment = cmVS10EscapeQuotes(comment);
- script = cmVS10EscapeQuotes(script);
- inputs_s = cmVS10EscapeQuotes(inputs_s);
- outputs_s = cmVS10EscapeQuotes(outputs_s);
- this->WriteCustomRuleCSharp(c, name, script, inputs_s, outputs_s,
+ this->WriteCustomRuleCSharp(c, name, script, inputs.str(), outputs.str(),
comment);
} else {
this->WriteCustomRuleCpp(c, script, inputs.str(), outputs.str(),
@@ -1286,17 +1311,19 @@ void cmVisualStudio10TargetGenerator::WriteCustomRuleCpp(
this->WritePlatformConfigTag("Message", config, 3);
(*this->BuildFileStream) << cmVS10EscapeXML(comment) << "</Message>\n";
this->WritePlatformConfigTag("Command", config, 3);
- (*this->BuildFileStream) << script << "</Command>\n";
+ (*this->BuildFileStream) << cmVS10EscapeXML(script) << "</Command>\n";
this->WritePlatformConfigTag("AdditionalInputs", config, 3);
- (*this->BuildFileStream) << inputs;
- (*this->BuildFileStream) << ";%(AdditionalInputs)</AdditionalInputs>\n";
+ (*this->BuildFileStream) << cmVS10EscapeXML(inputs);
+ (*this->BuildFileStream) << ";%(AdditionalInputs)"
+ "</AdditionalInputs>\n";
this->WritePlatformConfigTag("Outputs", config, 3);
- (*this->BuildFileStream) << outputs << "</Outputs>\n";
+ (*this->BuildFileStream) << cmVS10EscapeXML(outputs) << "</Outputs>\n";
if (this->LocalGenerator->GetVersion() >
cmGlobalVisualStudioGenerator::VS10) {
// VS >= 11 let us turn off linking of custom command outputs.
this->WritePlatformConfigTag("LinkObjects", config, 3);
- (*this->BuildFileStream) << "false</LinkObjects>\n";
+ (*this->BuildFileStream) << "false"
+ "</LinkObjects>\n";
}
}
@@ -1308,16 +1335,16 @@ void cmVisualStudio10TargetGenerator::WriteCustomRuleCSharp(
this->CSharpCustomCommandNames.insert(name);
std::stringstream attributes;
attributes << "\n Name=\"" << name << "\"";
- attributes << "\n Inputs=\"" << inputs << "\"";
- attributes << "\n Outputs=\"" << outputs << "\"";
+ attributes << "\n Inputs=\"" << cmVS10EscapeAttr(inputs) << "\"";
+ attributes << "\n Outputs=\"" << cmVS10EscapeAttr(outputs) << "\"";
this->WritePlatformConfigTag("Target", config, 1, attributes.str().c_str());
if (!comment.empty()) {
this->WriteString("<Exec Command=\"", 2);
- (*this->BuildFileStream) << "echo " << cmVS10EscapeXML(comment)
+ (*this->BuildFileStream) << "echo " << cmVS10EscapeAttr(comment)
<< "\" />\n";
}
this->WriteString("<Exec Command=\"", 2);
- (*this->BuildFileStream) << script << "\" />\n";
+ (*this->BuildFileStream) << cmVS10EscapeAttr(script) << "\" />\n";
this->WriteString("</Target>\n", 1);
}
@@ -1373,71 +1400,72 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
fout.SetCopyIfDifferent(true);
char magic[] = { char(0xEF), char(0xBB), char(0xBF) };
fout.write(magic, 3);
- cmGeneratedFileStream* save = this->BuildFileStream;
- this->BuildFileStream = &fout;
// get the tools version to use
const std::string toolsVer(this->GlobalGenerator->GetToolsVersion());
- std::string project_defaults = "<?xml version=\"1.0\" encoding=\"" +
- this->GlobalGenerator->Encoding() + "\"?>\n";
- project_defaults.append("<Project ToolsVersion=\"");
- project_defaults.append(toolsVer + "\" ");
- project_defaults.append(
- "xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n");
- this->WriteString(project_defaults.c_str(), 0);
+ fout << "<?xml version=\"1.0\" encoding=\""
+ << this->GlobalGenerator->Encoding() << "\"?>\n";
+
+ Elem e0(fout, 0);
+ e0.StartElement("Project");
+ e0.Attr("ToolsVersion", toolsVer);
+ e0.Attr("xmlns", "http://schemas.microsoft.com/developer/msbuild/2003");
+ e0.SetHasElements();
for (auto const& ti : this->Tools) {
- this->WriteGroupSources(ti.first.c_str(), ti.second, sourceGroups);
+ this->WriteGroupSources(e0, ti.first, ti.second, sourceGroups);
}
// Added files are images and the manifest.
if (!this->AddedFiles.empty()) {
- this->WriteString("<ItemGroup>\n", 1);
+ Elem e1(e0, "ItemGroup");
+ e1.SetHasElements();
for (std::string const& oi : this->AddedFiles) {
std::string fileName =
cmSystemTools::LowerCase(cmSystemTools::GetFilenameName(oi));
if (fileName == "wmappmanifest.xml") {
- this->WriteString("<XML Include=\"", 2);
- (*this->BuildFileStream) << oi << "\">\n";
- this->WriteElem("Filter", "Resource Files", 3);
- this->WriteString("</XML>\n", 2);
+ Elem e2(e1, "XML");
+ e2.Attr("Include", oi);
+ Elem(e2).WriteElem("Filter", "Resource Files");
+ e2.EndElement();
} else if (cmSystemTools::GetFilenameExtension(fileName) ==
".appxmanifest") {
- this->WriteString("<AppxManifest Include=\"", 2);
- (*this->BuildFileStream) << oi << "\">\n";
- this->WriteElem("Filter", "Resource Files", 3);
- this->WriteString("</AppxManifest>\n", 2);
+ Elem e2(e1, "AppxManifest");
+ e2.Attr("Include", oi);
+ Elem(e2).WriteElem("Filter", "Resource Files");
+ e2.EndElement();
} else if (cmSystemTools::GetFilenameExtension(fileName) == ".pfx") {
- this->WriteString("<None Include=\"", 2);
- (*this->BuildFileStream) << oi << "\">\n";
- this->WriteElem("Filter", "Resource Files", 3);
- this->WriteString("</None>\n", 2);
+ Elem e2(e1, "None");
+ e2.Attr("Include", oi);
+ Elem(e2).WriteElem("Filter", "Resource Files");
+ e2.EndElement();
} else {
- this->WriteString("<Image Include=\"", 2);
- (*this->BuildFileStream) << oi << "\">\n";
- this->WriteElem("Filter", "Resource Files", 3);
- this->WriteString("</Image>\n", 2);
+ Elem e2(e1, "Image");
+ e2.Attr("Include", oi);
+ Elem(e2).WriteElem("Filter", "Resource Files");
+ e2.EndElement();
}
}
- this->WriteString("</ItemGroup>\n", 1);
+ e1.EndElement();
}
std::vector<cmSourceFile const*> resxObjs;
this->GeneratorTarget->GetResxSources(resxObjs, "");
if (!resxObjs.empty()) {
- this->WriteString("<ItemGroup>\n", 1);
+ Elem e1(e0, "ItemGroup");
for (cmSourceFile const* oi : resxObjs) {
std::string obj = oi->GetFullPath();
- this->WriteString("<EmbeddedResource Include=\"", 2);
ConvertToWindowsSlash(obj);
- (*this->BuildFileStream) << cmVS10EscapeXML(obj) << "\">\n";
- this->WriteElem("Filter", "Resource Files", 3);
- this->WriteString("</EmbeddedResource>\n", 2);
+ Elem e2(e1, "EmbeddedResource");
+ e2.Attr("Include", cmVS10EscapeAttr(obj));
+ Elem(e2).WriteElem("Filter", "Resource Files");
+ e2.EndElement();
}
- this->WriteString("</ItemGroup>\n", 1);
+ e1.EndElement();
}
- this->WriteString("<ItemGroup>\n", 1);
+ Elem e1(e0, "ItemGroup");
+ e1.SetHasElements();
std::vector<cmSourceGroup*> groupsVec(groupsUsed.begin(), groupsUsed.end());
std::sort(groupsVec.begin(), groupsVec.end(),
[](cmSourceGroup* l, cmSourceGroup* r) {
@@ -1446,31 +1474,29 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
for (cmSourceGroup* sg : groupsVec) {
std::string const& name = sg->GetFullName();
if (!name.empty()) {
- this->WriteString("<Filter Include=\"", 2);
- (*this->BuildFileStream) << name << "\">\n";
- std::string guidName = "SG_Filter_";
- guidName += name;
+ std::string guidName = "SG_Filter_" + name;
std::string guid = this->GlobalGenerator->GetGUID(guidName);
- this->WriteElem("UniqueIdentifier", "{" + guid + "}", 3);
- this->WriteString("</Filter>\n", 2);
+ Elem e2(e1, "Filter");
+ e2.Attr("Include", name);
+ Elem(e2).WriteElem("UniqueIdentifier", "{" + guid + "}");
+ e2.EndElement();
}
}
if (!resxObjs.empty() || !this->AddedFiles.empty()) {
- this->WriteString("<Filter Include=\"Resource Files\">\n", 2);
std::string guidName = "SG_Filter_Resource Files";
std::string guid = this->GlobalGenerator->GetGUID(guidName);
- this->WriteElem("UniqueIdentifier", "{" + guid + "}", 3);
- this->WriteString("<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;", 3);
- (*this->BuildFileStream) << "gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;";
- (*this->BuildFileStream) << "mfcribbon-ms</Extensions>\n";
- this->WriteString("</Filter>\n", 2);
+ Elem e2(e1, "Filter");
+ e2.Attr("Include", "Resource Files");
+ Elem(e2).WriteElem("UniqueIdentifier", "{" + guid + "}");
+ Elem(e2).WriteElem("Extensions",
+ "rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;"
+ "gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms");
+ e2.EndElement();
}
- this->WriteString("</ItemGroup>\n", 1);
- this->WriteString("</Project>\n", 0);
- // restore stream pointer
- this->BuildFileStream = save;
+ e1.EndElement();
+ e0.EndElement();
if (fout.Close()) {
this->GlobalGenerator->FileReplacedDuringGenerate(path);
@@ -1515,30 +1541,27 @@ void cmVisualStudio10TargetGenerator::AddMissingSourceGroups(
}
void cmVisualStudio10TargetGenerator::WriteGroupSources(
- std::string const& name, ToolSources const& sources,
+ Elem& e0, std::string const& name, ToolSources const& sources,
std::vector<cmSourceGroup>& sourceGroups)
{
- this->WriteString("<ItemGroup>\n", 1);
+ Elem e1(e0, "ItemGroup");
+ e1.SetHasElements();
for (ToolSource const& s : sources) {
cmSourceFile const* sf = s.SourceFile;
std::string const& source = sf->GetFullPath();
cmSourceGroup* sourceGroup =
this->Makefile->FindSourceGroup(source, sourceGroups);
std::string const& filter = sourceGroup->GetFullName();
- this->WriteString("<", 2);
std::string path = this->ConvertPath(source, s.RelativePath);
ConvertToWindowsSlash(path);
- (*this->BuildFileStream) << name << " Include=\"" << cmVS10EscapeXML(path);
+ Elem e2(e1, name.c_str());
+ e2.Attr("Include", cmVS10EscapeAttr(path));
if (!filter.empty()) {
- (*this->BuildFileStream) << "\">\n";
- this->WriteElem("Filter", filter, 3);
- this->WriteString("</", 2);
- (*this->BuildFileStream) << name << ">\n";
- } else {
- (*this->BuildFileStream) << "\" />\n";
+ Elem(e2).WriteElem("Filter", filter);
}
+ e2.EndElement();
}
- this->WriteString("</ItemGroup>\n", 1);
+ e1.EndElement();
}
void cmVisualStudio10TargetGenerator::WriteHeaderSource(cmSourceFile const* sf)
@@ -1850,7 +1873,7 @@ void cmVisualStudio10TargetGenerator::WriteSource(std::string const& tool,
ConvertToWindowsSlash(sourceFile);
this->WriteString("<", 2);
(*this->BuildFileStream) << tool << " Include=\""
- << cmVS10EscapeXML(sourceFile) << "\"";
+ << cmVS10EscapeAttr(sourceFile) << "\"";
ToolSource toolSource = { sf, forceRelative };
this->Tools[tool].push_back(toolSource);
@@ -1871,7 +1894,14 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
std::vector<cmGeneratorTarget::AllConfigSource> const& sources =
this->GeneratorTarget->GetAllConfigSources();
+ cmSourceFile const* srcCMakeLists =
+ this->LocalGenerator->CreateVCProjBuildRule();
+
for (cmGeneratorTarget::AllConfigSource const& si : sources) {
+ if (si.Source == srcCMakeLists) {
+ // Skip explicit reference to CMakeLists.txt source.
+ continue;
+ }
const char* tool = nullptr;
switch (si.Kind) {
case cmGeneratorTarget::SourceKindAppManifest:
@@ -2163,8 +2193,8 @@ void cmVisualStudio10TargetGenerator::WriteExcludeFromBuild(
this->WriteString("", 3);
(*this->BuildFileStream)
<< "<ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='"
- << cmVS10EscapeXML(this->Configurations[ci]) << "|"
- << cmVS10EscapeXML(this->Platform) << "'\">true</ExcludedFromBuild>\n";
+ << cmVS10EscapeAttr(this->Configurations[ci]) << "|"
+ << cmVS10EscapeAttr(this->Platform) << "'\">true</ExcludedFromBuild>\n";
}
}
@@ -2395,6 +2425,22 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
clOptions.AddFlag("AssemblerListingLocation", asmLocation);
}
}
+
+ // check for managed C++ assembly compiler flag. This overrides any
+ // /clr* compiler flags which may be defined in the flags variable(s).
+ if (this->ProjectType != csproj) {
+ // TODO: add check here, if /clr was defined manually and issue
+ // warning that this is discouraged.
+ if (auto* clr =
+ this->GeneratorTarget->GetProperty("COMMON_LANGUAGE_RUNTIME")) {
+ std::string clrString = clr;
+ if (!clrString.empty()) {
+ clrString = ":" + clrString;
+ }
+ flags += " /clr" + clrString;
+ }
+ }
+
clOptions.Parse(flags.c_str());
clOptions.Parse(defineFlags.c_str());
std::vector<std::string> targetDefines;
@@ -2651,6 +2697,20 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions(
cudaOptions.AppendFlagString("AdditionalOptions", "-x cu");
}
+ // Specify the compiler program database file if configured.
+ std::string pdb = this->GeneratorTarget->GetCompilePDBPath(configName);
+ if (!pdb.empty()) {
+ // CUDA does not have a field for this and does not honor the
+ // ProgramDataBaseFileName field in ClCompile. Work around this
+ // limitation by creating the directory and passing the flag ourselves.
+ std::string const pdbDir = cmSystemTools::GetFilenamePath(pdb);
+ cmSystemTools::MakeDirectory(pdbDir);
+ pdb = this->ConvertPath(pdb, true);
+ ConvertToWindowsSlash(pdb);
+ std::string const clFd = "-Xcompiler=\"-Fd\\\"" + pdb + "\\\"\"";
+ cudaOptions.AppendFlagString("AdditionalOptions", clFd);
+ }
+
// CUDA automatically passes the proper '--machine' flag to nvcc
// for the current architecture, but does not reflect this default
// in the user-visible IDE settings. Set it explicitly.
@@ -3602,15 +3662,13 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences()
path += computeProjectFileExtension(dt, *this->Configurations.begin());
}
ConvertToWindowsSlash(path);
- (*this->BuildFileStream) << cmVS10EscapeXML(path) << "\">\n";
+ (*this->BuildFileStream) << cmVS10EscapeAttr(path) << "\">\n";
this->WriteElem("Project",
"{" + this->GlobalGenerator->GetGUID(name) + "}", 3);
this->WriteElem("Name", name, 3);
this->WriteDotNetReferenceCustomTags(name);
- if (csproj == this->ProjectType) {
- if (!this->GlobalGenerator->TargetCanBeReferenced(dt)) {
- this->WriteElem("ReferenceOutputAssembly", "false", 3);
- }
+ if (!this->GlobalGenerator->TargetCanBeReferenced(dt)) {
+ this->WriteElem("ReferenceOutputAssembly", "false", 3);
}
this->WriteString("</ProjectReference>\n", 2);
}
@@ -3670,7 +3728,7 @@ void cmVisualStudio10TargetGenerator::WriteSDKReferences()
hasWrittenItemGroup = true;
for (std::string const& ri : sdkReferences) {
this->WriteString("<SDKReference Include=\"", 2);
- (*this->BuildFileStream) << cmVS10EscapeXML(ri) << "\"/>\n";
+ (*this->BuildFileStream) << cmVS10EscapeAttr(ri) << "\"/>\n";
}
}
@@ -4012,7 +4070,7 @@ void cmVisualStudio10TargetGenerator::WriteMissingFilesWP80()
std::string sourceFile = this->ConvertPath(manifestFile, false);
ConvertToWindowsSlash(sourceFile);
this->WriteString("<Xml Include=\"", 2);
- (*this->BuildFileStream) << cmVS10EscapeXML(sourceFile) << "\">\n";
+ (*this->BuildFileStream) << cmVS10EscapeAttr(sourceFile) << "\">\n";
this->WriteElem("SubType", "Designer", 3);
this->WriteString("</Xml>\n", 2);
this->AddedFiles.push_back(sourceFile);
@@ -4022,14 +4080,14 @@ void cmVisualStudio10TargetGenerator::WriteMissingFilesWP80()
false);
ConvertToWindowsSlash(smallLogo);
this->WriteString("<Image Include=\"", 2);
- (*this->BuildFileStream) << cmVS10EscapeXML(smallLogo) << "\" />\n";
+ (*this->BuildFileStream) << cmVS10EscapeAttr(smallLogo) << "\" />\n";
this->AddedFiles.push_back(smallLogo);
std::string logo = this->DefaultArtifactDir + "/Logo.png";
cmSystemTools::CopyAFile(templateFolder + "/Logo.png", logo, false);
ConvertToWindowsSlash(logo);
this->WriteString("<Image Include=\"", 2);
- (*this->BuildFileStream) << cmVS10EscapeXML(logo) << "\" />\n";
+ (*this->BuildFileStream) << cmVS10EscapeAttr(logo) << "\" />\n";
this->AddedFiles.push_back(logo);
std::string applicationIcon =
@@ -4038,7 +4096,7 @@ void cmVisualStudio10TargetGenerator::WriteMissingFilesWP80()
applicationIcon, false);
ConvertToWindowsSlash(applicationIcon);
this->WriteString("<Image Include=\"", 2);
- (*this->BuildFileStream) << cmVS10EscapeXML(applicationIcon) << "\" />\n";
+ (*this->BuildFileStream) << cmVS10EscapeAttr(applicationIcon) << "\" />\n";
this->AddedFiles.push_back(applicationIcon);
}
@@ -4290,7 +4348,7 @@ void cmVisualStudio10TargetGenerator::WriteCommonMissingFiles(
std::string sourceFile = this->ConvertPath(manifestFile, false);
ConvertToWindowsSlash(sourceFile);
this->WriteString("<AppxManifest Include=\"", 2);
- (*this->BuildFileStream) << cmVS10EscapeXML(sourceFile) << "\">\n";
+ (*this->BuildFileStream) << cmVS10EscapeAttr(sourceFile) << "\">\n";
this->WriteElem("SubType", "Designer", 3);
this->WriteString("</AppxManifest>\n", 2);
this->AddedFiles.push_back(sourceFile);
@@ -4300,7 +4358,7 @@ void cmVisualStudio10TargetGenerator::WriteCommonMissingFiles(
false);
ConvertToWindowsSlash(smallLogo);
this->WriteString("<Image Include=\"", 2);
- (*this->BuildFileStream) << cmVS10EscapeXML(smallLogo) << "\" />\n";
+ (*this->BuildFileStream) << cmVS10EscapeAttr(smallLogo) << "\" />\n";
this->AddedFiles.push_back(smallLogo);
std::string smallLogo44 = this->DefaultArtifactDir + "/SmallLogo44x44.png";
@@ -4308,14 +4366,14 @@ void cmVisualStudio10TargetGenerator::WriteCommonMissingFiles(
false);
ConvertToWindowsSlash(smallLogo44);
this->WriteString("<Image Include=\"", 2);
- (*this->BuildFileStream) << cmVS10EscapeXML(smallLogo44) << "\" />\n";
+ (*this->BuildFileStream) << cmVS10EscapeAttr(smallLogo44) << "\" />\n";
this->AddedFiles.push_back(smallLogo44);
std::string logo = this->DefaultArtifactDir + "/Logo.png";
cmSystemTools::CopyAFile(templateFolder + "/Logo.png", logo, false);
ConvertToWindowsSlash(logo);
this->WriteString("<Image Include=\"", 2);
- (*this->BuildFileStream) << cmVS10EscapeXML(logo) << "\" />\n";
+ (*this->BuildFileStream) << cmVS10EscapeAttr(logo) << "\" />\n";
this->AddedFiles.push_back(logo);
std::string storeLogo = this->DefaultArtifactDir + "/StoreLogo.png";
@@ -4323,7 +4381,7 @@ void cmVisualStudio10TargetGenerator::WriteCommonMissingFiles(
false);
ConvertToWindowsSlash(storeLogo);
this->WriteString("<Image Include=\"", 2);
- (*this->BuildFileStream) << cmVS10EscapeXML(storeLogo) << "\" />\n";
+ (*this->BuildFileStream) << cmVS10EscapeAttr(storeLogo) << "\" />\n";
this->AddedFiles.push_back(storeLogo);
std::string splashScreen = this->DefaultArtifactDir + "/SplashScreen.png";
@@ -4331,14 +4389,14 @@ void cmVisualStudio10TargetGenerator::WriteCommonMissingFiles(
false);
ConvertToWindowsSlash(splashScreen);
this->WriteString("<Image Include=\"", 2);
- (*this->BuildFileStream) << cmVS10EscapeXML(splashScreen) << "\" />\n";
+ (*this->BuildFileStream) << cmVS10EscapeAttr(splashScreen) << "\" />\n";
this->AddedFiles.push_back(splashScreen);
// This file has already been added to the build so don't copy it
std::string keyFile = this->DefaultArtifactDir + "/Windows_TemporaryKey.pfx";
ConvertToWindowsSlash(keyFile);
this->WriteString("<None Include=\"", 2);
- (*this->BuildFileStream) << cmVS10EscapeXML(keyFile) << "\" />\n";
+ (*this->BuildFileStream) << cmVS10EscapeAttr(keyFile) << "\" />\n";
}
bool cmVisualStudio10TargetGenerator::ForceOld(const std::string& source) const
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index 7106737..3c53d1b 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -158,7 +158,8 @@ private:
void WriteEvent(const char* name,
std::vector<cmCustomCommand> const& commands,
std::string const& configName);
- void WriteGroupSources(std::string const& name, ToolSources const& sources,
+ void WriteGroupSources(Elem& e0, std::string const& name,
+ ToolSources const& sources,
std::vector<cmSourceGroup>&);
void AddMissingSourceGroups(std::set<cmSourceGroup*>& groupsUsed,
const std::vector<cmSourceGroup>& allGroups);
@@ -203,7 +204,7 @@ private:
bool MSTools;
bool Managed;
bool NsightTegra;
- int NsightTegraVersion[4];
+ unsigned int NsightTegraVersion[4];
bool TargetCompileAsWinRT;
cmGlobalVisualStudio10Generator* const GlobalGenerator;
cmGeneratedFileStream* BuildFileStream;
diff --git a/Source/cmXMLWriter.cxx b/Source/cmXMLWriter.cxx
index 3cbc70d..9d2a3c4 100644
--- a/Source/cmXMLWriter.cxx
+++ b/Source/cmXMLWriter.cxx
@@ -9,6 +9,7 @@ cmXMLWriter::cmXMLWriter(std::ostream& output, std::size_t level)
: Output(output)
, IndentationElement(1, '\t')
, Level(level)
+ , Indent(0)
, ElementOpen(false)
, BreakAttrib(false)
, IsContent(false)
@@ -17,7 +18,7 @@ cmXMLWriter::cmXMLWriter(std::ostream& output, std::size_t level)
cmXMLWriter::~cmXMLWriter()
{
- assert(this->Elements.empty());
+ assert(this->Indent == 0);
}
void cmXMLWriter::StartDocument(const char* encoding)
@@ -27,27 +28,29 @@ void cmXMLWriter::StartDocument(const char* encoding)
void cmXMLWriter::EndDocument()
{
- assert(this->Elements.empty());
+ assert(this->Indent == 0);
this->Output << '\n';
}
void cmXMLWriter::StartElement(std::string const& name)
{
this->CloseStartElement();
- this->ConditionalLineBreak(!this->IsContent, this->Elements.size());
+ this->ConditionalLineBreak(!this->IsContent);
this->Output << '<' << name;
this->Elements.push(name);
+ ++this->Indent;
this->ElementOpen = true;
this->BreakAttrib = false;
}
void cmXMLWriter::EndElement()
{
- assert(!this->Elements.empty());
+ assert(this->Indent > 0);
+ --this->Indent;
if (this->ElementOpen) {
this->Output << "/>";
} else {
- this->ConditionalLineBreak(!this->IsContent, this->Elements.size() - 1);
+ this->ConditionalLineBreak(!this->IsContent);
this->IsContent = false;
this->Output << "</" << this->Elements.top() << '>';
}
@@ -58,7 +61,7 @@ void cmXMLWriter::EndElement()
void cmXMLWriter::Element(const char* name)
{
this->CloseStartElement();
- this->ConditionalLineBreak(!this->IsContent, this->Elements.size());
+ this->ConditionalLineBreak(!this->IsContent);
this->Output << '<' << name << "/>";
}
@@ -70,7 +73,7 @@ void cmXMLWriter::BreakAttributes()
void cmXMLWriter::Comment(const char* comment)
{
this->CloseStartElement();
- this->ConditionalLineBreak(!this->IsContent, this->Elements.size());
+ this->ConditionalLineBreak(!this->IsContent);
this->Output << "<!-- " << comment << " -->";
}
@@ -83,14 +86,14 @@ void cmXMLWriter::CData(std::string const& data)
void cmXMLWriter::Doctype(const char* doctype)
{
this->CloseStartElement();
- this->ConditionalLineBreak(!this->IsContent, this->Elements.size());
+ this->ConditionalLineBreak(!this->IsContent);
this->Output << "<!DOCTYPE " << doctype << ">";
}
void cmXMLWriter::ProcessingInstruction(const char* target, const char* data)
{
this->CloseStartElement();
- this->ConditionalLineBreak(!this->IsContent, this->Elements.size());
+ this->ConditionalLineBreak(!this->IsContent);
this->Output << "<?" << target << ' ' << data << "?>";
}
@@ -106,11 +109,11 @@ void cmXMLWriter::SetIndentationElement(std::string const& element)
this->IndentationElement = element;
}
-void cmXMLWriter::ConditionalLineBreak(bool condition, std::size_t indent)
+void cmXMLWriter::ConditionalLineBreak(bool condition)
{
if (condition) {
this->Output << '\n';
- for (std::size_t i = 0; i < indent + this->Level; ++i) {
+ for (std::size_t i = 0; i < this->Indent + this->Level; ++i) {
this->Output << this->IndentationElement;
}
}
@@ -119,7 +122,7 @@ void cmXMLWriter::ConditionalLineBreak(bool condition, std::size_t indent)
void cmXMLWriter::PreAttribute()
{
assert(this->ElementOpen);
- this->ConditionalLineBreak(this->BreakAttrib, this->Elements.size());
+ this->ConditionalLineBreak(this->BreakAttrib);
if (!this->BreakAttrib) {
this->Output << ' ';
}
@@ -134,7 +137,7 @@ void cmXMLWriter::PreContent()
void cmXMLWriter::CloseStartElement()
{
if (this->ElementOpen) {
- this->ConditionalLineBreak(this->BreakAttrib, this->Elements.size());
+ this->ConditionalLineBreak(this->BreakAttrib);
this->Output << '>';
this->ElementOpen = false;
}
diff --git a/Source/cmXMLWriter.h b/Source/cmXMLWriter.h
index 80940ee..ff0df18 100644
--- a/Source/cmXMLWriter.h
+++ b/Source/cmXMLWriter.h
@@ -67,7 +67,7 @@ public:
void SetIndentationElement(std::string const& element);
private:
- void ConditionalLineBreak(bool condition, std::size_t indent);
+ void ConditionalLineBreak(bool condition);
void PreAttribute();
void PreContent();
@@ -128,6 +128,7 @@ private:
std::stack<std::string, std::vector<std::string>> Elements;
std::string IndentationElement;
std::size_t Level;
+ std::size_t Indent;
bool ElementOpen;
bool BreakAttrib;
bool IsContent;
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 83c5384..5bae4e7 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -1433,6 +1433,7 @@ int cmake::ActualConfigure()
// only save the cache if there were no fatal errors
if (this->GetWorkingMode() == NORMAL_MODE) {
+ this->State->SaveVerificationScript(this->GetHomeOutputDirectory());
this->SaveCache(this->GetHomeOutputDirectory());
}
if (cmSystemTools::GetErrorOccuredFlag()) {
@@ -1647,6 +1648,33 @@ void cmake::AddCacheEntry(const std::string& key, const char* value,
this->UnwatchUnusedCli(key);
}
+bool cmake::DoWriteGlobVerifyTarget() const
+{
+ return this->State->DoWriteGlobVerifyTarget();
+}
+
+std::string const& cmake::GetGlobVerifyScript() const
+{
+ return this->State->GetGlobVerifyScript();
+}
+
+std::string const& cmake::GetGlobVerifyStamp() const
+{
+ return this->State->GetGlobVerifyStamp();
+}
+
+void cmake::AddGlobCacheEntry(bool recurse, bool listDirectories,
+ bool followSymlinks, const std::string& relative,
+ const std::string& expression,
+ const std::vector<std::string>& files,
+ const std::string& variable,
+ cmListFileBacktrace const& backtrace)
+{
+ this->State->AddGlobCacheEntry(recurse, listDirectories, followSymlinks,
+ relative, expression, files, variable,
+ backtrace);
+}
+
std::string cmake::StripExtension(const std::string& file) const
{
auto dotpos = file.rfind('.');
@@ -2434,37 +2462,49 @@ int cmake::Build(const std::string& dir, const std::string& target,
cmGlobalVisualStudio9Generator::GetGenerateStampList();
// Note that the stampList file only exists for VS generators.
- if (cmSystemTools::FileExists(stampList) &&
- !cmakeCheckStampList(stampList.c_str(), false)) {
-
- // Correctly initialize the home (=source) and home output (=binary)
- // directories, which is required for running the generation step.
- std::string homeOrig = this->GetHomeDirectory();
- std::string homeOutputOrig = this->GetHomeOutputDirectory();
- this->SetDirectoriesFromFile(cachePath.c_str());
+ if (cmSystemTools::FileExists(stampList)) {
+ // Check if running for Visual Studio 9 - we need to explicitly run
+ // the glob verification script before starting the build
this->AddScriptingCommands();
- this->AddProjectCommands();
+ if (this->GlobalGenerator->MatchesGeneratorName("Visual Studio 9 2008")) {
+ std::string const globVerifyScript = cachePath + "/" +
+ GetCMakeFilesDirectoryPostSlash() + "VerifyGlobs.cmake";
+ if (cmSystemTools::FileExists(globVerifyScript)) {
+ std::vector<std::string> args;
+ this->ReadListFile(args, globVerifyScript.c_str());
+ }
+ }
- int ret = this->Configure();
- if (ret) {
- cmSystemTools::Message("CMake Configure step failed. "
- "Build files cannot be regenerated correctly.");
- return ret;
- }
- ret = this->Generate();
- if (ret) {
- cmSystemTools::Message("CMake Generate step failed. "
- "Build files cannot be regenerated correctly.");
- return ret;
- }
- std::string message = "Build files have been written to: ";
- message += this->GetHomeOutputDirectory();
- this->UpdateProgress(message.c_str(), -1);
-
- // Restore the previously set directories to their original value.
- this->SetHomeDirectory(homeOrig);
- this->SetHomeOutputDirectory(homeOutputOrig);
+ if (!cmakeCheckStampList(stampList.c_str(), false)) {
+ // Correctly initialize the home (=source) and home output (=binary)
+ // directories, which is required for running the generation step.
+ std::string homeOrig = this->GetHomeDirectory();
+ std::string homeOutputOrig = this->GetHomeOutputDirectory();
+ this->SetDirectoriesFromFile(cachePath.c_str());
+
+ this->AddProjectCommands();
+
+ int ret = this->Configure();
+ if (ret) {
+ cmSystemTools::Message("CMake Configure step failed. "
+ "Build files cannot be regenerated correctly.");
+ return ret;
+ }
+ ret = this->Generate();
+ if (ret) {
+ cmSystemTools::Message("CMake Generate step failed. "
+ "Build files cannot be regenerated correctly.");
+ return ret;
+ }
+ std::string message = "Build files have been written to: ";
+ message += this->GetHomeOutputDirectory();
+ this->UpdateProgress(message.c_str(), -1);
+
+ // Restore the previously set directories to their original value.
+ this->SetHomeDirectory(homeOrig);
+ this->SetHomeOutputDirectory(homeOutputOrig);
+ }
}
#endif
diff --git a/Source/cmake.h b/Source/cmake.h
index cc56a07..63dbe9f 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -255,6 +255,16 @@ public:
void AddCacheEntry(const std::string& key, const char* value,
const char* helpString, int type);
+ bool DoWriteGlobVerifyTarget() const;
+ std::string const& GetGlobVerifyScript() const;
+ std::string const& GetGlobVerifyStamp() const;
+ void AddGlobCacheEntry(bool recurse, bool listDirectories,
+ bool followSymlinks, const std::string& relative,
+ const std::string& expression,
+ const std::vector<std::string>& files,
+ const std::string& variable,
+ cmListFileBacktrace const& bt);
+
/**
* Get the system information and write it to the file specified
*/
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx
index 2b9d7b1..7426816 100644
--- a/Source/kwsys/SystemInformation.cxx
+++ b/Source/kwsys/SystemInformation.cxx
@@ -94,7 +94,6 @@ typedef int siginfo_t;
#endif
#ifdef __APPLE__
-#include <fenv.h>
#include <mach/host_info.h>
#include <mach/mach.h>
#include <mach/mach_types.h>
@@ -114,7 +113,6 @@ typedef int siginfo_t;
#endif
#if defined(__linux) || defined(__sun) || defined(_SCO_DS)
-#include <fenv.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 1344692..aad7cfc 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -1431,6 +1431,10 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
add_subdirectory(FindPython)
endif()
+ if(CMake_TEST_UseSWIG)
+ add_subdirectory(UseSWIG)
+ endif()
+
add_subdirectory(FindThreads)
# Matlab module
@@ -1438,6 +1442,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
ADD_TEST_MACRO(FindMatlab.basic_checks ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>)
ADD_TEST_MACRO(FindMatlab.versions_checks ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>)
ADD_TEST_MACRO(FindMatlab.components_checks ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>)
+ ADD_TEST_MACRO(FindMatlab.failure_reports ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>)
endif()
find_package(GTK2 QUIET)
diff --git a/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in b/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in
index 65487bb..9157c76 100644
--- a/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in
+++ b/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in
@@ -349,6 +349,12 @@ set(aix_xlf90_64_libs "xlf90;xlopt;xlf;xlomp_ser;m;c")
set(aix_xlf90_64_dirs "/usr/lpp/xlf/lib")
list(APPEND platforms aix_xlf90_64)
+# g++ dummy.c -v
+set(aix_g++_text " /prefix/libexec/gcc/powerpc-ibm-aix7.2.0.0/7.2.0/collect2 -bpT:0x10000000 -bpD:0x20000000 -btextro /lib/crt0.o /prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0/crtcxa.o /prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0/crtdbase.o -L/prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0 -L/prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0/../../.. /tmp//ccKROJ1f.o -lstdc++ -lm -lgcc_s /prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0/libgcc.a -lc -lgcc_s /prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0/libgcc.a")
+set(aix_g++_libs "stdc++;m;gcc_s;/prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0/libgcc.a;c;gcc_s;/prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0/libgcc.a")
+set(aix_g++_dirs "/prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0;/prefix/lib")
+list(APPEND platforms aix_g++)
+
#-----------------------------------------------------------------------------
# HP
diff --git a/Tests/CompileFeatures/CMakeLists.txt b/Tests/CompileFeatures/CMakeLists.txt
index e94473f..b0bc656 100644
--- a/Tests/CompileFeatures/CMakeLists.txt
+++ b/Tests/CompileFeatures/CMakeLists.txt
@@ -224,69 +224,22 @@ if (C_expected_features)
add_executable(CompileFeaturesGenex_C genex_test.c)
set_property(TARGET CompileFeaturesGenex_C PROPERTY C_STANDARD 11)
- if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
- if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.6)
- list(APPEND expected_defs
- EXPECT_C_RESTRICT=1
- EXPECT_C_STATIC_ASSERT=1
- )
- else()
- list(APPEND expected_defs
- EXPECT_C_RESTRICT=1
- EXPECT_C_STATIC_ASSERT=0
- )
- endif()
- elseif(CMAKE_C_COMPILER_ID STREQUAL "Clang"
- OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
- list(APPEND expected_defs
- EXPECT_C_RESTRICT=1
- EXPECT_C_STATIC_ASSERT=1
- )
- elseif (CMAKE_C_COMPILER_ID STREQUAL "Intel")
- if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 15)
- list(APPEND expected_defs
- EXPECT_C_RESTRICT=1
- EXPECT_C_STATIC_ASSERT=1
- )
- else()
- list(APPEND expected_defs
- EXPECT_C_RESTRICT=1
- EXPECT_C_STATIC_ASSERT=0
- )
- endif()
- elseif(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
- list(APPEND expected_defs
- EXPECT_C_RESTRICT=0
- EXPECT_C_STATIC_ASSERT=0
+ foreach(f
+ c_restrict
+ c_static_assert
+ c_function_prototypes
)
- elseif (CMAKE_C_COMPILER_ID STREQUAL "SunPro")
- if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5.13)
- list(APPEND expected_defs
- EXPECT_C_RESTRICT=1
- EXPECT_C_STATIC_ASSERT=1
- )
+ if(${f} IN_LIST C_expected_features)
+ set(expect_${f} 1)
else()
- list(APPEND expected_defs
- EXPECT_C_RESTRICT=1
- EXPECT_C_STATIC_ASSERT=0
- )
+ set(expect_${f} 0)
endif()
- else()
- list(APPEND expected_defs
- EXPECT_C_RESTRICT=1
+ string(TOUPPER "${f}" F)
+ target_compile_definitions(CompileFeaturesGenex_C PRIVATE
+ EXPECT_${F}=${expect_${f}}
+ HAVE_${F}=$<COMPILE_FEATURES:${f}>
)
- endif()
-
- list(APPEND expected_defs
- EXPECT_C_FUNCTION_PROTOTYPES=1
- )
-
- target_compile_definitions(CompileFeaturesGenex_C PRIVATE
- HAVE_C_FUNCTION_PROTOTYPES=$<COMPILE_FEATURES:c_function_prototypes>
- HAVE_C_RESTRICT=$<COMPILE_FEATURES:c_restrict>
- HAVE_C_STATIC_ASSERT=$<COMPILE_FEATURES:c_static_assert>
- ${expected_defs}
- )
+ endforeach()
endif()
if (CMAKE_CXX_COMPILE_FEATURES)
@@ -334,118 +287,43 @@ else()
add_executable(IfaceCompileFeatures main.cpp)
target_link_libraries(IfaceCompileFeatures iface)
- if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
- if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8)
- add_definitions(
- -DEXPECT_OVERRIDE_CONTROL=1
- -DEXPECT_INHERITING_CONSTRUCTORS=1
- -DEXPECT_FINAL=1
- -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=1
- )
- elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7)
- add_definitions(
- -DEXPECT_OVERRIDE_CONTROL=1
- -DEXPECT_INHERITING_CONSTRUCTORS=0
- -DEXPECT_FINAL=1
- -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=0
+ foreach(f
+ cxx_final
+ cxx_override
+ cxx_auto_type
+ cxx_inheriting_constructors
)
+ if(${f} IN_LIST CXX_expected_features)
+ set(expect_${f} 1)
else()
- add_definitions(
- -DEXPECT_OVERRIDE_CONTROL=0
- -DEXPECT_INHERITING_CONSTRUCTORS=0
- -DEXPECT_FINAL=0
- -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=0
- )
- endif()
- elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
- add_definitions(
- -DEXPECT_OVERRIDE_CONTROL=1
- -DEXPECT_INHERITING_CONSTRUCTORS=1
- -DEXPECT_FINAL=1
- -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=1
- )
- elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
- if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
- add_definitions(
- -DEXPECT_OVERRIDE_CONTROL=1
- -DEXPECT_INHERITING_CONSTRUCTORS=1
- -DEXPECT_FINAL=1
- -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=1
- )
- else()
- add_definitions(
- -DEXPECT_OVERRIDE_CONTROL=1
- -DEXPECT_INHERITING_CONSTRUCTORS=0
- -DEXPECT_FINAL=1
- -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=0
- )
- endif()
- elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
- if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.0)
- add_definitions(
- -DEXPECT_OVERRIDE_CONTROL=1
- -DEXPECT_INHERITING_CONSTRUCTORS=1
- -DEXPECT_FINAL=1
- -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=1
- )
- elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 17.0)
- add_definitions(
- -DEXPECT_OVERRIDE_CONTROL=1
- -DEXPECT_INHERITING_CONSTRUCTORS=0
- -DEXPECT_FINAL=1
- -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=0
- )
- else()
- add_definitions(
- -DEXPECT_OVERRIDE_CONTROL=0
- -DEXPECT_INHERITING_CONSTRUCTORS=0
- -DEXPECT_FINAL=0
- -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=0
- )
- endif()
- elseif (CMAKE_CXX_COMPILER_ID STREQUAL "SunPro")
- add_definitions(
- -DEXPECT_OVERRIDE_CONTROL=1
- -DEXPECT_INHERITING_CONSTRUCTORS=1
- -DEXPECT_FINAL=1
- -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=1
- )
- elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
- if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 15)
- add_definitions(
- -DEXPECT_OVERRIDE_CONTROL=1
- -DEXPECT_INHERITING_CONSTRUCTORS=1
- -DEXPECT_FINAL=1
- -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=1
- )
- elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 14)
- add_definitions(
- -DEXPECT_OVERRIDE_CONTROL=1
- -DEXPECT_INHERITING_CONSTRUCTORS=0
- -DEXPECT_FINAL=1
- -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=0
- )
- else()
- add_definitions(
- -DEXPECT_OVERRIDE_CONTROL=0
- -DEXPECT_INHERITING_CONSTRUCTORS=0
- -DEXPECT_FINAL=0
- -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=0
- )
+ set(expect_${f} 0)
endif()
+ endforeach()
+
+ if(expect_cxx_final AND expect_cxx_override)
+ set(expect_override_control 1)
+ else()
+ set(expect_override_control 0)
+ endif()
+ if(expect_cxx_inheriting_constructors AND expect_cxx_final)
+ set(expect_inheriting_constructors_and_final 1)
+ else()
+ set(expect_inheriting_constructors_and_final 0)
endif()
- add_executable(CompileFeaturesGenex genex_test.cpp)
- set_property(TARGET CompileFeaturesGenex PROPERTY CXX_STANDARD 11)
- target_compile_definitions(CompileFeaturesGenex PRIVATE
+ set(genex_test_defs
HAVE_OVERRIDE_CONTROL=$<COMPILE_FEATURES:cxx_final,cxx_override>
HAVE_AUTO_TYPE=$<COMPILE_FEATURES:cxx_auto_type>
HAVE_INHERITING_CONSTRUCTORS=$<COMPILE_FEATURES:cxx_inheriting_constructors>
HAVE_FINAL=$<COMPILE_FEATURES:cxx_final>
HAVE_INHERITING_CONSTRUCTORS_AND_FINAL=$<COMPILE_FEATURES:cxx_inheriting_constructors,cxx_final>
- )
+ EXPECT_OVERRIDE_CONTROL=${expect_override_control}
+ EXPECT_INHERITING_CONSTRUCTORS=${expect_cxx_inheriting_constructors}
+ EXPECT_FINAL=${expect_cxx_final}
+ EXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=${expect_inheriting_constructors_and_final}
+ )
if (CMAKE_CXX_STANDARD_DEFAULT)
- target_compile_definitions(CompileFeaturesGenex PRIVATE
+ list(APPEND genex_test_defs
TEST_CXX_STD
HAVE_CXX_STD_11=$<COMPILE_FEATURES:cxx_std_11>
HAVE_CXX_STD_14=$<COMPILE_FEATURES:cxx_std_14>
@@ -454,25 +332,17 @@ else()
)
endif()
+ add_executable(CompileFeaturesGenex genex_test.cpp)
+ set_property(TARGET CompileFeaturesGenex PROPERTY CXX_STANDARD 11)
+ target_compile_definitions(CompileFeaturesGenex PRIVATE ${genex_test_defs})
+
add_executable(CompileFeaturesGenex2 genex_test.cpp)
target_compile_features(CompileFeaturesGenex2 PRIVATE cxx_std_11)
- target_compile_definitions(CompileFeaturesGenex2 PRIVATE
- HAVE_OVERRIDE_CONTROL=$<COMPILE_FEATURES:cxx_final,cxx_override>
- HAVE_AUTO_TYPE=$<COMPILE_FEATURES:cxx_auto_type>
- HAVE_INHERITING_CONSTRUCTORS=$<COMPILE_FEATURES:cxx_inheriting_constructors>
- HAVE_FINAL=$<COMPILE_FEATURES:cxx_final>
- HAVE_INHERITING_CONSTRUCTORS_AND_FINAL=$<COMPILE_FEATURES:cxx_inheriting_constructors,cxx_final>
- )
+ target_compile_definitions(CompileFeaturesGenex2 PRIVATE ${genex_test_defs})
add_library(std_11_iface INTERFACE)
target_compile_features(std_11_iface INTERFACE cxx_std_11)
add_executable(CompileFeaturesGenex3 genex_test.cpp)
target_link_libraries(CompileFeaturesGenex3 PRIVATE std_11_iface)
- target_compile_definitions(CompileFeaturesGenex3 PRIVATE
- HAVE_OVERRIDE_CONTROL=$<COMPILE_FEATURES:cxx_final,cxx_override>
- HAVE_AUTO_TYPE=$<COMPILE_FEATURES:cxx_auto_type>
- HAVE_INHERITING_CONSTRUCTORS=$<COMPILE_FEATURES:cxx_inheriting_constructors>
- HAVE_FINAL=$<COMPILE_FEATURES:cxx_final>
- HAVE_INHERITING_CONSTRUCTORS_AND_FINAL=$<COMPILE_FEATURES:cxx_inheriting_constructors,cxx_final>
- )
+ target_compile_definitions(CompileFeaturesGenex3 PRIVATE ${genex_test_defs})
endif()
diff --git a/Tests/CudaOnly/CMakeLists.txt b/Tests/CudaOnly/CMakeLists.txt
index 5ad6e6b..59f3e84 100644
--- a/Tests/CudaOnly/CMakeLists.txt
+++ b/Tests/CudaOnly/CMakeLists.txt
@@ -2,6 +2,11 @@
ADD_TEST_MACRO(CudaOnly.EnableStandard CudaOnlyEnableStandard)
ADD_TEST_MACRO(CudaOnly.ExportPTX CudaOnlyExportPTX)
ADD_TEST_MACRO(CudaOnly.GPUDebugFlag CudaOnlyGPUDebugFlag)
+ADD_TEST_MACRO(CudaOnly.LinkSystemDeviceLibraries CudaOnlyLinkSystemDeviceLibraries)
ADD_TEST_MACRO(CudaOnly.ResolveDeviceSymbols CudaOnlyResolveDeviceSymbols)
ADD_TEST_MACRO(CudaOnly.SeparateCompilation CudaOnlySeparateCompilation)
ADD_TEST_MACRO(CudaOnly.WithDefs CudaOnlyWithDefs)
+
+if(MSVC)
+ ADD_TEST_MACRO(CudaOnly.PDB CudaOnlyPDB)
+endif()
diff --git a/Tests/CudaOnly/LinkSystemDeviceLibraries/CMakeLists.txt b/Tests/CudaOnly/LinkSystemDeviceLibraries/CMakeLists.txt
new file mode 100644
index 0000000..62be1e6
--- /dev/null
+++ b/Tests/CudaOnly/LinkSystemDeviceLibraries/CMakeLists.txt
@@ -0,0 +1,15 @@
+cmake_minimum_required(VERSION 3.8)
+project(CudaOnlyLinkSystemDeviceLibraries CUDA)
+
+string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_35,code=compute_35 -gencode arch=compute_35,code=sm_35")
+set(CMAKE_CUDA_STANDARD 11)
+
+add_executable(CudaOnlyLinkSystemDeviceLibraries main.cu)
+set_target_properties( CudaOnlyLinkSystemDeviceLibraries
+ PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
+target_link_libraries( CudaOnlyLinkSystemDeviceLibraries PRIVATE cublas_device)
+
+if(APPLE)
+ # Help the static cuda runtime find the driver (libcuda.dyllib) at runtime.
+ set_property(TARGET CudaOnlyLinkSystemDeviceLibraries PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES})
+endif()
diff --git a/Tests/CudaOnly/LinkSystemDeviceLibraries/main.cu b/Tests/CudaOnly/LinkSystemDeviceLibraries/main.cu
new file mode 100644
index 0000000..7eecec1
--- /dev/null
+++ b/Tests/CudaOnly/LinkSystemDeviceLibraries/main.cu
@@ -0,0 +1,77 @@
+
+#include <cublas_v2.h>
+#include <cuda_runtime.h>
+#include <iostream>
+
+__global__ void deviceCublasSgemm(int n, float alpha, float beta,
+ const float* d_A, const float* d_B,
+ float* d_C)
+{
+ cublasHandle_t cnpHandle;
+ cublasStatus_t status = cublasCreate(&cnpHandle);
+
+ if (status != CUBLAS_STATUS_SUCCESS) {
+ return;
+ }
+
+ // Call function defined in the cublas_device system static library.
+ // This way we can verify that we properly pass system libraries to the
+ // device link line
+ status = cublasSgemm(cnpHandle, CUBLAS_OP_N, CUBLAS_OP_N, n, n, n, &alpha,
+ d_A, n, d_B, n, &beta, d_C, n);
+
+ cublasDestroy(cnpHandle);
+}
+
+int choose_cuda_device()
+{
+ int nDevices = 0;
+ cudaError_t err = cudaGetDeviceCount(&nDevices);
+ if (err != cudaSuccess) {
+ std::cerr << "Failed to retrieve the number of CUDA enabled devices"
+ << std::endl;
+ return 1;
+ }
+ for (int i = 0; i < nDevices; ++i) {
+ cudaDeviceProp prop;
+ cudaError_t err = cudaGetDeviceProperties(&prop, i);
+ if (err != cudaSuccess) {
+ std::cerr << "Could not retrieve properties from CUDA device " << i
+ << std::endl;
+ return 1;
+ }
+
+ if (prop.major > 3 || (prop.major == 3 && prop.minor >= 5)) {
+ err = cudaSetDevice(i);
+ if (err != cudaSuccess) {
+ std::cout << "Could not select CUDA device " << i << std::endl;
+ } else {
+ return 0;
+ }
+ }
+ }
+
+ std::cout << "Could not find a CUDA enabled card supporting compute >=3.5"
+ << std::endl;
+ return 1;
+}
+
+int main(int argc, char** argv)
+{
+ int ret = choose_cuda_device();
+ if (ret) {
+ return 0;
+ }
+
+ // initial values that will make sure that the cublasSgemm won't actually
+ // do any work
+ int n = 0;
+ float alpha = 1;
+ float beta = 1;
+ float* d_A = nullptr;
+ float* d_B = nullptr;
+ float* d_C = nullptr;
+ deviceCublasSgemm<<<1, 1>>>(n, alpha, beta, d_A, d_B, d_C);
+
+ return 0;
+}
diff --git a/Tests/CudaOnly/PDB/CMakeLists.txt b/Tests/CudaOnly/PDB/CMakeLists.txt
new file mode 100644
index 0000000..34e1e5c
--- /dev/null
+++ b/Tests/CudaOnly/PDB/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 3.11)
+project (CudaOnlyPDB CUDA)
+
+add_executable(CudaOnlyPDB main.cu)
+set_target_properties(CudaOnlyPDB PROPERTIES
+ PDB_NAME LinkPDBName
+ PDB_OUTPUT_DIRECTORY LinkPDBDir
+ COMPILE_PDB_NAME CompPDBName
+ COMPILE_PDB_OUTPUT_DIRECTORY CompPDBDir
+ )
+
+set(pdbs
+ ${CMAKE_CURRENT_BINARY_DIR}/CompPDBDir/${CMAKE_CFG_INTDIR}/CompPDBName.pdb
+ ${CMAKE_CURRENT_BINARY_DIR}/LinkPDBDir/${CMAKE_CFG_INTDIR}/LinkPDBName.pdb
+ )
+add_custom_command(TARGET CudaOnlyPDB POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -Dconfig=$<CONFIG> "-Dpdbs=${pdbs}"
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/check_pdbs.cmake
+ )
diff --git a/Tests/CudaOnly/PDB/check_pdbs.cmake b/Tests/CudaOnly/PDB/check_pdbs.cmake
new file mode 100644
index 0000000..5e01ca7
--- /dev/null
+++ b/Tests/CudaOnly/PDB/check_pdbs.cmake
@@ -0,0 +1,10 @@
+if(NOT "${config}" MATCHES "[Dd][Ee][Bb]")
+ return()
+endif()
+foreach(pdb ${pdbs})
+ if(EXISTS "${pdb}")
+ message(STATUS "PDB Exists: ${pdb}")
+ else()
+ message(SEND_ERROR "PDB MISSING:\n ${pdb}")
+ endif()
+endforeach()
diff --git a/Tests/CudaOnly/PDB/main.cu b/Tests/CudaOnly/PDB/main.cu
new file mode 100644
index 0000000..f8b643a
--- /dev/null
+++ b/Tests/CudaOnly/PDB/main.cu
@@ -0,0 +1,4 @@
+int main()
+{
+ return 0;
+}
diff --git a/Tests/FindMatlab/basic_checks/CMakeLists.txt b/Tests/FindMatlab/basic_checks/CMakeLists.txt
index bf54427..951fcf2 100644
--- a/Tests/FindMatlab/basic_checks/CMakeLists.txt
+++ b/Tests/FindMatlab/basic_checks/CMakeLists.txt
@@ -24,11 +24,12 @@ matlab_add_mex(
matlab_add_unit_test(
NAME ${PROJECT_NAME}_matlabtest-1
- TIMEOUT 90
+ TIMEOUT 300
UNITTEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../cmake_matlab_unit_tests1.m
ADDITIONAL_PATH $<TARGET_FILE_DIR:cmake_matlab_test_wrapper1>
)
+# timeout tests, TIMEOUT set to very short on purpose
matlab_add_unit_test(
NAME ${PROJECT_NAME}_matlabtest-2
TIMEOUT 15
@@ -41,7 +42,7 @@ set_tests_properties(${PROJECT_NAME}_matlabtest-2 PROPERTIES WILL_FAIL TRUE)
# testing the test without the unittest framework of Matlab
matlab_add_unit_test(
NAME ${PROJECT_NAME}_matlabtest-3
- TIMEOUT 30
+ TIMEOUT 300
NO_UNITTEST_FRAMEWORK
UNITTEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../cmake_matlab_unit_tests2.m
ADDITIONAL_PATH $<TARGET_FILE_DIR:cmake_matlab_test_wrapper1>
@@ -49,7 +50,7 @@ matlab_add_unit_test(
matlab_add_unit_test(
NAME ${PROJECT_NAME}_matlabtest-4
- TIMEOUT 30
+ TIMEOUT 300
NO_UNITTEST_FRAMEWORK
UNITTEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../cmake_matlab_unit_tests3.m
ADDITIONAL_PATH $<TARGET_FILE_DIR:cmake_matlab_test_wrapper1>
diff --git a/Tests/FindMatlab/failure_reports/CMakeLists.txt b/Tests/FindMatlab/failure_reports/CMakeLists.txt
new file mode 100644
index 0000000..1cf9613
--- /dev/null
+++ b/Tests/FindMatlab/failure_reports/CMakeLists.txt
@@ -0,0 +1,39 @@
+
+cmake_minimum_required (VERSION 2.8.12)
+enable_testing()
+project(failure_reports)
+
+# gather tests about proper failure reports
+
+set(MATLAB_FIND_DEBUG TRUE)
+
+find_package(Matlab REQUIRED COMPONENTS MX_LIBRARY MAIN_PROGRAM)
+
+# main extensions for testing, same as other tests
+matlab_add_mex(
+ # target name
+ NAME cmake_matlab_test_wrapper1
+ # output name
+ OUTPUT_NAME cmake_matlab_mex1
+ SRC ${CMAKE_CURRENT_SOURCE_DIR}/../matlab_wrapper1.cpp
+ DOCUMENTATION ${CMAKE_CURRENT_SOURCE_DIR}/../help_text1.m.txt
+ )
+
+# the unit test file does not exist: the failure should be properly reported
+matlab_add_unit_test(
+ NAME ${PROJECT_NAME}_matlabtest-1
+ TIMEOUT 300
+ UNITTEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../nonexistantfile.m
+ ADDITIONAL_PATH $<TARGET_FILE_DIR:cmake_matlab_test_wrapper1>
+ )
+set_tests_properties(${PROJECT_NAME}_matlabtest-1 PROPERTIES WILL_FAIL TRUE)
+
+# without the unit test framework
+matlab_add_unit_test(
+ NAME ${PROJECT_NAME}_matlabtest-2
+ TIMEOUT 300
+ NO_UNITTEST_FRAMEWORK
+ UNITTEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../nonexistantfile2.m
+ ADDITIONAL_PATH $<TARGET_FILE_DIR:cmake_matlab_test_wrapper1>
+ )
+set_tests_properties(${PROJECT_NAME}_matlabtest-2 PROPERTIES WILL_FAIL TRUE)
diff --git a/Tests/Module/ExternalData/Data5/CMakeLists.txt b/Tests/Module/ExternalData/Data5/CMakeLists.txt
index 13c7fab..ea67f05 100644
--- a/Tests/Module/ExternalData/Data5/CMakeLists.txt
+++ b/Tests/Module/ExternalData/Data5/CMakeLists.txt
@@ -2,21 +2,21 @@
ExternalData_Add_Test(Data5.A
NAME Data5Check.A
COMMAND ${CMAKE_COMMAND}
- -D Data5=DATA{../Data.dat}
+ -D Data5=DATA{Data5.dat}
-P ${CMAKE_CURRENT_SOURCE_DIR}/Data5Check.cmake
)
ExternalData_Add_Target(Data5.A)
ExternalData_Add_Test(Data5.B
NAME Data5Check.B
COMMAND ${CMAKE_COMMAND}
- -D Data5=DATA{../Data.dat}
+ -D Data5=DATA{Data5.dat}
-P ${CMAKE_CURRENT_SOURCE_DIR}/Data5Check.cmake
)
ExternalData_Add_Target(Data5.B)
ExternalData_Add_Test(Data5.C
NAME Data5Check.C
COMMAND ${CMAKE_COMMAND}
- -D Data5=DATA{../Data.dat}
+ -D Data5=DATA{Data5.dat}
-P ${CMAKE_CURRENT_SOURCE_DIR}/Data5Check.cmake
)
ExternalData_Add_Target(Data5.C)
diff --git a/Tests/Module/ExternalData/Data5/Data5.dat.md5 b/Tests/Module/ExternalData/Data5/Data5.dat.md5
new file mode 100644
index 0000000..70e39bd
--- /dev/null
+++ b/Tests/Module/ExternalData/Data5/Data5.dat.md5
@@ -0,0 +1 @@
+8c018830e3efa5caf3c7415028335a57
diff --git a/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt b/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt
index 52d4613..45bb229 100644
--- a/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt
+++ b/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt
@@ -190,7 +190,7 @@ write_compiler_detection_header(
ALLOW_UNKNOWN_COMPILERS
)
-# intentionally abuse the TEST_NULLPR variable: this will only work
+# intentionally abuse the TEST_NULLPTR variable: this will only work
# with the fallback code.
check_cxx_source_compiles("#include \"${CMAKE_CURRENT_BINARY_DIR}/test_compiler_detection_allow_unknown.h\"
int main() {\n int i = TEST_NULLPTR;\n return 0; }\n"
@@ -199,3 +199,16 @@ int main() {\n int i = TEST_NULLPTR;\n return 0; }\n"
if (NOT file_include_works_allow_unknown)
message(SEND_ERROR "Inclusion of ${CMAKE_CURRENT_BINARY_DIR}/test_compiler_detection_allow_unknown.h was expected to work, but did not.")
endif()
+
+# test for BARE_FEATURES
+
+write_compiler_detection_header(
+ FILE "${CMAKE_CURRENT_BINARY_DIR}/test_compiler_detection_bare_features.h"
+ PREFIX TEST
+ COMPILERS GNU Clang AppleClang MSVC SunPro Intel
+ VERSION 3.1
+ BARE_FEATURES cxx_nullptr cxx_override cxx_noexcept cxx_final
+)
+
+add_executable(WriteCompilerDetectionHeaderBareFeatures main_bare.cpp)
+set_property(TARGET WriteCompilerDetectionHeaderBareFeatures PROPERTY CXX_STANDARD 11)
diff --git a/Tests/Module/WriteCompilerDetectionHeader/main_bare.cpp b/Tests/Module/WriteCompilerDetectionHeader/main_bare.cpp
new file mode 100644
index 0000000..6954318
--- /dev/null
+++ b/Tests/Module/WriteCompilerDetectionHeader/main_bare.cpp
@@ -0,0 +1,23 @@
+#include "test_compiler_detection_bare_features.h"
+
+class base
+{
+public:
+ virtual ~base() {}
+ virtual void baz() = 0;
+};
+
+class foo final
+{
+public:
+ virtual ~foo() {}
+ char* bar;
+ void baz() noexcept override { bar = nullptr; }
+};
+
+int main()
+{
+ foo f;
+
+ return 0;
+}
diff --git a/Tests/RunCMake/Android/android_lib.cxx b/Tests/RunCMake/Android/android_lib.cxx
new file mode 100644
index 0000000..82f9d27
--- /dev/null
+++ b/Tests/RunCMake/Android/android_lib.cxx
@@ -0,0 +1,4 @@
+int android_lib()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/Android/check_binary.cmake b/Tests/RunCMake/Android/check_binary.cmake
new file mode 100644
index 0000000..1d1b01a
--- /dev/null
+++ b/Tests/RunCMake/Android/check_binary.cmake
@@ -0,0 +1,8 @@
+if(NOT EXISTS "${file}")
+ message(FATAL_ERROR "Missing file:\n ${file}")
+endif()
+execute_process(COMMAND "${objdump}" -p ${file} OUTPUT_VARIABLE out)
+if(out MATCHES "NEEDED[^\n]*stdc\\+\\+")
+ string(REPLACE "\n" "\n " out " ${out}")
+ message(FATAL_ERROR "File:\n ${file}\ndepends on libstdc++:\n${out}")
+endif()
diff --git a/Tests/RunCMake/Android/common.cmake b/Tests/RunCMake/Android/common.cmake
index 015f202..f931be1 100644
--- a/Tests/RunCMake/Android/common.cmake
+++ b/Tests/RunCMake/Android/common.cmake
@@ -92,6 +92,23 @@ if(CMAKE_ANDROID_ARCH_ABI STREQUAL "armeabi-v7a")
endif()
add_executable(android_c android.c)
add_executable(android_cxx android.cxx)
+add_library(android_cxx_lib SHARED android_lib.cxx)
+
+set(objdump "${CMAKE_CXX_ANDROID_TOOLCHAIN_PREFIX}objdump")
+if(NOT EXISTS "${objdump}")
+ message(FATAL_ERROR "Expected tool missing:\n ${objdump}")
+endif()
+
+if(NOT CMAKE_ANDROID_STL_TYPE MATCHES "^(system|stlport_static|stlport_shared)$")
+ foreach(tgt android_cxx android_cxx_lib)
+ add_custom_command(TARGET ${tgt} POST_BUILD
+ COMMAND ${CMAKE_COMMAND}
+ -Dobjdump=${objdump}
+ -Dfile=$<TARGET_FILE:${tgt}>
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/check_binary.cmake
+ )
+ endforeach()
+endif()
# Test that an explicit /usr/include is ignored in favor of
# appearing as a standard include directory at the end.
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index ff4a80e..44a8c45 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -121,6 +121,9 @@ if(CMAKE_GENERATOR STREQUAL "Ninja")
-DCMAKE_C_OUTPUT_EXTENSION=${CMAKE_C_OUTPUT_EXTENSION}
-DCMAKE_SHARED_LIBRARY_PREFIX=${CMAKE_SHARED_LIBRARY_PREFIX}
-DCMAKE_SHARED_LIBRARY_SUFFIX=${CMAKE_SHARED_LIBRARY_SUFFIX})
+ if(CMAKE_Fortran_COMPILER)
+ list(APPEND Ninja_ARGS -DTEST_Fortran=1)
+ endif()
add_RunCMake_test(Ninja)
endif()
add_RunCMake_test(CTest)
@@ -336,6 +339,7 @@ add_RunCMake_test(CommandLine -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME})
add_RunCMake_test(CommandLineTar)
add_RunCMake_test(install)
+add_RunCMake_test(CPackCommandLine)
add_RunCMake_test(CPackConfig)
add_RunCMake_test(CPackInstallProperties)
add_RunCMake_test(ExternalProject)
@@ -362,11 +366,6 @@ if(CMake_TEST_FindMatlab)
add_RunCMake_test(FindMatlab)
endif()
-# UseSWIG related tests
-if(CMake_TEST_UseSWIG)
- add_RunCMake_test(UseSWIG)
-endif()
-
add_executable(pseudo_emulator pseudo_emulator.c)
add_executable(pseudo_emulator_custom_command pseudo_emulator_custom_command.c)
add_RunCMake_test(CrosscompilingEmulator
diff --git a/Tests/RunCMake/CPackCommandLine/NotAGenerator-result.txt b/Tests/RunCMake/CPackCommandLine/NotAGenerator-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CPackCommandLine/NotAGenerator-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CPackCommandLine/NotAGenerator-stderr.txt b/Tests/RunCMake/CPackCommandLine/NotAGenerator-stderr.txt
new file mode 100644
index 0000000..fe4e455
--- /dev/null
+++ b/Tests/RunCMake/CPackCommandLine/NotAGenerator-stderr.txt
@@ -0,0 +1 @@
+^CPack Error: Cannot initialize CPack generator: NotAGenerator
diff --git a/Tests/RunCMake/CPackCommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CPackCommandLine/RunCMakeTest.cmake
new file mode 100644
index 0000000..991146c
--- /dev/null
+++ b/Tests/RunCMake/CPackCommandLine/RunCMakeTest.cmake
@@ -0,0 +1,10 @@
+include(RunCMake)
+set(RunCMake_TEST_TIMEOUT 60)
+
+file(WRITE "${RunCMake_BINARY_DIR}/NotAGenerator-build/CPackConfig.cmake" [[
+set(CPACK_PACKAGE_NAME "Test")
+set(CPACK_PACKAGE_VERSION "1")
+]])
+set(RunCMake_TEST_NO_CLEAN 1)
+run_cmake_command(NotAGenerator ${CMAKE_CPACK_COMMAND} -G NotAGenerator)
+unset(RunCMake_TEST_NO_CLEAN)
diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
index 5df2fbf..d8dbeec 100644
--- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -287,6 +287,10 @@ set(RunCMake_TEST_OPTIONS --trace-expand)
run_cmake(trace-expand)
unset(RunCMake_TEST_OPTIONS)
+set(RunCMake_TEST_OPTIONS --trace-expand --warn-uninitialized)
+run_cmake(trace-expand-warn-uninitialized)
+unset(RunCMake_TEST_OPTIONS)
+
set(RunCMake_TEST_OPTIONS --trace-source=trace-only-this-file.cmake)
run_cmake(trace-source)
unset(RunCMake_TEST_OPTIONS)
diff --git a/Tests/RunCMake/CommandLine/trace-expand-warn-uninitialized-stderr.txt b/Tests/RunCMake/CommandLine/trace-expand-warn-uninitialized-stderr.txt
new file mode 100644
index 0000000..74429b6
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/trace-expand-warn-uninitialized-stderr.txt
@@ -0,0 +1,2 @@
+^.*/Tests/RunCMake/CommandLine/CMakeLists.txt\(1\): cmake_minimum_required\(VERSION 3.0 \)
+.*/Tests/RunCMake/CommandLine/CMakeLists.txt\(2\): project\(trace-expand-warn-uninitialized NONE \)
diff --git a/Tests/RunCMake/CommandLine/trace-expand-warn-uninitialized.cmake b/Tests/RunCMake/CommandLine/trace-expand-warn-uninitialized.cmake
new file mode 100644
index 0000000..ec3e4d4
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/trace-expand-warn-uninitialized.cmake
@@ -0,0 +1,4 @@
+cmake_policy(SET CMP0053 OLD)
+message(STATUS "'${uninitialized_variable}'")
+cmake_policy(SET CMP0053 NEW)
+message(STATUS "'${uninitialized_variable}'")
diff --git a/Tests/RunCMake/Ninja/RspFileC.cmake b/Tests/RunCMake/Ninja/RspFileC.cmake
new file mode 100644
index 0000000..4a40682
--- /dev/null
+++ b/Tests/RunCMake/Ninja/RspFileC.cmake
@@ -0,0 +1,2 @@
+set(ENV{CMAKE_NINJA_FORCE_RESPONSE_FILE} 1)
+enable_language(C)
diff --git a/Tests/RunCMake/Ninja/RspFileCXX.cmake b/Tests/RunCMake/Ninja/RspFileCXX.cmake
new file mode 100644
index 0000000..9e61ffe
--- /dev/null
+++ b/Tests/RunCMake/Ninja/RspFileCXX.cmake
@@ -0,0 +1,2 @@
+set(ENV{CMAKE_NINJA_FORCE_RESPONSE_FILE} 1)
+enable_language(CXX)
diff --git a/Tests/RunCMake/Ninja/RspFileFortran.cmake b/Tests/RunCMake/Ninja/RspFileFortran.cmake
new file mode 100644
index 0000000..8c18e37
--- /dev/null
+++ b/Tests/RunCMake/Ninja/RspFileFortran.cmake
@@ -0,0 +1,2 @@
+set(ENV{CMAKE_NINJA_FORCE_RESPONSE_FILE} 1)
+enable_language(Fortran)
diff --git a/Tests/RunCMake/Ninja/RunCMakeTest.cmake b/Tests/RunCMake/Ninja/RunCMakeTest.cmake
index b3720fb..3bb2b6b 100644
--- a/Tests/RunCMake/Ninja/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Ninja/RunCMakeTest.cmake
@@ -40,6 +40,12 @@ run_CMP0058(NEW-by)
run_cmake(CustomCommandDepfile)
+run_cmake(RspFileC)
+run_cmake(RspFileCXX)
+if(TEST_Fortran)
+ run_cmake(RspFileFortran)
+endif()
+
function(run_CommandConcat)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CommandConcat-build)
set(RunCMake_TEST_NO_CLEAN 1)
diff --git a/Tests/RunCMake/UseSWIG/BasicPerl.cmake b/Tests/RunCMake/UseSWIG/BasicPerl.cmake
deleted file mode 100644
index 67ad6bc..0000000
--- a/Tests/RunCMake/UseSWIG/BasicPerl.cmake
+++ /dev/null
@@ -1,18 +0,0 @@
-
-set(language "perl")
-
-include (BasicConfiguration.cmake)
-
-if (WIN32)
- file (TO_CMAKE_PATH "$ENV{PATH}" perl_path)
- string (REPLACE ";" "$<SEMICOLON>" perl_path "${perl_path}")
- set (perl_env "PATH=$<TARGET_FILE_DIR:example>$<SEMICOLON>${perl_path}")
-else()
- set (perl_env "LD_LIBRARY_PATH=$<TARGET_FILE_DIR:example>")
-endif()
-
-add_custom_target (RunTest
- COMMAND "${CMAKE_COMMAND}" -E env "${perl_env}"
- "${PERL_EXECUTABLE}" "-I$<TARGET_FILE_DIR:example>"
- "${CMAKE_CURRENT_SOURCE_DIR}/runme.pl"
- DEPENDS example)
diff --git a/Tests/RunCMake/UseSWIG/BasicPython.cmake b/Tests/RunCMake/UseSWIG/BasicPython.cmake
deleted file mode 100644
index 873dbe9..0000000
--- a/Tests/RunCMake/UseSWIG/BasicPython.cmake
+++ /dev/null
@@ -1,9 +0,0 @@
-
-set(language "python")
-
-include (BasicConfiguration.cmake)
-
-add_custom_target (RunTest
- COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$<TARGET_FILE_DIR:example>"
- "${Python_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/runme.py"
- DEPENDS example)
diff --git a/Tests/RunCMake/UseSWIG/CMakeLists.txt b/Tests/RunCMake/UseSWIG/CMakeLists.txt
deleted file mode 100644
index 2d75985..0000000
--- a/Tests/RunCMake/UseSWIG/CMakeLists.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-cmake_minimum_required(VERSION 3.1)
-project(${RunCMake_TEST} CXX)
-include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/UseSWIG/LegacyPerl.cmake b/Tests/RunCMake/UseSWIG/LegacyPerl.cmake
deleted file mode 100644
index 3428c46..0000000
--- a/Tests/RunCMake/UseSWIG/LegacyPerl.cmake
+++ /dev/null
@@ -1,18 +0,0 @@
-
-set(language "perl")
-
-include (LegacyConfiguration.cmake)
-
-if (WIN32)
- file (TO_CMAKE_PATH "$ENV{PATH}" perl_path)
- string (REPLACE ";" "$<SEMICOLON>" perl_path "${perl_path}")
- set (perl_env "PATH=$<TARGET_FILE_DIR:${SWIG_MODULE_example_REAL_NAME}>$<SEMICOLON>${perl_path}")
-else()
- set (perl_env "LD_LIBRARY_PATH=$<TARGET_FILE_DIR:${SWIG_MODULE_example_REAL_NAME}>")
-endif()
-
-add_custom_target (RunTest
- COMMAND "${CMAKE_COMMAND}" -E env "${perl_env}"
- "${PERL_EXECUTABLE}" "-I$<TARGET_FILE_DIR:${SWIG_MODULE_example_REAL_NAME}>"
- "${CMAKE_CURRENT_SOURCE_DIR}/runme.pl"
- DEPENDS ${SWIG_MODULE_example_REAL_NAME})
diff --git a/Tests/RunCMake/UseSWIG/LegacyPython.cmake b/Tests/RunCMake/UseSWIG/LegacyPython.cmake
deleted file mode 100644
index 8b47aa2..0000000
--- a/Tests/RunCMake/UseSWIG/LegacyPython.cmake
+++ /dev/null
@@ -1,9 +0,0 @@
-
-set(language "python")
-
-include (LegacyConfiguration.cmake)
-
-add_custom_target (RunTest
- COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$<TARGET_FILE_DIR:${SWIG_MODULE_example_REAL_NAME}>"
- "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/runme.py"
- DEPENDS ${SWIG_MODULE_example_REAL_NAME})
diff --git a/Tests/RunCMake/UseSWIG/MultipleModules.cmake b/Tests/RunCMake/UseSWIG/MultipleModules.cmake
deleted file mode 100644
index e3d579f..0000000
--- a/Tests/RunCMake/UseSWIG/MultipleModules.cmake
+++ /dev/null
@@ -1,30 +0,0 @@
-
-find_package(SWIG REQUIRED)
-include(${SWIG_USE_FILE})
-
-find_package(PythonLibs REQUIRED)
-find_package(PerlLibs REQUIRED)
-
-unset(CMAKE_SWIG_FLAGS)
-
-set (CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set_property(SOURCE example.i PROPERTY CPLUSPLUS ON)
-set_property(SOURCE example.i PROPERTY COMPILE_OPTIONS -includeall)
-
-set_property(SOURCE example.i PROPERTY GENERATED_INCLUDE_DIRECTORIES ${PYTHON_INCLUDE_PATH})
-
-swig_add_library(example1
- LANGUAGE python
- SOURCES example.i example.cxx)
-target_link_libraries(example1 PRIVATE ${PYTHON_LIBRARIES})
-
-# re-use sample interface file for another plugin
-set_property(SOURCE example.i PROPERTY GENERATED_INCLUDE_DIRECTORIES ${PERL_INCLUDE_PATH})
-separate_arguments(c_flags UNIX_COMMAND "${PERL_EXTRA_C_FLAGS}")
-set_property(SOURCE example.i PROPERTY GENERATED_COMPILE_OPTIONS ${c_flags})
-
-swig_add_library(example2
- LANGUAGE perl
- SOURCES example.i example.cxx)
-target_link_libraries(example2 PRIVATE ${PERL_LIBRARY})
diff --git a/Tests/RunCMake/UseSWIG/MultiplePython.cmake b/Tests/RunCMake/UseSWIG/MultiplePython.cmake
deleted file mode 100644
index 3804bdd..0000000
--- a/Tests/RunCMake/UseSWIG/MultiplePython.cmake
+++ /dev/null
@@ -1,26 +0,0 @@
-
-find_package(SWIG REQUIRED)
-include(${SWIG_USE_FILE})
-
-find_package(Python2 REQUIRED COMPONENTS Development)
-find_package(Python3 REQUIRED COMPONENTS Development)
-
-unset(CMAKE_SWIG_FLAGS)
-
-set (CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set_property(SOURCE example.i PROPERTY CPLUSPLUS ON)
-set_property(SOURCE example.i PROPERTY COMPILE_OPTIONS -includeall)
-
-swig_add_library(example1
- LANGUAGE python
- OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/Python2"
- SOURCES example.i example.cxx)
-target_link_libraries(example1 PRIVATE Python2::Python)
-
-# re-use sample interface file for another plugin
-swig_add_library(example2
- LANGUAGE python
- OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/Python3"
- SOURCES example.i example.cxx)
-target_link_libraries(example2 PRIVATE Python3::Python)
diff --git a/Tests/RunCMake/UseSWIG/RunCMakeTest.cmake b/Tests/RunCMake/UseSWIG/RunCMakeTest.cmake
deleted file mode 100644
index cded22f..0000000
--- a/Tests/RunCMake/UseSWIG/RunCMakeTest.cmake
+++ /dev/null
@@ -1,27 +0,0 @@
-include(RunCMake)
-
-function(run_SWIG test)
- cmake_parse_arguments(_SWIG_TEST "" "TARGET" "" ${ARGN})
- if (_SWIG_TEST_TARGET)
- list (INSERT _SWIG_TEST_TARGET 0 --target)
- endif()
-
- set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
- set(RunCMake_TEST_NO_CLEAN 1)
- file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
- file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
- if (NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
- set (RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Release)
- endif()
- run_cmake(${test})
- run_cmake_command(${test}-test ${CMAKE_COMMAND} --build ${RunCMake_TEST_BINARY_DIR} --config Release ${_SWIG_TEST_TARGET})
-endfunction()
-
-run_SWIG(LegacyPython TARGET RunTest)
-run_SWIG(LegacyPerl TARGET RunTest)
-
-run_SWIG(BasicPython TARGET RunTest)
-run_SWIG(BasicPerl TARGET RunTest)
-
-run_SWIG(MultipleModules)
-run_SWIG(MultiplePython)
diff --git a/Tests/RunCMake/VS10Project/ExplicitCMakeLists-check.cmake b/Tests/RunCMake/VS10Project/ExplicitCMakeLists-check.cmake
new file mode 100644
index 0000000..b671e35
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/ExplicitCMakeLists-check.cmake
@@ -0,0 +1,25 @@
+set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/foo.vcxproj")
+if(NOT EXISTS "${vcProjectFile}")
+ set(RunCMake_TEST_FAILED "Project file ${vcProjectFile} does not exist.")
+ return()
+endif()
+
+set(foundCMakeLists 0)
+file(STRINGS "${vcProjectFile}" lines)
+foreach(line IN LISTS lines)
+ if(line MATCHES "<([A-Za-z0-9_]+) +Include=.*CMakeLists.txt")
+ set(rule "${CMAKE_MATCH_1}")
+ if(NOT rule STREQUAL "CustomBuild")
+ set(RunCMake_TEST_FAILED "CMakeLists.txt referenced as ${rule} instead of CustomBuild")
+ return()
+ endif()
+ if(foundCMakeLists)
+ set(RunCMake_TEST_FAILED "CMakeLists.txt referenced multiple times")
+ return()
+ endif()
+ set(foundCMakeLists 1)
+ endif()
+endforeach()
+if(NOT foundCMakeLists)
+ set(RunCMake_TEST_FAILED "CMakeLists.txt not referenced")
+endif()
diff --git a/Tests/RunCMake/VS10Project/ExplicitCMakeLists.cmake b/Tests/RunCMake/VS10Project/ExplicitCMakeLists.cmake
new file mode 100644
index 0000000..c9e4456
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/ExplicitCMakeLists.cmake
@@ -0,0 +1,3 @@
+set(CMAKE_CONFIGURATION_TYPES Debug)
+enable_language(CXX)
+add_executable(foo foo.cpp ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt)
diff --git a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
index afe9d6d..e42e662 100644
--- a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
+++ b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
@@ -1,4 +1,7 @@
include(RunCMake)
+
+run_cmake(ExplicitCMakeLists)
+
run_cmake(VsConfigurationType)
run_cmake(VsTargetsFileReferences)
run_cmake(VsCustomProps)
diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidFeature-stderr.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidFeature-stderr.txt
index 0445744..f444992 100644
--- a/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidFeature-stderr.txt
+++ b/Tests/RunCMake/WriteCompilerDetectionHeader/InvalidFeature-stderr.txt
@@ -1,5 +1,6 @@
CMake Error at .*Modules/WriteCompilerDetectionHeader.cmake:[0-9]+ \(message\):
Unsupported feature not_a_feature.
Call Stack \(most recent call first\):
+ .*Modules/WriteCompilerDetectionHeader.cmake:[0-9]+ \(_check_feature_lists\)
InvalidFeature.cmake:4 \(write_compiler_detection_header\)
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/XcodeProject/ExplicitCMakeLists-check.cmake b/Tests/RunCMake/XcodeProject/ExplicitCMakeLists-check.cmake
new file mode 100644
index 0000000..3073e0b
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/ExplicitCMakeLists-check.cmake
@@ -0,0 +1,20 @@
+set(xcProjectFile "${RunCMake_TEST_BINARY_DIR}/ExplicitCMakeLists.xcodeproj/project.pbxproj")
+if(NOT EXISTS "${xcProjectFile}")
+ set(RunCMake_TEST_FAILED "Project file ${xcProjectFile} does not exist.")
+ return()
+endif()
+
+set(foundCMakeLists 0)
+file(STRINGS "${xcProjectFile}" lines)
+foreach(line IN LISTS lines)
+ if(line MATCHES "PBXBuildFile.*fileRef.*CMakeLists.txt")
+ if(foundCMakeLists)
+ set(RunCMake_TEST_FAILED "CMakeLists.txt referenced multiple times")
+ return()
+ endif()
+ set(foundCMakeLists 1)
+ endif()
+endforeach()
+if(NOT foundCMakeLists)
+ set(RunCMake_TEST_FAILED "CMakeLists.txt not referenced")
+endif()
diff --git a/Tests/RunCMake/XcodeProject/ExplicitCMakeLists.cmake b/Tests/RunCMake/XcodeProject/ExplicitCMakeLists.cmake
new file mode 100644
index 0000000..678b0ea
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/ExplicitCMakeLists.cmake
@@ -0,0 +1,2 @@
+enable_language(CXX)
+add_executable(foo foo.cpp ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt)
diff --git a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
index 5eff6b9..1150666 100644
--- a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
+++ b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
@@ -4,6 +4,8 @@ if(XCODE_VERSION VERSION_GREATER_EQUAL 9)
set(IOS_DEPLOYMENT_TARGET "-DCMAKE_XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET=10")
endif()
+run_cmake(ExplicitCMakeLists)
+
run_cmake(XcodeFileType)
run_cmake(XcodeAttributeLocation)
run_cmake(XcodeAttributeGenex)
diff --git a/Tests/RunCMake/file/GLOB-CONFIGURE_DEPENDS-RerunCMake-build-stdout.txt b/Tests/RunCMake/file/GLOB-CONFIGURE_DEPENDS-RerunCMake-build-stdout.txt
new file mode 100644
index 0000000..71ab721
--- /dev/null
+++ b/Tests/RunCMake/file/GLOB-CONFIGURE_DEPENDS-RerunCMake-build-stdout.txt
@@ -0,0 +1 @@
+.*b9fbdd8803c036dbe9f5ea6b74db4b9670c78a72
diff --git a/Tests/RunCMake/file/GLOB-CONFIGURE_DEPENDS-RerunCMake-rebuild_first-stdout.txt b/Tests/RunCMake/file/GLOB-CONFIGURE_DEPENDS-RerunCMake-rebuild_first-stdout.txt
new file mode 100644
index 0000000..ff90f9c
--- /dev/null
+++ b/Tests/RunCMake/file/GLOB-CONFIGURE_DEPENDS-RerunCMake-rebuild_first-stdout.txt
@@ -0,0 +1,2 @@
+.*Running CMake on GLOB-CONFIGURE_DEPENDS-RerunCMake
+.*6bc141b40c0f851d20fa9a1fe5fbdae94acc5de0
diff --git a/Tests/RunCMake/file/GLOB-CONFIGURE_DEPENDS-RerunCMake-rebuild_second-stdout.txt b/Tests/RunCMake/file/GLOB-CONFIGURE_DEPENDS-RerunCMake-rebuild_second-stdout.txt
new file mode 100644
index 0000000..cf2a5af
--- /dev/null
+++ b/Tests/RunCMake/file/GLOB-CONFIGURE_DEPENDS-RerunCMake-rebuild_second-stdout.txt
@@ -0,0 +1,2 @@
+.*Running CMake on GLOB-CONFIGURE_DEPENDS-RerunCMake
+.*0c3ceab9daa7914fde7410c34cae4049e140aa51
diff --git a/Tests/RunCMake/file/GLOB-CONFIGURE_DEPENDS-RerunCMake-stdout.txt b/Tests/RunCMake/file/GLOB-CONFIGURE_DEPENDS-RerunCMake-stdout.txt
new file mode 100644
index 0000000..66b6c44
--- /dev/null
+++ b/Tests/RunCMake/file/GLOB-CONFIGURE_DEPENDS-RerunCMake-stdout.txt
@@ -0,0 +1 @@
+.*Running CMake on GLOB-CONFIGURE_DEPENDS-RerunCMake
diff --git a/Tests/RunCMake/file/GLOB-CONFIGURE_DEPENDS-RerunCMake.cmake b/Tests/RunCMake/file/GLOB-CONFIGURE_DEPENDS-RerunCMake.cmake
new file mode 100644
index 0000000..fe87c78
--- /dev/null
+++ b/Tests/RunCMake/file/GLOB-CONFIGURE_DEPENDS-RerunCMake.cmake
@@ -0,0 +1,10 @@
+message(STATUS "Running CMake on GLOB-CONFIGURE_DEPENDS-RerunCMake")
+file(GLOB_RECURSE
+ CONTENT_LIST
+ CONFIGURE_DEPENDS
+ LIST_DIRECTORIES false
+ RELATIVE "${CMAKE_CURRENT_BINARY_DIR}"
+ "${CMAKE_CURRENT_BINARY_DIR}/test/*"
+ )
+string(SHA1 CONTENT_LIST_HASH "${CONTENT_LIST}")
+add_custom_target(CONTENT_ECHO ALL ${CMAKE_COMMAND} -E echo ${CONTENT_LIST_HASH})
diff --git a/Tests/RunCMake/file/GLOB-error-CONFIGURE_DEPENDS-SCRIPT_MODE-result.txt b/Tests/RunCMake/file/GLOB-error-CONFIGURE_DEPENDS-SCRIPT_MODE-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/file/GLOB-error-CONFIGURE_DEPENDS-SCRIPT_MODE-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/GLOB-error-CONFIGURE_DEPENDS-SCRIPT_MODE-stderr.txt b/Tests/RunCMake/file/GLOB-error-CONFIGURE_DEPENDS-SCRIPT_MODE-stderr.txt
new file mode 100644
index 0000000..40083c1
--- /dev/null
+++ b/Tests/RunCMake/file/GLOB-error-CONFIGURE_DEPENDS-SCRIPT_MODE-stderr.txt
@@ -0,0 +1 @@
+.*CONFIGURE_DEPENDS is invalid for script and find package modes\.
diff --git a/Tests/RunCMake/file/GLOB-error-CONFIGURE_DEPENDS-SCRIPT_MODE.cmake b/Tests/RunCMake/file/GLOB-error-CONFIGURE_DEPENDS-SCRIPT_MODE.cmake
new file mode 100644
index 0000000..9dc0f03
--- /dev/null
+++ b/Tests/RunCMake/file/GLOB-error-CONFIGURE_DEPENDS-SCRIPT_MODE.cmake
@@ -0,0 +1 @@
+file(GLOB CONTENT_LIST CONFIGURE_DEPENDS)
diff --git a/Tests/RunCMake/file/GLOB-error-CONFIGURE_DEPENDS-modified-result.txt b/Tests/RunCMake/file/GLOB-error-CONFIGURE_DEPENDS-modified-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/file/GLOB-error-CONFIGURE_DEPENDS-modified-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/GLOB-error-CONFIGURE_DEPENDS-modified-stderr.txt b/Tests/RunCMake/file/GLOB-error-CONFIGURE_DEPENDS-modified-stderr.txt
new file mode 100644
index 0000000..d7b36eb
--- /dev/null
+++ b/Tests/RunCMake/file/GLOB-error-CONFIGURE_DEPENDS-modified-stderr.txt
@@ -0,0 +1,7 @@
+^CMake Error: The glob expression
+.* at GLOB-error-CONFIGURE_DEPENDS-modified\.cmake:[0-9]+ \(file\)
+was already present in the glob cache but the directory
+contents have changed during the configuration run.
+Matching glob expressions:
+ CONTENT_LIST_1 at GLOB-error-CONFIGURE_DEPENDS-modified\.cmake:[0-9]+ \(file\)
+ CONTENT_LIST_2 at GLOB-error-CONFIGURE_DEPENDS-modified\.cmake:[0-9]+ \(file\)$
diff --git a/Tests/RunCMake/file/GLOB-error-CONFIGURE_DEPENDS-modified.cmake b/Tests/RunCMake/file/GLOB-error-CONFIGURE_DEPENDS-modified.cmake
new file mode 100644
index 0000000..8d74dea
--- /dev/null
+++ b/Tests/RunCMake/file/GLOB-error-CONFIGURE_DEPENDS-modified.cmake
@@ -0,0 +1,21 @@
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test/first")
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test/second")
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test/third")
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test/first/one" "one")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test/second/two" "two")
+file(GLOB_RECURSE CONTENT_LIST_1
+ CONFIGURE_DEPENDS
+ "${CMAKE_CURRENT_BINARY_DIR}/test/*"
+ )
+
+file(GLOB_RECURSE CONTENT_LIST_2
+ CONFIGURE_DEPENDS
+ "${CMAKE_CURRENT_BINARY_DIR}/test/*"
+ )
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test/third/three" "three")
+file(GLOB_RECURSE CONTENT_LIST_3
+ CONFIGURE_DEPENDS
+ "${CMAKE_CURRENT_BINARY_DIR}/test/*"
+ )
diff --git a/Tests/RunCMake/file/GLOB-noexp-CONFIGURE_DEPENDS-result.txt b/Tests/RunCMake/file/GLOB-noexp-CONFIGURE_DEPENDS-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/file/GLOB-noexp-CONFIGURE_DEPENDS-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/GLOB-noexp-CONFIGURE_DEPENDS-stderr.txt b/Tests/RunCMake/file/GLOB-noexp-CONFIGURE_DEPENDS-stderr.txt
new file mode 100644
index 0000000..01d204f
--- /dev/null
+++ b/Tests/RunCMake/file/GLOB-noexp-CONFIGURE_DEPENDS-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at GLOB-noexp-CONFIGURE_DEPENDS\.cmake:[0-9]+ \(file\):
+ file GLOB requires a glob expression after CONFIGURE_DEPENDS\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/file/GLOB-noexp-CONFIGURE_DEPENDS.cmake b/Tests/RunCMake/file/GLOB-noexp-CONFIGURE_DEPENDS.cmake
new file mode 100644
index 0000000..9dc0f03
--- /dev/null
+++ b/Tests/RunCMake/file/GLOB-noexp-CONFIGURE_DEPENDS.cmake
@@ -0,0 +1 @@
+file(GLOB CONTENT_LIST CONFIGURE_DEPENDS)
diff --git a/Tests/RunCMake/file/GLOB-warn-CONFIGURE_DEPENDS-late-stderr.txt b/Tests/RunCMake/file/GLOB-warn-CONFIGURE_DEPENDS-late-stderr.txt
new file mode 100644
index 0000000..af722a4
--- /dev/null
+++ b/Tests/RunCMake/file/GLOB-warn-CONFIGURE_DEPENDS-late-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Warning \(dev\) at GLOB-warn-CONFIGURE_DEPENDS-late\.cmake:[0-9]+ \(file\):
+ CONFIGURE_DEPENDS flag was given after a glob expression was already
+ evaluated\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
+This warning is for project developers\. Use -Wno-dev to suppress it\.$
diff --git a/Tests/RunCMake/file/GLOB-warn-CONFIGURE_DEPENDS-late.cmake b/Tests/RunCMake/file/GLOB-warn-CONFIGURE_DEPENDS-late.cmake
new file mode 100644
index 0000000..0b69552
--- /dev/null
+++ b/Tests/RunCMake/file/GLOB-warn-CONFIGURE_DEPENDS-late.cmake
@@ -0,0 +1,11 @@
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test/first")
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test/second")
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test/first/one" "Hi, Mom!")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test/second/two" "Love you!")
+
+file(GLOB CONTENT_LIST
+ "${CMAKE_CURRENT_BINARY_DIR}/test/first/*"
+ CONFIGURE_DEPENDS
+ "${CMAKE_CURRENT_BINARY_DIR}/test/second/*"
+ )
diff --git a/Tests/RunCMake/file/GLOB_RECURSE-warn-CONFIGURE_DEPENDS-ninja-version-stderr.txt b/Tests/RunCMake/file/GLOB_RECURSE-warn-CONFIGURE_DEPENDS-ninja-version-stderr.txt
new file mode 100644
index 0000000..8d22332
--- /dev/null
+++ b/Tests/RunCMake/file/GLOB_RECURSE-warn-CONFIGURE_DEPENDS-ninja-version-stderr.txt
@@ -0,0 +1,13 @@
+^CMake Warning \(dev\):
+ The detected version of Ninja:
+
+ .*
+
+ is less than the version of Ninja required by CMake for adding restat
+ dependencies to the build\.ninja manifest regeneration target:
+
+ 1\.8
+
+ Any pre-check scripts, such as those generated for file\(GLOB
+ CONFIGURE_DEPENDS\), will not be run by Ninja\.
+This warning is for project developers\. Use -Wno-dev to suppress it\.$
diff --git a/Tests/RunCMake/file/GLOB_RECURSE-warn-CONFIGURE_DEPENDS-ninja-version.cmake b/Tests/RunCMake/file/GLOB_RECURSE-warn-CONFIGURE_DEPENDS-ninja-version.cmake
new file mode 100644
index 0000000..8e80895
--- /dev/null
+++ b/Tests/RunCMake/file/GLOB_RECURSE-warn-CONFIGURE_DEPENDS-ninja-version.cmake
@@ -0,0 +1,6 @@
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test/first")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test/first/one" "one")
+file(GLOB_RECURSE CONTENT_LIST
+ CONFIGURE_DEPENDS
+ "${CMAKE_CURRENT_BINARY_DIR}/test/*"
+ )
diff --git a/Tests/RunCMake/file/RunCMakeTest.cmake b/Tests/RunCMake/file/RunCMakeTest.cmake
index 4aab32d..342606b 100644
--- a/Tests/RunCMake/file/RunCMakeTest.cmake
+++ b/Tests/RunCMake/file/RunCMakeTest.cmake
@@ -43,10 +43,79 @@ run_cmake(GLOB-error-FOLLOW_SYMLINKS)
run_cmake(GLOB-error-LIST_DIRECTORIES-not-boolean)
run_cmake(GLOB-error-LIST_DIRECTORIES-no-arg)
run_cmake(GLOB-error-RELATIVE-no-arg)
+run_cmake(GLOB-error-CONFIGURE_DEPENDS-modified)
+run_cmake(GLOB-noexp-CONFIGURE_DEPENDS)
run_cmake(GLOB-noexp-LIST_DIRECTORIES)
run_cmake(GLOB-noexp-RELATIVE)
+run_cmake_command(GLOB-error-CONFIGURE_DEPENDS-SCRIPT_MODE ${CMAKE_COMMAND} -P
+ ${RunCMake_SOURCE_DIR}/GLOB-error-CONFIGURE_DEPENDS-SCRIPT_MODE.cmake)
if(NOT WIN32 OR CYGWIN)
run_cmake(GLOB_RECURSE-cyclic-recursion)
run_cmake(INSTALL-SYMLINK)
endif()
+
+if(RunCMake_GENERATOR STREQUAL "Ninja")
+ # Detect ninja version so we know what tests can be supported.
+ execute_process(
+ COMMAND "${RunCMake_MAKE_PROGRAM}" --version
+ OUTPUT_VARIABLE ninja_out
+ ERROR_VARIABLE ninja_out
+ RESULT_VARIABLE ninja_res
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ if(ninja_res EQUAL 0 AND "x${ninja_out}" MATCHES "^x[0-9]+\\.[0-9]+")
+ set(ninja_version "${ninja_out}")
+ message(STATUS "ninja version: ${ninja_version}")
+ else()
+ message(FATAL_ERROR "'ninja --version' reported:\n${ninja_out}")
+ endif()
+
+ if("${ninja_version}" VERSION_LESS 1.8)
+ message(STATUS "Ninja is too old for GLOB CONFIGURE_DEPENDS; expect a warning.")
+ endif()
+endif()
+
+if(RunCMake_GENERATOR STREQUAL "Ninja" AND "${ninja_version}" VERSION_LESS 1.8)
+ run_cmake(GLOB_RECURSE-warn-CONFIGURE_DEPENDS-ninja-version)
+else()
+ run_cmake(GLOB-warn-CONFIGURE_DEPENDS-late)
+
+ # Use a single build tree for a few tests without cleaning.
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/GLOB-CONFIGURE_DEPENDS-RerunCMake-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ set(RunCMake_DEFAULT_stderr ".*")
+ if(RunCMake_GENERATOR STREQUAL "Borland Makefiles" OR
+ RunCMake_GENERATOR STREQUAL "Watcom WMake")
+ set(fs_delay 3)
+ else()
+ set(fs_delay 1.125)
+ endif()
+
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}/test")
+ set(tf_1 "${RunCMake_TEST_BINARY_DIR}/test/1.txt")
+ file(WRITE "${tf_1}" "1")
+
+ message(STATUS "GLOB-RerunCMake: first configuration...")
+ run_cmake(GLOB-CONFIGURE_DEPENDS-RerunCMake)
+ run_cmake_command(GLOB-CONFIGURE_DEPENDS-RerunCMake-build ${CMAKE_COMMAND} --build .)
+
+ execute_process(COMMAND ${CMAKE_COMMAND} -E sleep ${fs_delay})
+ message(STATUS "GLOB-CONFIGURE_DEPENDS-RerunCMake: add another file...")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}/test/sub")
+ set(tf_2 "${RunCMake_TEST_BINARY_DIR}/test/sub/2.txt")
+ file(WRITE "${tf_2}" "2")
+ run_cmake_command(GLOB-CONFIGURE_DEPENDS-RerunCMake-rebuild_first ${CMAKE_COMMAND} --build .)
+ run_cmake_command(GLOB-CONFIGURE_DEPENDS-RerunCMake-nowork ${CMAKE_COMMAND} --build .)
+
+ execute_process(COMMAND ${CMAKE_COMMAND} -E sleep ${fs_delay})
+ message(STATUS "GLOB-CONFIGURE_DEPENDS-RerunCMake: remove first test file...")
+ file(REMOVE "${RunCMake_TEST_BINARY_DIR}/test/1.txt")
+ run_cmake_command(GLOB-CONFIGURE_DEPENDS-RerunCMake-rebuild_second ${CMAKE_COMMAND} --build .)
+ run_cmake_command(GLOB-CONFIGURE_DEPENDS-RerunCMake-nowork ${CMAKE_COMMAND} --build .)
+
+ unset(RunCMake_TEST_BINARY_DIR)
+ unset(RunCMake_TEST_NO_CLEAN)
+ unset(RunCMake_DEFAULT_stderr)
+endif()
diff --git a/Tests/RunCMake/list/RunCMakeTest.cmake b/Tests/RunCMake/list/RunCMakeTest.cmake
index 3913783..bdc23a4 100644
--- a/Tests/RunCMake/list/RunCMakeTest.cmake
+++ b/Tests/RunCMake/list/RunCMakeTest.cmake
@@ -43,3 +43,44 @@ run_cmake(SUBLIST-NoArguments)
run_cmake(SUBLIST-NoVariable)
run_cmake(SUBLIST-InvalidLength)
run_cmake(SUBLIST)
+
+run_cmake(TRANSFORM-NoAction)
+run_cmake(TRANSFORM-InvalidAction)
+# 'action' oriented tests
+run_cmake(TRANSFORM-TOUPPER-TooManyArguments)
+run_cmake(TRANSFORM-TOLOWER-TooManyArguments)
+run_cmake(TRANSFORM-STRIP-TooManyArguments)
+run_cmake(TRANSFORM-GENEX_STRIP-TooManyArguments)
+run_cmake(TRANSFORM-APPEND-NoArguments)
+run_cmake(TRANSFORM-APPEND-TooManyArguments)
+run_cmake(TRANSFORM-PREPEND-NoArguments)
+run_cmake(TRANSFORM-PREPEND-TooManyArguments)
+run_cmake(TRANSFORM-REPLACE-NoArguments)
+run_cmake(TRANSFORM-REPLACE-NoEnoughArguments)
+run_cmake(TRANSFORM-REPLACE-TooManyArguments)
+run_cmake(TRANSFORM-REPLACE-InvalidRegex)
+run_cmake(TRANSFORM-REPLACE-InvalidReplace1)
+run_cmake(TRANSFORM-REPLACE-InvalidReplace2)
+# 'selector' oriented tests
+run_cmake(TRANSFORM-Selector-REGEX-NoArguments)
+run_cmake(TRANSFORM-Selector-REGEX-TooManyArguments)
+run_cmake(TRANSFORM-Selector-REGEX-InvalidRegex)
+run_cmake(TRANSFORM-Selector-AT-NoArguments)
+run_cmake(TRANSFORM-Selector-AT-BadArgument)
+run_cmake(TRANSFORM-Selector-AT-InvalidIndex)
+run_cmake(TRANSFORM-Selector-FOR-NoArguments)
+run_cmake(TRANSFORM-Selector-FOR-NoEnoughArguments)
+run_cmake(TRANSFORM-Selector-FOR-TooManyArguments)
+run_cmake(TRANSFORM-Selector-FOR-BadArgument)
+run_cmake(TRANSFORM-Selector-FOR-InvalidIndex)
+# 'output' oriented tests
+run_cmake(TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments)
+run_cmake(TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments)
+# Successful tests
+run_cmake(TRANSFORM-TOUPPER)
+run_cmake(TRANSFORM-TOLOWER)
+run_cmake(TRANSFORM-STRIP)
+run_cmake(TRANSFORM-GENEX_STRIP)
+run_cmake(TRANSFORM-APPEND)
+run_cmake(TRANSFORM-PREPEND)
+run_cmake(TRANSFORM-REPLACE)
diff --git a/Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments-stderr.txt
new file mode 100644
index 0000000..028f8d5
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-APPEND-NoArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, action APPEND expects 1 argument\(s\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments.cmake b/Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments.cmake
new file mode 100644
index 0000000..f161187
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist APPEND)
diff --git a/Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..aeb646d
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-APPEND-TooManyArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, 'one_too_many': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments.cmake b/Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments.cmake
new file mode 100644
index 0000000..8430a4c
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist APPEND delta one_too_many)
diff --git a/Tests/RunCMake/list/TRANSFORM-APPEND.cmake b/Tests/RunCMake/list/TRANSFORM-APPEND.cmake
new file mode 100644
index 0000000..9639088
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-APPEND.cmake
@@ -0,0 +1,48 @@
+set(mylist alpha bravo charlie delta)
+
+list(TRANSFORM mylist APPEND "_A" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha_A;bravo_A;charlie_A;delta_A")
+ message (FATAL_ERROR "TRANSFORM(APPEND) is \"${output}\", expected is \"alpha_A;bravo_A;charlie_A;delta_A\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist APPEND "_A" AT 1 3 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo_A;charlie;delta_A")
+ message (FATAL_ERROR "TRANSFORM(APPEND) is \"${output}\", expected is \"alpha;bravo_A;charlie;delta_A\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist APPEND "_A" AT 1 -2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo_A;charlie_A;delta")
+ message (FATAL_ERROR "TRANSFORM(APPEND) is \"${output}\", expected is \"alpha;bravo_A;charlie_A;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist APPEND "_A" FOR 1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo_A;charlie_A;delta")
+ message (FATAL_ERROR "TRANSFORM(APPEND) is \"${output}\", expected is \"alpha;bravo_A;charlie_A;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist APPEND "_A" FOR 1 -1 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo_A;charlie_A;delta_A")
+ message (FATAL_ERROR "TRANSFORM(APPEND) is \"${output}\", expected is \"alpha;bravo_A;charlie_A;delta_A\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist APPEND "_A" FOR 0 -1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha_A;bravo;charlie_A;delta")
+ message (FATAL_ERROR "TRANSFORM(APPEND) is \"${output}\", expected is \"alpha_A;bravo;charlie_A;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist APPEND "_A" REGEX "(r|t)a" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo_A;charlie;delta_A")
+ message (FATAL_ERROR "TRANSFORM(APPEND) is \"${output}\", expected is \"alpha;bravo_A;charlie;delta_A\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist APPEND "_A" REGEX "(r|t)a")
+if (NOT mylist STREQUAL "alpha;bravo_A;charlie;delta_A")
+ message (FATAL_ERROR "TRANSFORM(APPEND) is \"${mylist}\", expected is \"alpha;bravo_A;charlie;delta_A\"")
+endif()
diff --git a/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..6071a00
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-GENEX_STRIP-TooManyArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, 'one_too_many': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments.cmake b/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments.cmake
new file mode 100644
index 0000000..257d7fe
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist GENEX_STRIP one_too_many)
diff --git a/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP.cmake b/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP.cmake
new file mode 100644
index 0000000..8045eef
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP.cmake
@@ -0,0 +1,49 @@
+set(mylist one "$<1:two\;three>" four "$<TARGET_OBJECTS:some_target>")
+
+list(TRANSFORM mylist GENEX_STRIP OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "one;;four;")
+ message (FATAL_ERROR "TRANSFORM(GENEX_STRIP) is \"${output}\", expected is \"one;;four;\"")
+endif()
+
+set(mylist "one $<CONFIG>" "$<1:two\;three>-$<PLATFORM_ID>" "$<ANGLE-R>four" "$<TARGET_OBJECTS:some_target>")
+unset(output)
+list(TRANSFORM mylist GENEX_STRIP AT 1 3 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "one $<CONFIG>;-;$<ANGLE-R>four;")
+ message (FATAL_ERROR "TRANSFORM(GENEX_STRIP) is \"${output}\", expected is \"one $<CONFIG>;-;$<ANGLE-R>four;\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist GENEX_STRIP AT 1 -2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "one $<CONFIG>;-;four;$<TARGET_OBJECTS:some_target>")
+ message (FATAL_ERROR "TRANSFORM(GENEX_STRIP) is \"${output}\", expected is \"one $<CONFIG>;-;four;$<TARGET_OBJECTS:some_target>\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist GENEX_STRIP FOR 1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "one $<CONFIG>;-;four;$<TARGET_OBJECTS:some_target>")
+ message (FATAL_ERROR "TRANSFORM(GENEX_STRIP) is \"${output}\", expected is \"one $<CONFIG>;-;four;$<TARGET_OBJECTS:some_target>\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist GENEX_STRIP FOR 1 -1 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "one $<CONFIG>;-;four;")
+ message (FATAL_ERROR "TRANSFORM(GENEX_STRIP) is \"${output}\", expected is \"one $<CONFIG>;-;four;\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist GENEX_STRIP FOR 0 -1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "one ;$<1:two;three>-$<PLATFORM_ID>;four;$<TARGET_OBJECTS:some_target>")
+ message (FATAL_ERROR "TRANSFORM(GENEX_STRIP) is \"${output}\", expected is \"one ;$<1:two;three>-$<PLATFORM_ID>;four;$<TARGET_OBJECTS:some_target>\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist GENEX_STRIP REGEX "(D|G)>" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "one ;-;$<ANGLE-R>four;$<TARGET_OBJECTS:some_target>")
+ message (FATAL_ERROR "TRANSFORM(GENEX_STRIP) is \"${output}\", expected is \"one ;-;$<ANGLE-R>four;$<TARGET_OBJECTS:some_target>\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist GENEX_STRIP REGEX "(D|G)>")
+if (NOT mylist STREQUAL "one ;-;$<ANGLE-R>four;$<TARGET_OBJECTS:some_target>")
+ message (FATAL_ERROR "TRANSFORM(GENEX_STRIP) is \"${mylist}\", expected is \"one ;-;$<ANGLE-R>four;$<TARGET_OBJECTS:some_target>\"")
+endif()
diff --git a/Tests/RunCMake/list/TRANSFORM-InvalidAction-result.txt b/Tests/RunCMake/list/TRANSFORM-InvalidAction-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-InvalidAction-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-InvalidAction-stderr.txt b/Tests/RunCMake/list/TRANSFORM-InvalidAction-stderr.txt
new file mode 100644
index 0000000..0fa45c9
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-InvalidAction-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-InvalidAction.cmake:2 \(list\):
+ list sub-command TRANSFORM, BAD_ACTION invalid action.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-InvalidAction.cmake b/Tests/RunCMake/list/TRANSFORM-InvalidAction.cmake
new file mode 100644
index 0000000..fb2cc30
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-InvalidAction.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist BAD_ACTION)
diff --git a/Tests/RunCMake/list/TRANSFORM-NoAction-result.txt b/Tests/RunCMake/list/TRANSFORM-NoAction-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-NoAction-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-NoAction-stderr.txt b/Tests/RunCMake/list/TRANSFORM-NoAction-stderr.txt
new file mode 100644
index 0000000..68e9e9d
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-NoAction-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-NoAction.cmake:2 \(list\):
+ list sub-command TRANSFORM requires an action to be specified.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-NoAction.cmake b/Tests/RunCMake/list/TRANSFORM-NoAction.cmake
new file mode 100644
index 0000000..3690f14
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-NoAction.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist)
diff --git a/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments-stderr.txt
new file mode 100644
index 0000000..b4f4e06
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, OUTPUT_VARIABLE expects variable name argument.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments.cmake b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments.cmake
new file mode 100644
index 0000000..acc4094
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER OUTPUT_VARIABLE)
diff --git a/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..9a58346
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, 'one_too_many': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments.cmake b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments.cmake
new file mode 100644
index 0000000..c4da864
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER OUTPUT_VARIABLE output one_too_many)
diff --git a/Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments-stderr.txt
new file mode 100644
index 0000000..413ce30
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-PREPEND-NoArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, action PREPEND expects 1 argument\(s\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments.cmake b/Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments.cmake
new file mode 100644
index 0000000..a8e4530
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist PREPEND)
diff --git a/Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..6ff1b89
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-PREPEND-TooManyArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, 'one_too_many': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments.cmake b/Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments.cmake
new file mode 100644
index 0000000..1f904ad
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist PREPEND delta one_too_many)
diff --git a/Tests/RunCMake/list/TRANSFORM-PREPEND.cmake b/Tests/RunCMake/list/TRANSFORM-PREPEND.cmake
new file mode 100644
index 0000000..55b8867
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-PREPEND.cmake
@@ -0,0 +1,48 @@
+set(mylist alpha bravo charlie delta)
+
+list(TRANSFORM mylist PREPEND "P_" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "P_alpha;P_bravo;P_charlie;P_delta")
+ message (FATAL_ERROR "TRANSFORM(PREPEND) is \"${output}\", expected is \"P_alpha;P_bravo;P_charlie;P_delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist PREPEND "P_" AT 1 3 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;P_bravo;charlie;P_delta")
+ message (FATAL_ERROR "TRANSFORM(PREPEND) is \"${output}\", expected is \"alpha;P_bravo;charlie;P_delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist PREPEND "P_" AT 1 -2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;P_bravo;P_charlie;delta")
+ message (FATAL_ERROR "TRANSFORM(PREPEND) is \"${output}\", expected is \"alpha;P_bravo;P_charlie;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist PREPEND "P_" FOR 1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;P_bravo;P_charlie;delta")
+ message (FATAL_ERROR "TRANSFORM(PREPEND) is \"${output}\", expected is \"alpha;P_bravo;P_charlie;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist PREPEND "P_" FOR 1 -1 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;P_bravo;P_charlie;P_delta")
+ message (FATAL_ERROR "TRANSFORM(PREPEND) is \"${output}\", expected is \"alpha;P_bravo;P_charlie;P_delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist PREPEND "P_" FOR 0 -1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "P_alpha;bravo;P_charlie;delta")
+ message (FATAL_ERROR "TRANSFORM(PREPEND) is \"${output}\", expected is \"P_alpha;bravo;P_charlie;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist PREPEND "P_" REGEX "(r|t)a" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;P_bravo;charlie;P_delta")
+ message (FATAL_ERROR "TRANSFORM(PREPEND) is \"${output}\", expected is \"alpha;P_bravo;charlie;P_delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist PREPEND "P_" REGEX "(r|t)a")
+if (NOT mylist STREQUAL "alpha;P_bravo;charlie;P_delta")
+ message (FATAL_ERROR "TRANSFORM(PREPEND) is \"${mylist}\", expected is \"alpha;P_bravo;charlie;P_delta\"")
+endif()
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex-result.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex-stderr.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex-stderr.txt
new file mode 100644
index 0000000..334c96e
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at TRANSFORM-REPLACE-InvalidRegex.cmake:2 \(list\):
+ list sub-command TRANSFORM, action REPLACE: Failed to compile regex
+ "\^\(alpha\$".
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex.cmake b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex.cmake
new file mode 100644
index 0000000..f440c35
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist REPLACE "^(alpha$" "zulu")
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace-result.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1-result.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1-stderr.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1-stderr.txt
new file mode 100644
index 0000000..7671c83
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at TRANSFORM-REPLACE-InvalidReplace1.cmake:2 \(list\):
+ list sub-command TRANSFORM, action REPLACE: replace-expression ends in a
+ backslash.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1.cmake b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1.cmake
new file mode 100644
index 0000000..35387f0
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist REPLACE "^alpha$" "zulu\\")
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2-result.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2-stderr.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2-stderr.txt
new file mode 100644
index 0000000..e0aabd7
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at TRANSFORM-REPLACE-InvalidReplace2.cmake:2 \(list\):
+ list sub-command TRANSFORM, action REPLACE: Unknown escape "\\z" in
+ replace-expression.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2.cmake b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2.cmake
new file mode 100644
index 0000000..2f1f2c7
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist REPLACE "^alpha$" "\\zulu")
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments-stderr.txt
new file mode 100644
index 0000000..3d39e72
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-REPLACE-NoArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, action REPLACE expects 2 argument\(s\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments.cmake b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments.cmake
new file mode 100644
index 0000000..b7b1e9d
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist REPLACE)
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments-stderr.txt
new file mode 100644
index 0000000..dc80f33
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-REPLACE-NoEnoughArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, action REPLACE expects 2 argument\(s\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments.cmake b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments.cmake
new file mode 100644
index 0000000..1d418c0
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist REPLACE "^alpha$")
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..3d4e15a
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-REPLACE-TooManyArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, 'one_too_many': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments.cmake b/Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments.cmake
new file mode 100644
index 0000000..baed0af
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist REPLACE "^alpha$" "zulu" "one_too_many")
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE.cmake b/Tests/RunCMake/list/TRANSFORM-REPLACE.cmake
new file mode 100644
index 0000000..256b1b8
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE.cmake
@@ -0,0 +1,48 @@
+set(mylist alpha bravo charlie delta)
+
+list(TRANSFORM mylist REPLACE "(.+a)$" "\\1_\\1" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha_alpha;bravo;charlie;delta_delta")
+ message (FATAL_ERROR "TRANSFORM(REPLACE) is \"${output}\", expected is \"alpha_alpha;bravo;charlie;delta_delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist REPLACE "(.+a)$" "\\1_\\1" AT 1 3 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo;charlie;delta_delta")
+ message (FATAL_ERROR "TRANSFORM(REPLACE) is \"${output}\", expected is \"alpha;bravo;charlie;delta_delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist REPLACE "(.+e)$" "\\1_\\1" AT 1 -2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo;charlie_charlie;delta")
+ message (FATAL_ERROR "TRANSFORM(REPLACE) is \"${output}\", expected is \"alpha;bravo;charlie_charlie;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist REPLACE "(.+e)$" "\\1_\\1" FOR 1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo;charlie_charlie;delta")
+ message (FATAL_ERROR "TRANSFORM(REPLACE) is \"${output}\", expected is \"alpha;bravo;charlie_charlie;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist REPLACE "(.+a)$" "\\1_\\1" FOR 1 -1 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo;charlie;delta_delta")
+ message (FATAL_ERROR "TRANSFORM(REPLACE) is \"${output}\", expected is \"alpha;bravo;charlie_A;delta_delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist REPLACE "(.+a)$" "\\1_\\1" FOR 0 -1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha_alpha;bravo;charlie;delta")
+ message (FATAL_ERROR "TRANSFORM(REPLACE) is \"${output}\", expected is \"alpha_alpha;bravo;charlie;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist REPLACE "(.+a)$" "\\1_\\1" REGEX "(r|t)a" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo;charlie;delta_delta")
+ message (FATAL_ERROR "TRANSFORM(REPLACE) is \"${output}\", expected is \"alpha;bravo;charlie;delta_delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist REPLACE "(.+a)$" "\\1_\\1" REGEX "(r|t)a")
+if (NOT mylist STREQUAL "alpha;bravo;charlie;delta_delta")
+ message (FATAL_ERROR "TRANSFORM(REPLACE) is \"${mylist}\", expected is \"alpha;bravo;charlie;delta_delta\"")
+endif()
diff --git a/Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..534f940
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-STRIP-TooManyArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, 'one_too_many': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments.cmake b/Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments.cmake
new file mode 100644
index 0000000..c6a8213
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist STRIP one_too_many)
diff --git a/Tests/RunCMake/list/TRANSFORM-STRIP.cmake b/Tests/RunCMake/list/TRANSFORM-STRIP.cmake
new file mode 100644
index 0000000..366c63a
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-STRIP.cmake
@@ -0,0 +1,49 @@
+set(mylist " alpha" "bravo " " charlie " delta)
+
+list(TRANSFORM mylist STRIP OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo;charlie;delta")
+ message (FATAL_ERROR "TRANSFORM(STRIP) is \"${output}\", expected is \"alpha;bravo;charlie;delta\"")
+endif()
+
+set(mylist " alpha" "bravo " " charlie " "delta ")
+unset(output)
+list(TRANSFORM mylist STRIP AT 1 3 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL " alpha;bravo; charlie ;delta")
+ message (FATAL_ERROR "TRANSFORM(STRIP) is \"${output}\", expected is \" alpha;bravo; charlie ;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist STRIP AT 1 -2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL " alpha;bravo;charlie;delta ")
+ message (FATAL_ERROR "TRANSFORM(STRIP) is \"${output}\", expected is \" alpha;bravo;charlie;delta \"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist STRIP FOR 1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL " alpha;bravo;charlie;delta ")
+ message (FATAL_ERROR "TRANSFORM(STRIP) is \"${output}\", expected is \" alpha;bravo;charlie;delta \"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist STRIP FOR 1 -1 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL " alpha;bravo;charlie;delta")
+ message (FATAL_ERROR "TRANSFORM(STRIP) is \"${output}\", expected is \" alpha;bravo;charlie;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist STRIP FOR 0 -1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo ;charlie;delta ")
+ message (FATAL_ERROR "TRANSFORM(STRIP) is \"${output}\", expected is \"alpha;bravo ;charlie;delta \"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist STRIP REGEX "(r|t)a" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL " alpha;bravo; charlie ;delta")
+ message (FATAL_ERROR "TRANSFORM(STRIP) is \"${output}\", expected is \" alpha;bravo; charlie ;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist STRIP REGEX "(r|t)a")
+if (NOT mylist STREQUAL " alpha;bravo; charlie ;delta")
+ message (FATAL_ERROR "TRANSFORM(STRIP) is \"${mylist}\", expected is \" alpha;bravo; charlie ;delta\"")
+endif()
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument-stderr.txt
new file mode 100644
index 0000000..cec520f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-Selector-AT-BadArgument.cmake:2 \(list\):
+ list sub-command TRANSFORM, '1x 2': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument.cmake
new file mode 100644
index 0000000..f61b86b
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER AT 0 1x 2)
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex-stderr.txt
new file mode 100644
index 0000000..7e2898b
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-Selector-AT-InvalidIndex.cmake:2 \(list\):
+ list sub-command TRANSFORM, selector AT, index: 3 out of range \(-3, 2\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex.cmake
new file mode 100644
index 0000000..d33586c
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER AT 0 3 2)
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments-stderr.txt
new file mode 100644
index 0000000..eaf5281
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-Selector-AT-NoArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, selector AT expects at least one numeric value.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments.cmake
new file mode 100644
index 0000000..052b79b
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER AT)
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument-stderr.txt
new file mode 100644
index 0000000..a0f701f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at TRANSFORM-Selector-FOR-BadArgument.cmake:2 \(list\):
+ list sub-command TRANSFORM, selector FOR expects, at least, two numeric
+ values.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument.cmake
new file mode 100644
index 0000000..55527be
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER FOR 0 1x 2)
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex-stderr.txt
new file mode 100644
index 0000000..c50cc0a
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-Selector-FOR-InvalidIndex.cmake:2 \(list\):
+ list sub-command TRANSFORM, selector FOR, index: 6 out of range \(-3, 2\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex.cmake
new file mode 100644
index 0000000..6e2374e
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER FOR 0 6 2)
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments-stderr.txt
new file mode 100644
index 0000000..5881b67
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-Selector-FOR-NoArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, selector FOR expects, at least, two arguments.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments.cmake
new file mode 100644
index 0000000..4902cc9
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER FOR)
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments-stderr.txt
new file mode 100644
index 0000000..b1081d9
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-Selector-FOR-NoEnoughArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, selector FOR expects, at least, two arguments.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments.cmake
new file mode 100644
index 0000000..81417de
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER FOR 1)
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..2221cb3
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-Selector-FOR-TooManyArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, '3': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments.cmake
new file mode 100644
index 0000000..80917d6
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER FOR 0 1 2 3)
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex-stderr.txt
new file mode 100644
index 0000000..31ba939
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at TRANSFORM-Selector-REGEX-InvalidRegex.cmake:2 \(list\):
+ list sub-command TRANSFORM, selector REGEX failed to compile regex
+ "\^\(alpha\$".
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex.cmake
new file mode 100644
index 0000000..56e202b
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER REGEX "^(alpha$")
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments-stderr.txt
new file mode 100644
index 0000000..2784785
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at TRANSFORM-Selector-REGEX-NoArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, selector REGEX expects 'regular expression'
+ argument.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments.cmake
new file mode 100644
index 0000000..f199d0e
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER REGEX)
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..db5b1ff
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-Selector-REGEX-TooManyArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, 'one_too_many': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments.cmake
new file mode 100644
index 0000000..4aa1619
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER REGEX "^alpha$" "one_too_many")
diff --git a/Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..90248ae
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-TOLOWER-TooManyArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, 'one_too_many': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments.cmake b/Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments.cmake
new file mode 100644
index 0000000..1758e19
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOLOWER one_too_many)
diff --git a/Tests/RunCMake/list/TRANSFORM-TOLOWER.cmake b/Tests/RunCMake/list/TRANSFORM-TOLOWER.cmake
new file mode 100644
index 0000000..a2d7348
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-TOLOWER.cmake
@@ -0,0 +1,48 @@
+set(mylist ALPHA BRAVO CHARLIE DELTA)
+
+list(TRANSFORM mylist TOLOWER OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo;charlie;delta")
+ message (FATAL_ERROR "TRANSFORM(TOLOWER) is \"${output}\", expected is \"alpha;bravo;charlie;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOLOWER AT 1 3 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "ALPHA;bravo;CHARLIE;delta")
+ message (FATAL_ERROR "TRANSFORM(TOLOWER) is \"${output}\", expected is \"ALPHA;bravo;CHARLIE;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOLOWER AT 1 -2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "ALPHA;bravo;charlie;DELTA")
+ message (FATAL_ERROR "TRANSFORM(TOLOWER) is \"${output}\", expected is \"ALPHA;bravo;charlie;DELTA\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOLOWER FOR 1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "ALPHA;bravo;charlie;DELTA")
+ message (FATAL_ERROR "TRANSFORM(TOLOWER) is \"${output}\", expected is \"ALPHA;bravo;charlie;DELTA\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOLOWER FOR 1 -1 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "ALPHA;bravo;charlie;delta")
+ message (FATAL_ERROR "TRANSFORM(TOLOWER) is \"${output}\", expected is \"ALPHA;bravo;charlie;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOLOWER FOR 0 -1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;BRAVO;charlie;DELTA")
+ message (FATAL_ERROR "TRANSFORM(TOLOWER) is \"${output}\", expected is \"alpha;BRAVO;charlie;DELTA\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOLOWER REGEX "(R|T)A" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "ALPHA;bravo;CHARLIE;delta")
+ message (FATAL_ERROR "TRANSFORM(TOLOWER) is \"${output}\", expected is \"ALPHA;bravo;CHARLIE;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOLOWER REGEX "(R|T)A")
+if (NOT mylist STREQUAL "ALPHA;bravo;CHARLIE;delta")
+ message (FATAL_ERROR "TRANSFORM(TOLOWER) is \"${mylist}\", expected is \"ALPHA;bravo;CHARLIE;delta\"")
+endif()
diff --git a/Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..9da241b
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-TOUPPER-TooManyArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, 'one_too_many': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments.cmake b/Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments.cmake
new file mode 100644
index 0000000..58d6a8c
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER one_too_many)
diff --git a/Tests/RunCMake/list/TRANSFORM-TOUPPER.cmake b/Tests/RunCMake/list/TRANSFORM-TOUPPER.cmake
new file mode 100644
index 0000000..5b1fcb6
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-TOUPPER.cmake
@@ -0,0 +1,48 @@
+set(mylist alpha bravo charlie delta)
+
+list(TRANSFORM mylist TOUPPER OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "ALPHA;BRAVO;CHARLIE;DELTA")
+ message (FATAL_ERROR "TRANSFORM(TOUPPER) is \"${output}\", expected is \"ALPHA;BRAVO;CHARLIE;DELTA\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOUPPER AT 1 3 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;BRAVO;charlie;DELTA")
+ message (FATAL_ERROR "TRANSFORM(TOUPPER) is \"${output}\", expected is \"alpha;BRAVO;charlie;DELTA\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOUPPER AT 1 -2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;BRAVO;CHARLIE;delta")
+ message (FATAL_ERROR "TRANSFORM(TOUPPER) is \"${output}\", expected is \"alpha;BRAVO;CHARLIE;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOUPPER FOR 1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;BRAVO;CHARLIE;delta")
+ message (FATAL_ERROR "TRANSFORM(TOUPPER) is \"${output}\", expected is \"alpha;BRAVO;CHARLIE;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOUPPER FOR 1 -1 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;BRAVO;CHARLIE;DELTA")
+ message (FATAL_ERROR "TRANSFORM(TOUPPER) is \"${output}\", expected is \"alpha;BRAVO;CHARLIE;DELTA\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOUPPER FOR 0 -1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "ALPHA;bravo;CHARLIE;delta")
+ message (FATAL_ERROR "TRANSFORM(TOUPPER) is \"${output}\", expected is \"ALPHA;bravo;CHARLIE;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOUPPER REGEX "(r|t)a" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;BRAVO;charlie;DELTA")
+ message (FATAL_ERROR "TRANSFORM(TOUPPER) is \"${output}\", expected is \"alpha;BRAVO;charlie;DELTA\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOUPPER REGEX "(r|t)a")
+if (NOT mylist STREQUAL "alpha;BRAVO;charlie;DELTA")
+ message (FATAL_ERROR "TRANSFORM(TOUPPER) is \"${mylist}\", expected is \"alpha;BRAVO;charlie;DELTA\"")
+endif()
diff --git a/Tests/RunCMake/variable_watch/RaiseInParentScope-stderr.txt b/Tests/RunCMake/variable_watch/RaiseInParentScope-stderr.txt
new file mode 100644
index 0000000..51db19c
--- /dev/null
+++ b/Tests/RunCMake/variable_watch/RaiseInParentScope-stderr.txt
@@ -0,0 +1,2 @@
+var MODIFIED_ACCESS a
+var MODIFIED_ACCESS b
diff --git a/Tests/RunCMake/variable_watch/RaiseInParentScope.cmake b/Tests/RunCMake/variable_watch/RaiseInParentScope.cmake
new file mode 100644
index 0000000..207798e
--- /dev/null
+++ b/Tests/RunCMake/variable_watch/RaiseInParentScope.cmake
@@ -0,0 +1,15 @@
+
+function(watch variable access value)
+ message("${variable} ${access} ${value}")
+endfunction ()
+
+# --------------
+
+variable_watch(var watch)
+set(var "a")
+
+function(f)
+ set(var "b" PARENT_SCOPE)
+endfunction(f)
+
+f()
diff --git a/Tests/RunCMake/variable_watch/RunCMakeTest.cmake b/Tests/RunCMake/variable_watch/RunCMakeTest.cmake
index 2fa6275..3883999 100644
--- a/Tests/RunCMake/variable_watch/RunCMakeTest.cmake
+++ b/Tests/RunCMake/variable_watch/RunCMakeTest.cmake
@@ -4,3 +4,4 @@ run_cmake(ModifiedAccess)
run_cmake(NoWatcher)
run_cmake(WatchTwice)
run_cmake(ModifyWatchInCallback)
+run_cmake(RaiseInParentScope)
diff --git a/Tests/RunCMake/UseSWIG/BasicConfiguration.cmake b/Tests/UseSWIG/BasicConfiguration.cmake
index 2f46d63..d025d2a 100644
--- a/Tests/RunCMake/UseSWIG/BasicConfiguration.cmake
+++ b/Tests/UseSWIG/BasicConfiguration.cmake
@@ -2,6 +2,13 @@
find_package(SWIG REQUIRED)
include(${SWIG_USE_FILE})
+# Path separator
+if (WIN32)
+ set (PS "$<SEMICOLON>")
+else()
+ set (PS ":")
+endif()
+
unset(SWIG_LANG_TYPE)
unset(SWIG_LANG_INCLUDE_DIRECTORIES)
unset(SWIG_LANG_DEFINITIONS)
@@ -52,16 +59,21 @@ unset(CMAKE_SWIG_FLAGS)
set (CMAKE_INCLUDE_CURRENT_DIR ON)
-set_property(SOURCE example.i PROPERTY CPLUSPLUS ON)
-set_property(SOURCE example.i PROPERTY COMPILE_OPTIONS -includeall)
+set_property(SOURCE "${CMAKE_CURRENT_LIST_DIR}/example.i" PROPERTY CPLUSPLUS ON)
+set_property(SOURCE "${CMAKE_CURRENT_LIST_DIR}/example.i" PROPERTY COMPILE_OPTIONS -includeall)
-set_property(SOURCE example.i PROPERTY GENERATED_INCLUDE_DIRECTORIES ${SWIG_LANG_INCLUDE_DIRECTORIES})
-set_property(SOURCE example.i PROPERTY GENERATED_COMPILE_DEFINITIONS ${SWIG_LANG_DEFINITIONS})
-set_property(SOURCE example.i PROPERTY GENERATED_COMPILE_OPTIONS ${SWIG_LANG_OPTIONS})
+set_property(SOURCE "${CMAKE_CURRENT_LIST_DIR}/example.i"
+ PROPERTY GENERATED_INCLUDE_DIRECTORIES ${SWIG_LANG_INCLUDE_DIRECTORIES}
+ "${CMAKE_CURRENT_LIST_DIR}")
+set_property(SOURCE "${CMAKE_CURRENT_LIST_DIR}/example.i"
+ PROPERTY GENERATED_COMPILE_DEFINITIONS ${SWIG_LANG_DEFINITIONS})
+set_property(SOURCE "${CMAKE_CURRENT_LIST_DIR}/example.i"
+ PROPERTY GENERATED_COMPILE_OPTIONS ${SWIG_LANG_OPTIONS})
SWIG_ADD_LIBRARY(example
LANGUAGE "${language}"
${SWIG_LANG_TYPE}
- SOURCES example.i example.cxx)
+ SOURCES "${CMAKE_CURRENT_LIST_DIR}/example.i"
+ "${CMAKE_CURRENT_LIST_DIR}/example.cxx")
TARGET_LINK_LIBRARIES(example PRIVATE ${SWIG_LANG_LIBRARIES})
diff --git a/Tests/UseSWIG/BasicPerl/CMakeLists.txt b/Tests/UseSWIG/BasicPerl/CMakeLists.txt
new file mode 100644
index 0000000..476ef0e
--- /dev/null
+++ b/Tests/UseSWIG/BasicPerl/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestBasicPerl CXX)
+
+include(CTest)
+
+set(language "perl")
+
+include (../BasicConfiguration.cmake)
+
+add_test (NAME BasicPerl
+ COMMAND "${PERL_EXECUTABLE}" "-I${CMAKE_CURRENT_BINARY_DIR}"
+ "-I$<TARGET_FILE_DIR:example>"
+ "${CMAKE_CURRENT_SOURCE_DIR}/../runme.pl")
diff --git a/Tests/UseSWIG/BasicPython/CMakeLists.txt b/Tests/UseSWIG/BasicPython/CMakeLists.txt
new file mode 100644
index 0000000..cf1d821
--- /dev/null
+++ b/Tests/UseSWIG/BasicPython/CMakeLists.txt
@@ -0,0 +1,13 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestBasicPython CXX)
+
+include(CTest)
+
+set(language "python")
+
+include (../BasicConfiguration.cmake)
+
+add_test (NAME BasicPython
+ COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}${PS}$<TARGET_FILE_DIR:example>"
+ "${Python_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/../runme.py")
diff --git a/Tests/UseSWIG/CMakeLists.txt b/Tests/UseSWIG/CMakeLists.txt
new file mode 100644
index 0000000..0c4ec8a
--- /dev/null
+++ b/Tests/UseSWIG/CMakeLists.txt
@@ -0,0 +1,76 @@
+add_test(NAME UseSWIG.LegacyPython COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/UseSWIG/LegacyPython"
+ "${CMake_BINARY_DIR}/Tests/UseSWIG/LegacyPython"
+ ${build_generator_args}
+ --build-project TestLegacyPython
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+add_test(NAME UseSWIG.LegacyPerl COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/UseSWIG/LegacyPerl"
+ "${CMake_BINARY_DIR}/Tests/UseSWIG/LegacyPerl"
+ ${build_generator_args}
+ --build-project TestLegacyPerl
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+
+
+add_test(NAME UseSWIG.BasicPython COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/UseSWIG/BasicPython"
+ "${CMake_BINARY_DIR}/Tests/UseSWIG/BasicPython"
+ ${build_generator_args}
+ --build-project TestBasicPython
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+add_test(NAME UseSWIG.BasicPerl COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/UseSWIG/BasicPerl"
+ "${CMake_BINARY_DIR}/Tests/UseSWIG/BasicPerl"
+ ${build_generator_args}
+ --build-project TestBasicPerl
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+
+
+add_test(NAME UseSWIG.MultipleModules COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/UseSWIG/MultipleModules"
+ "${CMake_BINARY_DIR}/Tests/UseSWIG/MultipleModules"
+ ${build_generator_args}
+ --build-project TestMultipleModules
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+add_test(NAME UseSWIG.MultiplePython COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/UseSWIG/MultiplePython"
+ "${CMake_BINARY_DIR}/Tests/UseSWIG/MultiplePython"
+ ${build_generator_args}
+ --build-project TestMultiplePython
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+
+
+add_test(NAME UseSWIG.ModuleVersion2 COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/UseSWIG/ModuleVersion2"
+ "${CMake_BINARY_DIR}/Tests/UseSWIG/ModuleVersion2"
+ ${build_generator_args}
+ --build-project TestModuleVersion2
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
diff --git a/Tests/RunCMake/UseSWIG/LegacyConfiguration.cmake b/Tests/UseSWIG/LegacyConfiguration.cmake
index 3ce0790..1acc05a 100644
--- a/Tests/RunCMake/UseSWIG/LegacyConfiguration.cmake
+++ b/Tests/UseSWIG/LegacyConfiguration.cmake
@@ -5,6 +5,13 @@ set (CMAKE_WARN_DEPRECATED FALSE)
find_package(SWIG REQUIRED)
include(${SWIG_USE_FILE})
+# Path separator
+if (WIN32)
+ set (PS "$<SEMICOLON>")
+else()
+ set (PS ":")
+endif()
+
unset(SWIG_LANG_TYPE)
if(${language} MATCHES python)
find_package(PythonInterp REQUIRED)
@@ -51,10 +58,11 @@ unset(CMAKE_SWIG_FLAGS)
include_directories(${CMAKE_CURRENT_LIST_DIR})
-set_source_files_properties(example.i PROPERTIES CPLUSPLUS ON)
-set_source_files_properties(example.i PROPERTIES SWIG_FLAGS "-includeall")
+set_source_files_properties("${CMAKE_CURRENT_LIST_DIR}/example.i" PROPERTIES CPLUSPLUS ON)
+set_source_files_properties("${CMAKE_CURRENT_LIST_DIR}/example.i" PROPERTIES SWIG_FLAGS "-includeall")
SWIG_ADD_LIBRARY(example
LANGUAGE "${language}"
${SWIG_LANG_TYPE}
- SOURCES example.i example.cxx)
+ SOURCES "${CMAKE_CURRENT_LIST_DIR}/example.i"
+ "${CMAKE_CURRENT_LIST_DIR}/example.cxx")
SWIG_LINK_LIBRARIES(example ${SWIG_LANG_LIBRARIES})
diff --git a/Tests/UseSWIG/LegacyPerl/CMakeLists.txt b/Tests/UseSWIG/LegacyPerl/CMakeLists.txt
new file mode 100644
index 0000000..90d92f4
--- /dev/null
+++ b/Tests/UseSWIG/LegacyPerl/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestLegacyPerl CXX)
+
+include(CTest)
+
+set(language "perl")
+
+include (../LegacyConfiguration.cmake)
+
+add_test (NAME LegacyPerl
+ COMMAND "${PERL_EXECUTABLE}" "-I${CMAKE_CURRENT_BINARY_DIR}"
+ "-I$<TARGET_FILE_DIR:${SWIG_MODULE_example_REAL_NAME}>"
+ "${CMAKE_CURRENT_SOURCE_DIR}/../runme.pl")
diff --git a/Tests/UseSWIG/LegacyPython/CMakeLists.txt b/Tests/UseSWIG/LegacyPython/CMakeLists.txt
new file mode 100644
index 0000000..03facb1
--- /dev/null
+++ b/Tests/UseSWIG/LegacyPython/CMakeLists.txt
@@ -0,0 +1,13 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestLegacyPython CXX)
+
+include(CTest)
+
+set(language "python")
+
+include (../LegacyConfiguration.cmake)
+
+add_test (NAME LegacyPython
+ COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}${PS}$<TARGET_FILE_DIR:${SWIG_MODULE_example_REAL_NAME}>"
+ "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/../runme.py")
diff --git a/Tests/UseSWIG/ModuleVersion2/CMakeLists.txt b/Tests/UseSWIG/ModuleVersion2/CMakeLists.txt
new file mode 100644
index 0000000..3f9d363
--- /dev/null
+++ b/Tests/UseSWIG/ModuleVersion2/CMakeLists.txt
@@ -0,0 +1,56 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestModuleVersion2 CXX)
+
+include(CTest)
+
+find_package(SWIG REQUIRED)
+include(${SWIG_USE_FILE})
+
+find_package(Python2 REQUIRED COMPONENTS Interpreter Development)
+find_package(Python3 REQUIRED COMPONENTS Interpreter Development)
+
+if (WIN32)
+ set (PS $<SEMICOLON>)
+else()
+ set (PS ":")
+endif()
+
+set (UseSWIG_MODULE_VERSION 2)
+unset(CMAKE_SWIG_FLAGS)
+
+set_property(SOURCE "../example.i" PROPERTY CPLUSPLUS ON)
+set_property(SOURCE "../example.i" PROPERTY COMPILE_OPTIONS -includeall)
+
+set_property(SOURCE "../example.i"
+ PROPERTY GENERATED_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/..")
+
+swig_add_library(example1
+ LANGUAGE python
+ SOURCES ../example.i ../example.cxx)
+set_target_properties (example1 PROPERTIES
+ OUTPUT_NAME example
+ LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python2"
+ ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python2"
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python2")
+target_link_libraries(example1 PRIVATE Python2::Python)
+
+# re-use sample interface file for another plugin
+swig_add_library(example2
+ LANGUAGE python
+ SOURCES ../example.i ../example.cxx)
+set_target_properties (example2 PROPERTIES
+ OUTPUT_NAME example
+ LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python3"
+ ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python3"
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python3")
+target_link_libraries(example2 PRIVATE Python3::Python)
+
+
+add_test (NAME ModuleVersion2.example1
+ COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$<TARGET_PROPERTY:example1,SWIG_SUPPORT_FILES_DIRECTORY>${PS}$<TARGET_FILE_DIR:example1>"
+ "${Python2_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/../runme.py")
+
+add_test (NAME ModuleVersion2.example2
+ COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$<TARGET_PROPERTY:example2,SWIG_SUPPORT_FILES_DIRECTORY>${PS}$<TARGET_FILE_DIR:example2>"
+ "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/../runme.py")
diff --git a/Tests/UseSWIG/MultipleModules/CMakeLists.txt b/Tests/UseSWIG/MultipleModules/CMakeLists.txt
new file mode 100644
index 0000000..578825f
--- /dev/null
+++ b/Tests/UseSWIG/MultipleModules/CMakeLists.txt
@@ -0,0 +1,68 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestMultipleModules CXX)
+
+include(CTest)
+
+find_package(SWIG REQUIRED)
+include(${SWIG_USE_FILE})
+
+find_package(Python REQUIRED COMPONENTS Interpreter Development)
+
+find_package(Perl REQUIRED)
+find_package(PerlLibs REQUIRED)
+
+# Path separator
+if (WIN32)
+ set (PS "$<SEMICOLON>")
+else()
+ set (PS ":")
+endif()
+
+unset(CMAKE_SWIG_FLAGS)
+
+set_property(SOURCE "../example.i" PROPERTY CPLUSPLUS ON)
+set_property(SOURCE "../example.i" PROPERTY COMPILE_OPTIONS -includeall)
+
+set_property(SOURCE "../example.i"
+ PROPERTY GENERATED_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/..")
+
+swig_add_library(example1
+ LANGUAGE python
+ OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/Python"
+ SOURCES ../example.i ../example.cxx)
+set_target_properties (example1 PROPERTIES
+ OUTPUT_NAME example
+ LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python"
+ ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python"
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python")
+target_link_libraries(example1 PRIVATE Python::Python)
+
+# re-use sample interface file for another plugin
+set_property(SOURCE "../example.i" APPEND PROPERTY
+ GENERATED_INCLUDE_DIRECTORIES ${PERL_INCLUDE_PATH})
+separate_arguments(c_flags UNIX_COMMAND "${PERL_EXTRA_C_FLAGS}")
+set_property(SOURCE "../example.i" PROPERTY GENERATED_COMPILE_OPTIONS ${c_flags})
+
+swig_add_library(example2
+ LANGUAGE perl
+ OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/Perl"
+ SOURCES ../example.i ../example.cxx)
+set_target_properties (example2 PROPERTIES
+ OUTPUT_NAME example
+ LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Perl"
+ ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Perl"
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Perl")
+target_link_libraries(example2 PRIVATE ${PERL_LIBRARY})
+
+
+
+add_test (NAME MultipleModules.Python
+ COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}/Python${PS}$<TARGET_FILE_DIR:example1>"
+ "${Python_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/../runme.py")
+
+
+add_test (NAME MultipleModules.Perl
+ COMMAND "${PERL_EXECUTABLE}" "-I${CMAKE_CURRENT_BINARY_DIR}/Perl"
+ "-I$<TARGET_FILE_DIR:example2>"
+ "${CMAKE_CURRENT_SOURCE_DIR}/../runme.pl")
diff --git a/Tests/UseSWIG/MultiplePython/CMakeLists.txt b/Tests/UseSWIG/MultiplePython/CMakeLists.txt
new file mode 100644
index 0000000..a5e3eed
--- /dev/null
+++ b/Tests/UseSWIG/MultiplePython/CMakeLists.txt
@@ -0,0 +1,59 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestMultiplePython CXX)
+
+include(CTest)
+
+find_package(SWIG REQUIRED)
+include(${SWIG_USE_FILE})
+
+find_package(Python2 REQUIRED COMPONENTS Interpreter Development)
+find_package(Python3 REQUIRED COMPONENTS Interpreter Development)
+
+# Path separator
+if (WIN32)
+ set (PS "$<SEMICOLON>")
+else()
+ set (PS ":")
+endif()
+
+unset(CMAKE_SWIG_FLAGS)
+
+set_property(SOURCE "../example.i" PROPERTY CPLUSPLUS ON)
+set_property(SOURCE "../example.i" PROPERTY COMPILE_OPTIONS -includeall)
+
+set_property(SOURCE "../example.i"
+ PROPERTY GENERATED_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/..")
+
+swig_add_library(example1
+ LANGUAGE python
+ OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/Python2"
+ SOURCES ../example.i ../example.cxx)
+set_target_properties (example1 PROPERTIES
+ OUTPUT_NAME example
+ LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python2"
+ ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python2"
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python2")
+target_link_libraries(example1 PRIVATE Python2::Python)
+
+# re-use sample interface file for another plugin
+swig_add_library(example2
+ LANGUAGE python
+ OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/Python3"
+ SOURCES ../example.i ../example.cxx)
+set_target_properties (example2 PROPERTIES
+ OUTPUT_NAME example
+ LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python3"
+ ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python3"
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Python3")
+target_link_libraries(example2 PRIVATE Python3::Python)
+
+
+
+add_test (NAME MultiplePython.example1
+ COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}/Python2${PS}$<TARGET_FILE_DIR:example1>"
+ "${Python2_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/../runme.py")
+
+add_test (NAME MultiplePython.example2
+ COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}/Python3${PS}$<TARGET_FILE_DIR:example2>"
+ "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/../runme.py")
diff --git a/Tests/RunCMake/UseSWIG/example.cxx b/Tests/UseSWIG/example.cxx
index 961d6dd..961d6dd 100644
--- a/Tests/RunCMake/UseSWIG/example.cxx
+++ b/Tests/UseSWIG/example.cxx
diff --git a/Tests/RunCMake/UseSWIG/example.h b/Tests/UseSWIG/example.h
index 366deb0..366deb0 100644
--- a/Tests/RunCMake/UseSWIG/example.h
+++ b/Tests/UseSWIG/example.h
diff --git a/Tests/RunCMake/UseSWIG/example.i b/Tests/UseSWIG/example.i
index fbdf724..fbdf724 100644
--- a/Tests/RunCMake/UseSWIG/example.i
+++ b/Tests/UseSWIG/example.i
diff --git a/Tests/RunCMake/UseSWIG/runme.php4 b/Tests/UseSWIG/runme.php4
index 653ced2..653ced2 100644
--- a/Tests/RunCMake/UseSWIG/runme.php4
+++ b/Tests/UseSWIG/runme.php4
diff --git a/Tests/RunCMake/UseSWIG/runme.pike b/Tests/UseSWIG/runme.pike
index ec28dd7..ec28dd7 100644
--- a/Tests/RunCMake/UseSWIG/runme.pike
+++ b/Tests/UseSWIG/runme.pike
diff --git a/Tests/RunCMake/UseSWIG/runme.pl b/Tests/UseSWIG/runme.pl
index 965e063..965e063 100644
--- a/Tests/RunCMake/UseSWIG/runme.pl
+++ b/Tests/UseSWIG/runme.pl
diff --git a/Tests/RunCMake/UseSWIG/runme.py b/Tests/UseSWIG/runme.py
index af5e07d..af5e07d 100644
--- a/Tests/RunCMake/UseSWIG/runme.py
+++ b/Tests/UseSWIG/runme.py
diff --git a/Tests/RunCMake/UseSWIG/runme.rb b/Tests/UseSWIG/runme.rb
index de73bcd..de73bcd 100644
--- a/Tests/RunCMake/UseSWIG/runme.rb
+++ b/Tests/UseSWIG/runme.rb
diff --git a/Tests/RunCMake/UseSWIG/runme.tcl b/Tests/UseSWIG/runme.tcl
index 6055cf6..6055cf6 100644
--- a/Tests/RunCMake/UseSWIG/runme.tcl
+++ b/Tests/UseSWIG/runme.tcl
diff --git a/Tests/RunCMake/UseSWIG/runme2.tcl b/Tests/UseSWIG/runme2.tcl
index d0b5c21..d0b5c21 100644
--- a/Tests/RunCMake/UseSWIG/runme2.tcl
+++ b/Tests/UseSWIG/runme2.tcl
diff --git a/Utilities/Release/linux64_release.cmake b/Utilities/Release/linux64_release.cmake
index 97fc33c..2fd4f12 100644
--- a/Utilities/Release/linux64_release.cmake
+++ b/Utilities/Release/linux64_release.cmake
@@ -34,7 +34,7 @@ OPENSSL_INCLUDE_DIR:PATH=/home/kitware/openssl-1.1.0g/include
OPENSSL_SSL_LIBRARY:FILEPATH=/home/kitware/openssl-1.1.0g/lib/libssl.a
PYTHON_EXECUTABLE:FILEPATH=/usr/bin/python3
CPACK_SYSTEM_NAME:STRING=Linux-x86_64
-BUILD_QtDialog:BOOL:=TRUE
+BUILD_QtDialog:BOOL=TRUE
CMAKE_SKIP_BOOTSTRAP_TEST:STRING=TRUE
CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL:STRING=3
CMAKE_PREFIX_PATH:STRING=${qt_prefix}
diff --git a/Utilities/Release/win32_release.cmake b/Utilities/Release/win32_release.cmake
index bdf002e..f9e35a5 100644
--- a/Utilities/Release/win32_release.cmake
+++ b/Utilities/Release/win32_release.cmake
@@ -21,7 +21,7 @@ CMAKE_USE_OPENSSL:BOOL=OFF
CMAKE_SKIP_BOOTSTRAP_TEST:STRING=TRUE
CMAKE_Fortran_COMPILER:FILEPATH=FALSE
CMAKE_GENERATOR:INTERNAL=Ninja
-BUILD_QtDialog:BOOL:=TRUE
+BUILD_QtDialog:BOOL=TRUE
CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL:STRING=3
CMAKE_C_FLAGS_RELEASE:STRING=-MT -O2 -Ob2 -DNDEBUG
CMAKE_CXX_FLAGS_RELEASE:STRING=-MT -O2 -Ob2 -DNDEBUG
diff --git a/Utilities/Release/win64_release.cmake b/Utilities/Release/win64_release.cmake
index 1c81f82..02e4096 100644
--- a/Utilities/Release/win64_release.cmake
+++ b/Utilities/Release/win64_release.cmake
@@ -21,7 +21,7 @@ CMAKE_USE_OPENSSL:BOOL=OFF
CMAKE_SKIP_BOOTSTRAP_TEST:STRING=TRUE
CMAKE_Fortran_COMPILER:FILEPATH=FALSE
CMAKE_GENERATOR:INTERNAL=Ninja
-BUILD_QtDialog:BOOL:=TRUE
+BUILD_QtDialog:BOOL=TRUE
CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL:STRING=3
CMAKE_C_FLAGS_RELEASE:STRING=-MT -O2 -Ob2 -DNDEBUG
CMAKE_CXX_FLAGS_RELEASE:STRING=-MT -O2 -Ob2 -DNDEBUG
diff --git a/bootstrap b/bootstrap
index 3d5b0d0..6604f54 100755
--- a/bootstrap
+++ b/bootstrap
@@ -332,6 +332,7 @@ CMAKE_CXX_SOURCES="\
cmGlobalCommonGenerator \
cmGlobalGenerator \
cmGlobalUnixMakefileGenerator3 \
+ cmGlobVerificationManager \
cmHexFileConverter \
cmIfCommand \
cmIncludeCommand \
@@ -399,6 +400,7 @@ CMAKE_CXX_SOURCES="\
cmState \
cmStateDirectory \
cmStateSnapshot \
+ cmStringReplaceHelper \
cmStringCommand \
cmSubdirCommand \
cmSystemTools \
@@ -569,6 +571,8 @@ Configuration:
--no-system-libarchive use cmake-provided libarchive library (default)
--system-librhash use system-installed librhash library
--no-system-librhash use cmake-provided librhash library (default)
+ --system-libuv use system-installed libuv library
+ --no-system-libuv use cmake-provided libuv library (default)
--qt-gui build the Qt-based GUI (requires Qt >= 4.2)
--no-qt-gui do not build the Qt-based GUI (default)
@@ -803,10 +807,10 @@ while test $# != 0; do
--init=*) cmake_init_file=`cmake_arg "$1"` ;;
--system-libs) cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARIES=1" ;;
--no-system-libs) cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARIES=0" ;;
- --system-bzip2|--system-curl|--system-expat|--system-jsoncpp|--system-libarchive|--system-librhash|--system-zlib|--system-liblzma)
+ --system-bzip2|--system-curl|--system-expat|--system-jsoncpp|--system-libarchive|--system-librhash|--system-zlib|--system-liblzma|--system-libuv)
lib=`cmake_arg "$1" "--system-"`
cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARY_`cmake_toupper $lib`=1" ;;
- --no-system-bzip2|--no-system-curl|--no-system-expat|--no-system-jsoncpp|--no-system-libarchive|--no-system-librhash|--no-system-zlib|--no-system-liblzma)
+ --no-system-bzip2|--no-system-curl|--no-system-expat|--no-system-jsoncpp|--no-system-libarchive|--no-system-librhash|--no-system-zlib|--no-system-liblzma|--no-system-libuv)
lib=`cmake_arg "$1" "--no-system-"`
cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARY_`cmake_toupper $lib`=0" ;;
--qt-gui) cmake_bootstrap_qt_gui="1" ;;