summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rw-r--r--Auxiliary/vim/syntax/cmake.vim2
-rw-r--r--CMakeLists.txt14
-rw-r--r--CompileFlags.cmake2
-rw-r--r--Help/command/export.rst15
-rw-r--r--Help/command/file.rst6
-rw-r--r--Help/command/find_package.rst18
-rw-r--r--Help/command/include.rst6
-rw-r--r--Help/command/install.rst14
-rw-r--r--Help/command/separate_arguments.rst12
-rw-r--r--Help/command/string.rst2
-rw-r--r--Help/index.rst1
-rw-r--r--Help/manual/cmake-properties.7.rst4
-rw-r--r--Help/manual/cmake-server.7.rst237
-rw-r--r--Help/manual/cmake-variables.7.rst6
-rw-r--r--Help/manual/cmake.1.rst3
-rw-r--r--Help/prop_dir/BINARY_DIR.rst5
-rw-r--r--Help/prop_dir/BUILDSYSTEM_TARGETS.rst11
-rw-r--r--Help/prop_dir/SOURCE_DIR.rst5
-rw-r--r--Help/prop_dir/SUBDIRECTORIES.rst15
-rw-r--r--Help/release/dev/ExternalProject-HTTP_HEADER.rst5
-rw-r--r--Help/release/dev/ExternalProject-http-credentials.rst5
-rw-r--r--Help/release/dev/add_androidmk_generator.rst10
-rw-r--r--Help/release/dev/cmake-gui-open-project.rst5
-rw-r--r--Help/release/dev/cmake-server-basic.rst6
-rw-r--r--Help/release/dev/cpack-rpm-srpm-package.rst7
-rw-r--r--Help/release/dev/cpack.hash_computing.rst5
-rw-r--r--Help/release/dev/directory-list-targets-and-subdirs.rst16
-rw-r--r--Help/release/dev/file-curl-httpheader.rst5
-rw-r--r--Help/release/dev/file-curl-userpw.rst5
-rw-r--r--Help/release/dev/find_package-dir-sort.rst13
-rw-r--r--Help/release/dev/fortran-submodules.rst7
-rw-r--r--Help/release/dev/ifw-package-resources.rst6
-rw-r--r--Help/release/dev/ifw-user-interfaces.rst7
-rw-r--r--Help/release/dev/timestamp-names.rst6
-rw-r--r--Help/variable/CMAKE_COMPILER_IS_GNUCC.rst5
-rw-r--r--Help/variable/CMAKE_COMPILER_IS_GNUCXX.rst5
-rw-r--r--Help/variable/CMAKE_COMPILER_IS_GNUG77.rst5
-rw-r--r--Help/variable/CMAKE_COMPILER_IS_GNULANG.rst15
-rw-r--r--Help/variable/CMAKE_FIND_PACKAGE_SORT_DIRECTION.rst16
-rw-r--r--Help/variable/CMAKE_FIND_PACKAGE_SORT_ORDER.rst36
-rw-r--r--Modules/CPack.cmake14
-rw-r--r--Modules/CPackIFW.cmake247
-rw-r--r--Modules/CPackRPM.cmake232
-rw-r--r--Modules/ExternalProject-download.cmake.in2
-rw-r--r--Modules/ExternalProject.cmake31
-rw-r--r--Modules/FeatureSummary.cmake677
-rw-r--r--Modules/FindCUDA.cmake13
-rw-r--r--Modules/FindMatlab.cmake51
-rw-r--r--Modules/FindPostgreSQL.cmake4
-rw-r--r--Modules/FindPythonInterp.cmake2
-rw-r--r--Modules/FindPythonLibs.cmake2
-rw-r--r--Modules/GenerateExportHeader.cmake2
-rw-r--r--Modules/MatlabTestsRedirect.cmake41
-rw-r--r--Source/CMakeLists.txt15
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CPack/IFW/cmCPackIFWGenerator.cxx13
-rw-r--r--Source/CPack/IFW/cmCPackIFWInstaller.cxx84
-rw-r--r--Source/CPack/IFW/cmCPackIFWInstaller.h3
-rw-r--r--Source/CPack/IFW/cmCPackIFWPackage.cxx30
-rw-r--r--Source/CPack/IFW/cmCPackIFWPackage.h3
-rw-r--r--Source/CPack/cmCPackGenerator.cxx33
-rw-r--r--Source/CTest/cmCTestSVN.cxx17
-rw-r--r--Source/CTest/cmCTestSVN.h2
-rw-r--r--Source/Checks/cm_cxx_features.cmake5
-rw-r--r--Source/Checks/cm_cxx_make_unique.cxx6
-rw-r--r--Source/Checks/cm_cxx_unique_ptr.cxx6
-rw-r--r--Source/CursesDialog/cmCursesStandardIncludes.h4
-rw-r--r--Source/CursesDialog/form/form.h4
-rw-r--r--Source/QtDialog/CMakeSetupDialog.cxx37
-rw-r--r--Source/QtDialog/CMakeSetupDialog.h2
-rw-r--r--Source/QtDialog/CMakeSetupDialog.ui7
-rw-r--r--Source/cmAddCompileOptionsCommand.cxx2
-rw-r--r--Source/cmAddCustomCommandCommand.cxx4
-rw-r--r--Source/cmAddCustomTargetCommand.cxx2
-rw-r--r--Source/cmAddDefinitionsCommand.cxx2
-rw-r--r--Source/cmAddLibraryCommand.cxx2
-rw-r--r--Source/cmAddSubDirectoryCommand.cxx2
-rw-r--r--Source/cmBuildCommand.cxx2
-rw-r--r--Source/cmBuildNameCommand.cxx2
-rw-r--r--Source/cmCMakeHostSystemInformationCommand.cxx4
-rw-r--r--Source/cmCMakePolicyCommand.cxx17
-rw-r--r--Source/cmCPluginAPI.cxx15
-rw-r--r--Source/cmCommandArgumentsHelper.cxx9
-rw-r--r--Source/cmCommonTargetGenerator.cxx12
-rw-r--r--Source/cmCommonTargetGenerator.h4
-rw-r--r--Source/cmConditionEvaluator.cxx22
-rw-r--r--Source/cmConfigure.cmake.h.in2
-rw-r--r--Source/cmCoreTryCompile.cxx3
-rw-r--r--Source/cmDefinePropertyCommand.cxx2
-rw-r--r--Source/cmDependsC.cxx17
-rw-r--r--Source/cmDependsFortran.cxx63
-rw-r--r--Source/cmEnableLanguageCommand.cxx2
-rw-r--r--Source/cmExecProgramCommand.cxx2
-rw-r--r--Source/cmExecuteProcessCommand.cxx7
-rw-r--r--Source/cmExportBuildAndroidMKGenerator.cxx193
-rw-r--r--Source/cmExportBuildAndroidMKGenerator.h69
-rw-r--r--Source/cmExportCommand.cxx21
-rw-r--r--Source/cmExportCommand.h1
-rw-r--r--Source/cmExportFileGenerator.cxx45
-rw-r--r--Source/cmExportFileGenerator.h39
-rw-r--r--Source/cmExportInstallAndroidMKGenerator.cxx146
-rw-r--r--Source/cmExportInstallAndroidMKGenerator.h73
-rw-r--r--Source/cmExportInstallFileGenerator.cxx153
-rw-r--r--Source/cmExportInstallFileGenerator.h12
-rw-r--r--Source/cmExportLibraryDependenciesCommand.cxx4
-rw-r--r--Source/cmExportTryCompileFileGenerator.cxx5
-rw-r--r--Source/cmExternalMakefileProjectGenerator.h2
-rw-r--r--Source/cmExtraEclipseCDT4Generator.cxx2
-rw-r--r--Source/cmFileCommand.cxx133
-rw-r--r--Source/cmFileLockUnix.cxx9
-rw-r--r--Source/cmFindBase.cxx3
-rw-r--r--Source/cmFindLibraryCommand.cxx6
-rw-r--r--Source/cmFindPackageCommand.cxx144
-rw-r--r--Source/cmFindPackageCommand.h26
-rw-r--r--Source/cmFindPathCommand.cxx3
-rw-r--r--Source/cmFindProgramCommand.cxx3
-rw-r--r--Source/cmForEachCommand.cxx7
-rw-r--r--Source/cmFortranLexer.cxx535
-rw-r--r--Source/cmFortranLexer.h2
-rw-r--r--Source/cmFortranLexer.in.l7
-rw-r--r--Source/cmFortranParser.cxx556
-rw-r--r--Source/cmFortranParser.y26
-rw-r--r--Source/cmFortranParserTokens.h50
-rw-r--r--Source/cmFunctionCommand.cxx7
-rw-r--r--Source/cmGeneratorTarget.cxx51
-rw-r--r--Source/cmGeneratorTarget.h5
-rw-r--r--Source/cmGetPropertyCommand.cxx34
-rw-r--r--Source/cmGlobalGenerator.cxx237
-rw-r--r--Source/cmGlobalGenerator.h29
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx42
-rw-r--r--Source/cmGlobalNinjaGenerator.h3
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx36
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx4
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx3
-rw-r--r--Source/cmGlobalXCodeGenerator.h1
-rw-r--r--Source/cmHexFileConverter.cxx3
-rw-r--r--Source/cmIfCommand.cxx3
-rw-r--r--Source/cmIncludeCommand.cxx2
-rw-r--r--Source/cmIncludeDirectoryCommand.cxx2
-rw-r--r--Source/cmIncludeRegularExpressionCommand.cxx2
-rw-r--r--Source/cmInstallCommand.cxx120
-rw-r--r--Source/cmInstallCommand.h1
-rw-r--r--Source/cmInstallExportAndroidMKGenerator.cxx149
-rw-r--r--Source/cmInstallExportAndroidMKGenerator.h46
-rw-r--r--Source/cmInstallExportGenerator.cxx13
-rw-r--r--Source/cmInstallExportGenerator.h3
-rw-r--r--Source/cmInstallFilesCommand.cxx10
-rw-r--r--Source/cmInstallProgramsCommand.cxx10
-rw-r--r--Source/cmInstallTargetsCommand.cxx17
-rw-r--r--Source/cmLinkDirectoriesCommand.cxx2
-rw-r--r--Source/cmLinkLibrariesCommand.cxx2
-rw-r--r--Source/cmLinkedTree.h4
-rw-r--r--Source/cmListFileCache.cxx8
-rw-r--r--Source/cmLoadCacheCommand.cxx2
-rw-r--r--Source/cmLoadCommandCommand.cxx2
-rw-r--r--Source/cmLocalCommonGenerator.cxx13
-rw-r--r--Source/cmLocalCommonGenerator.h9
-rw-r--r--Source/cmLocalGenerator.cxx35
-rw-r--r--Source/cmLocalNinjaGenerator.cxx13
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx42
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx18
-rw-r--r--Source/cmLocalVisualStudioGenerator.cxx4
-rw-r--r--Source/cmMacroCommand.cxx7
-rw-r--r--Source/cmMakefile.cxx22
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx47
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx59
-rw-r--r--Source/cmMakefileTargetGenerator.cxx116
-rw-r--r--Source/cmMakefileUtilityTargetGenerator.cxx9
-rw-r--r--Source/cmMarkAsAdvancedCommand.cxx2
-rw-r--r--Source/cmMathCommand.cxx2
-rw-r--r--Source/cmMessageCommand.cxx2
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx16
-rw-r--r--Source/cmNinjaTargetGenerator.cxx5
-rw-r--r--Source/cmOutputConverter.cxx121
-rw-r--r--Source/cmOutputConverter.h44
-rw-r--r--Source/cmOutputRequiredFilesCommand.cxx21
-rw-r--r--Source/cmProjectCommand.cxx2
-rw-r--r--Source/cmRemoveCommand.cxx2
-rw-r--r--Source/cmRemoveDefinitionsCommand.cxx2
-rw-r--r--Source/cmSearchPath.cxx3
-rw-r--r--Source/cmServer.cxx473
-rw-r--r--Source/cmServer.h97
-rw-r--r--Source/cmServerProtocol.cxx272
-rw-r--r--Source/cmServerProtocol.h121
-rw-r--r--Source/cmSetCommand.cxx4
-rw-r--r--Source/cmSetDirectoryPropertiesCommand.cxx5
-rw-r--r--Source/cmSetTestsPropertiesCommand.cxx2
-rw-r--r--Source/cmSourceGroupCommand.cxx2
-rw-r--r--Source/cmState.cxx73
-rw-r--r--Source/cmState.h10
-rw-r--r--Source/cmStringCommand.cxx72
-rw-r--r--Source/cmSubdirCommand.cxx2
-rw-r--r--Source/cmSystemTools.cxx77
-rw-r--r--Source/cmSystemTools.h10
-rw-r--r--Source/cmTarget.cxx34
-rw-r--r--Source/cmTarget.h21
-rw-r--r--Source/cmTargetLinkLibrariesCommand.cxx9
-rw-r--r--Source/cmTimestamp.cxx2
-rw-r--r--Source/cmUnsetCommand.cxx14
-rw-r--r--Source/cmVariableWatchCommand.cxx2
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx4
-rw-r--r--Source/cmWhileCommand.cxx7
-rw-r--r--Source/cm_auto_ptr.hxx6
-rw-r--r--Source/cmake.cxx65
-rw-r--r--Source/cmake.h12
-rw-r--r--Source/cmcmd.cxx43
-rw-r--r--Source/kwsys/CMakeLists.txt20
-rw-r--r--Source/kwsys/ConsoleBuf.hxx.in348
-rw-r--r--Source/kwsys/SystemTools.cxx70
-rw-r--r--Source/kwsys/SystemTools.hxx.in9
-rw-r--r--Source/kwsys/testConsoleBuf.cxx714
-rw-r--r--Source/kwsys/testConsoleBuf.hxx25
-rw-r--r--Source/kwsys/testConsoleBufChild.cxx63
-rw-r--r--Source/kwsys/testSystemTools.cxx4
-rw-r--r--Tests/CMakeLib/CMakeLists.txt1
-rw-r--r--Tests/CMakeLib/testFindPackageCommand.cxx76
-rw-r--r--Tests/CMakeLib/testSystemTools.cxx72
-rw-r--r--Tests/CMakeLists.txt9
-rw-r--r--Tests/CMakeTests/String-TIMESTAMP-MonthWeekNames.cmake11
-rw-r--r--Tests/CMakeTests/StringTest.cmake.in3
-rw-r--r--Tests/FindPackageTest/CMakeLists.txt30
-rw-r--r--Tests/FindPackageTest/SortLib-3.1.1/SortLibConfig.cmake2
-rw-r--r--Tests/FindPackageTest/SortLib-3.1.1/SortLibConfigVersion.cmake9
-rw-r--r--Tests/FindPackageTest/SortLib-3.10.1/SortLibConfig.cmake2
-rw-r--r--Tests/FindPackageTest/SortLib-3.10.1/SortLibConfigVersion.cmake9
-rw-r--r--Tests/RunCMake/AndroidMK/AndroidMK-check.cmake30
-rw-r--r--Tests/RunCMake/AndroidMK/AndroidMK.cmake11
-rw-r--r--Tests/RunCMake/AndroidMK/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/AndroidMK/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/AndroidMK/expectedBuildAndroidMK.txt23
-rw-r--r--Tests/RunCMake/AndroidMK/expectedInstallAndroidMK.txt25
-rw-r--r--Tests/RunCMake/AndroidMK/foo.cxx3
-rw-r--r--Tests/RunCMake/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/CPack/CMakeLists.txt6
-rw-r--r--Tests/RunCMake/CPack/CPackTestHelpers.cmake55
-rw-r--r--Tests/RunCMake/CPack/PACKAGE_CHECKSUM.cmake4
-rw-r--r--Tests/RunCMake/CPack/RPM/SOURCE_PACKAGE-ExpectedFiles.cmake5
-rw-r--r--Tests/RunCMake/CPack/RPM/SOURCE_PACKAGE-VerifyResult.cmake63
-rw-r--r--Tests/RunCMake/CPack/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/CPack/SOURCE_PACKAGE.cmake9
-rw-r--r--Tests/RunCMake/CPack/TGZ/PACKAGE_CHECKSUM-ExpectedFiles.cmake9
-rw-r--r--Tests/RunCMake/CPack/TGZ/PACKAGE_CHECKSUM-VerifyResult.cmake14
-rw-r--r--Tests/RunCMake/CPack/TGZ/PACKAGE_CHECKSUM-invalid-stderr.txt2
-rw-r--r--Tests/RunCMake/CPack/VerifyResult.cmake8
-rw-r--r--Tests/RunCMake/CommandLine/E_server-arg-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_server-arg-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/add_custom_command/AppendNotOutput-stderr.txt5
-rw-r--r--Tests/RunCMake/file/DOWNLOAD-httpheader-not-set-result.txt1
-rw-r--r--Tests/RunCMake/file/DOWNLOAD-httpheader-not-set-stderr.txt4
-rw-r--r--Tests/RunCMake/file/DOWNLOAD-httpheader-not-set.cmake1
-rw-r--r--Tests/RunCMake/file/DOWNLOAD-pass-not-set-result.txt1
-rw-r--r--Tests/RunCMake/file/DOWNLOAD-pass-not-set-stderr.txt4
-rw-r--r--Tests/RunCMake/file/DOWNLOAD-pass-not-set.cmake1
-rw-r--r--Tests/RunCMake/file/DOWNLOAD-unused-argument-result.txt0
-rw-r--r--Tests/RunCMake/file/DOWNLOAD-unused-argument-stderr.txt5
-rw-r--r--Tests/RunCMake/file/DOWNLOAD-unused-argument.cmake5
-rw-r--r--Tests/RunCMake/file/DOWNLOAD-unused-argument.txt0
-rw-r--r--Tests/RunCMake/file/LOCK-lowercase.cmake11
-rw-r--r--Tests/RunCMake/file/RunCMakeTest.cmake7
-rw-r--r--Tests/RunCMake/file/UPLOAD-httpheader-not-set-result.txt1
-rw-r--r--Tests/RunCMake/file/UPLOAD-httpheader-not-set-stderr.txt4
-rw-r--r--Tests/RunCMake/file/UPLOAD-httpheader-not-set.cmake1
-rw-r--r--Tests/RunCMake/file/UPLOAD-pass-not-set-result.txt1
-rw-r--r--Tests/RunCMake/file/UPLOAD-pass-not-set-stderr.txt4
-rw-r--r--Tests/RunCMake/file/UPLOAD-pass-not-set.cmake1
-rw-r--r--Tests/RunCMake/file/UPLOAD-unused-argument-result.txt0
-rw-r--r--Tests/RunCMake/file/UPLOAD-unused-argument-stderr.txt5
-rw-r--r--Tests/RunCMake/file/UPLOAD-unused-argument.cmake5
-rw-r--r--Tests/RunCMake/file/UPLOAD-unused-argument.txt0
-rw-r--r--Tests/RunCMake/get_filename_component/KnownComponents.cmake12
-rw-r--r--Tests/RunCMake/get_property/directory_properties-stderr.txt18
-rw-r--r--Tests/RunCMake/get_property/directory_properties.cmake15
-rw-r--r--Tests/RunCMake/get_property/directory_properties/CMakeLists.txt6
-rw-r--r--Tests/RunCMake/get_property/directory_properties/sub1/CMakeLists.txt0
-rw-r--r--Tests/RunCMake/get_property/directory_properties/sub2/CMakeLists.txt0
-rw-r--r--Tests/Server/CMakeLists.txt23
-rw-r--r--Tests/Server/cmakelib.py126
-rw-r--r--Tests/Server/empty.cpp5
-rw-r--r--Tests/Server/server-test.py82
-rw-r--r--Tests/Server/tc_handshake.json71
-rw-r--r--Utilities/Doxygen/CMakeLists.txt2
-rw-r--r--Utilities/Release/linux64_release.cmake2
-rw-r--r--Utilities/Release/osx_release.cmake2
-rw-r--r--Utilities/Release/win32_release.cmake2
-rw-r--r--Utilities/Release/win64_release.cmake2
-rw-r--r--Utilities/Sphinx/CMakeLists.txt2
288 files changed, 7644 insertions, 2095 deletions
diff --git a/.gitignore b/.gitignore
index 0d09cdc..5d1732d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,7 @@
# Exclude MacOS Finder files.
.DS_Store
+
+*.user*
+
+*.pyc
+Testing
diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim
index 715676d..11b0fcb 100644
--- a/Auxiliary/vim/syntax/cmake.vim
+++ b/Auxiliary/vim/syntax/cmake.vim
@@ -44,7 +44,7 @@ syn keyword cmakeModule
\ contained
syn keyword cmakeKWExternalProject
- \ ALGO ALWAYS BINARY_DIR BUILD_ALWAYS BUILD_BYPRODUCTS BUILD_COMMAND BUILD_IN_SOURCE BYPRODUCTS CMAKE_ARGS CMAKE_CACHE_ARGS CMAKE_CACHE_DEFAULT_ARGS COMMAND COMMENT CONFIGURE_COMMAND CVS CVSROOT CVS_ CVS_MODULE CVS_REPOSITORY CVS_TAG DEPENDEES DEPENDERS DEPENDS DIRECTORY DOWNLOAD_COMMAND DOWNLOAD_DIR DOWNLOAD_NAME DOWNLOAD_NO_PROGRESS EP_BASE EP_INDEPENDENT_STEP_TARGETS EP_PREFIX EP_STEP_TARGETS EP_UPDATE_DISCONNECTED EXCLUDE_FROM_ALL EXCLUDE_FROM_MAIN FORCE GIT_REMOTE_NAME GIT_REPOSITORY GIT_SUBMODULES GIT_TAG HG_REPOSITORY HG_TAG INDEPENDENT INDEPENDENT_STEP_TARGETS INSTALL_COMMAND INSTALL_DIR JOB_POOLS LIST_SEPARATOR LOG LOG_BUILD LOG_CONFIGURE LOG_DOWNLOAD LOG_INSTALL LOG_TEST LOG_UPDATE NO_DEPENDS PATCH_COMMAND PREFIX PROPERTY SOURCE_DIR STAMP_DIR STEP_TARGETS SVN_ SVN_PASSWORD SVN_REPOSITORY SVN_REVISION SVN_TRUST_CERT SVN_USERNAME TEST_AFTER_INSTALL TEST_BEFORE_INSTALL TEST_COMMAND TEST_EXCLUDE_FROM_MAIN TIMEOUT TLS_CAINFO TLS_VERIFY TMP_DIR UPDATE_COMMAND UPDATE_DISCONNECTED URL URL_HASH USES_TERMINAL USES_TERMINAL_BUILD USES_TERMINAL_CONFIGURE USES_TERMINAL_DOWNLOAD USES_TERMINAL_INSTALL USES_TERMINAL_TEST USES_TERMINAL_UPDATE WORKING_DIRECTORY _COMMAND _DIR
+ \ ALGO ALWAYS BINARY_DIR BUILD_ALWAYS BUILD_BYPRODUCTS BUILD_COMMAND BUILD_IN_SOURCE BYPRODUCTS CMAKE_ARGS CMAKE_CACHE_ARGS CMAKE_CACHE_DEFAULT_ARGS COMMAND COMMENT CONFIGURE_COMMAND CVS CVSROOT CVS_ CVS_MODULE CVS_REPOSITORY CVS_TAG DEPENDEES DEPENDERS DEPENDS DIRECTORY DOWNLOAD_COMMAND DOWNLOAD_DIR DOWNLOAD_NAME DOWNLOAD_NO_PROGRESS EP_BASE EP_INDEPENDENT_STEP_TARGETS EP_PREFIX EP_STEP_TARGETS EP_UPDATE_DISCONNECTED EXCLUDE_FROM_ALL EXCLUDE_FROM_MAIN FORCE GIT_REMOTE_NAME GIT_REPOSITORY GIT_SUBMODULES GIT_TAG HG_REPOSITORY HG_TAG INDEPENDENT INDEPENDENT_STEP_TARGETS INSTALL_COMMAND INSTALL_DIR JOB_POOLS LIST_SEPARATOR LOG LOG_BUILD LOG_CONFIGURE LOG_DOWNLOAD LOG_INSTALL LOG_TEST LOG_UPDATE NO_DEPENDS PATCH_COMMAND PREFIX PROPERTY SOURCE_DIR STAMP_DIR STEP_TARGETS SVN_ SVN_PASSWORD SVN_REPOSITORY SVN_REVISION SVN_TRUST_CERT SVN_USERNAME TEST_AFTER_INSTALL TEST_BEFORE_INSTALL TEST_COMMAND TEST_EXCLUDE_FROM_MAIN TIMEOUT TLS_CAINFO TLS_VERIFY TMP_DIR UPDATE_COMMAND UPDATE_DISCONNECTED URL URL_HASH HTTP_USERNAME HTTP_PASSWORD HTTP_HEADER USES_TERMINAL USES_TERMINAL_BUILD USES_TERMINAL_CONFIGURE USES_TERMINAL_DOWNLOAD USES_TERMINAL_INSTALL USES_TERMINAL_TEST USES_TERMINAL_UPDATE WORKING_DIRECTORY _COMMAND _DIR
\ contained
syn keyword cmakeKWadd_compile_options
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4ef2ca2..2ec8b57 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -9,7 +9,7 @@
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
-cmake_minimum_required(VERSION 2.8.4 FATAL_ERROR)
+cmake_minimum_required(VERSION 2.8.12.2 FATAL_ERROR)
if(POLICY CMP0025)
cmake_policy(SET CMP0025 NEW)
endif()
@@ -702,6 +702,18 @@ endif()
# setup some Testing support (a macro defined in this file)
CMAKE_SETUP_TESTING()
+# Check whether to build server mode or not:
+set(CMake_HAVE_SERVER_MODE 0)
+if(NOT CMake_TEST_EXTERNAL_CMAKE AND NOT CMAKE_BOOTSTRAP AND CMAKE_USE_LIBUV)
+ list(FIND CMAKE_CXX_COMPILE_FEATURES cxx_auto_type CMake_HAVE_CXX_AUTO_TYPE)
+ list(FIND CMAKE_CXX_COMPILE_FEATURES cxx_range_for CMake_HAVE_CXX_RANGE_FOR)
+ if(CMake_HAVE_CXX_AUTO_TYPE AND CMake_HAVE_CXX_RANGE_FOR)
+ if(CMake_HAVE_CXX_MAKE_UNIQUE)
+ set(CMake_HAVE_SERVER_MODE 1)
+ endif()
+ endif()
+endif()
+
if(NOT CMake_TEST_EXTERNAL_CMAKE)
if(NOT CMake_VERSION_IS_RELEASE)
if(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND
diff --git a/CompileFlags.cmake b/CompileFlags.cmake
index 3c053fa..535f68b 100644
--- a/CompileFlags.cmake
+++ b/CompileFlags.cmake
@@ -64,7 +64,7 @@ endif()
# Workaround for short jump tables on PA-RISC
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^parisc")
- if(CMAKE_COMPILER_IS_GNUC)
+ if(CMAKE_COMPILER_IS_GNUCC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mlong-calls")
endif()
if(CMAKE_COMPILER_IS_GNUCXX)
diff --git a/Help/command/export.rst b/Help/command/export.rst
index 4419dc1..53675a7 100644
--- a/Help/command/export.rst
+++ b/Help/command/export.rst
@@ -55,3 +55,18 @@ build tree. In some cases, for example for packaging and for system
wide installations, it is not desirable to write the user package
registry. If the :variable:`CMAKE_EXPORT_NO_PACKAGE_REGISTRY` variable
is enabled, the ``export(PACKAGE)`` command will do nothing.
+
+::
+
+ export(TARGETS [target1 [target2 [...]]] [ANDROID_MK <filename>])
+
+This signature exports cmake built targets to the android ndk build system
+by creating an Android.mk file that references the prebuilt targets. 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
+and defines required to use the libraries. The signature takes a list of
+targets and puts them in the Android.mk file specified by the ``<filename>``
+given. This signature can only be used if policy CMP0022 is NEW for all
+targets given. A error will be issued if that policy is set to OLD for one
+of the targets.
diff --git a/Help/command/file.rst b/Help/command/file.rst
index 256d16d..77e9f62 100644
--- a/Help/command/file.rst
+++ b/Help/command/file.rst
@@ -222,6 +222,12 @@ Options to both ``DOWNLOAD`` and ``UPLOAD`` are:
``TIMEOUT <seconds>``
Terminate the operation after a given total time has elapsed.
+``USERPWD <username>:<password>``
+ Set username and password for operation.
+
+``HTTPHEADER <HTTP-header>``
+ HTTP header for operation. Suboption can be repeated several times.
+
Additional options to ``DOWNLOAD`` are:
``EXPECTED_HASH ALGO=<value>``
diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst
index c44fe86..2cb1e5f 100644
--- a/Help/command/find_package.rst
+++ b/Help/command/find_package.rst
@@ -170,11 +170,21 @@ is acceptable the following variables are set:
``<package>_VERSION_COUNT``
number of version components, 0 to 4
-and the corresponding package configuration file is loaded. When
-multiple package configuration files are available whose version files
+and the corresponding package configuration file is loaded.
+When multiple package configuration files are available whose version files
claim compatibility with the version requested it is unspecified which
-one is chosen. No attempt is made to choose a highest or closest
-version number.
+one is chosen: unless the variable :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER`
+is set no attempt is made to choose a highest or closest version number.
+
+To control the order in which ``find_package`` checks for compatibiliy use
+the two variables :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER` and
+:variable:`CMAKE_FIND_PACKAGE_SORT_DIRECTION`.
+For instance in order to select the highest version one can set::
+
+ SET(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL)
+ SET(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC)
+
+before calling ``find_package``.
Config mode provides an elaborate interface and search procedure.
Much of the interface is provided for completeness and for use
diff --git a/Help/command/include.rst b/Help/command/include.rst
index c391561..eeca4c6 100644
--- a/Help/command/include.rst
+++ b/Help/command/include.rst
@@ -15,10 +15,10 @@ is present, then no error is raised if the file does not exist. If
which has been included or NOTFOUND if it failed.
If a module is specified instead of a file, the file with name
-<modulename>.cmake is searched first in :variable:`CMAKE_MODULE_PATH`,
+``<modulename>.cmake`` is searched first in :variable:`CMAKE_MODULE_PATH`,
then in the CMake module directory. There is one exception to this: if
-the file which calls ``include()`` is located itself in the CMake module
-directory, then first the CMake module directory is searched and
+the file which calls ``include()`` is located itself in the CMake builtin
+module directory, then first the CMake builtin module directory is searched and
:variable:`CMAKE_MODULE_PATH` afterwards. See also policy :policy:`CMP0017`.
See the :command:`cmake_policy` command documentation for discussion of the
diff --git a/Help/command/install.rst b/Help/command/install.rst
index aaf12cc..d57dd75 100644
--- a/Help/command/install.rst
+++ b/Help/command/install.rst
@@ -314,7 +314,8 @@ Installing Exports
::
install(EXPORT <export-name> DESTINATION <dir>
- [NAMESPACE <namespace>] [FILE <name>.cmake]
+ [NAMESPACE <namespace>] [[FILE <name>.cmake]|
+ [EXPORT_ANDROID_MK <name>.mk]]
[PERMISSIONS permissions...]
[CONFIGURATIONS [Debug|Release|...]]
[EXPORT_LINK_INTERFACE_LIBRARIES]
@@ -342,6 +343,13 @@ 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 additon to cmake language files, the ``EXPORT_ANDROID_MK`` option maybe
+used to specifiy an export to the android ndk build system. 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
+and defines required to use the libraries.
+
The ``EXPORT`` form is useful to help outside projects use targets built
and installed by the current project. For example, the code
@@ -349,9 +357,11 @@ and installed by the current project. For example, the code
install(TARGETS myexe EXPORT myproj DESTINATION bin)
install(EXPORT myproj NAMESPACE mp_ DESTINATION lib/myproj)
+ install(EXPORT_ANDROID_MK myexp DESTINATION share/ndk-modules)
will install the executable myexe to ``<prefix>/bin`` and code to import
-it in the file ``<prefix>/lib/myproj/myproj.cmake``. An outside project
+it in the file ``<prefix>/lib/myproj/myproj.cmake`` and
+``<prefix>/lib/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/separate_arguments.rst b/Help/command/separate_arguments.rst
index 0e3e5a5..1fd3cd1 100644
--- a/Help/command/separate_arguments.rst
+++ b/Help/command/separate_arguments.rst
@@ -13,19 +13,21 @@ entire command line must be given in one "<args>" argument.
The ``UNIX_COMMAND`` mode separates arguments by unquoted whitespace. It
recognizes both single-quote and double-quote pairs. A backslash
-escapes the next literal character (\" is "); there are no special
-escapes (\n is just n).
+escapes the next literal character (``\"`` is ``"``); there are no special
+escapes (``\n`` is just ``n``).
The ``WINDOWS_COMMAND`` mode parses a windows command-line using the same
syntax the runtime library uses to construct argv at startup. It
separates arguments by whitespace that is not double-quoted.
Backslashes are literal unless they precede double-quotes. See the
-MSDN article "Parsing C Command-Line Arguments" for details.
+MSDN article `Parsing C Command-Line Arguments`_ for details.
+
+.. _`Parsing C Command-Line Arguments`: https://msdn.microsoft.com/library/a1y7w461.aspx
::
- separate_arguments(VARIABLE)
+ separate_arguments(<var>)
-Convert the value of ``VARIABLE`` to a semi-colon separated list. All
+Convert the value of ``<var>`` to a semi-colon separated list. All
spaces are replaced with ';'. This helps with generating command
lines.
diff --git a/Help/command/string.rst b/Help/command/string.rst
index 19a095a..8028333 100644
--- a/Help/command/string.rst
+++ b/Help/command/string.rst
@@ -278,12 +278,14 @@ specifiers:
%I The hour on a 12-hour clock (01-12).
%j The day of the current year (001-366).
%m The month of the current year (01-12).
+ %b Abbreviated month name (e.g. Oct).
%M The minute of the current hour (00-59).
%s Seconds since midnight (UTC) 1-Jan-1970 (UNIX time).
%S The second of the current minute.
60 represents a leap second. (00-60)
%U The week number of the current year (00-53).
%w The day of the current week. 0 is Sunday. (0-6)
+ %a Abbreviated weekday name (e.g. Fri).
%y The last two digits of the current year (00-99)
%Y The current year.
diff --git a/Help/index.rst b/Help/index.rst
index 2d3f156..97cd107 100644
--- a/Help/index.rst
+++ b/Help/index.rst
@@ -32,6 +32,7 @@ Reference Manuals
/manual/cmake-generator-expressions.7
/manual/cmake-generators.7
/manual/cmake-language.7
+ /manual/cmake-server.7
/manual/cmake-modules.7
/manual/cmake-packages.7
/manual/cmake-policies.7
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 0f1bfad..2cb6a1a 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -54,6 +54,8 @@ Properties on Directories
:maxdepth: 1
/prop_dir/ADDITIONAL_MAKE_CLEAN_FILES
+ /prop_dir/BINARY_DIR
+ /prop_dir/BUILDSYSTEM_TARGETS
/prop_dir/CACHE_VARIABLES
/prop_dir/CLEAN_NO_CUSTOM
/prop_dir/CMAKE_CONFIGURE_DEPENDS
@@ -73,6 +75,8 @@ Properties on Directories
/prop_dir/RULE_LAUNCH_COMPILE
/prop_dir/RULE_LAUNCH_CUSTOM
/prop_dir/RULE_LAUNCH_LINK
+ /prop_dir/SOURCE_DIR
+ /prop_dir/SUBDIRECTORIES
/prop_dir/TEST_INCLUDE_FILE
/prop_dir/VARIABLES
/prop_dir/VS_GLOBAL_SECTION_POST_section
diff --git a/Help/manual/cmake-server.7.rst b/Help/manual/cmake-server.7.rst
new file mode 100644
index 0000000..75aa0ee
--- /dev/null
+++ b/Help/manual/cmake-server.7.rst
@@ -0,0 +1,237 @@
+.. cmake-manual-description: CMake Server
+
+cmake-server(7)
+***************
+
+.. only:: html
+
+ .. contents::
+
+Introduction
+============
+
+:manual:`cmake(1)` is capable of providing semantic information about
+CMake code it executes to generate a buildsystem. If executed with
+the ``-E server`` command line options, it starts in a long running mode
+and allows a client to request the available information via a JSON protocol.
+
+The protocol is designed to be useful to IDEs, refactoring tools, and
+other tools which have a need to understand the buildsystem in entirety.
+
+A single :manual:`cmake-buildsystem(7)` may describe buildsystem contents
+and build properties which differ based on
+:manual:`generation-time context <cmake-generator-expressions(7)>`
+including:
+
+* The Platform (eg, Windows, APPLE, Linux).
+* The build configuration (eg, Debug, Release, Coverage).
+* The Compiler (eg, MSVC, GCC, Clang) and compiler version.
+* The language of the source files compiled.
+* Available compile features (eg CXX variadic templates).
+* CMake policies.
+
+The protocol aims to provide information to tooling to satisfy several
+needs:
+
+#. Provide a complete and easily parsed source of all information relevant
+ to the tooling as it relates to the source code. There should be no need
+ for tooling to parse generated buildsystems to access include directories
+ or compile definitions for example.
+#. Semantic information about the CMake buildsystem itself.
+#. Provide a stable interface for reading the information in the CMake cache.
+#. Information for determining when cmake needs to be re-run as a result of
+ file changes.
+
+
+Operation
+=========
+
+Start :manual:`cmake(1)` in the server command mode, supplying the path to
+the build directory to process::
+
+ cmake -E server
+
+The server will start up and reply with an hello message on stdout::
+
+ [== CMake Server ==[
+ {"supportedProtocolVersions":[{"major":0,"minor":1}],"type":"hello"}
+ ]== CMake Server ==]
+
+Messages sent to and from the process are wrapped in magic strings::
+
+ [== CMake Server ==[
+ {
+ ... some JSON message ...
+ }
+ ]== CMake Server ==]
+
+The server is now ready to accept further requests via stdin.
+
+
+Debugging
+=========
+
+CMake server mode can be asked to provide statistics on execution times, etc.
+or to dump a copy of the response into a file. This is done passing a "debug"
+JSON object as a child of the request.
+
+The debug object supports the "showStats" key, which takes a boolean and makes
+the server mode return a "zzzDebug" object with stats as part of its response.
+"dumpToFile" takes a string value and will cause the cmake server to copy
+the response into the given filename.
+
+This is a response from the cmake server with "showStats" set to true::
+
+ [== CMake Server ==[
+ {
+ "cookie":"",
+ "errorMessage":"Waiting for type \"handshake\".",
+ "inReplyTo":"unknown",
+ "type":"error",
+ "zzzDebug": {
+ "dumpFile":"/tmp/error.txt",
+ "jsonSerialization":0.011016,
+ "size":111,
+ "totalTime":0.025995
+ }
+ }
+ ]== CMake Server ==]
+
+The server has made a copy of this response into the file /tmp/error.txt and
+took 0.011 seconds to turn the JSON response into a string, and it took 0.025
+seconds to process the request in total. The reply has a size of 111 bytes.
+
+
+Protocol API
+============
+
+
+General Message Layout
+----------------------
+
+All messages need to have a "type" value, which identifies the type of
+message that is passed back or forth. E.g. the initial message sent by the
+server is of type "hello". Messages without a type will generate an response
+of type "error".
+
+All requests sent to the server may contain a "cookie" value. This value
+will he handed back unchanged in all responses triggered by the request.
+
+All responses will contain a value "inReplyTo", which may be empty in
+case of parse errors, but will contain the type of the request message
+in all other cases.
+
+
+Type "reply"
+^^^^^^^^^^^^
+
+This type is used by the server to reply to requests.
+
+The message may -- depending on the type of the original request --
+contain values.
+
+Example::
+
+ [== CMake Server ==[
+ {"cookie":"zimtstern","inReplyTo":"handshake","type":"reply"}
+ ]== CMake Server ==]
+
+
+Type "error"
+^^^^^^^^^^^^
+
+This type is used to return an error condition to the client. It will
+contain an "errorMessage".
+
+Example::
+
+ [== CMake Server ==[
+ {"cookie":"","errorMessage":"Protocol version not supported.","inReplyTo":"handshake","type":"error"}
+ ]== CMake Server ==]
+
+
+Type "progress"
+^^^^^^^^^^^^^^^
+
+When the server is busy for a long time, it is polite to send back replies of
+type "progress" to the client. These will contain a "progressMessage" with a
+string describing the action currently taking place as well as
+"progressMinimum", "progressMaximum" and "progressCurrent" with integer values
+describing the range of progess.
+
+Messages of type "progress" will be followed by more "progress" messages or with
+a message of type "reply" or "error" that complete the request.
+
+"progress" messages may not be emitted after the "reply" or "error" message for
+the request that triggered the responses was delivered.
+
+
+Type "message"
+^^^^^^^^^^^^^^
+
+A message is triggered when the server processes a request and produces some
+form of output that should be displayed to the user. A Message has a "message"
+with the actual text to display as well as a "title" with a suggested dialog
+box title.
+
+Example::
+
+ [== CMake Server ==[
+ {"cookie":"","message":"Something happened.","title":"Title Text","inReplyTo":"handshake","type":"message"}
+ ]== CMake Server ==]
+
+
+Specific Message Types
+----------------------
+
+
+Type "hello"
+^^^^^^^^^^^^
+
+The initial message send by the cmake server on startup is of type "hello".
+This is the only message ever sent by the server that is not of type "reply",
+"progress" or "error".
+
+It will contain "supportedProtocolVersions" with an array of server protocol
+versions supported by the cmake server. These are JSON objects with "major" and
+"minor" keys containing non-negative integer values.
+
+Example::
+
+ [== CMake Server ==[
+ {"supportedProtocolVersions":[{"major":0,"minor":1}],"type":"hello"}
+ ]== CMake Server ==]
+
+
+Type "handshake"
+^^^^^^^^^^^^^^^^
+
+The first request that the client may send to the server is of type "handshake".
+
+This request needs to pass one of the "supportedProtocolVersions" of the "hello"
+type response received earlier back to the server in the "protocolVersion" field.
+
+Each protocol version may request additional attributes to be present.
+
+Protocol version 1.0 requires the following attributes to be set:
+
+ * "sourceDirectory" with a path to the sources
+ * "buildDirectory" with a path to the build directory
+ * "generator" with the generator name
+ * "extraGenerator" (optional!) with the extra generator to be used.
+
+Example::
+
+ [== CMake Server ==[
+ {"cookie":"zimtstern","type":"handshake","protocolVersion":{"major":0},
+ "sourceDirectory":"/home/code/cmake", "buildDirectory":"/tmp/testbuild",
+ "generator":"Ninja"}
+ ]== CMake Server ==]
+
+which will result in a response type "reply"::
+
+ [== CMake Server ==[
+ {"cookie":"zimtstern","inReplyTo":"handshake","type":"reply"}
+ ]== CMake Server ==]
+
+indicating that the server is ready for action.
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index b14f667..9e0efe9 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -38,6 +38,8 @@ Variables that Provide Information
/variable/CMAKE_EXTRA_GENERATOR
/variable/CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES
/variable/CMAKE_FIND_PACKAGE_NAME
+ /variable/CMAKE_FIND_PACKAGE_SORT_DIRECTION
+ /variable/CMAKE_FIND_PACKAGE_SORT_ORDER
/variable/CMAKE_GENERATOR
/variable/CMAKE_GENERATOR_PLATFORM
/variable/CMAKE_GENERATOR_TOOLSET
@@ -332,7 +334,9 @@ Variables for Languages
.. toctree::
:maxdepth: 1
- /variable/CMAKE_COMPILER_IS_GNULANG
+ /variable/CMAKE_COMPILER_IS_GNUCC
+ /variable/CMAKE_COMPILER_IS_GNUCXX
+ /variable/CMAKE_COMPILER_IS_GNUG77
/variable/CMAKE_C_COMPILE_FEATURES
/variable/CMAKE_C_EXTENSIONS
/variable/CMAKE_C_STANDARD
diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst
index 2ccc6be..063aea1 100644
--- a/Help/manual/cmake.1.rst
+++ b/Help/manual/cmake.1.rst
@@ -273,6 +273,9 @@ Available commands are:
``rename <oldname> <newname>``
Rename a file or directory (on one volume).
+``server``
+ Launch :manual:`cmake-server(7)` mode.
+
``sleep <number>...``
Sleep for given number of seconds.
diff --git a/Help/prop_dir/BINARY_DIR.rst b/Help/prop_dir/BINARY_DIR.rst
new file mode 100644
index 0000000..597c79a
--- /dev/null
+++ b/Help/prop_dir/BINARY_DIR.rst
@@ -0,0 +1,5 @@
+BINARY_DIR
+----------
+
+This read-only directory property reports absolute path to the binary
+directory corresponding to the source on which it is read.
diff --git a/Help/prop_dir/BUILDSYSTEM_TARGETS.rst b/Help/prop_dir/BUILDSYSTEM_TARGETS.rst
new file mode 100644
index 0000000..da907cb
--- /dev/null
+++ b/Help/prop_dir/BUILDSYSTEM_TARGETS.rst
@@ -0,0 +1,11 @@
+BUILDSYSTEM_TARGETS
+-------------------
+
+This read-only directory property contains a
+:ref:`;-list <CMake Language Lists>` of buildsystem targets added in the
+directory by calls to the :command:`add_library`, :command:`add_executable`,
+and :command:`add_custom_target` commands. The list does not include any
+:ref:`Imported Targets` or :ref:`Alias Targets`, but does include
+:ref:`Interface Libraries`. Each entry in the list is the logical name
+of a target, suitable to pass to the :command:`get_property` command
+``TARGET`` option.
diff --git a/Help/prop_dir/SOURCE_DIR.rst b/Help/prop_dir/SOURCE_DIR.rst
new file mode 100644
index 0000000..ac98c3b
--- /dev/null
+++ b/Help/prop_dir/SOURCE_DIR.rst
@@ -0,0 +1,5 @@
+SOURCE_DIR
+----------
+
+This read-only directory property reports absolute path to the source
+directory on which it is read.
diff --git a/Help/prop_dir/SUBDIRECTORIES.rst b/Help/prop_dir/SUBDIRECTORIES.rst
new file mode 100644
index 0000000..2c2ea77
--- /dev/null
+++ b/Help/prop_dir/SUBDIRECTORIES.rst
@@ -0,0 +1,15 @@
+SUBDIRECTORIES
+--------------
+
+This read-only directory property contains a
+:ref:`;-list <CMake Language Lists>` of subdirectories processed so far by
+the :command:`add_subdirectory` or :command:`subdirs` commands. Each entry is
+the absolute path to the source directory (containing the ``CMakeLists.txt``
+file). This is suitable to pass to the :command:`get_property` command
+``DIRECTORY`` option.
+
+.. note::
+
+ The :command:`subdirs` command does not process its arguments until
+ after the calling directory is fully processed. Therefore looking
+ up this property in the current directory will not see them.
diff --git a/Help/release/dev/ExternalProject-HTTP_HEADER.rst b/Help/release/dev/ExternalProject-HTTP_HEADER.rst
new file mode 100644
index 0000000..927d1b2
--- /dev/null
+++ b/Help/release/dev/ExternalProject-HTTP_HEADER.rst
@@ -0,0 +1,5 @@
+ExternalProject-HTTP_HEADER
+---------------------------
+
+* The :module:`ExternalProject` module gained a ``HTTP_HEADER``
+ option to add http download headers.
diff --git a/Help/release/dev/ExternalProject-http-credentials.rst b/Help/release/dev/ExternalProject-http-credentials.rst
new file mode 100644
index 0000000..e3a362a
--- /dev/null
+++ b/Help/release/dev/ExternalProject-http-credentials.rst
@@ -0,0 +1,5 @@
+ExternalProject-http-credentials
+--------------------------------
+
+* The :module:`ExternalProject` module gained ``HTTP_USERNAME`` and
+ ``HTTP_PASSWORD`` options to set http download credentials.
diff --git a/Help/release/dev/add_androidmk_generator.rst b/Help/release/dev/add_androidmk_generator.rst
new file mode 100644
index 0000000..dd7867c
--- /dev/null
+++ b/Help/release/dev/add_androidmk_generator.rst
@@ -0,0 +1,10 @@
+add_androidmk_generator
+-----------------------
+
+* The :command:`install` command gained an ``EXPORT_ANDROID_MK``
+ subcommand to install ``Android.mk`` files referencing installed
+ libraries as prebuilts for the Android NDK build system.
+
+* The :command:`export` command gained an ``ANDROID_MK`` option
+ to generate ``Android.mk`` files referencing CMake-built
+ libraries as prebuilts for the Android NDK build system.
diff --git a/Help/release/dev/cmake-gui-open-project.rst b/Help/release/dev/cmake-gui-open-project.rst
new file mode 100644
index 0000000..32f0f0f
--- /dev/null
+++ b/Help/release/dev/cmake-gui-open-project.rst
@@ -0,0 +1,5 @@
+cmake-gui-open-project
+----------------------
+
+* :manual:`cmake-gui(1)` gained a button to open the generated project file
+ for :ref:`Visual Studio Generators` and the :generator:`Xcode` generator.
diff --git a/Help/release/dev/cmake-server-basic.rst b/Help/release/dev/cmake-server-basic.rst
new file mode 100644
index 0000000..0b97660
--- /dev/null
+++ b/Help/release/dev/cmake-server-basic.rst
@@ -0,0 +1,6 @@
+cmake-server-basic
+------------------
+
+* A new :manual:`cmake-server(7)` mode was added to provide semantic
+ information about a CMake-generated buildsystem to clients through
+ a JSON protocol.
diff --git a/Help/release/dev/cpack-rpm-srpm-package.rst b/Help/release/dev/cpack-rpm-srpm-package.rst
new file mode 100644
index 0000000..803b9fc
--- /dev/null
+++ b/Help/release/dev/cpack-rpm-srpm-package.rst
@@ -0,0 +1,7 @@
+cpack-rpm-srpm-package
+----------------------
+
+* The :module:`CPackRPM` module learned to generate source rpm
+ (SRPM) packages on demand. See :variable:`CPACK_RPM_PACKAGE_SOURCES`,
+ :variable:`CPACK_RPM_SOURCE_PKG_BUILD_PARAMS` and
+ :variable:`CPACK_RPM_SOURCE_PKG_PACKAGING_INSTALL_PREFIX`.
diff --git a/Help/release/dev/cpack.hash_computing.rst b/Help/release/dev/cpack.hash_computing.rst
new file mode 100644
index 0000000..9780bb2
--- /dev/null
+++ b/Help/release/dev/cpack.hash_computing.rst
@@ -0,0 +1,5 @@
+cpack.hash_computing
+--------------------
+
+* CPack gained a new :variable:`CPACK_PACKAGE_CHECKSUM` variable to
+ enable generation of a checksum file for each package file.
diff --git a/Help/release/dev/directory-list-targets-and-subdirs.rst b/Help/release/dev/directory-list-targets-and-subdirs.rst
new file mode 100644
index 0000000..85f2c82
--- /dev/null
+++ b/Help/release/dev/directory-list-targets-and-subdirs.rst
@@ -0,0 +1,16 @@
+directory-list-targets-and-subdirs
+----------------------------------
+
+* A :prop_dir:`SOURCE_DIR` directory property was added to get the
+ absolute path to the source directory associated with a directory.
+
+* A :prop_dir:`BINARY_DIR` directory property was added to get the
+ absolute path to the binary directory corresponding to the source
+ directory on which the property is read.
+
+* A :prop_dir:`BUILDSYSTEM_TARGETS` directory property was added to
+ get the list of logical buildsystem target names added by the
+ project in a directory.
+
+* A :prop_dir:`SUBDIRECTORIES` directory property was added to
+ get the list of subdirectories added by a project in a directory.
diff --git a/Help/release/dev/file-curl-httpheader.rst b/Help/release/dev/file-curl-httpheader.rst
new file mode 100644
index 0000000..2147d40
--- /dev/null
+++ b/Help/release/dev/file-curl-httpheader.rst
@@ -0,0 +1,5 @@
+file-curl-httpheader
+--------------------
+
+* The :command:`file(DOWNLOAD)` and :command:`file(UPLOAD)` commands
+ gained a ``HTTPHEADER <HTTP-header>`` option.
diff --git a/Help/release/dev/file-curl-userpw.rst b/Help/release/dev/file-curl-userpw.rst
new file mode 100644
index 0000000..4ae1fee
--- /dev/null
+++ b/Help/release/dev/file-curl-userpw.rst
@@ -0,0 +1,5 @@
+file-curl-userpw
+----------------
+
+* The :command:`file(DOWNLOAD)` and :command:`file(UPLOAD)` commands
+ gained a ``USERPWD <username>:<password>`` option.
diff --git a/Help/release/dev/find_package-dir-sort.rst b/Help/release/dev/find_package-dir-sort.rst
new file mode 100644
index 0000000..67b93eb
--- /dev/null
+++ b/Help/release/dev/find_package-dir-sort.rst
@@ -0,0 +1,13 @@
+find_package-dir-sort
+---------------------
+
+* The :command:`find_package` command gained the possibility of
+ sorting compatible libraries by ``NAME`` or by ``NATURAL`` sorting by
+ setting the two new variables :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER`
+ and :variable:`CMAKE_FIND_PACKAGE_SORT_DIRECTION`.
+
+* Variable :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER` was added to control
+ the sorting mode of the :command:`find_package` command.
+
+* Variable :variable:`CMAKE_FIND_PACKAGE_SORT_DIRECTION` was added to control
+ the sorting direction the :command:`find_package` command.
diff --git a/Help/release/dev/fortran-submodules.rst b/Help/release/dev/fortran-submodules.rst
new file mode 100644
index 0000000..e4e9657
--- /dev/null
+++ b/Help/release/dev/fortran-submodules.rst
@@ -0,0 +1,7 @@
+fortran-submodules
+------------------
+
+* The Fortran dependency scanner learned to support the syntax of
+ `Fortran Submodules`_.
+
+.. _`Fortran Submodules`: http://fortranwiki.org/fortran/show/Submodules
diff --git a/Help/release/dev/ifw-package-resources.rst b/Help/release/dev/ifw-package-resources.rst
new file mode 100644
index 0000000..28ea5c4
--- /dev/null
+++ b/Help/release/dev/ifw-package-resources.rst
@@ -0,0 +1,6 @@
+ifw-package-resources
+---------------------
+
+* The :module:`CPackIFW` module gained a new
+ :command:`cpack_ifw_add_package_resources` command to include additional
+ resources in the installer binary.
diff --git a/Help/release/dev/ifw-user-interfaces.rst b/Help/release/dev/ifw-user-interfaces.rst
new file mode 100644
index 0000000..26e241a
--- /dev/null
+++ b/Help/release/dev/ifw-user-interfaces.rst
@@ -0,0 +1,7 @@
+ifw-user-interfaces
+-------------------
+
+* The :module:`CPackIFW` module :command:`cpack_ifw_configure_component` and
+ :command:`cpack_ifw_configure_component_group` commands gained a new
+ ``USER_INTERFACES`` option to add a list of additonal pages to the IFW
+ installer.
diff --git a/Help/release/dev/timestamp-names.rst b/Help/release/dev/timestamp-names.rst
new file mode 100644
index 0000000..ea54b5c
--- /dev/null
+++ b/Help/release/dev/timestamp-names.rst
@@ -0,0 +1,6 @@
+timestamp-names
+---------------
+
+* The :command:`string(TIMESTAMP)` and :command:`file(TIMESTAMP)`
+ commands gained support for the ``%a`` and ``%b`` placeholders.
+ These are the abbreviated weekday and month names.
diff --git a/Help/variable/CMAKE_COMPILER_IS_GNUCC.rst b/Help/variable/CMAKE_COMPILER_IS_GNUCC.rst
new file mode 100644
index 0000000..a40667e
--- /dev/null
+++ b/Help/variable/CMAKE_COMPILER_IS_GNUCC.rst
@@ -0,0 +1,5 @@
+CMAKE_COMPILER_IS_GNUCC
+-----------------------
+
+True if the ``C`` compiler is GNU.
+Use :variable:`CMAKE_C_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` instead.
diff --git a/Help/variable/CMAKE_COMPILER_IS_GNUCXX.rst b/Help/variable/CMAKE_COMPILER_IS_GNUCXX.rst
new file mode 100644
index 0000000..f1f5cf7
--- /dev/null
+++ b/Help/variable/CMAKE_COMPILER_IS_GNUCXX.rst
@@ -0,0 +1,5 @@
+CMAKE_COMPILER_IS_GNUCXX
+------------------------
+
+True if the C++ (``CXX``) compiler is GNU.
+Use :variable:`CMAKE_CXX_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` instead.
diff --git a/Help/variable/CMAKE_COMPILER_IS_GNUG77.rst b/Help/variable/CMAKE_COMPILER_IS_GNUG77.rst
new file mode 100644
index 0000000..3d6dab4
--- /dev/null
+++ b/Help/variable/CMAKE_COMPILER_IS_GNUG77.rst
@@ -0,0 +1,5 @@
+CMAKE_COMPILER_IS_GNUG77
+------------------------
+
+True if the ``Fortran`` compiler is GNU.
+Use :variable:`CMAKE_Fortran_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` instead.
diff --git a/Help/variable/CMAKE_COMPILER_IS_GNULANG.rst b/Help/variable/CMAKE_COMPILER_IS_GNULANG.rst
deleted file mode 100644
index 4b652c0..0000000
--- a/Help/variable/CMAKE_COMPILER_IS_GNULANG.rst
+++ /dev/null
@@ -1,15 +0,0 @@
-CMAKE_COMPILER_IS_GNU<LANG>
----------------------------
-
-True if the compiler is GNU.
-
-If the selected ``<LANG>`` compiler is the GNU compiler then this is ``TRUE``,
-if not it is ``FALSE``. Unlike the other per-language variables, this
-uses the GNU syntax for identifying languages instead of the CMake
-syntax. Recognized values of the ``<LANG>`` suffix are:
-
-::
-
- CC = C compiler
- CXX = C++ compiler
- G77 = Fortran compiler
diff --git a/Help/variable/CMAKE_FIND_PACKAGE_SORT_DIRECTION.rst b/Help/variable/CMAKE_FIND_PACKAGE_SORT_DIRECTION.rst
new file mode 100644
index 0000000..99e4ec1
--- /dev/null
+++ b/Help/variable/CMAKE_FIND_PACKAGE_SORT_DIRECTION.rst
@@ -0,0 +1,16 @@
+CMAKE_FIND_PACKAGE_SORT_DIRECTION
+---------------------------------
+
+The sorting direction used by :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER`.
+It can assume one of the following values:
+
+``DEC``
+ Default. Ordering is done in descending mode.
+ The highest folder found will be tested first.
+
+``ASC``
+ Ordering is done in ascending mode.
+ The lowest folder found will be tested first.
+
+If :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER` is not set or is set to ``NONE``
+this variable has no effect.
diff --git a/Help/variable/CMAKE_FIND_PACKAGE_SORT_ORDER.rst b/Help/variable/CMAKE_FIND_PACKAGE_SORT_ORDER.rst
new file mode 100644
index 0000000..ba5f3a8
--- /dev/null
+++ b/Help/variable/CMAKE_FIND_PACKAGE_SORT_ORDER.rst
@@ -0,0 +1,36 @@
+CMAKE_FIND_PACKAGE_SORT_ORDER
+-----------------------------
+
+The default order for sorting packages found using :command:`find_package`.
+It can assume one of the following values:
+
+``NONE``
+ Default. No attempt is done to sort packages.
+ The first valid package found will be selected.
+
+``NAME``
+ Sort packages lexicographically before selecting one.
+
+``NATURAL``
+ Sort packages using natural order (see ``strverscmp(3)`` manual),
+ i.e. such that contiguous digits are compared as whole numbers.
+
+Natural sorting can be employed to return the highest version when multiple
+versions of the same library are found by :command:`find_package`. For
+example suppose that the following libraries have been found:
+
+* libX-1.1.0
+* libX-1.2.9
+* libX-1.2.10
+
+By setting ``NATURAL`` order we can select the one with the highest
+version number ``libX-1.2.10``.
+
+.. code-block:: cmake
+
+ set(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL)
+ find_package(libX CONFIG)
+
+The sort direction can be controlled using the
+:variable:`CMAKE_FIND_PACKAGE_SORT_DIRECTION` variable
+(by default decrescent, e.g. lib-B will be tested before lib-A).
diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake
index 675b38b..99f22ec 100644
--- a/Modules/CPack.cmake
+++ b/Modules/CPack.cmake
@@ -116,6 +116,15 @@
# A branding image that will be displayed inside the installer (used by GUI
# installers).
#
+# .. variable:: CPACK_PACKAGE_CHECKSUM
+#
+# An algorithm that will be used to generate additional file with checksum
+# of the package. Output file name will be::
+#
+# ${CPACK_PACKAGE_FILE_NAME}.${CPACK_PACKAGE_CHECKSUM}
+#
+# Current supported alogorithms: MD5|SHA1|SHA224|SHA256|SHA384|SHA512.
+#
# .. variable:: CPACK_PROJECT_CONFIG_FILE
#
# CPack-time project CPack configuration file. This file included at cpack
@@ -502,6 +511,7 @@ if(NOT CPACK_SOURCE_GENERATOR)
if(CYGWIN)
option(CPACK_SOURCE_CYGWIN "Enable to build Cygwin source packages" ON)
else()
+ option(CPACK_SOURCE_RPM "Enable to build RPM source packages" OFF)
option(CPACK_SOURCE_TBZ2 "Enable to build TBZ2 source packages" ON)
option(CPACK_SOURCE_TGZ "Enable to build TGZ source packages" ON)
option(CPACK_SOURCE_TXZ "Enable to build TXZ source packages" ON)
@@ -515,6 +525,7 @@ if(NOT CPACK_SOURCE_GENERATOR)
cpack_optional_append(CPACK_SOURCE_GENERATOR CPACK_SOURCE_7Z 7Z)
cpack_optional_append(CPACK_SOURCE_GENERATOR CPACK_SOURCE_CYGWIN CygwinSource)
+ cpack_optional_append(CPACK_SOURCE_GENERATOR CPACK_SOURCE_RPM RPM)
cpack_optional_append(CPACK_SOURCE_GENERATOR CPACK_SOURCE_TBZ2 TBZ2)
cpack_optional_append(CPACK_SOURCE_GENERATOR CPACK_SOURCE_TGZ TGZ)
cpack_optional_append(CPACK_SOURCE_GENERATOR CPACK_SOURCE_TXZ TXZ)
@@ -544,6 +555,7 @@ mark_as_advanced(
CPACK_BINARY_ZIP
CPACK_SOURCE_7Z
CPACK_SOURCE_CYGWIN
+ CPACK_SOURCE_RPM
CPACK_SOURCE_TBZ2
CPACK_SOURCE_TGZ
CPACK_SOURCE_TXZ
@@ -651,6 +663,8 @@ set(CPACK_PACKAGE_FILE_NAME "${CPACK_SOURCE_PACKAGE_FILE_NAME}")
set(CPACK_IGNORE_FILES "${CPACK_SOURCE_IGNORE_FILES}")
set(CPACK_STRIP_FILES "${CPACK_SOURCE_STRIP_FILES}")
+set(CPACK_RPM_PACKAGE_SOURCES "ON")
+
cpack_encode_variables()
configure_file("${cpack_source_input_file}"
"${CPACK_SOURCE_OUTPUT_CONFIG_FILE}" @ONLY)
diff --git a/Modules/CPackIFW.cmake b/Modules/CPackIFW.cmake
index ebc5c90..bb1285d 100644
--- a/Modules/CPackIFW.cmake
+++ b/Modules/CPackIFW.cmake
@@ -131,6 +131,14 @@
#
# Filename for a custom installer control script.
#
+# .. variable:: CPACK_IFW_PACKAGE_RESOURCES
+#
+# List of additional resources ('.qrc' files) to include in the installer
+# binary.
+#
+# You can use :command:`cpack_ifw_add_package_resources` command to resolve
+# relative paths.
+#
# .. variable:: CPACK_IFW_REPOSITORIES_ALL
#
# The list of remote repositories.
@@ -181,136 +189,174 @@
#
# The module defines the following commands:
#
-# --------------------------------------------------------------------------
-#
# .. command:: cpack_ifw_configure_component
#
-# Sets the arguments specific to the CPack IFW generator.
+# Sets the arguments specific to the CPack IFW generator.
+#
+# ::
#
-# ::
+# cpack_ifw_configure_component(<compname> [COMMON] [ESSENTIAL]
+# [NAME <name>]
+# [VERSION <version>]
+# [SCRIPT <script>]
+# [PRIORITY <priority>]
+# [DEPENDS <com_id> ...]
+# [LICENSES <display_name> <file_path> ...]
+# [USER_INTERFACES <file_path> <file_path> ...])
#
-# cpack_ifw_configure_component(<compname> [COMMON] [ESSENTIAL]
-# [NAME <name>]
-# [VERSION <version>]
-# [SCRIPT <script>]
-# [PRIORITY <priority>]
-# [DEPENDS <com_id> ...]
-# [LICENSES <display_name> <file_path> ...])
+# This command should be called after :command:`cpack_add_component` command.
#
-# This command should be called after :command:`cpack_add_component` command.
+# ``COMMON``
+# if set, then the component will be packaged and installed as part
+# of a group to which it belongs.
#
-# ``COMMON`` if set, then the component will be packaged and installed as part
-# of a group to which it belongs.
+# ``ESSENTIAL``
+# if set, then the package manager stays disabled until that
+# component is updated.
#
-# ``ESSENTIAL`` if set, then the package manager stays disabled until that
-# component is updated.
+# ``NAME``
+# is used to create domain-like identification for this component.
+# By default used origin component name.
#
-# ``NAME`` is used to create domain-like identification for this component.
-# By default used origin component name.
+# ``VERSION``
+# is version of component.
+# By default used :variable:`CPACK_PACKAGE_VERSION`.
#
-# ``VERSION`` is version of component.
-# By default used :variable:`CPACK_PACKAGE_VERSION`.
+# ``SCRIPT``
+# is a relative or absolute path to operations script
+# for this component.
#
-# ``SCRIPT`` is a relative or absolute path to operations script
-# for this component.
+# ``PRIORITY``
+# is priority of the component in the tree.
#
-# ``PRIORITY`` is priority of the component in the tree.
+# ``DEPENDS``
+# list of dependency component identifiers in QtIFW_ style.
#
-# ``DEPENDS`` list of dependency component identifiers in QtIFW_ style.
+# ``LICENSES``
+# pair of <display_name> and <file_path> of license text for this
+# component. You can specify more then one license.
#
-# ``LICENSES`` pair of <display_name> and <file_path> of license text for this
-# component. You can specify more then one license.
+# ``USER_INTERFACES``
+# a list of <file_path> representing pages to load
#
-# --------------------------------------------------------------------------
#
# .. command:: cpack_ifw_configure_component_group
#
-# Sets the arguments specific to the CPack IFW generator.
+# Sets the arguments specific to the CPack IFW generator.
#
-# ::
+# ::
#
-# cpack_ifw_configure_component_group(<groupname>
-# [NAME <name>]
-# [VERSION <version>]
-# [SCRIPT <script>]
-# [PRIORITY <priority>]
-# [LICENSES <display_name> <file_path> ...])
+# cpack_ifw_configure_component_group(<groupname>
+# [NAME <name>]
+# [VERSION <version>]
+# [SCRIPT <script>]
+# [PRIORITY <priority>]
+# [LICENSES <display_name> <file_path> ...]
+# [USER_INTERFACES <file_path> <file_path> ...])
#
-# This command should be called after :command:`cpack_add_component_group`
-# command.
+# This command should be called after :command:`cpack_add_component_group`
+# command.
#
-# ``NAME`` is used to create domain-like identification for this component
-# group.
-# By default used origin component group name.
+# ``NAME``
+# is used to create domain-like identification for this component group.
+# By default used origin component group name.
#
-# ``VERSION`` is version of component group.
-# By default used :variable:`CPACK_PACKAGE_VERSION`.
+# ``VERSION``
+# is version of component group.
+# By default used :variable:`CPACK_PACKAGE_VERSION`.
#
-# ``SCRIPT`` is a relative or absolute path to operations script
-# for this component group.
+# ``SCRIPT``
+# is a relative or absolute path to operations script
+# for this component group.
#
-# ``PRIORITY`` is priority of the component group in the tree.
+# ``PRIORITY``
+# is priority of the component group in the tree.
#
-# ``LICENSES`` pair of <display_name> and <file_path> of license text for this
-# component group. You can specify more then one license.
+# ``LICENSES``
+# pair of <display_name> and <file_path> of license text for this
+# component group. You can specify more then one license.
#
-# --------------------------------------------------------------------------
+# ``USER_INTERFACES``
+# a list of <file_path> representing pages to load
#
-# .. command:: cpack_ifw_add_repository
#
-# Add QtIFW_ specific remote repository to binary installer.
+# .. command:: cpack_ifw_add_repository
#
-# ::
+# Add QtIFW_ specific remote repository to binary installer.
#
-# cpack_ifw_add_repository(<reponame> [DISABLED]
-# URL <url>
-# [USERNAME <username>]
-# [PASSWORD <password>]
-# [DISPLAY_NAME <display_name>])
+# ::
#
-# This command will also add the <reponame> repository
-# to a variable :variable:`CPACK_IFW_REPOSITORIES_ALL`.
+# cpack_ifw_add_repository(<reponame> [DISABLED]
+# URL <url>
+# [USERNAME <username>]
+# [PASSWORD <password>]
+# [DISPLAY_NAME <display_name>])
#
-# ``DISABLED`` if set, then the repository will be disabled by default.
+# This command will also add the <reponame> repository
+# to a variable :variable:`CPACK_IFW_REPOSITORIES_ALL`.
#
-# ``URL`` is points to a list of available components.
+# ``DISABLED``
+# if set, then the repository will be disabled by default.
#
-# ``USERNAME`` is used as user on a protected repository.
+# ``URL``
+# is points to a list of available components.
#
-# ``PASSWORD`` is password to use on a protected repository.
+# ``USERNAME``
+# is used as user on a protected repository.
#
-# ``DISPLAY_NAME`` is string to display instead of the URL.
+# ``PASSWORD``
+# is password to use on a protected repository.
#
+# ``DISPLAY_NAME``
+# is string to display instead of the URL.
#
-# --------------------------------------------------------------------------
#
# .. command:: cpack_ifw_update_repository
#
-# Update QtIFW_ specific repository from remote repository.
+# Update QtIFW_ specific repository from remote repository.
+#
+# ::
+#
+# cpack_ifw_update_repository(<reponame>
+# [[ADD|REMOVE] URL <url>]|
+# [REPLACE OLD_URL <old_url> NEW_URL <new_url>]]
+# [USERNAME <username>]
+# [PASSWORD <password>]
+# [DISPLAY_NAME <display_name>])
+#
+# This command will also add the <reponame> repository
+# to a variable :variable:`CPACK_IFW_REPOSITORIES_ALL`.
+#
+# ``URL``
+# is points to a list of available components.
+#
+# ``OLD_URL``
+# is points to a list that will replaced.
#
-# ::
+# ``NEW_URL``
+# is points to a list that will replace to.
#
-# cpack_ifw_update_repository(<reponame>
-# [[ADD|REMOVE] URL <url>]|
-# [REPLACE OLD_URL <old_url> NEW_URL <new_url>]]
-# [USERNAME <username>]
-# [PASSWORD <password>]
-# [DISPLAY_NAME <display_name>])
+# ``USERNAME``
+# is used as user on a protected repository.
#
-# This command will also add the <reponame> repository
-# to a variable :variable:`CPACK_IFW_REPOSITORIES_ALL`.
+# ``PASSWORD``
+# is password to use on a protected repository.
#
-# ``URL`` is points to a list of available components.
+# ``DISPLAY_NAME``
+# is string to display instead of the URL.
#
-# ``OLD_URL`` is points to a list that will replaced.
#
-# ``NEW_URL`` is points to a list that will replace to.
+# .. command:: cpack_ifw_add_package_resources
#
-# ``USERNAME`` is used as user on a protected repository.
+# Add additional resources in the installer binary.
#
-# ``PASSWORD`` is password to use on a protected repository.
+# ::
+#
+# cpack_ifw_add_package_resources(<file_path> <file_path> ...)
+#
+# This command will also add the specified files
+# to a variable :variable:`CPACK_IFW_PACKAGE_RESOURCES`.
#
-# ``DISPLAY_NAME`` is string to display instead of the URL.
#
# Example usage
# ^^^^^^^^^^^^^
@@ -362,16 +408,16 @@
#
# Qt Installer Framework Manual:
#
-# Index page
+# * Index page:
# http://doc.qt.io/qtinstallerframework/index.html
#
-# Component Scripting
+# * Component Scripting:
# http://doc.qt.io/qtinstallerframework/scripting.html
#
-# Predefined Variables
+# * Predefined Variables:
# http://doc.qt.io/qtinstallerframework/scripting.html#predefined-variables
#
-# Promoting Updates
+# * Promoting Updates:
# http://doc.qt.io/qtinstallerframework/ifw-updates.html
#
# Download Qt Installer Framework for you platform from Qt site:
@@ -543,6 +589,22 @@ macro(_cpack_ifw_resolve_lisenses _variable)
endif()
endmacro()
+# Resolve full path to a list of provided files
+macro(_cpack_ifw_resolve_file_list _variable)
+ if(${_variable})
+ set(_ifw_list_fix)
+ foreach(_ifw_file_arg ${${_variable}})
+ get_filename_component(_ifw_file_arg "${_ifw_file_arg}" ABSOLUTE)
+ if(EXISTS ${_ifw_file_arg})
+ list(APPEND _ifw_list_fix "${_ifw_file_arg}")
+ else()
+ message(WARNING "CPack IFW: page file \"${_ifw_file_arg}\" does not exist. Skipping")
+ endif()
+ endforeach(_ifw_file_arg)
+ set(${_variable} "${_ifw_list_fix}")
+ endif()
+endmacro()
+
# Macro for configure component
macro(cpack_ifw_configure_component compname)
@@ -550,11 +612,12 @@ macro(cpack_ifw_configure_component compname)
set(_IFW_OPT COMMON ESSENTIAL)
set(_IFW_ARGS NAME VERSION SCRIPT PRIORITY)
- set(_IFW_MULTI_ARGS DEPENDS LICENSES)
+ set(_IFW_MULTI_ARGS DEPENDS LICENSES USER_INTERFACES)
cmake_parse_arguments(CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME} "${_IFW_OPT}" "${_IFW_ARGS}" "${_IFW_MULTI_ARGS}" ${ARGN})
_cpack_ifw_resolve_script(CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_SCRIPT)
_cpack_ifw_resolve_lisenses(CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_LICENSES)
+ _cpack_ifw_resolve_file_list(CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_USER_INTERFACES)
set(_CPACK_IFWCOMP_STR "\n# Configuration for IFW component \"${compname}\"\n")
@@ -589,11 +652,12 @@ macro(cpack_ifw_configure_component_group grpname)
set(_IFW_OPT)
set(_IFW_ARGS NAME VERSION SCRIPT PRIORITY)
- set(_IFW_MULTI_ARGS LICENSES)
+ set(_IFW_MULTI_ARGS LICENSES USER_INTERFACES)
cmake_parse_arguments(CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME} "${_IFW_OPT}" "${_IFW_ARGS}" "${_IFW_MULTI_ARGS}" ${ARGN})
_cpack_ifw_resolve_script(CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME}_SCRIPT)
_cpack_ifw_resolve_lisenses(CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME}_LICENSES)
+ _cpack_ifw_resolve_file_list(CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME}_USER_INTERFACES)
set(_CPACK_IFWGRP_STR "\n# Configuration for IFW component group \"${grpname}\"\n")
@@ -698,6 +762,17 @@ macro(cpack_ifw_update_repository reponame)
endmacro()
+# Macro for adding resources
+macro(cpack_ifw_add_package_resources)
+ set(_CPACK_IFW_PACKAGE_RESOURCES ${ARGV})
+ _cpack_ifw_resolve_file_list(_CPACK_IFW_PACKAGE_RESOURCES)
+ list(APPEND CPACK_IFW_PACKAGE_RESOURCES ${_CPACK_IFW_PACKAGE_RESOURCES})
+ set(_CPACK_IFWQRC_STR "list(APPEND CPACK_IFW_PACKAGE_RESOURCES \"${_CPACK_IFW_PACKAGE_RESOURCES}\")\n")
+ if(CPack_CMake_INCLUDED)
+ file(APPEND "${CPACK_OUTPUT_CONFIG_FILE}" "${_CPACK_IFWQRC_STR}")
+ endif()
+endmacro()
+
# Resolve package control script
_cpack_ifw_resolve_script(CPACK_IFW_PACKAGE_CONTROL_SCRIPT)
diff --git a/Modules/CPackRPM.cmake b/Modules/CPackRPM.cmake
index 36caac6..d78f7fa 100644
--- a/Modules/CPackRPM.cmake
+++ b/Modules/CPackRPM.cmake
@@ -706,6 +706,77 @@
# symbolic link(s) is also on a relocatable path, relocating it during
# package installation may cause initial symbolic link to point to an
# invalid location.
+#
+# Packaging of sources (SRPM)
+# ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#
+# SRPM packaging is enabled by setting :variable:`CPACK_RPM_PACKAGE_SOURCES`
+# variable while usually using :variable:`CPACK_INSTALLED_DIRECTORIES` variable
+# to provide directory containing CMakeLists.txt and source files.
+#
+# For CMake projects SRPM package would be product by executing:
+#
+# ``cpack -G RPM --config ./CPackSourceConfig.cmake``
+#
+# .. note::
+#
+# Produced SRPM package is expected to be built with :manual:`cmake(1)` executable
+# and packaged with :manual:`cpack(1)` executable so CMakeLists.txt has to be
+# located in root source directory and must be able to generate binary rpm
+# packages by executing ``cpack -G`` command. The two executables as well as
+# rpmbuild must also be present when generating binary rpm packages from the
+# produced SRPM package.
+#
+# Once the SRPM package is generated it can be used to generate binary packages
+# by creating a directory structure for rpm generation and executing rpmbuild
+# tool:
+#
+# ``mkdir -p build_dir/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}``
+# ``rpmbuild --define "_topdir <path_to_build_dir>" --rebuild <SRPM_file_name>``
+#
+# Generated packages will be located in build_dir/RPMS directory or its sub
+# directories.
+#
+# .. note::
+#
+# SRPM package internally uses CPack/RPM generator to generate binary packages
+# so CMakeScripts.txt can decide during the SRPM to binary rpm generation step
+# what content the package(s) should have as well as how they should be packaged
+# (monolithic or components). CMake can decide this for e.g. by reading environment
+# variables set by the package manager before starting the process of generating
+# binary rpm packages. This way a single SRPM package can be used to produce
+# different binary rpm packages on different platforms depending on the platform's
+# packaging rules.
+#
+# Source RPM packaging has it's own set of variables:
+#
+# .. variable:: CPACK_RPM_PACKAGE_SOURCES
+#
+# Should the content be packaged as a source rpm (default is binary rpm).
+#
+# * Mandatory : NO
+# * Default : OFF
+#
+# .. note::
+#
+# For cmake projects :variable:`CPACK_RPM_PACKAGE_SOURCES` variable is set
+# to ``OFF`` in CPackConfig.cmake and ``ON`` in CPackSourceConfig.cmake
+# generated files.
+#
+# .. variable:: CPACK_RPM_SOURCE_PKG_BUILD_PARAMS
+#
+# Additional command-line parameters provided to :manual:`cmake(1)` executable.
+#
+# * Mandatory : NO
+# * Default : -
+#
+# .. variable:: CPACK_RPM_SOURCE_PKG_PACKAGING_INSTALL_PREFIX
+#
+# Packaging install prefix that would be provided in :variable:`CPACK_PACKAGING_INSTALL_PREFIX`
+# variable for producing binary RPM packages.
+#
+# * Mandatory : YES
+# * Default : "/"
#=============================================================================
# Copyright 2007-2016 Kitware, Inc.
@@ -847,7 +918,10 @@ function(cpack_rpm_prepare_content_list)
set(_DISTINCT_PATH "${_RPM_RELOCATION_PREFIX}")
string(REPLACE "/" ";" _CPACK_RPM_PACKAGE_PREFIX_ELEMS " ${_RPM_RELOCATION_PREFIX}")
- list(REMOVE_AT _CPACK_RPM_PACKAGE_PREFIX_ELEMS -1)
+ cmake_policy(PUSH)
+ cmake_policy(SET CMP0007 NEW)
+ list(REMOVE_AT _CPACK_RPM_PACKAGE_PREFIX_ELEMS -1)
+ cmake_policy(POP)
unset(_TMP_LIST)
# Now generate all of the parent dirs of the relocation path
foreach(_PREFIX_PATH_ELEM ${_CPACK_RPM_PACKAGE_PREFIX_ELEMS})
@@ -1515,18 +1589,27 @@ function(cpack_rpm_generate_package)
set(CPACK_RPM_COMPRESSION_TYPE_TMP "")
endif()
- if(CPACK_PACKAGE_RELOCATABLE OR CPACK_RPM_PACKAGE_RELOCATABLE)
- if(CPACK_RPM_PACKAGE_DEBUG)
- message("CPackRPM:Debug: Trying to build a relocatable package")
+ if(NOT CPACK_RPM_PACKAGE_SOURCES)
+ if(CPACK_PACKAGE_RELOCATABLE OR CPACK_RPM_PACKAGE_RELOCATABLE)
+ if(CPACK_RPM_PACKAGE_DEBUG)
+ message("CPackRPM:Debug: Trying to build a relocatable package")
+ endif()
+ if(CPACK_SET_DESTDIR AND (NOT CPACK_SET_DESTDIR STREQUAL "I_ON"))
+ message("CPackRPM:Warning: CPACK_SET_DESTDIR is set (=${CPACK_SET_DESTDIR}) while requesting a relocatable package (CPACK_RPM_PACKAGE_RELOCATABLE is set): this is not supported, the package won't be relocatable.")
+ set(CPACK_RPM_PACKAGE_RELOCATABLE FALSE)
+ else()
+ set(CPACK_RPM_PACKAGE_PREFIX ${CPACK_PACKAGING_INSTALL_PREFIX}) # kept for back compatibility (provided external RPM spec files)
+ cpack_rpm_prepare_relocation_paths()
+ set(CPACK_RPM_PACKAGE_RELOCATABLE TRUE)
+ endif()
endif()
- if(CPACK_SET_DESTDIR AND (NOT CPACK_SET_DESTDIR STREQUAL "I_ON"))
- message("CPackRPM:Warning: CPACK_SET_DESTDIR is set (=${CPACK_SET_DESTDIR}) while requesting a relocatable package (CPACK_RPM_PACKAGE_RELOCATABLE is set): this is not supported, the package won't be relocatable.")
- set(CPACK_RPM_PACKAGE_RELOCATABLE FALSE)
- else()
- set(CPACK_RPM_PACKAGE_PREFIX ${CPACK_PACKAGING_INSTALL_PREFIX}) # kept for back compatibility (provided external RPM spec files)
- cpack_rpm_prepare_relocation_paths()
- set(CPACK_RPM_PACKAGE_RELOCATABLE TRUE)
+ else()
+ if(CPACK_RPM_PACKAGE_COMPONENT)
+ message(FATAL_ERROR "CPACK_RPM_PACKAGE_SOURCES parameter can not be used"
+ " in combination with CPACK_RPM_PACKAGE_COMPONENT parameter!")
endif()
+
+ set(CPACK_RPM_PACKAGE_RELOCATABLE FALSE) # disable relocatable option if building source RPM
endif()
# Check if additional fields for RPM spec header are given
@@ -1870,13 +1953,50 @@ function(cpack_rpm_generate_package)
endif()
endif()
- # We should generate a USER spec file template:
- # - either because the user asked for it : CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE
- # - or the user did not provide one : NOT CPACK_RPM_USER_BINARY_SPECFILE
- if(CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE OR NOT CPACK_RPM_USER_BINARY_SPECFILE)
+ if(CPACK_RPM_PACKAGE_SOURCES) # source rpm
+ set(archive_name_ "${CPACK_RPM_PACKAGE_NAME}-${CPACK_RPM_PACKAGE_VERSION}")
+
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E tar "cfvz" "${CPACK_RPM_DIRECTORY}/SOURCES/${archive_name_}.tar.gz" "${CPACK_PACKAGE_FILE_NAME}"
+ WORKING_DIRECTORY ${CPACK_RPM_DIRECTORY}
+ )
+ set(TMP_RPM_SOURCE "Source: ${archive_name_}.tar.gz")
+
+ if(CPACK_RPM_BUILDREQUIRES)
+ set(TMP_RPM_BUILD_REQUIRES "BuildRequires: ${CPACK_RPM_BUILDREQUIRES}")
+ endif()
+
+ # Disable debuginfo packages - srpm generates invalid packages due to
+ # releasing controll to cpack to generate binary packages.
+ # Note however that this doesn't prevent cpack to generate debuginfo
+ # packages when run from srpm with --rebuild.
+ set(TMP_RPM_DISABLE_DEBUGINFO "%define debug_package %{nil}")
+
+ if(NOT CPACK_RPM_SOURCE_PKG_PACKAGING_INSTALL_PREFIX)
+ set(CPACK_RPM_SOURCE_PKG_PACKAGING_INSTALL_PREFIX "/")
+ endif()
+
+ set(TMP_RPM_BUILD
+ "
+%build
+mkdir cpack_rpm_build_dir
+cd cpack_rpm_build_dir
+cmake ${CPACK_RPM_SOURCE_PKG_BUILD_PARAMS} -DCPACK_PACKAGING_INSTALL_PREFIX=${CPACK_RPM_SOURCE_PKG_PACKAGING_INSTALL_PREFIX} ../${CPACK_PACKAGE_FILE_NAME}
+make %{?_smp_mflags}" # %{?_smp_mflags} -> -j option
+ )
+ set(TMP_RPM_INSTALL
+ "
+cd cpack_rpm_build_dir
+cpack -G RPM
+mv *.rpm %_rpmdir"
+ )
+ set(TMP_RPM_PREP "%setup -c")
+
+ set(RPMBUILD_FLAGS "-bs")
+
file(WRITE ${CPACK_RPM_BINARY_SPECFILE}.in
"# -*- rpm-spec -*-
-BuildRoot: \@CPACK_RPM_DIRECTORY\@/\@CPACK_PACKAGE_FILE_NAME\@\@CPACK_RPM_PACKAGE_COMPONENT_PART_PATH\@
+BuildRoot: %_topdir/\@CPACK_PACKAGE_FILE_NAME\@
Summary: \@CPACK_RPM_PACKAGE_SUMMARY\@
Name: \@CPACK_RPM_PACKAGE_NAME\@
Version: \@CPACK_RPM_PACKAGE_VERSION\@
@@ -1884,6 +2004,64 @@ Release: \@CPACK_RPM_PACKAGE_RELEASE\@
License: \@CPACK_RPM_PACKAGE_LICENSE\@
Group: \@CPACK_RPM_PACKAGE_GROUP\@
Vendor: \@CPACK_RPM_PACKAGE_VENDOR\@
+
+\@TMP_RPM_SOURCE\@
+\@TMP_RPM_BUILD_REQUIRES\@
+\@TMP_RPM_BUILDARCH\@
+\@TMP_RPM_PREFIXES\@
+
+\@TMP_RPM_DISABLE_DEBUGINFO\@
+
+%define _rpmdir %_topdir/RPMS
+%define _srcrpmdir %_topdir/SRPMS
+\@FILE_NAME_DEFINE\@
+%define _unpackaged_files_terminate_build 0
+\@TMP_RPM_SPEC_INSTALL_POST\@
+\@CPACK_RPM_SPEC_MORE_DEFINE\@
+\@CPACK_RPM_COMPRESSION_TYPE_TMP\@
+
+%description
+\@CPACK_RPM_PACKAGE_DESCRIPTION\@
+
+# This is a shortcutted spec file generated by CMake RPM generator
+# we skip _install step because CPack does that for us.
+# We do only save CPack installed tree in _prepr
+# and then restore it in build.
+%prep
+\@TMP_RPM_PREP\@
+
+\@TMP_RPM_BUILD\@
+
+#p build
+
+%install
+\@TMP_RPM_INSTALL\@
+
+%clean
+
+%changelog
+\@CPACK_RPM_SPEC_CHANGELOG\@
+"
+ )
+ else() # binary rpm
+
+ # We should generate a USER spec file template:
+ # - either because the user asked for it : CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE
+ # - or the user did not provide one : NOT CPACK_RPM_USER_BINARY_SPECFILE
+ if(CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE OR NOT CPACK_RPM_USER_BINARY_SPECFILE)
+ set(RPMBUILD_FLAGS "-bb")
+
+ file(WRITE ${CPACK_RPM_BINARY_SPECFILE}.in
+ "# -*- rpm-spec -*-
+BuildRoot: %_topdir/\@CPACK_PACKAGE_FILE_NAME\@\@CPACK_RPM_PACKAGE_COMPONENT_PART_PATH\@
+Summary: \@CPACK_RPM_PACKAGE_SUMMARY\@
+Name: \@CPACK_RPM_PACKAGE_NAME\@
+Version: \@CPACK_RPM_PACKAGE_VERSION\@
+Release: \@CPACK_RPM_PACKAGE_RELEASE\@
+License: \@CPACK_RPM_PACKAGE_LICENSE\@
+Group: \@CPACK_RPM_PACKAGE_GROUP\@
+Vendor: \@CPACK_RPM_PACKAGE_VENDOR\@
+
\@TMP_RPM_URL\@
\@TMP_RPM_REQUIRES\@
\@TMP_RPM_REQUIRES_PRE\@
@@ -1901,10 +2079,10 @@ Vendor: \@CPACK_RPM_PACKAGE_VENDOR\@
\@TMP_RPM_DEBUGINFO\@
-%define _rpmdir \@CPACK_RPM_DIRECTORY\@
+%define _rpmdir %_topdir/RPMS
+%define _srcrpmdir %_topdir/SRPMS
\@FILE_NAME_DEFINE\@
%define _unpackaged_files_terminate_build 0
-%define _topdir \@CPACK_RPM_DIRECTORY\@
\@TMP_RPM_SPEC_INSTALL_POST\@
\@CPACK_RPM_SPEC_MORE_DEFINE\@
\@CPACK_RPM_COMPRESSION_TYPE_TMP\@
@@ -1917,16 +2095,14 @@ Vendor: \@CPACK_RPM_PACKAGE_VENDOR\@
# We do only save CPack installed tree in _prepr
# and then restore it in build.
%prep
-mv $RPM_BUILD_ROOT \"\@CPACK_TOPLEVEL_DIRECTORY\@/tmpBBroot\"
-
-#p build
+mv $RPM_BUILD_ROOT %_topdir/tmpBBroot
%install
if [ -e $RPM_BUILD_ROOT ];
then
rm -rf $RPM_BUILD_ROOT
fi
-mv \"\@CPACK_TOPLEVEL_DIRECTORY\@/tmpBBroot\" $RPM_BUILD_ROOT
+mv %_topdir/tmpBBroot $RPM_BUILD_ROOT
%clean
@@ -1951,7 +2127,10 @@ mv \"\@CPACK_TOPLEVEL_DIRECTORY\@/tmpBBroot\" $RPM_BUILD_ROOT
%changelog
\@CPACK_RPM_SPEC_CHANGELOG\@
-")
+"
+ )
+ endif()
+
# Stop here if we were asked to only generate a template USER spec file
# The generated file may then be used as a template by user who wants
# to customize their own spec file.
@@ -1977,9 +2156,9 @@ mv \"\@CPACK_TOPLEVEL_DIRECTORY\@/tmpBBroot\" $RPM_BUILD_ROOT
if(RPMBUILD_EXECUTABLE)
# Now call rpmbuild using the SPECFILE
execute_process(
- COMMAND "${RPMBUILD_EXECUTABLE}" -bb
+ COMMAND "${RPMBUILD_EXECUTABLE}" ${RPMBUILD_FLAGS}
--define "_topdir ${CPACK_RPM_DIRECTORY}"
- --buildroot "${CPACK_RPM_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}"
+ --buildroot "%_topdir/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}" # TODO should I remove this variable? or change the path?
--target "${CPACK_RPM_PACKAGE_ARCHITECTURE}"
"${CPACK_RPM_BINARY_SPECFILE}"
WORKING_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}"
@@ -2006,7 +2185,8 @@ mv \"\@CPACK_TOPLEVEL_DIRECTORY\@/tmpBBroot\" $RPM_BUILD_ROOT
# Tell file(GLOB_RECURSE) not to follow directory symlinks
# even if the project does not set this policy to NEW.
cmake_policy(SET CMP0009 NEW)
- file(GLOB_RECURSE GENERATED_FILES "${CPACK_RPM_DIRECTORY}/*.rpm")
+ file(GLOB_RECURSE GENERATED_FILES "${CPACK_RPM_DIRECTORY}/RPMS/*.rpm"
+ "${CPACK_RPM_DIRECTORY}/SRPMS/*.rpm")
cmake_policy(POP)
if(NOT GENERATED_FILES)
diff --git a/Modules/ExternalProject-download.cmake.in b/Modules/ExternalProject-download.cmake.in
index 91d74e0..8e39a7e 100644
--- a/Modules/ExternalProject-download.cmake.in
+++ b/Modules/ExternalProject-download.cmake.in
@@ -135,6 +135,8 @@ foreach(i RANGE ${retry_number})
@TIMEOUT_ARGS@
STATUS status
LOG log
+ @USERPWD_ARGS@
+ @HTTP_HEADERS_ARGS@
)
list(GET status 0 status_code)
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index 5ea309f..79054a1 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -75,6 +75,12 @@ Create custom targets to build projects in external trees
Hash of file at URL
``URL_MD5 md5``
Equivalent to URL_HASH MD5=md5
+ ``HTTP_USERNAME <username>``
+ Username for download operation
+ ``HTTP_PASSWORD <username>``
+ Password for download operation
+ ``HTTP_HEADER <header>``
+ HTTP header for download operation. Suboption can be repeated several times.
``TLS_VERIFY <bool>``
Should certificate for https be checked
``TLS_CAINFO <file>``
@@ -858,7 +864,7 @@ endif()
endfunction(_ep_write_gitupdate_script)
-function(_ep_write_downloadfile_script script_filename REMOTE LOCAL timeout no_progress hash tls_verify tls_cainfo)
+function(_ep_write_downloadfile_script script_filename REMOTE LOCAL timeout no_progress hash tls_verify tls_cainfo userpwd http_headers)
if(timeout)
set(TIMEOUT_ARGS TIMEOUT ${timeout})
set(TIMEOUT_MSG "${timeout} seconds")
@@ -906,6 +912,22 @@ function(_ep_write_downloadfile_script script_filename REMOTE LOCAL timeout no_p
set(TLS_CAINFO_CODE "set(CMAKE_TLS_CAINFO \"${tls_cainfo}\")")
endif()
+ if(userpwd STREQUAL ":")
+ set(USERPWD_ARGS)
+ else()
+ set(USERPWD_ARGS USERPWD "${userpwd}")
+ endif()
+
+ set(HTTP_HEADERS_ARGS "")
+ if(NOT http_headers STREQUAL "")
+ foreach(header ${http_headers})
+ set(
+ HTTP_HEADERS_ARGS
+ "HTTPHEADER \"${header}\"\n ${HTTP_HEADERS_ARGS}"
+ )
+ endforeach()
+ endif()
+
# Used variables:
# * TLS_VERIFY_CODE
# * TLS_CAINFO_CODE
@@ -916,6 +938,8 @@ function(_ep_write_downloadfile_script script_filename REMOTE LOCAL timeout no_p
# * SHOW_PROGRESS
# * TIMEOUT_ARGS
# * TIMEOUT_MSG
+ # * USERPWD_ARGS
+ # * HTTP_HEADERS_ARGS
configure_file(
"${_ExternalProject_SELF_DIR}/ExternalProject-download.cmake.in"
"${script_filename}"
@@ -1919,8 +1943,11 @@ function(_ep_add_download_command name)
get_property(no_progress TARGET ${name} PROPERTY _EP_DOWNLOAD_NO_PROGRESS)
get_property(tls_verify TARGET ${name} PROPERTY _EP_TLS_VERIFY)
get_property(tls_cainfo TARGET ${name} PROPERTY _EP_TLS_CAINFO)
+ get_property(http_username TARGET ${name} PROPERTY _EP_HTTP_USERNAME)
+ get_property(http_password TARGET ${name} PROPERTY _EP_HTTP_PASSWORD)
+ get_property(http_headers TARGET ${name} PROPERTY _EP_HTTP_HEADER)
set(download_script "${stamp_dir}/download-${name}.cmake")
- _ep_write_downloadfile_script("${download_script}" "${url}" "${file}" "${timeout}" "${no_progress}" "${hash}" "${tls_verify}" "${tls_cainfo}")
+ _ep_write_downloadfile_script("${download_script}" "${url}" "${file}" "${timeout}" "${no_progress}" "${hash}" "${tls_verify}" "${tls_cainfo}" "${http_username}:${http_password}" "${http_headers}")
set(cmd ${CMAKE_COMMAND} -P "${download_script}"
COMMAND)
if (no_extract)
diff --git a/Modules/FeatureSummary.cmake b/Modules/FeatureSummary.cmake
index 764a5f7..548d12a 100644
--- a/Modules/FeatureSummary.cmake
+++ b/Modules/FeatureSummary.cmake
@@ -1,268 +1,27 @@
-#.rst:
-# FeatureSummary
-# --------------
-#
-# Macros for generating a summary of enabled/disabled features
-#
-#
-#
-# This module provides the macros feature_summary(),
-# set_package_properties() and add_feature_info(). For compatibility it
-# also still provides set_package_info(), set_feature_info(),
-# print_enabled_features() and print_disabled_features().
-#
-# These macros can be used to generate a summary of enabled and disabled
-# packages and/or feature for a build tree:
-#
-# ::
-#
-# -- The following OPTIONAL packages have been found:
-# LibXml2 (required version >= 2.4), XML processing lib, <http://xmlsoft.org>
-# * Enables HTML-import in MyWordProcessor
-# * Enables odt-export in MyWordProcessor
-# PNG , A PNG image library. , <http://www.libpng.org/pub/png/>
-# * Enables saving screenshots
-# -- The following OPTIONAL packages have not been found:
-# Lua51 , The Lua scripting language. , <http://www.lua.org>
-# * Enables macros in MyWordProcessor
-# Foo , Foo provides cool stuff.
-#
-#
-#
-#
-#
-# ::
-#
-# FEATURE_SUMMARY( [FILENAME <file>]
-# [APPEND]
-# [VAR <variable_name>]
-# [INCLUDE_QUIET_PACKAGES]
-# [FATAL_ON_MISSING_REQUIRED_PACKAGES]
-# [DESCRIPTION "Found packages:"]
-# WHAT (ALL | PACKAGES_FOUND | PACKAGES_NOT_FOUND
-# | ENABLED_FEATURES | DISABLED_FEATURES)
-# )
-#
-#
-#
-# The FEATURE_SUMMARY() macro can be used to print information about
-# enabled or disabled packages or features of a project. By default,
-# only the names of the features/packages will be printed and their
-# required version when one was specified. Use SET_PACKAGE_PROPERTIES()
-# to add more useful information, like e.g. a download URL for the
-# respective package or their purpose in the project.
-#
-# The WHAT option is the only mandatory option. Here you specify what
-# information will be printed:
-#
-# ``ALL``
-# print everything
-# ``ENABLED_FEATURES``
-# the list of all features which are enabled
-# ``DISABLED_FEATURES``
-# the list of all features which are disabled
-# ``PACKAGES_FOUND``
-# the list of all packages which have been found
-# ``PACKAGES_NOT_FOUND``
-# the list of all packages which have not been found
-# ``OPTIONAL_PACKAGES_FOUND``
-# only those packages which have been found which have the type OPTIONAL
-# ``OPTIONAL_PACKAGES_NOT_FOUND``
-# only those packages which have not been found which have the type OPTIONAL
-# ``RECOMMENDED_PACKAGES_FOUND``
-# only those packages which have been found which have the type RECOMMENDED
-# ``RECOMMENDED_PACKAGES_NOT_FOUND``
-# only those packages which have not been found which have the type RECOMMENDED
-# ``REQUIRED_PACKAGES_FOUND``
-# only those packages which have been found which have the type REQUIRED
-# ``REQUIRED_PACKAGES_NOT_FOUND``
-# only those packages which have not been found which have the type REQUIRED
-# ``RUNTIME_PACKAGES_FOUND``
-# only those packages which have been found which have the type RUNTIME
-# ``RUNTIME_PACKAGES_NOT_FOUND``
-# only those packages which have not been found which have the type RUNTIME
-#
-# With the exception of the ``ALL`` value, these values can be combined
-# in order to customize the output. For example:
-#
-# ::
-#
-# feature_summary(WHAT ENABLED_FEATURES DISABLED_FEATURES)
-#
-#
-#
-# If a FILENAME is given, the information is printed into this file. If
-# APPEND is used, it is appended to this file, otherwise the file is
-# overwritten if it already existed. If the VAR option is used, the
-# information is "printed" into the specified variable. If FILENAME is
-# not used, the information is printed to the terminal. Using the
-# DESCRIPTION option a description or headline can be set which will be
-# printed above the actual content. If INCLUDE_QUIET_PACKAGES is given,
-# packages which have been searched with find_package(... QUIET) will
-# also be listed. By default they are skipped. If
-# FATAL_ON_MISSING_REQUIRED_PACKAGES is given, CMake will abort if a
-# package which is marked as REQUIRED has not been found.
-#
-# Example 1, append everything to a file:
-#
-# ::
-#
-# feature_summary(WHAT ALL
-# FILENAME ${CMAKE_BINARY_DIR}/all.log APPEND)
-#
-#
-#
-# Example 2, print the enabled features into the variable
-# enabledFeaturesText, including QUIET packages:
-#
-# ::
-#
-# feature_summary(WHAT ENABLED_FEATURES
-# INCLUDE_QUIET_PACKAGES
-# DESCRIPTION "Enabled Features:"
-# VAR enabledFeaturesText)
-# message(STATUS "${enabledFeaturesText}")
-#
-#
-#
-#
-#
-# ::
-#
-# SET_PACKAGE_PROPERTIES(<name> PROPERTIES
-# [ URL <url> ]
-# [ DESCRIPTION <description> ]
-# [ TYPE (RUNTIME|OPTIONAL|RECOMMENDED|REQUIRED) ]
-# [ PURPOSE <purpose> ]
-# )
-#
-#
-#
-# Use this macro to set up information about the named package, which
-# can then be displayed via FEATURE_SUMMARY(). This can be done either
-# directly in the Find-module or in the project which uses the module
-# after the find_package() call. The features for which information can
-# be set are added automatically by the find_package() command.
-#
-# URL: this should be the homepage of the package, or something similar.
-# Ideally this is set already directly in the Find-module.
-#
-# DESCRIPTION: A short description what that package is, at most one
-# sentence. Ideally this is set already directly in the Find-module.
-#
-# TYPE: What type of dependency has the using project on that package.
-# Default is OPTIONAL. In this case it is a package which can be used
-# by the project when available at buildtime, but it also work without.
-# RECOMMENDED is similar to OPTIONAL, i.e. the project will build if
-# the package is not present, but the functionality of the resulting
-# binaries will be severly limited. If a REQUIRED package is not
-# available at buildtime, the project may not even build. This can be
-# combined with the FATAL_ON_MISSING_REQUIRED_PACKAGES argument for
-# feature_summary(). Last, a RUNTIME package is a package which is
-# actually not used at all during the build, but which is required for
-# actually running the resulting binaries. So if such a package is
-# missing, the project can still be built, but it may not work later on.
-# If set_package_properties() is called multiple times for the same
-# package with different TYPEs, the TYPE is only changed to higher TYPEs
-# ( RUNTIME < OPTIONAL < RECOMMENDED < REQUIRED ), lower TYPEs are
-# ignored. The TYPE property is project-specific, so it cannot be set
-# by the Find-module, but must be set in the project.
-#
-# PURPOSE: This describes which features this package enables in the
-# project, i.e. it tells the user what functionality he gets in the
-# resulting binaries. If set_package_properties() is called multiple
-# times for a package, all PURPOSE properties are appended to a list of
-# purposes of the package in the project. As the TYPE property, also
-# the PURPOSE property is project-specific, so it cannot be set by the
-# Find-module, but must be set in the project.
-#
-#
-#
-# Example for setting the info for a package:
-#
-# ::
-#
-# find_package(LibXml2)
-# set_package_properties(LibXml2 PROPERTIES
-# DESCRIPTION "A XML processing library."
-# URL "http://xmlsoft.org/")
-#
-#
-#
-# ::
-#
-# set_package_properties(LibXml2 PROPERTIES
-# TYPE RECOMMENDED
-# PURPOSE "Enables HTML-import in MyWordProcessor")
-# ...
-# set_package_properties(LibXml2 PROPERTIES
-# TYPE OPTIONAL
-# PURPOSE "Enables odt-export in MyWordProcessor")
-#
-#
-#
-# ::
-#
-# find_package(DBUS)
-# set_package_properties(DBUS PROPERTIES
-# TYPE RUNTIME
-# PURPOSE "Necessary to disable the screensaver during a presentation" )
-#
-#
-#
-# ::
-#
-# ADD_FEATURE_INFO(<name> <enabled> <description>)
-#
-# Use this macro to add information about a feature with the given
-# <name>. <enabled> contains whether this feature is enabled or not,
-# <description> is a text describing the feature. The information can
-# be displayed using feature_summary() for ENABLED_FEATURES and
-# DISABLED_FEATURES respectively.
-#
-# Example for setting the info for a feature:
-#
-# ::
-#
-# option(WITH_FOO "Help for foo" ON)
-# add_feature_info(Foo WITH_FOO "The Foo feature provides very cool stuff.")
-#
-#
-#
-#
-#
-# The following macros are provided for compatibility with previous
-# CMake versions:
-#
-# ::
-#
-# SET_PACKAGE_INFO(<name> <description> [<url> [<purpose>] ] )
-#
-# Use this macro to set up information about the named package, which
-# can then be displayed via FEATURE_SUMMARY(). This can be done either
-# directly in the Find-module or in the project which uses the module
-# after the find_package() call. The features for which information can
-# be set are added automatically by the find_package() command.
-#
-# ::
-#
-# PRINT_ENABLED_FEATURES()
-#
-# Does the same as FEATURE_SUMMARY(WHAT ENABLED_FEATURES DESCRIPTION
-# "Enabled features:")
-#
-# ::
-#
-# PRINT_DISABLED_FEATURES()
-#
-# Does the same as FEATURE_SUMMARY(WHAT DISABLED_FEATURES DESCRIPTION
-# "Disabled features:")
-#
-# ::
-#
-# SET_FEATURE_INFO(<name> <description> [<url>] )
-#
-# Does the same as SET_PACKAGE_INFO(<name> <description> <url> )
+#[=======================================================================[.rst:
+FeatureSummary
+--------------
+
+Functions for generating a summary of enabled/disabled features.
+
+These functions can be used to generate a summary of enabled and disabled
+packages and/or feature for a build tree such as::
+
+ -- The following OPTIONAL packages have been found:
+ LibXml2 (required version >= 2.4), XML processing lib, <http://xmlsoft.org>
+ * Enables HTML-import in MyWordProcessor
+ * Enables odt-export in MyWordProcessor
+ PNG , A PNG image library. , <http://www.libpng.org/pub/png/>
+ * Enables saving screenshots
+ -- The following OPTIONAL packages have not been found:
+ Lua51 , The Lua scripting language. , <http://www.lua.org>
+ * Enables macros in MyWordProcessor
+ Foo , Foo provides cool stuff.
+
+Functions
+^^^^^^^^^
+
+#]=======================================================================]
#=============================================================================
# Copyright 2007-2015 Kitware, Inc.
@@ -280,83 +39,6 @@
include("${CMAKE_CURRENT_LIST_DIR}/CMakeParseArguments.cmake")
-function(ADD_FEATURE_INFO _name _enabled _desc)
- if (${_enabled})
- set_property(GLOBAL APPEND PROPERTY ENABLED_FEATURES "${_name}")
- else ()
- set_property(GLOBAL APPEND PROPERTY DISABLED_FEATURES "${_name}")
- endif ()
-
- set_property(GLOBAL PROPERTY _CMAKE_${_name}_DESCRIPTION "${_desc}" )
-endfunction()
-
-
-
-function(SET_PACKAGE_PROPERTIES _name _props)
- if(NOT "${_props}" STREQUAL "PROPERTIES")
- message(FATAL_ERROR "PROPERTIES keyword is missing in SET_PACKAGE_PROPERTIES() call.")
- endif()
-
- set(options ) # none
- set(oneValueArgs DESCRIPTION URL TYPE PURPOSE )
- set(multiValueArgs ) # none
-
- CMAKE_PARSE_ARGUMENTS(_SPP "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
-
- if(_SPP_UNPARSED_ARGUMENTS)
- message(FATAL_ERROR "Unknown keywords given to SET_PACKAGE_PROPERTIES(): \"${_SPP_UNPARSED_ARGUMENTS}\"")
- endif()
-
- if(_SPP_DESCRIPTION)
- get_property(_info GLOBAL PROPERTY _CMAKE_${_name}_DESCRIPTION)
- if(_info AND NOT "${_info}" STREQUAL "${_SPP_DESCRIPTION}")
- message(STATUS "Warning: Property DESCRIPTION for package ${_name} already set to \"${_info}\", overriding it with \"${_SPP_DESCRIPTION}\"")
- endif()
-
- set_property(GLOBAL PROPERTY _CMAKE_${_name}_DESCRIPTION "${_SPP_DESCRIPTION}" )
- endif()
-
-
- if(_SPP_URL)
- get_property(_info GLOBAL PROPERTY _CMAKE_${_name}_URL)
- if(_info AND NOT "${_info}" STREQUAL "${_SPP_URL}")
- message(STATUS "Warning: Property URL already set to \"${_info}\", overriding it with \"${_SPP_URL}\"")
- endif()
-
- set_property(GLOBAL PROPERTY _CMAKE_${_name}_URL "${_SPP_URL}" )
- endif()
-
-
- # handle the PURPOSE: use APPEND, since there can be multiple purposes for one package inside a project
- if(_SPP_PURPOSE)
- set_property(GLOBAL APPEND PROPERTY _CMAKE_${_name}_PURPOSE "${_SPP_PURPOSE}" )
- endif()
-
- # handle the TYPE
- if(NOT _SPP_TYPE)
- set(_SPP_TYPE OPTIONAL)
- endif()
-
- # List the supported types, according to their priority
- set(validTypes "RUNTIME" "OPTIONAL" "RECOMMENDED" "REQUIRED" )
- list(FIND validTypes ${_SPP_TYPE} _typeIndexInList)
- if("${_typeIndexInList}" STREQUAL "-1" )
- message(FATAL_ERROR "Bad package property type ${_SPP_TYPE} used in SET_PACKAGE_PROPERTIES(). "
- "Valid types are OPTIONAL, RECOMMENDED, REQUIRED and RUNTIME." )
- endif()
-
- get_property(_previousType GLOBAL PROPERTY _CMAKE_${_name}_TYPE)
- list(FIND validTypes "${_previousType}" _prevTypeIndexInList)
-
- # make sure a previously set TYPE is not overridden with a lower new TYPE:
- if("${_typeIndexInList}" GREATER "${_prevTypeIndexInList}")
- set_property(GLOBAL PROPERTY _CMAKE_${_name}_TYPE "${_SPP_TYPE}" )
- endif()
-
-endfunction()
-
-
-
function(_FS_GET_FEATURE_SUMMARY _property _var _includeQuiet)
set(_type "ANY")
@@ -439,6 +121,97 @@ function(_FS_GET_FEATURE_SUMMARY _property _var _includeQuiet)
endfunction()
+#[=======================================================================[.rst:
+.. command:: feature_summary
+
+ ::
+
+ feature_summary( [FILENAME <file>]
+ [APPEND]
+ [VAR <variable_name>]
+ [INCLUDE_QUIET_PACKAGES]
+ [FATAL_ON_MISSING_REQUIRED_PACKAGES]
+ [DESCRIPTION "Found packages:"]
+ WHAT (ALL | PACKAGES_FOUND | PACKAGES_NOT_FOUND
+ | ENABLED_FEATURES | DISABLED_FEATURES)
+ )
+
+ The ``feature_summary()`` macro can be used to print information about
+ enabled or disabled packages or features of a project. By default,
+ only the names of the features/packages will be printed and their
+ required version when one was specified. Use ``set_package_properties()``
+ to add more useful information, like e.g. a download URL for the
+ respective package or their purpose in the project.
+
+ The ``WHAT`` option is the only mandatory option. Here you specify what
+ information will be printed:
+
+ ``ALL``
+ print everything
+ ``ENABLED_FEATURES``
+ the list of all features which are enabled
+ ``DISABLED_FEATURES``
+ the list of all features which are disabled
+ ``PACKAGES_FOUND``
+ the list of all packages which have been found
+ ``PACKAGES_NOT_FOUND``
+ the list of all packages which have not been found
+ ``OPTIONAL_PACKAGES_FOUND``
+ only those packages which have been found which have the type OPTIONAL
+ ``OPTIONAL_PACKAGES_NOT_FOUND``
+ only those packages which have not been found which have the type OPTIONAL
+ ``RECOMMENDED_PACKAGES_FOUND``
+ only those packages which have been found which have the type RECOMMENDED
+ ``RECOMMENDED_PACKAGES_NOT_FOUND``
+ only those packages which have not been found which have the type RECOMMENDED
+ ``REQUIRED_PACKAGES_FOUND``
+ only those packages which have been found which have the type REQUIRED
+ ``REQUIRED_PACKAGES_NOT_FOUND``
+ only those packages which have not been found which have the type REQUIRED
+ ``RUNTIME_PACKAGES_FOUND``
+ only those packages which have been found which have the type RUNTIME
+ ``RUNTIME_PACKAGES_NOT_FOUND``
+ only those packages which have not been found which have the type RUNTIME
+
+ With the exception of the ``ALL`` value, these values can be combined
+ in order to customize the output. For example:
+
+ .. code-block:: cmake
+
+ feature_summary(WHAT ENABLED_FEATURES DISABLED_FEATURES)
+
+ If a ``FILENAME`` is given, the information is printed into this file. If
+ ``APPEND`` is used, it is appended to this file, otherwise the file is
+ overwritten if it already existed. If the VAR option is used, the
+ information is "printed" into the specified variable. If ``FILENAME`` is
+ not used, the information is printed to the terminal. Using the
+ ``DESCRIPTION`` option a description or headline can be set which will be
+ printed above the actual content. If ``INCLUDE_QUIET_PACKAGES`` is given,
+ packages which have been searched with ``find_package(... QUIET)`` will
+ also be listed. By default they are skipped. If
+ ``FATAL_ON_MISSING_REQUIRED_PACKAGES`` is given, CMake will abort if a
+ package which is marked as ``REQUIRED`` has not been found.
+
+ Example 1, append everything to a file:
+
+ .. code-block:: cmake
+
+ include(FeatureSummary)
+ feature_summary(WHAT ALL
+ FILENAME ${CMAKE_BINARY_DIR}/all.log APPEND)
+
+ Example 2, print the enabled features into the variable
+ enabledFeaturesText, including QUIET packages:
+
+ .. code-block:: cmake
+
+ include(FeatureSummary)
+ feature_summary(WHAT ENABLED_FEATURES
+ INCLUDE_QUIET_PACKAGES
+ DESCRIPTION "Enabled Features:"
+ VAR enabledFeaturesText)
+ message(STATUS "${enabledFeaturesText}")
+#]=======================================================================]
function(FEATURE_SUMMARY)
# CMAKE_PARSE_ARGUMENTS(<prefix> <options> <one_value_keywords> <multi_value_keywords> args...)
@@ -558,9 +331,198 @@ function(FEATURE_SUMMARY)
endfunction()
+#[=======================================================================[.rst:
+.. command:: set_package_properties
+
+ ::
+
+ set_package_properties(<name> PROPERTIES
+ [ URL <url> ]
+ [ DESCRIPTION <description> ]
+ [ TYPE (RUNTIME|OPTIONAL|RECOMMENDED|REQUIRED) ]
+ [ PURPOSE <purpose> ]
+ )
+
+ Use this macro to set up information about the named package, which
+ can then be displayed via FEATURE_SUMMARY(). This can be done either
+ directly in the Find-module or in the project which uses the module
+ after the find_package() call. The features for which information can
+ be set are added automatically by the find_package() command.
+
+ ``URL <url>``
+ This should be the homepage of the package, or something similar.
+ Ideally this is set already directly in the Find-module.
+
+ ``DESCRIPTION <description>``
+ A short description what that package is, at most one sentence.
+ Ideally this is set already directly in the Find-module.
+
+ ``TYPE <type>``
+ What type of dependency has the using project on that package.
+ Default is ``OPTIONAL``. In this case it is a package which can be used
+ by the project when available at buildtime, but it also work without.
+ ``RECOMMENDED`` is similar to ``OPTIONAL``, i.e. the project will build if
+ the package is not present, but the functionality of the resulting
+ binaries will be severly limited. If a ``REQUIRED`` package is not
+ available at buildtime, the project may not even build. This can be
+ combined with the ``FATAL_ON_MISSING_REQUIRED_PACKAGES`` argument for
+ ``feature_summary()``. Last, a ``RUNTIME`` package is a package which is
+ actually not used at all during the build, but which is required for
+ actually running the resulting binaries. So if such a package is
+ missing, the project can still be built, but it may not work later on.
+ If ``set_package_properties()`` is called multiple times for the same
+ package with different TYPEs, the ``TYPE`` is only changed to higher
+ TYPEs (``RUNTIME < OPTIONAL < RECOMMENDED < REQUIRED``), lower TYPEs are
+ ignored. The ``TYPE`` property is project-specific, so it cannot be set
+ by the Find-module, but must be set in the project.
+
+
+ ``PURPOSE <purpose>``
+ This describes which features this package enables in the
+ project, i.e. it tells the user what functionality he gets in the
+ resulting binaries. If set_package_properties() is called multiple
+ times for a package, all PURPOSE properties are appended to a list of
+ purposes of the package in the project. As the TYPE property, also
+ the PURPOSE property is project-specific, so it cannot be set by the
+ Find-module, but must be set in the project.
+
+ Example for setting the info for a package:
+
+ .. code-block:: cmake
+
+ find_package(LibXml2)
+ set_package_properties(LibXml2 PROPERTIES
+ DESCRIPTION "A XML processing library."
+ URL "http://xmlsoft.org/")
+ # or
+ set_package_properties(LibXml2 PROPERTIES
+ TYPE RECOMMENDED
+ PURPOSE "Enables HTML-import in MyWordProcessor")
+ # or
+ set_package_properties(LibXml2 PROPERTIES
+ TYPE OPTIONAL
+ PURPOSE "Enables odt-export in MyWordProcessor")
+
+ find_package(DBUS)
+ set_package_properties(DBUS PROPERTIES
+ TYPE RUNTIME
+ PURPOSE "Necessary to disable the screensaver during a presentation")
+#]=======================================================================]
+function(SET_PACKAGE_PROPERTIES _name _props)
+ if(NOT "${_props}" STREQUAL "PROPERTIES")
+ message(FATAL_ERROR "PROPERTIES keyword is missing in SET_PACKAGE_PROPERTIES() call.")
+ endif()
+
+ set(options ) # none
+ set(oneValueArgs DESCRIPTION URL TYPE PURPOSE )
+ set(multiValueArgs ) # none
+
+ CMAKE_PARSE_ARGUMENTS(_SPP "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+ if(_SPP_UNPARSED_ARGUMENTS)
+ message(FATAL_ERROR "Unknown keywords given to SET_PACKAGE_PROPERTIES(): \"${_SPP_UNPARSED_ARGUMENTS}\"")
+ endif()
+
+ if(_SPP_DESCRIPTION)
+ get_property(_info GLOBAL PROPERTY _CMAKE_${_name}_DESCRIPTION)
+ if(_info AND NOT "${_info}" STREQUAL "${_SPP_DESCRIPTION}")
+ message(STATUS "Warning: Property DESCRIPTION for package ${_name} already set to \"${_info}\", overriding it with \"${_SPP_DESCRIPTION}\"")
+ endif()
+
+ set_property(GLOBAL PROPERTY _CMAKE_${_name}_DESCRIPTION "${_SPP_DESCRIPTION}" )
+ endif()
+
+
+ if(_SPP_URL)
+ get_property(_info GLOBAL PROPERTY _CMAKE_${_name}_URL)
+ if(_info AND NOT "${_info}" STREQUAL "${_SPP_URL}")
+ message(STATUS "Warning: Property URL already set to \"${_info}\", overriding it with \"${_SPP_URL}\"")
+ endif()
+
+ set_property(GLOBAL PROPERTY _CMAKE_${_name}_URL "${_SPP_URL}" )
+ endif()
+
+
+ # handle the PURPOSE: use APPEND, since there can be multiple purposes for one package inside a project
+ if(_SPP_PURPOSE)
+ set_property(GLOBAL APPEND PROPERTY _CMAKE_${_name}_PURPOSE "${_SPP_PURPOSE}" )
+ endif()
+
+ # handle the TYPE
+ if(NOT _SPP_TYPE)
+ set(_SPP_TYPE OPTIONAL)
+ endif()
+
+ # List the supported types, according to their priority
+ set(validTypes "RUNTIME" "OPTIONAL" "RECOMMENDED" "REQUIRED" )
+ list(FIND validTypes ${_SPP_TYPE} _typeIndexInList)
+ if("${_typeIndexInList}" STREQUAL "-1" )
+ message(FATAL_ERROR "Bad package property type ${_SPP_TYPE} used in SET_PACKAGE_PROPERTIES(). "
+ "Valid types are OPTIONAL, RECOMMENDED, REQUIRED and RUNTIME." )
+ endif()
+
+ get_property(_previousType GLOBAL PROPERTY _CMAKE_${_name}_TYPE)
+ list(FIND validTypes "${_previousType}" _prevTypeIndexInList)
+
+ # make sure a previously set TYPE is not overridden with a lower new TYPE:
+ if("${_typeIndexInList}" GREATER "${_prevTypeIndexInList}")
+ set_property(GLOBAL PROPERTY _CMAKE_${_name}_TYPE "${_SPP_TYPE}" )
+ endif()
+
+endfunction()
+
+#[=======================================================================[.rst:
+.. command:: add_feature_info
+
+ ::
+
+ add_feature_info(<name> <enabled> <description>)
+
+ Use this macro to add information about a feature with the given ``<name>``.
+ ``<enabled>`` contains whether this feature is enabled or not.
+ ``<description>`` is a text describing the feature. The information can
+ be displayed using ``feature_summary()`` for ``ENABLED_FEATURES`` and
+ ``DISABLED_FEATURES`` respectively.
+
+ Example for setting the info for a feature:
+
+ .. code-block:: cmake
+
+ option(WITH_FOO "Help for foo" ON)
+ add_feature_info(Foo WITH_FOO "The Foo feature provides very cool stuff.")
+#]=======================================================================]
+function(ADD_FEATURE_INFO _name _enabled _desc)
+ if (${_enabled})
+ set_property(GLOBAL APPEND PROPERTY ENABLED_FEATURES "${_name}")
+ else ()
+ set_property(GLOBAL APPEND PROPERTY DISABLED_FEATURES "${_name}")
+ endif ()
+
+ set_property(GLOBAL PROPERTY _CMAKE_${_name}_DESCRIPTION "${_desc}" )
+endfunction()
+
# The stuff below is only kept for compatibility
+#[=======================================================================[.rst:
+Legacy Macros
+^^^^^^^^^^^^^
+
+The following macros are provided for compatibility with previous
+CMake versions:
+
+.. command:: set_package_info
+
+ ::
+
+ set_package_info(<name> <description> [ <url> [<purpose>] ])
+
+ Use this macro to set up information about the named package, which
+ can then be displayed via ``feature_summary()``. This can be done either
+ directly in the Find-module or in the project which uses the module
+ after the :command:`find_package` call. The features for which information
+ can be set are added automatically by the ``find_package()`` command.
+#]=======================================================================]
function(SET_PACKAGE_INFO _name _desc)
unset(_url)
unset(_purpose)
@@ -579,20 +541,51 @@ function(SET_PACKAGE_INFO _name _desc)
endif()
endfunction()
+#[=======================================================================[.rst:
+.. command:: set_feature_info
+ ::
+ set_feature_info(<name> <description> [<url>])
+
+ Does the same as::
+
+ set_package_info(<name> <description> <url>)
+#]=======================================================================]
function(SET_FEATURE_INFO)
SET_PACKAGE_INFO(${ARGN})
endfunction()
+#[=======================================================================[.rst:
+.. command:: print_enabled_features
+
+ ::
+
+ print_enabled_features()
+ Does the same as
+ .. code-block:: cmake
+
+ feature_summary(WHAT ENABLED_FEATURES DESCRIPTION "Enabled features:")
+#]=======================================================================]
function(PRINT_ENABLED_FEATURES)
FEATURE_SUMMARY(WHAT ENABLED_FEATURES DESCRIPTION "Enabled features:")
endfunction()
+#[=======================================================================[.rst:
+.. command:: print_disabled_features
+
+ ::
+
+ print_disabled_features()
+
+ Does the same as
+ .. code-block:: cmake
+ feature_summary(WHAT DISABLED_FEATURES DESCRIPTION "Disabled features:")
+#]=======================================================================]
function(PRINT_DISABLED_FEATURES)
FEATURE_SUMMARY(WHAT DISABLED_FEATURES DESCRIPTION "Disabled features:")
endfunction()
diff --git a/Modules/FindCUDA.cmake b/Modules/FindCUDA.cmake
index aaa1536..6b76c25 100644
--- a/Modules/FindCUDA.cmake
+++ b/Modules/FindCUDA.cmake
@@ -303,6 +303,8 @@
# CUDA_ADD_CUBLAS_TO_TARGET macro).
# CUDA_cudart_static_LIBRARY -- Statically linkable cuda runtime library.
# Only available for CUDA version 5.5+
+# CUDA_cudadevrt_LIBRARY -- Device runtime library.
+# Required for separable compilation.
# CUDA_cupti_LIBRARY -- CUDA Profiling Tools Interface library.
# Only available for CUDA version 4.0+.
# CUDA_curand_LIBRARY -- CUDA Random Number Generation library.
@@ -564,6 +566,7 @@ macro(cuda_unset_include_and_libraries)
unset(CUDA_CUDARTEMU_LIBRARY CACHE)
endif()
unset(CUDA_cudart_static_LIBRARY CACHE)
+ unset(CUDA_cudadevrt_LIBRARY CACHE)
unset(CUDA_cublas_LIBRARY CACHE)
unset(CUDA_cublas_device_LIBRARY CACHE)
unset(CUDA_cublasemu_LIBRARY CACHE)
@@ -794,6 +797,10 @@ else()
set(CUDA_USE_STATIC_CUDA_RUNTIME OFF CACHE INTERNAL "")
set(CUDA_CUDART_LIBRARY_VAR CUDA_CUDART_LIBRARY)
endif()
+if(NOT CUDA_VERSION VERSION_LESS "5.0")
+ cuda_find_library_local_first(CUDA_cudadevrt_LIBRARY cudadevrt "\"cudadevrt\" library")
+ mark_as_advanced(CUDA_cudadevrt_LIBRARY)
+endif()
if(CUDA_USE_STATIC_CUDA_RUNTIME)
if(UNIX)
@@ -1737,6 +1744,12 @@ macro(CUDA_ADD_LIBRARY cuda_target)
${CUDA_LIBRARIES}
)
+ if(CUDA_SEPARABLE_COMPILATION)
+ target_link_libraries(${cuda_target}
+ ${CUDA_cudadevrt_LIBRARY}
+ )
+ endif()
+
# We need to set the linker language based on what the expected generated file
# would be. CUDA_C_OR_CXX is computed based on CUDA_HOST_COMPILATION_CPP.
set_target_properties(${cuda_target}
diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake
index b501599..c813f8f 100644
--- a/Modules/FindMatlab.cmake
+++ b/Modules/FindMatlab.cmake
@@ -635,7 +635,7 @@ function(matlab_get_version_from_matlab_run matlab_binary_program matlab_list_ve
set(devnull INPUT_FILE NUL)
endif()
- # timeout set to 30 seconds, in case it does not start
+ # timeout set to 120 seconds, in case it does not start
# note as said before OUTPUT_VARIABLE cannot be used in a platform
# independent manner however, not setting it would flush the output of Matlab
# in the current console (unix variant)
@@ -644,11 +644,18 @@ function(matlab_get_version_from_matlab_run matlab_binary_program matlab_list_ve
OUTPUT_VARIABLE _matlab_version_from_cmd_dummy
RESULT_VARIABLE _matlab_result_version_call
ERROR_VARIABLE _matlab_result_version_call_error
- TIMEOUT 30
+ TIMEOUT 120
WORKING_DIRECTORY "${_matlab_temporary_folder}"
${devnull}
)
+ if("${_matlab_result_version_call}" MATCHES "timeout")
+ if(MATLAB_FIND_DEBUG)
+ message(WARNING "[MATLAB] Unable to determine the version of Matlab."
+ " Matlab call timed out after 120 seconds.")
+ endif()
+ return()
+ endif()
if(${_matlab_result_version_call})
if(MATLAB_FIND_DEBUG)
@@ -698,7 +705,6 @@ function(matlab_get_version_from_matlab_run matlab_binary_program matlab_list_ve
endfunction()
-
#.rst:
# .. command:: matlab_add_unit_test
#
@@ -720,6 +726,7 @@ endfunction()
# matlab_add_unit_test(
# NAME <name>
# UNITTEST_FILE matlab_file_containing_unittest.m
+# [CUSTOM_MATLAB_COMMAND matlab_command_to_run_as_test]
# [UNITTEST_PRECOMMAND matlab_command_to_run]
# [TIMEOUT timeout]
# [ADDITIONAL_PATH path1 [path2 ...]]
@@ -735,6 +742,11 @@ endfunction()
# ``UNITTEST_FILE``
# the matlab unittest file. Its path will be automatically
# added to the Matlab path.
+# ``CUSTOM_MATLAB_COMMAND``
+# Matlab script command to run as the test.
+# IIf this is not set, then the following is run:
+# "runtests('matlab_file_name'), exit(max([ans(1,:).Failed]))
+# matlab_file_name comes from UNITTEST_FILE without the .m.
# ``UNITTEST_PRECOMMAND``
# Matlab script command to be ran before the file
# containing the test (eg. GPU device initialisation based on CMake
@@ -748,12 +760,18 @@ endfunction()
# ``MATLAB_ADDITIONAL_STARTUP_OPTIONS``
# a list of additional option in order
# to run Matlab from the command line.
+# -nosplash -nodesktop -nodisplay are always added.
# ``TEST_ARGS``
# Additional options provided to the add_test command. These
# options are added to the default options (eg. "CONFIGURATIONS Release")
# ``NO_UNITTEST_FRAMEWORK``
# when set, indicates that the test should not
# use the unittest framework of Matlab (available for versions >= R2013a).
+# ``WORKING_DIRECTORY``
+# This will be the working directory for the test. If specified it will
+# also be the output directory used for the log file of the test run.
+# If not specifed the temporary directory ${CMAKE_BINARY_DIR}/Matlab will
+# be used as the working directory and the log location.
#
function(matlab_add_unit_test)
@@ -762,11 +780,12 @@ function(matlab_add_unit_test)
endif()
set(options NO_UNITTEST_FRAMEWORK)
- set(oneValueArgs NAME UNITTEST_PRECOMMAND UNITTEST_FILE TIMEOUT)
+ set(oneValueArgs NAME UNITTEST_FILE TIMEOUT WORKING_DIRECTORY
+ UNITTEST_PRECOMMAND CUSTOM_TEST_COMMAND)
set(multiValueArgs ADDITIONAL_PATH MATLAB_ADDITIONAL_STARTUP_OPTIONS TEST_ARGS)
set(prefix _matlab_unittest_prefix)
- cmake_parse_arguments(${prefix} "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
+ cmake_parse_arguments(PARSE_ARGV 0 ${prefix} "${options}" "${oneValueArgs}" "${multiValueArgs}" )
if(NOT ${prefix}_NAME)
message(FATAL_ERROR "[MATLAB] The Matlab test name cannot be empty")
@@ -774,15 +793,17 @@ function(matlab_add_unit_test)
add_test(NAME ${${prefix}_NAME}
COMMAND ${CMAKE_COMMAND}
- -Dtest_name=${${prefix}_NAME}
- -Dadditional_paths=${${prefix}_ADDITIONAL_PATH}
- -Dtest_timeout=${${prefix}_TIMEOUT}
- -Doutput_directory=${_matlab_temporary_folder}
- -DMatlab_PROGRAM=${Matlab_MAIN_PROGRAM}
- -Dno_unittest_framework=${${prefix}_NO_UNITTEST_FRAMEWORK}
- -DMatlab_ADDITIONNAL_STARTUP_OPTIONS=${${prefix}_MATLAB_ADDITIONAL_STARTUP_OPTIONS}
- -Dunittest_file_to_run=${${prefix}_UNITTEST_FILE}
- -Dcmd_to_run_before_test=${${prefix}_UNITTEST_PRECOMMAND}
+ "-Dtest_name=${${prefix}_NAME}"
+ "-Dadditional_paths=${${prefix}_ADDITIONAL_PATH}"
+ "-Dtest_timeout=${${prefix}_TIMEOUT}"
+ "-Doutput_directory=${_matlab_temporary_folder}"
+ "-Dworking_directory=${${prefix}_WORKING_DIRECTORY}"
+ "-DMatlab_PROGRAM=${Matlab_MAIN_PROGRAM}"
+ "-Dno_unittest_framework=${${prefix}_NO_UNITTEST_FRAMEWORK}"
+ "-DMatlab_ADDITIONNAL_STARTUP_OPTIONS=${${prefix}_MATLAB_ADDITIONAL_STARTUP_OPTIONS}"
+ "-Dunittest_file_to_run=${${prefix}_UNITTEST_FILE}"
+ "-Dcustom_Matlab_test_command=${${prefix}_CUSTOM_TEST_COMMAND}"
+ "-Dcmd_to_run_before_test=${${prefix}_UNITTEST_PRECOMMAND}"
-P ${_FindMatlab_SELF_DIR}/MatlabTestsRedirect.cmake
${${prefix}_TEST_ARGS}
${${prefix}_UNPARSED_ARGUMENTS}
@@ -1034,7 +1055,7 @@ function(_Matlab_get_version_from_root matlab_root matlab_known_version matlab_f
if(${list_of_all_versions_length} GREATER 0)
list(GET matlab_list_of_all_versions 0 _matlab_version_tmp)
else()
- set(_matlab_version_tmp "")
+ set(_matlab_version_tmp "unknown")
endif()
# set the version into the cache
diff --git a/Modules/FindPostgreSQL.cmake b/Modules/FindPostgreSQL.cmake
index 32a3f0a..84fa541 100644
--- a/Modules/FindPostgreSQL.cmake
+++ b/Modules/FindPostgreSQL.cmake
@@ -37,7 +37,7 @@
# In Windows the default installation of PostgreSQL uses that as part of the path.
# E.g C:\Program Files\PostgreSQL\8.4.
# Currently, the following version numbers are known to this module:
-# "9.4" "9.3" "9.2" "9.1" "9.0" "8.4" "8.3" "8.2" "8.1" "8.0"
+# "9.6" "9.5" "9.4" "9.3" "9.2" "9.1" "9.0" "8.4" "8.3" "8.2" "8.1" "8.0"
#
# To use this variable just do something like this:
# set(PostgreSQL_ADDITIONAL_VERSIONS "9.2" "8.4.4")
@@ -81,7 +81,7 @@ set(PostgreSQL_ROOT_DIR_MESSAGE "Set the PostgreSQL_ROOT system variable to wher
set(PostgreSQL_KNOWN_VERSIONS ${PostgreSQL_ADDITIONAL_VERSIONS}
- "9.5" "9.4" "9.3" "9.2" "9.1" "9.0" "8.4" "8.3" "8.2" "8.1" "8.0")
+ "9.6" "9.5" "9.4" "9.3" "9.2" "9.1" "9.0" "8.4" "8.3" "8.2" "8.1" "8.0")
# Define additional search paths for root directories.
set( PostgreSQL_ROOT_DIRECTORIES
diff --git a/Modules/FindPythonInterp.cmake b/Modules/FindPythonInterp.cmake
index e194185..4d726f2 100644
--- a/Modules/FindPythonInterp.cmake
+++ b/Modules/FindPythonInterp.cmake
@@ -52,7 +52,7 @@ unset(_Python_NAMES)
set(_PYTHON1_VERSIONS 1.6 1.5)
set(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
-set(_PYTHON3_VERSIONS 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
+set(_PYTHON3_VERSIONS 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
if(PythonInterp_FIND_VERSION)
if(PythonInterp_FIND_VERSION_COUNT GREATER 1)
diff --git a/Modules/FindPythonLibs.cmake b/Modules/FindPythonLibs.cmake
index ab92f86..d9916a1 100644
--- a/Modules/FindPythonLibs.cmake
+++ b/Modules/FindPythonLibs.cmake
@@ -84,7 +84,7 @@ set(CMAKE_FIND_FRAMEWORK LAST)
set(_PYTHON1_VERSIONS 1.6 1.5)
set(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
-set(_PYTHON3_VERSIONS 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
+set(_PYTHON3_VERSIONS 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
if(PythonLibs_FIND_VERSION)
if(PythonLibs_FIND_VERSION_COUNT GREATER 1)
diff --git a/Modules/GenerateExportHeader.cmake b/Modules/GenerateExportHeader.cmake
index e33b927..bacf137 100644
--- a/Modules/GenerateExportHeader.cmake
+++ b/Modules/GenerateExportHeader.cmake
@@ -208,7 +208,7 @@ macro(_test_compiler_hidden_visibility)
if(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.2")
set(GCC_TOO_OLD TRUE)
- elseif(CMAKE_COMPILER_IS_GNUC AND CMAKE_C_COMPILER_VERSION VERSION_LESS "4.2")
+ elseif(CMAKE_COMPILER_IS_GNUCC AND CMAKE_C_COMPILER_VERSION VERSION_LESS "4.2")
set(GCC_TOO_OLD TRUE)
elseif(CMAKE_CXX_COMPILER_ID MATCHES Intel AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "12.0")
set(_INTEL_TOO_OLD TRUE)
diff --git a/Modules/MatlabTestsRedirect.cmake b/Modules/MatlabTestsRedirect.cmake
index 0ef4c3e..76f9a53 100644
--- a/Modules/MatlabTestsRedirect.cmake
+++ b/Modules/MatlabTestsRedirect.cmake
@@ -23,11 +23,12 @@
# -DMatlab_PROGRAM=matlab_exe_location
# -DMatlab_ADDITIONNAL_STARTUP_OPTIONS=""
# -Dtest_name=name_of_the_test
+# -Dcustom_Matlab_test_command=""
# -Dcmd_to_run_before_test=""
# -Dunittest_file_to_run
# -P FindMatlab_TestsRedirect.cmake
-set(Matlab_UNIT_TESTS_CMD -nosplash -nojvm -nodesktop -nodisplay ${Matlab_ADDITIONNAL_STARTUP_OPTIONS})
+set(Matlab_UNIT_TESTS_CMD -nosplash -nodesktop -nodisplay ${Matlab_ADDITIONNAL_STARTUP_OPTIONS})
if(WIN32)
set(Matlab_UNIT_TESTS_CMD ${Matlab_UNIT_TESTS_CMD} -wait)
endif()
@@ -36,6 +37,13 @@ if(NOT test_timeout)
set(test_timeout 180)
endif()
+# If timeout is -1, then do not put a timeout on the execute_process
+if(test_timeout EQUAL -1)
+ set(test_timeout "")
+else()
+ set(test_timeout TIMEOUT ${test_timeout})
+endif()
+
if(NOT cmd_to_run_before_test)
set(cmd_to_run_before_test)
endif()
@@ -50,16 +58,30 @@ foreach(s IN LISTS additional_paths)
endif()
endforeach()
-set(unittest_to_run "runtests('${unittest_file_to_run_name}'), exit(max([ans(1,:).Failed]))")
+if(custom_Matlab_test_command)
+ set(unittest_to_run "${custom_Matlab_test_command}")
+else()
+ set(unittest_to_run "runtests('${unittest_file_to_run_name}'), exit(max([ans(1,:).Failed]))")
+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)")
endif()
set(Matlab_SCRIPT_TO_RUN
- "addpath(${concat_string}), path, ${cmd_to_run_before_test}, ${unittest_to_run}"
+ "addpath(${concat_string}); ${cmd_to_run_before_test}; ${unittest_to_run}"
)
+# if the working directory is not specified then default
+# to the output_directory because the log file will go there
+# if the working_directory is specified it will override the
+# output_directory
+if(NOT working_directory)
+ set(working_directory "${output_directory}")
+endif()
-set(Matlab_LOG_FILE "${output_directory}/${test_name}.log")
+string(REPLACE "/" "_" log_file_name "${test_name}.log")
+set(Matlab_LOG_FILE "${working_directory}/${log_file_name}")
set(devnull)
if(UNIX)
@@ -69,11 +91,14 @@ elseif(WIN32)
endif()
execute_process(
- COMMAND "${Matlab_PROGRAM}" ${Matlab_UNIT_TESTS_CMD} -logfile "${test_name}.log" -r "${Matlab_SCRIPT_TO_RUN}"
+ # Do not use a full path to log file. Depend on the fact that the log file
+ # is always going to go in the working_directory. This is because matlab
+ # on unix is a shell script that does not handle spaces in the logfile path.
+ COMMAND "${Matlab_PROGRAM}" ${Matlab_UNIT_TESTS_CMD} -logfile "${log_file_name}" -r "${Matlab_SCRIPT_TO_RUN}"
RESULT_VARIABLE res
- TIMEOUT ${test_timeout}
+ ${test_timeout}
OUTPUT_QUIET # we do not want the output twice
- WORKING_DIRECTORY "${output_directory}"
+ WORKING_DIRECTORY "${working_directory}"
${devnull}
)
@@ -87,5 +112,5 @@ message("Matlab test ${name_of_the_test} output:\n${matlab_log_content}") # if w
if(NOT (res EQUAL 0))
- message( FATAL_ERROR "[MATLAB] TEST FAILED" )
+ message( FATAL_ERROR "[MATLAB] TEST FAILED Matlab returned ${res}" )
endif()
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index f5c2e52..a2dead6 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -221,10 +221,14 @@ set(SRCS
cmExprLexer.cxx
cmExprParser.cxx
cmExprParserHelper.cxx
+ cmExportBuildAndroidMKGenerator.h
+ cmExportBuildAndroidMKGenerator.cxx
cmExportBuildFileGenerator.h
cmExportBuildFileGenerator.cxx
cmExportFileGenerator.h
cmExportFileGenerator.cxx
+ cmExportInstallAndroidMKGenerator.h
+ cmExportInstallAndroidMKGenerator.cxx
cmExportInstallFileGenerator.h
cmExportInstallFileGenerator.cxx
cmExportTryCompileFileGenerator.h
@@ -782,6 +786,17 @@ add_executable(cmake cmakemain.cxx cmcmd.cxx cmcmd.h ${MANIFEST_FILE})
list(APPEND _tools cmake)
target_link_libraries(cmake CMakeLib)
+if(CMake_HAVE_SERVER_MODE)
+ add_library(CMakeServerLib
+ cmServer.cxx cmServer.h
+ cmServerProtocol.cxx cmServerProtocol.h
+ )
+ target_link_libraries(CMakeServerLib CMakeLib)
+ set_property(SOURCE cmcmd.cxx APPEND PROPERTY COMPILE_DEFINITIONS HAVE_SERVER_MODE=1)
+
+ target_link_libraries(cmake CMakeServerLib)
+endif()
+
# Build CTest executable
add_executable(ctest ctest.cxx ${MANIFEST_FILE})
list(APPEND _tools ctest)
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index e77c982..d725626 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 6)
-set(CMake_VERSION_PATCH 20160912)
+set(CMake_VERSION_PATCH 20160921)
#set(CMake_VERSION_RC 1)
diff --git a/Source/CPack/IFW/cmCPackIFWGenerator.cxx b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
index a6f1585..fa7e0aa 100644
--- a/Source/CPack/IFW/cmCPackIFWGenerator.cxx
+++ b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
@@ -130,6 +130,19 @@ int cmCPackIFWGenerator::PackageFiles()
{
std::string ifwCmd = BinCreator;
ifwCmd += " -c " + this->toplevel + "/config/config.xml";
+
+ if (!Installer.Resources.empty()) {
+ ifwCmd += " -r ";
+ std::vector<std::string>::iterator it = Installer.Resources.begin();
+ std::string path = this->toplevel + "/resources/";
+ ifwCmd += path + *it;
+ ++it;
+ while (it != Installer.Resources.end()) {
+ ifwCmd += "," + path + *it;
+ ++it;
+ }
+ }
+
ifwCmd += " -p " + this->toplevel + "/packages";
if (!PkgsDirsVector.empty()) {
diff --git a/Source/CPack/IFW/cmCPackIFWInstaller.cxx b/Source/CPack/IFW/cmCPackIFWInstaller.cxx
index 5a3efc9..aa609e2 100644
--- a/Source/CPack/IFW/cmCPackIFWInstaller.cxx
+++ b/Source/CPack/IFW/cmCPackIFWInstaller.cxx
@@ -13,11 +13,13 @@
#include "cmCPackIFWInstaller.h"
#include "CPack/cmCPackGenerator.h"
+#include "CPack/cmCPackLog.h"
#include "cmCPackIFWGenerator.h"
#include "cmCPackIFWPackage.h"
#include "cmCPackIFWRepository.h"
#include "cmGeneratedFileStream.h"
#include "cmSystemTools.h"
+#include "cmXMLParser.h"
#include "cmXMLWriter.h"
#include <cmConfigure.h>
@@ -198,8 +200,70 @@ void cmCPackIFWInstaller::ConfigureFromOptions()
this->GetOption("CPACK_IFW_PACKAGE_CONTROL_SCRIPT")) {
ControlScript = optIFW_CONTROL_SCRIPT;
}
+
+ // Resources
+ if (const char* optIFW_PACKAGE_RESOURCES =
+ this->GetOption("CPACK_IFW_PACKAGE_RESOURCES")) {
+ Resources.clear();
+ cmSystemTools::ExpandListArgument(optIFW_PACKAGE_RESOURCES, Resources);
+ }
}
+/** \class cmCPackIFWResourcesParser
+ * \brief Helper class that parse resources form .qrc (Qt)
+ */
+class cmCPackIFWResourcesParser : public cmXMLParser
+{
+public:
+ cmCPackIFWResourcesParser(cmCPackIFWInstaller* i)
+ : installer(i)
+ , file(false)
+ {
+ path = i->Directory + "/resources";
+ }
+
+ bool ParseResource(size_t r)
+ {
+ hasFiles = false;
+ hasErrors = false;
+
+ basePath = cmSystemTools::GetFilenamePath(installer->Resources[r].data());
+
+ ParseFile(installer->Resources[r].data());
+
+ return hasFiles && !hasErrors;
+ }
+
+ cmCPackIFWInstaller* installer;
+ bool file, hasFiles, hasErrors;
+ std::string path, basePath;
+
+protected:
+ void StartElement(const std::string& name, const char** /*atts*/) CM_OVERRIDE
+ {
+ file = name == "file" ? true : false;
+ if (file) {
+ hasFiles = true;
+ }
+ }
+
+ void CharacterDataHandler(const char* data, int length) CM_OVERRIDE
+ {
+ if (file) {
+ std::string content(data, data + length);
+ content = cmSystemTools::TrimWhitespace(content);
+ std::string source = basePath + "/" + content;
+ std::string destination = path + "/" + content;
+ if (!cmSystemTools::CopyFileIfDifferent(source.data(),
+ destination.data())) {
+ hasErrors = true;
+ }
+ }
+ }
+
+ void EndElement(const std::string& /*name*/) CM_OVERRIDE {}
+};
+
void cmCPackIFWInstaller::GenerateInstallerFile()
{
// Lazy directory initialization
@@ -315,6 +379,26 @@ void cmCPackIFWInstaller::GenerateInstallerFile()
xout.Element("ControlScript", name);
}
+ // Resources (copy to resources dir)
+ if (!Resources.empty()) {
+ std::vector<std::string> resources;
+ cmCPackIFWResourcesParser parser(this);
+ for (size_t i = 0; i < Resources.size(); i++) {
+ if (parser.ParseResource(i)) {
+ std::string name = cmSystemTools::GetFilenameName(Resources[i]);
+ std::string path = Directory + "/resources/" + name;
+ cmsys::SystemTools::CopyFileIfDifferent(Resources[i].data(),
+ path.data());
+ resources.push_back(name);
+ } else {
+ cmCPackLogger(cmCPackLog::LOG_WARNING, "Can't copy resources from \""
+ << Resources[i] << "\". Resource will be skipped."
+ << std::endl);
+ }
+ }
+ Resources = resources;
+ }
+
xout.EndElement();
xout.EndDocument();
}
diff --git a/Source/CPack/IFW/cmCPackIFWInstaller.h b/Source/CPack/IFW/cmCPackIFWInstaller.h
index f72d379..c9265ec 100644
--- a/Source/CPack/IFW/cmCPackIFWInstaller.h
+++ b/Source/CPack/IFW/cmCPackIFWInstaller.h
@@ -94,6 +94,9 @@ public:
/// Filename for a custom installer control script
std::string ControlScript;
+ /// List of resources to include in the installer binary
+ std::vector<std::string> Resources;
+
public:
// Internal implementation
diff --git a/Source/CPack/IFW/cmCPackIFWPackage.cxx b/Source/CPack/IFW/cmCPackIFWPackage.cxx
index bc503fc..2d3cf12 100644
--- a/Source/CPack/IFW/cmCPackIFWPackage.cxx
+++ b/Source/CPack/IFW/cmCPackIFWPackage.cxx
@@ -153,6 +153,7 @@ void cmCPackIFWPackage::DefaultConfiguration()
ReleaseDate = "";
Script = "";
Licenses.clear();
+ UserInterfaces.clear();
SortingPriority = "";
Default = "";
Essential = "";
@@ -229,6 +230,12 @@ int cmCPackIFWPackage::ConfigureFromComponent(cmCPackComponent* component)
Script = option;
}
+ // User interfaces
+ if (const char* option = this->GetOption(prefix + "USER_INTERFACES")) {
+ UserInterfaces.clear();
+ cmSystemTools::ExpandListArgument(option, UserInterfaces);
+ }
+
// CMake dependencies
if (!component->Dependencies.empty()) {
std::vector<cmCPackComponent*>::iterator dit;
@@ -322,6 +329,12 @@ int cmCPackIFWPackage::ConfigureFromGroup(cmCPackComponentGroup* group)
Script = option;
}
+ // User interfaces
+ if (const char* option = this->GetOption(prefix + "USER_INTERFACES")) {
+ UserInterfaces.clear();
+ cmSystemTools::ExpandListArgument(option, UserInterfaces);
+ }
+
// Licenses
if (const char* option = this->GetOption(prefix + "LICENSES")) {
Licenses.clear();
@@ -417,6 +430,23 @@ void cmCPackIFWPackage::GeneratePackageFile()
xout.Element("Script", name);
}
+ // User Interfaces (copy to meta dir)
+ std::vector<std::string> userInterfaces = UserInterfaces;
+ for (size_t i = 0; i < userInterfaces.size(); i++) {
+ std::string name = cmSystemTools::GetFilenameName(userInterfaces[i]);
+ std::string path = Directory + "/meta/" + name;
+ cmsys::SystemTools::CopyFileIfDifferent(userInterfaces[i].data(),
+ path.data());
+ userInterfaces[i] = name;
+ }
+ if (!userInterfaces.empty()) {
+ xout.StartElement("UserInterfaces");
+ for (size_t i = 0; i < userInterfaces.size(); i++) {
+ xout.Element("UserInterface", userInterfaces[i]);
+ }
+ xout.EndElement();
+ }
+
// Dependencies
std::set<DependenceStruct> compDepSet;
for (std::set<DependenceStruct*>::iterator ait = AlienDependencies.begin();
diff --git a/Source/CPack/IFW/cmCPackIFWPackage.h b/Source/CPack/IFW/cmCPackIFWPackage.h
index 579eeb8..739ae3e 100644
--- a/Source/CPack/IFW/cmCPackIFWPackage.h
+++ b/Source/CPack/IFW/cmCPackIFWPackage.h
@@ -99,6 +99,9 @@ public:
/// List of license agreements to be accepted by the installing user
std::vector<std::string> Licenses;
+ /// List of pages to load
+ std::vector<std::string> UserInterfaces;
+
/// Priority of the component in the tree
std::string SortingPriority;
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index d6b58f2..e6aba89 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -14,6 +14,7 @@
#include "cmCPackComponentGroup.h"
#include "cmCPackLog.h"
+#include "cmCryptoHash.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
@@ -163,6 +164,14 @@ int cmCPackGenerator::PrepareNames()
<< std::endl);
return 0;
}
+ const char* algoSignature = this->GetOption("CPACK_PACKAGE_CHECKSUM");
+ if (algoSignature) {
+ if (cmCryptoHash::New(algoSignature).get() == CM_NULLPTR) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot recognize algorithm: "
+ << algoSignature << std::endl);
+ return 0;
+ }
+ }
this->SetOptionIfNotSet("CPACK_REMOVE_TOPLEVEL_DIRECTORY", "1");
@@ -980,6 +989,10 @@ int cmCPackGenerator::DoPackage()
return 0;
}
+ /* Prepare checksum algorithm*/
+ const char* algo = this->GetOption("CPACK_PACKAGE_CHECKSUM");
+ CM_AUTO_PTR<cmCryptoHash> crypto = cmCryptoHash::New(algo ? algo : "");
+
/*
* Copy the generated packages to final destination
* - there may be several of them
@@ -992,8 +1005,9 @@ int cmCPackGenerator::DoPackage()
/* now copy package one by one */
for (it = packageFileNames.begin(); it != packageFileNames.end(); ++it) {
std::string tmpPF(this->GetOption("CPACK_OUTPUT_FILE_PREFIX"));
+ std::string filename(cmSystemTools::GetFilenameName(*it));
tempPackageFileName = it->c_str();
- tmpPF += "/" + cmSystemTools::GetFilenameName(*it);
+ tmpPF += "/" + filename;
const char* packageFileName = tmpPF.c_str();
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Copy final package(s): "
<< (tempPackageFileName ? tempPackageFileName : "(NULL)")
@@ -1009,6 +1023,23 @@ int cmCPackGenerator::DoPackage()
}
cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- package: "
<< packageFileName << " generated." << std::endl);
+
+ /* Generate checksum file */
+ if (crypto.get() != CM_NULLPTR) {
+ std::string hashFile(this->GetOption("CPACK_OUTPUT_FILE_PREFIX"));
+ hashFile +=
+ "/" + filename.substr(0, filename.rfind(this->GetOutputExtension()));
+ hashFile += "." + cmSystemTools::LowerCase(algo);
+ cmsys::ofstream outF(hashFile.c_str());
+ if (!outF) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot create checksum file: "
+ << hashFile << std::endl);
+ return 0;
+ }
+ outF << crypto->HashFile(packageFileName) << " " << filename << "\n";
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- checksum file: "
+ << hashFile << " generated." << std::endl);
+ }
}
return 1;
diff --git a/Source/CTest/cmCTestSVN.cxx b/Source/CTest/cmCTestSVN.cxx
index f680612..0832820 100644
--- a/Source/CTest/cmCTestSVN.cxx
+++ b/Source/CTest/cmCTestSVN.cxx
@@ -108,13 +108,8 @@ std::string cmCTestSVN::LoadInfo(SVNInfo& svninfo)
void cmCTestSVN::NoteOldRevision()
{
- // Info for root repository
- this->Repositories.push_back(SVNInfo(""));
- this->RootInfo = &(this->Repositories.back());
- // Info for the external repositories
- this->LoadExternals();
+ this->LoadRepositories();
- // Get info for all the repositories
std::list<SVNInfo>::iterator itbeg = this->Repositories.begin();
std::list<SVNInfo>::iterator itend = this->Repositories.end();
for (; itbeg != itend; itbeg++) {
@@ -134,7 +129,8 @@ void cmCTestSVN::NoteOldRevision()
void cmCTestSVN::NoteNewRevision()
{
- // Get info for the external repositories
+ this->LoadRepositories();
+
std::list<SVNInfo>::iterator itbeg = this->Repositories.begin();
std::list<SVNInfo>::iterator itend = this->Repositories.end();
for (; itbeg != itend; itbeg++) {
@@ -534,8 +530,13 @@ private:
}
};
-void cmCTestSVN::LoadExternals()
+void cmCTestSVN::LoadRepositories()
{
+ // Info for root repository
+ this->Repositories.clear();
+ this->Repositories.push_back(SVNInfo(""));
+ this->RootInfo = &(this->Repositories.back());
+
// Run "svn status" to get the list of external repositories
std::vector<const char*> svn_status;
svn_status.push_back("status");
diff --git a/Source/CTest/cmCTestSVN.h b/Source/CTest/cmCTestSVN.h
index 6f2374d..2301b10 100644
--- a/Source/CTest/cmCTestSVN.h
+++ b/Source/CTest/cmCTestSVN.h
@@ -86,7 +86,7 @@ private:
SVNInfo* RootInfo;
std::string LoadInfo(SVNInfo& svninfo);
- void LoadExternals();
+ void LoadRepositories();
void LoadModifications() CM_OVERRIDE;
void LoadRevisions() CM_OVERRIDE;
void LoadRevisions(SVNInfo& svninfo);
diff --git a/Source/Checks/cm_cxx_features.cmake b/Source/Checks/cm_cxx_features.cmake
index 6fde7b6..c6a532f 100644
--- a/Source/Checks/cm_cxx_features.cmake
+++ b/Source/Checks/cm_cxx_features.cmake
@@ -32,8 +32,13 @@ function(cm_check_cxx_feature name)
endfunction()
if(CMAKE_CXX_STANDARD)
+ cm_check_cxx_feature(make_unique)
+ if(CMake_HAVE_CXX_MAKE_UNIQUE)
+ set(CMake_HAVE_CXX_UNIQUE_PTR 1)
+ endif()
cm_check_cxx_feature(nullptr)
cm_check_cxx_feature(override)
+ cm_check_cxx_feature(unique_ptr)
cm_check_cxx_feature(unordered_map)
cm_check_cxx_feature(unordered_set)
endif()
diff --git a/Source/Checks/cm_cxx_make_unique.cxx b/Source/Checks/cm_cxx_make_unique.cxx
new file mode 100644
index 0000000..a3ff68f
--- /dev/null
+++ b/Source/Checks/cm_cxx_make_unique.cxx
@@ -0,0 +1,6 @@
+#include <memory>
+int main()
+{
+ std::unique_ptr<int> u = std::make_unique<int>(0);
+ return *u;
+}
diff --git a/Source/Checks/cm_cxx_unique_ptr.cxx b/Source/Checks/cm_cxx_unique_ptr.cxx
new file mode 100644
index 0000000..a9d4ce5
--- /dev/null
+++ b/Source/Checks/cm_cxx_unique_ptr.cxx
@@ -0,0 +1,6 @@
+#include <memory>
+int main()
+{
+ std::unique_ptr<int> u(new int(0));
+ return *u;
+}
diff --git a/Source/CursesDialog/cmCursesStandardIncludes.h b/Source/CursesDialog/cmCursesStandardIncludes.h
index 4929958..1d8d7c6 100644
--- a/Source/CursesDialog/cmCursesStandardIncludes.h
+++ b/Source/CursesDialog/cmCursesStandardIncludes.h
@@ -14,10 +14,6 @@
#include <cmConfigure.h>
-#if defined(__sun__) && defined(__GNUC__)
-#define _MSE_INT_H
-#endif
-
#if defined(__hpux)
#define _BOOL_DEFINED
#include <sys/time.h>
diff --git a/Source/CursesDialog/form/form.h b/Source/CursesDialog/form/form.h
index 1219cb5..b65a3ca 100644
--- a/Source/CursesDialog/form/form.h
+++ b/Source/CursesDialog/form/form.h
@@ -33,10 +33,6 @@
#ifndef FORM_H
#define FORM_H
-#if defined(__sun__) && defined(__GNUC__)
- #define _MSE_INT_H
-#endif
-
#include <cmFormConfigure.h>
/* figure out which curses.h to include */
diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx
index 5b84597..14ce3f7 100644
--- a/Source/QtDialog/CMakeSetupDialog.cxx
+++ b/Source/QtDialog/CMakeSetupDialog.cxx
@@ -14,6 +14,7 @@
#include <QCloseEvent>
#include <QCoreApplication>
+#include <QDesktopServices>
#include <QDialogButtonBox>
#include <QDragEnterEvent>
#include <QFileDialog>
@@ -227,6 +228,8 @@ void CMakeSetupDialog::initialize()
QObject::connect(this->GenerateButton, SIGNAL(clicked(bool)), this,
SLOT(doGenerate()));
+ QObject::connect(this->OpenProjectButton, SIGNAL(clicked(bool)), this,
+ SLOT(doOpenProject()));
QObject::connect(this->BrowseSourceDirectoryButton, SIGNAL(clicked(bool)),
this, SLOT(doSourceBrowse()));
@@ -499,6 +502,26 @@ void CMakeSetupDialog::doGenerate()
this->ConfigureNeeded = true;
}
+QString CMakeSetupDialog::getProjectFilename()
+{
+ QStringList nameFilter;
+ nameFilter << "*.sln"
+ << "*.xcodeproj";
+ QDir directory(this->BinaryDirectory->currentText());
+ QStringList nlnFile = directory.entryList(nameFilter);
+
+ if (nlnFile.count() == 1) {
+ return this->BinaryDirectory->currentText() + "/" + nlnFile.at(0);
+ }
+
+ return QString();
+}
+
+void CMakeSetupDialog::doOpenProject()
+{
+ QDesktopServices::openUrl(QUrl::fromLocalFile(this->getProjectFilename()));
+}
+
void CMakeSetupDialog::closeEvent(QCloseEvent* e)
{
// prompt for close if there are unsaved changes, and we're not busy
@@ -617,6 +640,11 @@ void CMakeSetupDialog::updateBinaryDirectory(const QString& dir)
this->BinaryDirectory->setEditText(dir);
this->BinaryDirectory->blockSignals(false);
}
+ if (!this->getProjectFilename().isEmpty()) {
+ this->OpenProjectButton->setEnabled(true);
+ } else {
+ this->OpenProjectButton->setEnabled(false);
+ }
}
void CMakeSetupDialog::doBinaryBrowse()
@@ -1002,22 +1030,28 @@ void CMakeSetupDialog::enterState(CMakeSetupDialog::State s)
if (s == Interrupting) {
this->ConfigureButton->setEnabled(false);
this->GenerateButton->setEnabled(false);
+ this->OpenProjectButton->setEnabled(false);
} else if (s == Configuring) {
this->setEnabledState(false);
this->GenerateButton->setEnabled(false);
this->GenerateAction->setEnabled(false);
+ this->OpenProjectButton->setEnabled(false);
this->ConfigureButton->setText(tr("&Stop"));
} else if (s == Generating) {
this->CacheModified = false;
this->setEnabledState(false);
this->ConfigureButton->setEnabled(false);
this->GenerateAction->setEnabled(false);
+ this->OpenProjectButton->setEnabled(false);
this->GenerateButton->setText(tr("&Stop"));
} else if (s == ReadyConfigure) {
this->setEnabledState(true);
this->GenerateButton->setEnabled(true);
this->GenerateAction->setEnabled(true);
this->ConfigureButton->setEnabled(true);
+ if (!this->getProjectFilename().isEmpty()) {
+ this->OpenProjectButton->setEnabled(true);
+ }
this->ConfigureButton->setText(tr("&Configure"));
this->GenerateButton->setText(tr("&Generate"));
} else if (s == ReadyGenerate) {
@@ -1025,6 +1059,9 @@ void CMakeSetupDialog::enterState(CMakeSetupDialog::State s)
this->GenerateButton->setEnabled(true);
this->GenerateAction->setEnabled(true);
this->ConfigureButton->setEnabled(true);
+ if (!this->getProjectFilename().isEmpty()) {
+ this->OpenProjectButton->setEnabled(true);
+ }
this->ConfigureButton->setText(tr("&Configure"));
this->GenerateButton->setText(tr("&Generate"));
}
diff --git a/Source/QtDialog/CMakeSetupDialog.h b/Source/QtDialog/CMakeSetupDialog.h
index 2a4ea7a..992de01 100644
--- a/Source/QtDialog/CMakeSetupDialog.h
+++ b/Source/QtDialog/CMakeSetupDialog.h
@@ -41,6 +41,8 @@ protected slots:
void initialize();
void doConfigure();
void doGenerate();
+ QString getProjectFilename();
+ void doOpenProject();
void doInstallForCommandLine();
void doHelp();
void doAbout();
diff --git a/Source/QtDialog/CMakeSetupDialog.ui b/Source/QtDialog/CMakeSetupDialog.ui
index b04bd93..8d8e0cd 100644
--- a/Source/QtDialog/CMakeSetupDialog.ui
+++ b/Source/QtDialog/CMakeSetupDialog.ui
@@ -238,6 +238,13 @@
</property>
</widget>
</item>
+ <item>
+ <widget class="QPushButton" name="OpenProjectButton">
+ <property name="text">
+ <string>Open &amp;Project</string>
+ </property>
+ </widget>
+ </item>
<item>
<widget class="QLabel" name="Generator">
<property name="text">
diff --git a/Source/cmAddCompileOptionsCommand.cxx b/Source/cmAddCompileOptionsCommand.cxx
index 2223cf4..cbba831 100644
--- a/Source/cmAddCompileOptionsCommand.cxx
+++ b/Source/cmAddCompileOptionsCommand.cxx
@@ -14,7 +14,7 @@
bool cmAddCompileOptionsCommand::InitialPass(
std::vector<std::string> const& args, cmExecutionStatus&)
{
- if (args.size() < 1) {
+ if (args.empty()) {
return true;
}
diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx
index 2c4a4ca..2e28498 100644
--- a/Source/cmAddCustomCommandCommand.cxx
+++ b/Source/cmAddCustomCommandCommand.cxx
@@ -263,8 +263,8 @@ bool cmAddCustomCommandCommand::InitialPass(
// No command for this output exists.
std::ostringstream e;
- e << "given APPEND option with output \"" << output[0]
- << "\" which is not already a custom command output.";
+ e << "given APPEND option with output\n\"" << output[0]
+ << "\"\nwhich is not already a custom command output.";
this->SetError(e.str());
return false;
}
diff --git a/Source/cmAddCustomTargetCommand.cxx b/Source/cmAddCustomTargetCommand.cxx
index 9dc7c59..8e14966 100644
--- a/Source/cmAddCustomTargetCommand.cxx
+++ b/Source/cmAddCustomTargetCommand.cxx
@@ -18,7 +18,7 @@
bool cmAddCustomTargetCommand::InitialPass(
std::vector<std::string> const& args, cmExecutionStatus&)
{
- if (args.size() < 1) {
+ if (args.empty()) {
this->SetError("called with incorrect number of arguments");
return false;
}
diff --git a/Source/cmAddDefinitionsCommand.cxx b/Source/cmAddDefinitionsCommand.cxx
index 2d0d026..5f2b32f 100644
--- a/Source/cmAddDefinitionsCommand.cxx
+++ b/Source/cmAddDefinitionsCommand.cxx
@@ -16,7 +16,7 @@ bool cmAddDefinitionsCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&)
{
// it is OK to have no arguments
- if (args.size() < 1) {
+ if (args.empty()) {
return true;
}
diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx
index 4516ed2..5a40050 100644
--- a/Source/cmAddLibraryCommand.cxx
+++ b/Source/cmAddLibraryCommand.cxx
@@ -18,7 +18,7 @@
bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&)
{
- if (args.size() < 1) {
+ if (args.empty()) {
this->SetError("called with incorrect number of arguments");
return false;
}
diff --git a/Source/cmAddSubDirectoryCommand.cxx b/Source/cmAddSubDirectoryCommand.cxx
index 63a9051..1a781cc 100644
--- a/Source/cmAddSubDirectoryCommand.cxx
+++ b/Source/cmAddSubDirectoryCommand.cxx
@@ -15,7 +15,7 @@
bool cmAddSubDirectoryCommand::InitialPass(
std::vector<std::string> const& args, cmExecutionStatus&)
{
- if (args.size() < 1) {
+ if (args.empty()) {
this->SetError("called with incorrect number of arguments");
return false;
}
diff --git a/Source/cmBuildCommand.cxx b/Source/cmBuildCommand.cxx
index 9830867..6146053 100644
--- a/Source/cmBuildCommand.cxx
+++ b/Source/cmBuildCommand.cxx
@@ -27,7 +27,7 @@ bool cmBuildCommand::InitialPass(std::vector<std::string> const& args,
bool cmBuildCommand::MainSignature(std::vector<std::string> const& args)
{
- if (args.size() < 1) {
+ if (args.empty()) {
this->SetError("requires at least one argument naming a CMake variable");
return false;
}
diff --git a/Source/cmBuildNameCommand.cxx b/Source/cmBuildNameCommand.cxx
index 27234d7..3d02034 100644
--- a/Source/cmBuildNameCommand.cxx
+++ b/Source/cmBuildNameCommand.cxx
@@ -22,7 +22,7 @@ bool cmBuildNameCommand::InitialPass(std::vector<std::string> const& args,
"The build_name command should not be called; see CMP0036.")) {
return true;
}
- if (args.size() < 1) {
+ if (args.empty()) {
this->SetError("called with incorrect number of arguments");
return false;
}
diff --git a/Source/cmCMakeHostSystemInformationCommand.cxx b/Source/cmCMakeHostSystemInformationCommand.cxx
index fdbd5e7..6ff7575 100644
--- a/Source/cmCMakeHostSystemInformationCommand.cxx
+++ b/Source/cmCMakeHostSystemInformationCommand.cxx
@@ -42,9 +42,9 @@ bool cmCMakeHostSystemInformationCommand::InitialPass(
result_list += ";";
}
std::string value;
- if (!this->GetValue(info, key, value))
+ if (!this->GetValue(info, key, value)) {
return false;
-
+ }
result_list += value;
}
diff --git a/Source/cmCMakePolicyCommand.cxx b/Source/cmCMakePolicyCommand.cxx
index 07e0885..d29e208 100644
--- a/Source/cmCMakePolicyCommand.cxx
+++ b/Source/cmCMakePolicyCommand.cxx
@@ -17,30 +17,34 @@
bool cmCMakePolicyCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&)
{
- if (args.size() < 1) {
+ if (args.empty()) {
this->SetError("requires at least one argument.");
return false;
}
if (args[0] == "SET") {
return this->HandleSetMode(args);
- } else if (args[0] == "GET") {
+ }
+ if (args[0] == "GET") {
return this->HandleGetMode(args);
- } else if (args[0] == "PUSH") {
+ }
+ if (args[0] == "PUSH") {
if (args.size() > 1) {
this->SetError("PUSH may not be given additional arguments.");
return false;
}
this->Makefile->PushPolicy();
return true;
- } else if (args[0] == "POP") {
+ }
+ if (args[0] == "POP") {
if (args.size() > 1) {
this->SetError("POP may not be given additional arguments.");
return false;
}
this->Makefile->PopPolicy();
return true;
- } else if (args[0] == "VERSION") {
+ }
+ if (args[0] == "VERSION") {
return this->HandleVersionMode(args);
}
@@ -148,7 +152,8 @@ bool cmCMakePolicyCommand::HandleVersionMode(
if (args.size() <= 1) {
this->SetError("VERSION not given an argument");
return false;
- } else if (args.size() >= 3) {
+ }
+ if (args.size() >= 3) {
this->SetError("VERSION given too many arguments");
return false;
}
diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx
index f97791a..3d7839b 100644
--- a/Source/cmCPluginAPI.cxx
+++ b/Source/cmCPluginAPI.cxx
@@ -524,9 +524,8 @@ void CCONV* cmGetSource(void* arg, const char* name)
i = cmCPluginAPISourceFiles.insert(entry).first;
}
return (void*)i->second;
- } else {
- return CM_NULLPTR;
}
+ return CM_NULLPTR;
}
void* CCONV cmAddSource(void* arg, void* arg2)
@@ -574,12 +573,11 @@ const char* CCONV cmSourceFileGetProperty(void* arg, const char* prop)
cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
if (cmSourceFile* rsf = sf->RealSourceFile) {
return rsf->GetProperty(prop);
- } else {
- if (!strcmp(prop, "LOCATION")) {
- return sf->FullPath.c_str();
- }
- return sf->Properties.GetPropertyValue(prop);
}
+ if (!strcmp(prop, "LOCATION")) {
+ return sf->FullPath.c_str();
+ }
+ return sf->Properties.GetPropertyValue(prop);
}
int CCONV cmSourceFileGetPropertyAsBool(void* arg, const char* prop)
@@ -587,9 +585,8 @@ int CCONV cmSourceFileGetPropertyAsBool(void* arg, const char* prop)
cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
if (cmSourceFile* rsf = sf->RealSourceFile) {
return rsf->GetPropertyAsBool(prop) ? 1 : 0;
- } else {
- return cmSystemTools::IsOn(cmSourceFileGetProperty(arg, prop)) ? 1 : 0;
}
+ return cmSystemTools::IsOn(cmSourceFileGetProperty(arg, prop)) ? 1 : 0;
}
void CCONV cmSourceFileSetProperty(void* arg, const char* prop,
diff --git a/Source/cmCommandArgumentsHelper.cxx b/Source/cmCommandArgumentsHelper.cxx
index 1345bd5..b8fe365 100644
--- a/Source/cmCommandArgumentsHelper.cxx
+++ b/Source/cmCommandArgumentsHelper.cxx
@@ -57,14 +57,7 @@ bool cmCommandArgument::MayFollow(const cmCommandArgument* current) const
if (this->ArgumentsBeforeEmpty) {
return true;
}
-
- std::set<const cmCommandArgument*>::const_iterator argIt =
- this->ArgumentsBefore.find(current);
- if (argIt != this->ArgumentsBefore.end()) {
- return true;
- }
-
- return false;
+ return this->ArgumentsBefore.find(current) != this->ArgumentsBefore.end();
}
bool cmCommandArgument::KeyMatches(const std::string& key) const
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
index 6167e2c..fdf0b0e 100644
--- a/Source/cmCommonTargetGenerator.cxx
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -47,13 +47,6 @@ std::string const& cmCommonTargetGenerator::GetConfigName() const
return this->ConfigName;
}
-std::string cmCommonTargetGenerator::Convert(
- std::string const& source, cmOutputConverter::RelativeRoot relative,
- cmOutputConverter::OutputFormat output)
-{
- return this->LocalGenerator->Convert(source, relative, output);
-}
-
const char* cmCommonTargetGenerator::GetFeature(const std::string& feature)
{
return this->GeneratorTarget->GetFeature(feature, this->ConfigName);
@@ -204,8 +197,9 @@ std::string cmCommonTargetGenerator::GetManifests()
std::vector<std::string> manifests;
for (std::vector<cmSourceFile const*>::iterator mi = manifest_srcs.begin();
mi != manifest_srcs.end(); ++mi) {
- manifests.push_back(this->Convert(
- (*mi)->GetFullPath(), this->LocalGenerator->GetWorkingDirectory(),
+ manifests.push_back(this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->GetWorkingDirectory(), (*mi)->GetFullPath()),
cmOutputConverter::SHELL));
}
diff --git a/Source/cmCommonTargetGenerator.h b/Source/cmCommonTargetGenerator.h
index b433c18..4c52fe5 100644
--- a/Source/cmCommonTargetGenerator.h
+++ b/Source/cmCommonTargetGenerator.h
@@ -57,10 +57,6 @@ protected:
// The windows module definition source file (.def), if any.
cmSourceFile const* ModuleDefinitionFile;
- std::string Convert(std::string const& source,
- cmOutputConverter::RelativeRoot relative,
- cmOutputConverter::OutputFormat output);
-
void AppendFortranFormatFlags(std::string& flags,
cmSourceFile const& source);
diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx
index 94f03e8..f78e840 100644
--- a/Source/cmConditionEvaluator.cxx
+++ b/Source/cmConditionEvaluator.cxx
@@ -85,7 +85,7 @@ bool cmConditionEvaluator::IsTrue(
errorString = "";
// handle empty invocation
- if (args.size() < 1) {
+ if (args.empty()) {
return false;
}
@@ -249,20 +249,19 @@ bool cmConditionEvaluator::GetBooleanValueOld(
// Old IsTrue behavior for single argument.
if (arg == "0") {
return false;
- } else if (arg == "1") {
+ }
+ if (arg == "1") {
return true;
- } else {
- const char* def = this->GetDefinitionIfUnquoted(arg);
- return !cmSystemTools::IsOff(def);
}
- } else {
- // Old GetVariableOrNumber behavior.
const char* def = this->GetDefinitionIfUnquoted(arg);
- if (!def && atoi(arg.c_str())) {
- def = arg.c_str();
- }
return !cmSystemTools::IsOff(def);
}
+ // Old GetVariableOrNumber behavior.
+ const char* def = this->GetDefinitionIfUnquoted(arg);
+ if (!def && atoi(arg.c_str())) {
+ def = arg.c_str();
+ }
+ return !cmSystemTools::IsOff(def);
}
//=========================================================================
@@ -274,7 +273,8 @@ bool cmConditionEvaluator::GetBooleanValueWithAutoDereference(
// Use the policy if it is set.
if (this->Policy12Status == cmPolicies::NEW) {
return GetBooleanValue(newArg);
- } else if (this->Policy12Status == cmPolicies::OLD) {
+ }
+ if (this->Policy12Status == cmPolicies::OLD) {
return GetBooleanValueOld(newArg, oneArg);
}
diff --git a/Source/cmConfigure.cmake.h.in b/Source/cmConfigure.cmake.h.in
index ccea22d..8365367 100644
--- a/Source/cmConfigure.cmake.h.in
+++ b/Source/cmConfigure.cmake.h.in
@@ -30,8 +30,10 @@
#cmakedefine CMAKE_USE_MACH_PARSER
#cmakedefine CMAKE_USE_LIBUV
#cmakedefine CMAKE_ENCODING_UTF8
+#cmakedefine CMake_HAVE_CXX_MAKE_UNIQUE
#cmakedefine CMake_HAVE_CXX_NULLPTR
#cmakedefine CMake_HAVE_CXX_OVERRIDE
+#cmakedefine CMake_HAVE_CXX_UNIQUE_PTR
#cmakedefine CMake_HAVE_CXX_UNORDERED_MAP
#cmakedefine CMake_HAVE_CXX_UNORDERED_SET
#define CMAKE_BIN_DIR "/@CMAKE_BIN_DIR@"
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index e9367b1..3fdf35a 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -565,9 +565,8 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
if (copyFileError.empty()) {
this->Makefile->IssueMessage(cmake::FATAL_ERROR, emsg.str());
return -1;
- } else {
- copyFileErrorMessage = emsg.str();
}
+ copyFileErrorMessage = emsg.str();
}
}
diff --git a/Source/cmDefinePropertyCommand.cxx b/Source/cmDefinePropertyCommand.cxx
index 484a970..3589529 100644
--- a/Source/cmDefinePropertyCommand.cxx
+++ b/Source/cmDefinePropertyCommand.cxx
@@ -17,7 +17,7 @@
bool cmDefinePropertyCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&)
{
- if (args.size() < 1) {
+ if (args.empty()) {
this->SetError("called with incorrect number of arguments");
return false;
}
diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx
index fbbf42f..3296ffc 100644
--- a/Source/cmDependsC.cxx
+++ b/Source/cmDependsC.cxx
@@ -239,19 +239,18 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources,
// written by the original local generator for this directory
// convert the dependencies to paths relative to the home output
// directory. We must do the same here.
- std::string obj_i = this->LocalGenerator->ConvertToRelativePath(
- obj, cmOutputConverter::HOME_OUTPUT);
- std::string obj_m = this->LocalGenerator->ConvertToOutputFormat(
- obj_i, cmOutputConverter::MAKERULE);
+ std::string binDir = this->LocalGenerator->GetBinaryDirectory();
+ std::string obj_i = this->LocalGenerator->ConvertToRelativePath(binDir, obj);
+ std::string obj_m = cmSystemTools::ConvertToOutputPath(obj_i.c_str());
internalDepends << obj_i << std::endl;
for (std::set<std::string>::const_iterator i = dependencies.begin();
i != dependencies.end(); ++i) {
- makeDepends << obj_m << ": "
- << this->LocalGenerator->Convert(
- *i, cmOutputConverter::HOME_OUTPUT,
- cmOutputConverter::MAKERULE)
- << std::endl;
+ makeDepends
+ << obj_m << ": "
+ << cmSystemTools::ConvertToOutputPath(
+ this->LocalGenerator->ConvertToRelativePath(binDir, *i).c_str())
+ << std::endl;
internalDepends << " " << *i << std::endl;
}
makeDepends << std::endl;
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx
index eb4c1ec..ba0617f 100644
--- a/Source/cmDependsFortran.cxx
+++ b/Source/cmDependsFortran.cxx
@@ -189,6 +189,8 @@ bool cmDependsFortran::Finalize(std::ostream& makeDepends,
cmGeneratedFileStream fcStream(fcName.c_str());
fcStream << "# Remove fortran modules provided by this target.\n";
fcStream << "FILE(REMOVE";
+ std::string currentBinDir =
+ this->LocalGenerator->GetCurrentBinaryDirectory();
for (std::set<std::string>::const_iterator i = provides.begin();
i != provides.end(); ++i) {
std::string mod_upper = mod_dir;
@@ -205,16 +207,16 @@ bool cmDependsFortran::Finalize(std::ostream& makeDepends,
stamp += ".mod.stamp";
fcStream << "\n";
fcStream << " \""
- << this->LocalGenerator->ConvertToRelativePath(
- mod_lower, cmOutputConverter::START_OUTPUT)
+ << this->LocalGenerator->ConvertToRelativePath(currentBinDir,
+ mod_lower)
<< "\"\n";
fcStream << " \""
- << this->LocalGenerator->ConvertToRelativePath(
- mod_upper, cmOutputConverter::START_OUTPUT)
+ << this->LocalGenerator->ConvertToRelativePath(currentBinDir,
+ mod_upper)
<< "\"\n";
fcStream << " \""
- << this->LocalGenerator->ConvertToRelativePath(
- stamp, cmOutputConverter::START_OUTPUT)
+ << this->LocalGenerator->ConvertToRelativePath(currentBinDir,
+ stamp)
<< "\"\n";
}
fcStream << " )\n";
@@ -329,19 +331,18 @@ bool cmDependsFortran::WriteDependenciesReal(const char* obj,
const char* src = info.Source.c_str();
// Write the include dependencies to the output stream.
- std::string obj_i = this->LocalGenerator->ConvertToRelativePath(
- obj, cmOutputConverter::HOME_OUTPUT);
- std::string obj_m = this->LocalGenerator->ConvertToOutputFormat(
- obj_i, cmOutputConverter::MAKERULE);
+ std::string binDir = this->LocalGenerator->GetBinaryDirectory();
+ std::string obj_i = this->LocalGenerator->ConvertToRelativePath(binDir, obj);
+ std::string obj_m = cmSystemTools::ConvertToOutputPath(obj_i.c_str());
internalDepends << obj_i << std::endl;
internalDepends << " " << src << std::endl;
for (std::set<std::string>::const_iterator i = info.Includes.begin();
i != info.Includes.end(); ++i) {
- makeDepends << obj_m << ": "
- << this->LocalGenerator->Convert(
- *i, cmOutputConverter::HOME_OUTPUT,
- cmOutputConverter::MAKERULE)
- << std::endl;
+ makeDepends
+ << obj_m << ": "
+ << cmSystemTools::ConvertToOutputPath(
+ this->LocalGenerator->ConvertToRelativePath(binDir, *i).c_str())
+ << std::endl;
internalDepends << " " << *i << std::endl;
}
makeDepends << std::endl;
@@ -366,8 +367,8 @@ bool cmDependsFortran::WriteDependenciesReal(const char* obj,
proxy += "/";
proxy += *i;
proxy += ".mod.proxy";
- proxy = this->LocalGenerator->Convert(
- proxy, cmOutputConverter::HOME_OUTPUT, cmOutputConverter::MAKERULE);
+ proxy = cmSystemTools::ConvertToOutputPath(
+ this->LocalGenerator->ConvertToRelativePath(binDir, proxy).c_str());
// since we require some things add them to our list of requirements
makeDepends << obj_m << ".requires: " << proxy << std::endl;
@@ -382,17 +383,17 @@ bool cmDependsFortran::WriteDependenciesReal(const char* obj,
}
if (!required->second.empty()) {
// This module is known. Depend on its timestamp file.
- std::string stampFile = this->LocalGenerator->Convert(
- required->second, cmOutputConverter::HOME_OUTPUT,
- cmOutputConverter::MAKERULE);
+ std::string stampFile = cmSystemTools::ConvertToOutputPath(
+ this->LocalGenerator->ConvertToRelativePath(binDir, required->second)
+ .c_str());
makeDepends << obj_m << ": " << stampFile << "\n";
} else {
// This module is not known to CMake. Try to locate it where
// the compiler will and depend on that.
std::string module;
if (this->FindModule(*i, module)) {
- module = this->LocalGenerator->Convert(
- module, cmOutputConverter::HOME_OUTPUT, cmOutputConverter::MAKERULE);
+ module = cmSystemTools::ConvertToOutputPath(
+ this->LocalGenerator->ConvertToRelativePath(binDir, module).c_str());
makeDepends << obj_m << ": " << module << "\n";
}
}
@@ -405,8 +406,8 @@ bool cmDependsFortran::WriteDependenciesReal(const char* obj,
proxy += "/";
proxy += *i;
proxy += ".mod.proxy";
- proxy = this->LocalGenerator->Convert(
- proxy, cmOutputConverter::HOME_OUTPUT, cmOutputConverter::MAKERULE);
+ proxy = cmSystemTools::ConvertToOutputPath(
+ this->LocalGenerator->ConvertToRelativePath(binDir, proxy).c_str());
makeDepends << proxy << ": " << obj_m << ".provides" << std::endl;
}
@@ -427,14 +428,16 @@ bool cmDependsFortran::WriteDependenciesReal(const char* obj,
std::string modFile = mod_dir;
modFile += "/";
modFile += *i;
- modFile = this->LocalGenerator->Convert(
- modFile, cmOutputConverter::HOME_OUTPUT, cmOutputConverter::SHELL);
+ modFile = this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->ConvertToRelativePath(binDir, modFile),
+ cmOutputConverter::SHELL);
std::string stampFile = stamp_dir;
stampFile += "/";
stampFile += m;
stampFile += ".mod.stamp";
- stampFile = this->LocalGenerator->Convert(
- stampFile, cmOutputConverter::HOME_OUTPUT, cmOutputConverter::SHELL);
+ stampFile = this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->ConvertToRelativePath(binDir, stampFile),
+ cmOutputConverter::SHELL);
makeDepends << "\t$(CMAKE_COMMAND) -E cmake_copy_f90_mod " << modFile
<< " " << stampFile;
cmMakefile* mf = this->LocalGenerator->GetMakefile();
@@ -453,8 +456,8 @@ bool cmDependsFortran::WriteDependenciesReal(const char* obj,
// the target finishes building.
std::string driver = this->TargetDirectory;
driver += "/build";
- driver = this->LocalGenerator->Convert(
- driver, cmOutputConverter::HOME_OUTPUT, cmOutputConverter::MAKERULE);
+ driver = cmSystemTools::ConvertToOutputPath(
+ this->LocalGenerator->ConvertToRelativePath(binDir, driver).c_str());
makeDepends << driver << ": " << obj_m << ".provides.build\n";
}
diff --git a/Source/cmEnableLanguageCommand.cxx b/Source/cmEnableLanguageCommand.cxx
index 0ebe778..9b7dd03 100644
--- a/Source/cmEnableLanguageCommand.cxx
+++ b/Source/cmEnableLanguageCommand.cxx
@@ -17,7 +17,7 @@ bool cmEnableLanguageCommand::InitialPass(std::vector<std::string> const& args,
{
bool optional = false;
std::vector<std::string> languages;
- if (args.size() < 1) {
+ if (args.empty()) {
this->SetError("called with incorrect number of arguments");
return false;
}
diff --git a/Source/cmExecProgramCommand.cxx b/Source/cmExecProgramCommand.cxx
index 58bbc31..284f486 100644
--- a/Source/cmExecProgramCommand.cxx
+++ b/Source/cmExecProgramCommand.cxx
@@ -19,7 +19,7 @@
bool cmExecProgramCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&)
{
- if (args.size() < 1) {
+ if (args.empty()) {
this->SetError("called with incorrect number of arguments");
return false;
}
diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx
index d97b25f..ab7e0cc 100644
--- a/Source/cmExecuteProcessCommand.cxx
+++ b/Source/cmExecuteProcessCommand.cxx
@@ -31,7 +31,7 @@ void cmExecuteProcessCommandAppend(std::vector<char>& output, const char* data,
bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&)
{
- if (args.size() < 1) {
+ if (args.empty()) {
this->SetError("called with incorrect number of arguments");
return false;
}
@@ -159,10 +159,9 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args,
if (cmds[i].empty()) {
this->SetError(" given COMMAND argument with no value.");
return false;
- } else {
- // Add the null terminating pointer to the command argument list.
- cmds[i].push_back(CM_NULLPTR);
}
+ // Add the null terminating pointer to the command argument list.
+ cmds[i].push_back(CM_NULLPTR);
}
// Parse the timeout string.
diff --git a/Source/cmExportBuildAndroidMKGenerator.cxx b/Source/cmExportBuildAndroidMKGenerator.cxx
new file mode 100644
index 0000000..41d2f7a
--- /dev/null
+++ b/Source/cmExportBuildAndroidMKGenerator.cxx
@@ -0,0 +1,193 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmExportBuildAndroidMKGenerator.h"
+
+#include "cmExportSet.h"
+#include "cmGeneratorTarget.h"
+#include "cmGlobalGenerator.h"
+#include "cmLocalGenerator.h"
+#include "cmMakefile.h"
+#include "cmTargetExport.h"
+
+cmExportBuildAndroidMKGenerator::cmExportBuildAndroidMKGenerator()
+{
+ this->LG = CM_NULLPTR;
+ this->ExportSet = CM_NULLPTR;
+}
+
+void cmExportBuildAndroidMKGenerator::GenerateImportHeaderCode(
+ std::ostream& os, const std::string&)
+{
+ os << "LOCAL_PATH := $(call my-dir)\n\n";
+}
+
+void cmExportBuildAndroidMKGenerator::GenerateImportFooterCode(std::ostream&)
+{
+}
+
+void cmExportBuildAndroidMKGenerator::GenerateExpectedTargetsCode(
+ std::ostream&, const std::string&)
+{
+}
+
+void cmExportBuildAndroidMKGenerator::GenerateImportTargetCode(
+ std::ostream& os, const cmGeneratorTarget* target)
+{
+ std::string targetName = this->Namespace;
+ targetName += target->GetExportName();
+ os << "include $(CLEAR_VARS)\n";
+ os << "LOCAL_MODULE := ";
+ os << targetName << "\n";
+ os << "LOCAL_SRC_FILES := ";
+ std::string path =
+ cmSystemTools::ConvertToOutputPath(target->GetFullPath().c_str());
+ os << path << "\n";
+}
+
+void cmExportBuildAndroidMKGenerator::GenerateImportPropertyCode(
+ std::ostream&, const std::string&, cmGeneratorTarget const*,
+ ImportPropertyMap const&)
+{
+}
+
+void cmExportBuildAndroidMKGenerator::GenerateMissingTargetsCheckCode(
+ std::ostream&, const std::vector<std::string>&)
+{
+}
+
+void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
+ const cmGeneratorTarget* target, std::ostream& os,
+ const ImportPropertyMap& properties)
+{
+ std::string config = "";
+ if (!this->Configurations.empty()) {
+ config = this->Configurations[0];
+ }
+ cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
+ target, os, properties, cmExportBuildAndroidMKGenerator::BUILD, config);
+}
+
+void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
+ const cmGeneratorTarget* target, std::ostream& os,
+ const ImportPropertyMap& properties, GenerateType type,
+ std::string const& config)
+{
+ const bool newCMP0022Behavior =
+ target->GetPolicyStatusCMP0022() != cmPolicies::WARN &&
+ target->GetPolicyStatusCMP0022() != cmPolicies::OLD;
+ if (!newCMP0022Behavior) {
+ std::ostringstream w;
+ if (type == cmExportBuildAndroidMKGenerator::BUILD) {
+ w << "export(TARGETS ... ANDROID_MK) called with policy CMP0022";
+ } else {
+ w << "install( EXPORT_ANDROID_MK ...) called with policy CMP0022";
+ }
+ w << " set to OLD for target " << target->Target->GetName() << ". "
+ << "The export will only work with CMP0022 set to NEW.";
+ target->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+ }
+ if (!properties.empty()) {
+ os << "LOCAL_CPP_FEATURES := rtti exceptions\n";
+ for (ImportPropertyMap::const_iterator pi = properties.begin();
+ pi != properties.end(); ++pi) {
+ if (pi->first == "INTERFACE_COMPILE_OPTIONS") {
+ os << "LOCAL_CPP_FEATURES += ";
+ os << (pi->second) << "\n";
+ } else if (pi->first == "INTERFACE_LINK_LIBRARIES") {
+ // need to look at list in pi->second and see if static or shared
+ // FindTargetToLink
+ // target->GetLocalGenerator()->FindGeneratorTargetToUse()
+ // then add to LOCAL_CPPFLAGS
+ std::vector<std::string> libraries;
+ cmSystemTools::ExpandListArgument(pi->second, libraries);
+ std::string staticLibs;
+ std::string sharedLibs;
+ std::string ldlibs;
+ for (std::vector<std::string>::iterator i = libraries.begin();
+ i != libraries.end(); ++i) {
+ cmGeneratorTarget* gt =
+ target->GetLocalGenerator()->FindGeneratorTargetToUse(*i);
+ if (gt) {
+
+ if (gt->GetType() == cmState::SHARED_LIBRARY ||
+ gt->GetType() == cmState::MODULE_LIBRARY) {
+ sharedLibs += " " + *i;
+ } else {
+ staticLibs += " " + *i;
+ }
+ } else {
+ // evaluate any generator expressions with the current
+ // build type of the makefile
+ cmGeneratorExpression ge;
+ CM_AUTO_PTR<cmCompiledGeneratorExpression> cge = ge.Parse(*i);
+ std::string evaluated =
+ cge->Evaluate(target->GetLocalGenerator(), config);
+ bool relpath = false;
+ if (type == cmExportBuildAndroidMKGenerator::INSTALL) {
+ relpath = i->substr(0, 3) == "../";
+ }
+ // check for full path or if it already has a -l, or
+ // in the case of an install check for relative paths
+ // if it is full or a link library then use string directly
+ if (cmSystemTools::FileIsFullPath(evaluated) ||
+ evaluated.substr(0, 2) == "-l" || relpath) {
+ ldlibs += " " + evaluated;
+ // if it is not a path and does not have a -l then add -l
+ } else if (!evaluated.empty()) {
+ ldlibs += " -l" + evaluated;
+ }
+ }
+ }
+ if (!sharedLibs.empty()) {
+ os << "LOCAL_SHARED_LIBRARIES :=" << sharedLibs << "\n";
+ }
+ if (!staticLibs.empty()) {
+ os << "LOCAL_STATIC_LIBRARIES :=" << staticLibs << "\n";
+ }
+ if (!ldlibs.empty()) {
+ os << "LOCAL_EXPORT_LDLIBS :=" << ldlibs << "\n";
+ }
+ } else if (pi->first == "INTERFACE_INCLUDE_DIRECTORIES") {
+ std::string includes = pi->second;
+ std::vector<std::string> includeList;
+ cmSystemTools::ExpandListArgument(includes, includeList);
+ os << "LOCAL_EXPORT_C_INCLUDES := ";
+ std::string end;
+ for (std::vector<std::string>::iterator i = includeList.begin();
+ i != includeList.end(); ++i) {
+ os << end << *i;
+ end = "\\\n";
+ }
+ os << "\n";
+ } else {
+ os << "# " << pi->first << " " << (pi->second) << "\n";
+ }
+ }
+ }
+ switch (target->GetType()) {
+ case cmState::SHARED_LIBRARY:
+ case cmState::MODULE_LIBRARY:
+ os << "include $(PREBUILT_SHARED_LIBRARY)\n";
+ break;
+ case cmState::STATIC_LIBRARY:
+ os << "include $(PREBUILT_STATIC_LIBRARY)\n";
+ break;
+ case cmState::EXECUTABLE:
+ case cmState::UTILITY:
+ case cmState::OBJECT_LIBRARY:
+ case cmState::GLOBAL_TARGET:
+ case cmState::INTERFACE_LIBRARY:
+ case cmState::UNKNOWN_LIBRARY:
+ break;
+ }
+ os << "\n";
+}
diff --git a/Source/cmExportBuildAndroidMKGenerator.h b/Source/cmExportBuildAndroidMKGenerator.h
new file mode 100644
index 0000000..d15245e
--- /dev/null
+++ b/Source/cmExportBuildAndroidMKGenerator.h
@@ -0,0 +1,69 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmExportBuildAndroidMKGenerator_h
+#define cmExportBuildAndroidMKGenerator_h
+
+#include "cmExportBuildFileGenerator.h"
+#include "cmListFileCache.h"
+
+class cmExportSet;
+
+/** \class cmExportBuildAndroidMKGenerator
+ * \brief Generate a file exporting targets from a build tree.
+ *
+ * cmExportBuildAndroidMKGenerator generates a file exporting targets from
+ * a build tree. This exports the targets to the Android ndk build tool
+ * makefile format for prebuilt libraries.
+ *
+ * This is used to implement the EXPORT() command.
+ */
+class cmExportBuildAndroidMKGenerator : public cmExportBuildFileGenerator
+{
+public:
+ cmExportBuildAndroidMKGenerator();
+ // this is so cmExportInstallAndroidMKGenerator can share this
+ // function as they are almost the same
+ enum GenerateType
+ {
+ BUILD,
+ INSTALL
+ };
+ static void GenerateInterfaceProperties(cmGeneratorTarget const* target,
+ std::ostream& os,
+ const ImportPropertyMap& properties,
+ GenerateType type,
+ std::string const& config);
+
+protected:
+ // Implement virtual methods from the superclass.
+ void GeneratePolicyHeaderCode(std::ostream&) CM_OVERRIDE {}
+ void GeneratePolicyFooterCode(std::ostream&) CM_OVERRIDE {}
+ void GenerateImportHeaderCode(std::ostream& os,
+ const std::string& config = "") CM_OVERRIDE;
+ void GenerateImportFooterCode(std::ostream& os) CM_OVERRIDE;
+ void GenerateImportTargetCode(std::ostream& os,
+ const cmGeneratorTarget* target) CM_OVERRIDE;
+ void GenerateExpectedTargetsCode(
+ std::ostream& os, const std::string& expectedTargets) CM_OVERRIDE;
+ void GenerateImportPropertyCode(std::ostream& os, const std::string& config,
+ cmGeneratorTarget const* target,
+ ImportPropertyMap const& properties)
+ CM_OVERRIDE;
+ void GenerateMissingTargetsCheckCode(
+ std::ostream& os,
+ const std::vector<std::string>& missingTargets) CM_OVERRIDE;
+ void GenerateInterfaceProperties(
+ cmGeneratorTarget const* target, std::ostream& os,
+ const ImportPropertyMap& properties) CM_OVERRIDE;
+};
+
+#endif
diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx
index fc62492..466fad3 100644
--- a/Source/cmExportCommand.cxx
+++ b/Source/cmExportCommand.cxx
@@ -18,6 +18,7 @@
#include <cmsys/Encoding.hxx>
#include <cmsys/RegularExpression.hxx>
+#include "cmExportBuildAndroidMKGenerator.h"
#include "cmExportBuildFileGenerator.h"
#if defined(__HAIKU__)
@@ -34,6 +35,7 @@ cmExportCommand::cmExportCommand()
, Namespace(&Helper, "NAMESPACE", &ArgumentGroup)
, Filename(&Helper, "FILE", &ArgumentGroup)
, ExportOld(&Helper, "EXPORT_LINK_INTERFACE_LIBRARIES", &ArgumentGroup)
+ , AndroidMKFile(&Helper, "ANDROID_MK")
{
this->ExportSet = CM_NULLPTR;
}
@@ -49,7 +51,8 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args,
if (args[0] == "PACKAGE") {
return this->HandlePackage(args);
- } else if (args[0] == "EXPORT") {
+ }
+ if (args[0] == "EXPORT") {
this->ExportSetName.Follows(CM_NULLPTR);
this->ArgumentGroup.Follows(&this->ExportSetName);
} else {
@@ -66,13 +69,18 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args,
}
std::string fname;
- if (!this->Filename.WasFound()) {
+ bool android = false;
+ if (this->AndroidMKFile.WasFound()) {
+ fname = this->AndroidMKFile.GetString();
+ android = true;
+ }
+ if (!this->Filename.WasFound() && fname.empty()) {
if (args[0] != "EXPORT") {
this->SetError("FILE <filename> option missing.");
return false;
}
fname = this->ExportSetName.GetString() + ".cmake";
- } else {
+ } else if (fname.empty()) {
// Make sure the file has a .cmake extension.
if (cmSystemTools::GetFilenameLastExtension(this->Filename.GetCString()) !=
".cmake") {
@@ -176,7 +184,12 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args,
}
// Setup export file generation.
- cmExportBuildFileGenerator* ebfg = new cmExportBuildFileGenerator;
+ cmExportBuildFileGenerator* ebfg = CM_NULLPTR;
+ if (android) {
+ ebfg = new cmExportBuildAndroidMKGenerator;
+ } else {
+ ebfg = new cmExportBuildFileGenerator;
+ }
ebfg->SetExportFile(fname.c_str());
ebfg->SetNamespace(this->Namespace.GetCString());
ebfg->SetAppendMode(this->Append.IsEnabled());
diff --git a/Source/cmExportCommand.h b/Source/cmExportCommand.h
index 0a149af..481d2c5 100644
--- a/Source/cmExportCommand.h
+++ b/Source/cmExportCommand.h
@@ -54,6 +54,7 @@ private:
cmCAString Namespace;
cmCAString Filename;
cmCAEnabler ExportOld;
+ cmCAString AndroidMKFile;
cmExportSet* ExportSet;
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 23c77d9..c4c7d7d 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -96,24 +96,8 @@ bool cmExportFileGenerator::GenerateImportFile()
}
std::ostream& os = *foutPtr;
- // Protect that file against use with older CMake versions.
- /* clang-format off */
- os << "# Generated by CMake\n\n";
- os << "if(\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" LESS 2.5)\n"
- << " message(FATAL_ERROR \"CMake >= 2.6.0 required\")\n"
- << "endif()\n";
- /* clang-format on */
-
- // Isolate the file policy level.
- // We use 2.6 here instead of the current version because newer
- // versions of CMake should be able to export files imported by 2.6
- // until the import format changes.
- /* clang-format off */
- os << "cmake_policy(PUSH)\n"
- << "cmake_policy(VERSION 2.6)\n";
- /* clang-format on */
-
// Start with the import file header.
+ this->GeneratePolicyHeaderCode(os);
this->GenerateImportHeaderCode(os);
// Create all the imported targets.
@@ -121,7 +105,7 @@ bool cmExportFileGenerator::GenerateImportFile()
// End with the import file footer.
this->GenerateImportFooterCode(os);
- os << "cmake_policy(POP)\n";
+ this->GeneratePolicyFooterCode(os);
return result;
}
@@ -832,6 +816,31 @@ void cmExportFileGenerator::SetImportLinkProperty(
properties[prop] = link_entries;
}
+void cmExportFileGenerator::GeneratePolicyHeaderCode(std::ostream& os)
+{
+ // Protect that file against use with older CMake versions.
+ /* clang-format off */
+ os << "# Generated by CMake\n\n";
+ os << "if(\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" LESS 2.5)\n"
+ << " message(FATAL_ERROR \"CMake >= 2.6.0 required\")\n"
+ << "endif()\n";
+ /* clang-format on */
+
+ // Isolate the file policy level.
+ // We use 2.6 here instead of the current version because newer
+ // versions of CMake should be able to export files imported by 2.6
+ // until the import format changes.
+ /* clang-format off */
+ os << "cmake_policy(PUSH)\n"
+ << "cmake_policy(VERSION 2.6)\n";
+ /* clang-format on */
+}
+
+void cmExportFileGenerator::GeneratePolicyFooterCode(std::ostream& os)
+{
+ os << "cmake_policy(POP)\n";
+}
+
void cmExportFileGenerator::GenerateImportHeaderCode(std::ostream& os,
const std::string& config)
{
diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h
index 354994a..d106ab7 100644
--- a/Source/cmExportFileGenerator.h
+++ b/Source/cmExportFileGenerator.h
@@ -78,25 +78,28 @@ protected:
std::vector<std::string>& missingTargets);
// Methods to implement export file code generation.
- void GenerateImportHeaderCode(std::ostream& os,
- const std::string& config = "");
- void GenerateImportFooterCode(std::ostream& os);
+ virtual void GeneratePolicyHeaderCode(std::ostream& os);
+ virtual void GeneratePolicyFooterCode(std::ostream& os);
+ virtual void GenerateImportHeaderCode(std::ostream& os,
+ const std::string& config = "");
+ virtual void GenerateImportFooterCode(std::ostream& os);
void GenerateImportVersionCode(std::ostream& os);
- void GenerateImportTargetCode(std::ostream& os,
- cmGeneratorTarget const* target);
- void GenerateImportPropertyCode(std::ostream& os, const std::string& config,
- cmGeneratorTarget const* target,
- ImportPropertyMap const& properties);
- void GenerateImportedFileChecksCode(
+ virtual void GenerateImportTargetCode(std::ostream& os,
+ cmGeneratorTarget const* target);
+ virtual void GenerateImportPropertyCode(std::ostream& os,
+ const std::string& config,
+ cmGeneratorTarget const* target,
+ ImportPropertyMap const& properties);
+ virtual void GenerateImportedFileChecksCode(
std::ostream& os, cmGeneratorTarget* target,
ImportPropertyMap const& properties,
const std::set<std::string>& importedLocations);
- void GenerateImportedFileCheckLoop(std::ostream& os);
- void GenerateMissingTargetsCheckCode(
+ virtual void GenerateImportedFileCheckLoop(std::ostream& os);
+ virtual void GenerateMissingTargetsCheckCode(
std::ostream& os, const std::vector<std::string>& missingTargets);
- void GenerateExpectedTargetsCode(std::ostream& os,
- const std::string& expectedTargets);
+ virtual void GenerateExpectedTargetsCode(std::ostream& os,
+ const std::string& expectedTargets);
// Collect properties with detailed information about targets beyond
// their location on disk.
@@ -140,9 +143,9 @@ protected:
ImportPropertyMap& properties);
void PopulateCompatibleInterfaceProperties(cmGeneratorTarget* target,
ImportPropertyMap& properties);
- void GenerateInterfaceProperties(cmGeneratorTarget const* target,
- std::ostream& os,
- const ImportPropertyMap& properties);
+ virtual void GenerateInterfaceProperties(
+ cmGeneratorTarget const* target, std::ostream& os,
+ const ImportPropertyMap& properties);
void PopulateIncludeDirectoriesInterface(
cmTargetExport* target,
cmGeneratorExpression::PreprocessContext preprocessRule,
@@ -169,8 +172,8 @@ protected:
std::vector<std::string>& missingTargets,
FreeTargetsReplace replace = NoReplaceFreeTargets);
- void GenerateRequiredCMakeVersion(std::ostream& os,
- const char* versionString);
+ virtual void GenerateRequiredCMakeVersion(std::ostream& os,
+ const char* versionString);
// The namespace in which the exports are placed in the generated file.
std::string Namespace;
diff --git a/Source/cmExportInstallAndroidMKGenerator.cxx b/Source/cmExportInstallAndroidMKGenerator.cxx
new file mode 100644
index 0000000..10ba6ee
--- /dev/null
+++ b/Source/cmExportInstallAndroidMKGenerator.cxx
@@ -0,0 +1,146 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmExportInstallAndroidMKGenerator.h"
+
+#include "cmAlgorithms.h"
+#include "cmExportBuildAndroidMKGenerator.h"
+#include "cmExportSet.h"
+#include "cmExportSetMap.h"
+#include "cmGeneratedFileStream.h"
+#include "cmGeneratorTarget.h"
+#include "cmGlobalGenerator.h"
+#include "cmInstallExportGenerator.h"
+#include "cmInstallTargetGenerator.h"
+#include "cmLocalGenerator.h"
+#include "cmTargetExport.h"
+
+cmExportInstallAndroidMKGenerator::cmExportInstallAndroidMKGenerator(
+ cmInstallExportGenerator* iegen)
+ : cmExportInstallFileGenerator(iegen)
+{
+}
+
+void cmExportInstallAndroidMKGenerator::GenerateImportHeaderCode(
+ std::ostream& os, const std::string&)
+{
+ std::string installDir = this->IEGen->GetDestination();
+ os << "LOCAL_PATH := $(call my-dir)\n";
+ size_t numDotDot = cmSystemTools::CountChar(installDir.c_str(), '/');
+ numDotDot += (installDir.size() > 0) ? 1 : 0;
+ std::string path;
+ for (size_t n = 0; n < numDotDot; n++) {
+ path += "/..";
+ }
+ os << "_IMPORT_PREFIX := "
+ << "$(LOCAL_PATH)" << path << "\n\n";
+ for (std::vector<cmTargetExport*>::const_iterator tei =
+ this->IEGen->GetExportSet()->GetTargetExports()->begin();
+ tei != this->IEGen->GetExportSet()->GetTargetExports()->end(); ++tei) {
+ // Collect import properties for this target.
+ cmTargetExport const* te = *tei;
+ if (te->Target->GetType() == cmState::INTERFACE_LIBRARY) {
+ continue;
+ }
+ std::string dest;
+ if (te->LibraryGenerator) {
+ dest = te->LibraryGenerator->GetDestination("");
+ }
+ if (te->ArchiveGenerator) {
+ dest = te->ArchiveGenerator->GetDestination("");
+ }
+ te->Target->Target->SetProperty("__dest", dest.c_str());
+ }
+}
+
+void cmExportInstallAndroidMKGenerator::GenerateImportFooterCode(std::ostream&)
+{
+}
+
+void cmExportInstallAndroidMKGenerator::GenerateImportTargetCode(
+ std::ostream& os, const cmGeneratorTarget* target)
+{
+ std::string targetName = this->Namespace;
+ targetName += target->GetExportName();
+ os << "include $(CLEAR_VARS)\n";
+ os << "LOCAL_MODULE := ";
+ os << targetName << "\n";
+ os << "LOCAL_SRC_FILES := $(_IMPORT_PREFIX)/";
+ os << target->Target->GetProperty("__dest") << "/";
+ std::string config = "";
+ if (!this->Configurations.empty()) {
+ config = this->Configurations[0];
+ }
+ os << target->GetFullName(config) << "\n";
+}
+
+void cmExportInstallAndroidMKGenerator::GenerateExpectedTargetsCode(
+ std::ostream&, const std::string&)
+{
+}
+
+void cmExportInstallAndroidMKGenerator::GenerateImportPropertyCode(
+ std::ostream&, const std::string&, cmGeneratorTarget const*,
+ ImportPropertyMap const&)
+{
+}
+
+void cmExportInstallAndroidMKGenerator::GenerateMissingTargetsCheckCode(
+ std::ostream&, const std::vector<std::string>&)
+{
+}
+
+void cmExportInstallAndroidMKGenerator::GenerateInterfaceProperties(
+ cmGeneratorTarget const* target, std::ostream& os,
+ const ImportPropertyMap& properties)
+{
+ std::string config = "";
+ if (!this->Configurations.empty()) {
+ config = this->Configurations[0];
+ }
+ cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
+ target, os, properties, cmExportBuildAndroidMKGenerator::INSTALL, config);
+}
+
+void cmExportInstallAndroidMKGenerator::LoadConfigFiles(std::ostream&)
+{
+}
+
+void cmExportInstallAndroidMKGenerator::GenerateImportPrefix(std::ostream&)
+{
+}
+
+void cmExportInstallAndroidMKGenerator::GenerateRequiredCMakeVersion(
+ std::ostream&, const char*)
+{
+}
+
+void cmExportInstallAndroidMKGenerator::CleanupTemporaryVariables(
+ std::ostream&)
+{
+}
+
+void cmExportInstallAndroidMKGenerator::GenerateImportedFileCheckLoop(
+ std::ostream&)
+{
+}
+
+void cmExportInstallAndroidMKGenerator::GenerateImportedFileChecksCode(
+ std::ostream&, cmGeneratorTarget*, ImportPropertyMap const&,
+ const std::set<std::string>&)
+{
+}
+
+bool cmExportInstallAndroidMKGenerator::GenerateImportFileConfig(
+ const std::string&, std::vector<std::string>&)
+{
+ return true;
+}
diff --git a/Source/cmExportInstallAndroidMKGenerator.h b/Source/cmExportInstallAndroidMKGenerator.h
new file mode 100644
index 0000000..ccfe6f8
--- /dev/null
+++ b/Source/cmExportInstallAndroidMKGenerator.h
@@ -0,0 +1,73 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmExportInstallAndroidMKGenerator_h
+#define cmExportInstallAndroidMKGenerator_h
+
+#include "cmExportInstallFileGenerator.h"
+
+class cmInstallExportGenerator;
+class cmInstallTargetGenerator;
+
+/** \class cmExportInstallAndroidMKGenerator
+ * \brief Generate a file exporting targets from an install tree.
+ *
+ * cmExportInstallAndroidMKGenerator generates files exporting targets from
+ * install an installation tree. The files are placed in a temporary
+ * location for installation by cmInstallExportGenerator. The file format
+ * is for the ndk build system and is a makefile fragment specifing prebuilt
+ * libraries to the ndk build system.
+ *
+ * This is used to implement the INSTALL(EXPORT_ANDROID_MK) command.
+ */
+class cmExportInstallAndroidMKGenerator : public cmExportInstallFileGenerator
+{
+public:
+ /** Construct with the export installer that will install the
+ files. */
+ cmExportInstallAndroidMKGenerator(cmInstallExportGenerator* iegen);
+
+protected:
+ // Implement virtual methods from the superclass.
+ void GeneratePolicyHeaderCode(std::ostream&) CM_OVERRIDE {}
+ void GeneratePolicyFooterCode(std::ostream&) CM_OVERRIDE {}
+ void GenerateImportHeaderCode(std::ostream& os,
+ const std::string& config = "") CM_OVERRIDE;
+ void GenerateImportFooterCode(std::ostream& os) CM_OVERRIDE;
+ void GenerateImportTargetCode(std::ostream& os,
+ const cmGeneratorTarget* target) CM_OVERRIDE;
+ void GenerateExpectedTargetsCode(
+ std::ostream& os, const std::string& expectedTargets) CM_OVERRIDE;
+ void GenerateImportPropertyCode(std::ostream& os, const std::string& config,
+ cmGeneratorTarget const* target,
+ ImportPropertyMap const& properties)
+ CM_OVERRIDE;
+ void GenerateMissingTargetsCheckCode(
+ std::ostream& os,
+ const std::vector<std::string>& missingTargets) CM_OVERRIDE;
+ void GenerateInterfaceProperties(
+ cmGeneratorTarget const* target, std::ostream& os,
+ const ImportPropertyMap& properties) CM_OVERRIDE;
+ void GenerateImportPrefix(std::ostream& os) CM_OVERRIDE;
+ void LoadConfigFiles(std::ostream&) CM_OVERRIDE;
+ void GenerateRequiredCMakeVersion(std::ostream& os,
+ const char* versionString) CM_OVERRIDE;
+ void CleanupTemporaryVariables(std::ostream&) CM_OVERRIDE;
+ void GenerateImportedFileCheckLoop(std::ostream& os) CM_OVERRIDE;
+ void GenerateImportedFileChecksCode(
+ std::ostream& os, cmGeneratorTarget* target,
+ ImportPropertyMap const& properties,
+ const std::set<std::string>& importedLocations) CM_OVERRIDE;
+ bool GenerateImportFileConfig(const std::string& config,
+ std::vector<std::string>&) CM_OVERRIDE;
+};
+
+#endif
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index bcadaa0..f47038f 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -75,58 +75,8 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
this->GenerateExpectedTargetsCode(os, expectedTargets);
}
- // Set an _IMPORT_PREFIX variable for import location properties
- // to reference if they are relative to the install prefix.
- std::string installPrefix =
- this->IEGen->GetLocalGenerator()->GetMakefile()->GetSafeDefinition(
- "CMAKE_INSTALL_PREFIX");
- std::string const& expDest = this->IEGen->GetDestination();
- if (cmSystemTools::FileIsFullPath(expDest)) {
- // The export file is being installed to an absolute path so the
- // package is not relocatable. Use the configured install prefix.
- /* clang-format off */
- os <<
- "# The installation prefix configured by this project.\n"
- "set(_IMPORT_PREFIX \"" << installPrefix << "\")\n"
- "\n";
- /* clang-format on */
- } else {
- // Add code to compute the installation prefix relative to the
- // import file location.
- std::string absDest = installPrefix + "/" + expDest;
- std::string absDestS = absDest + "/";
- os << "# Compute the installation prefix relative to this file.\n"
- << "get_filename_component(_IMPORT_PREFIX"
- << " \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n";
- if (cmHasLiteralPrefix(absDestS.c_str(), "/lib/") ||
- cmHasLiteralPrefix(absDestS.c_str(), "/lib64/") ||
- cmHasLiteralPrefix(absDestS.c_str(), "/usr/lib/") ||
- cmHasLiteralPrefix(absDestS.c_str(), "/usr/lib64/")) {
- // Handle "/usr move" symlinks created by some Linux distros.
- /* clang-format off */
- os <<
- "# Use original install prefix when loaded through a\n"
- "# cross-prefix symbolic link such as /lib -> /usr/lib.\n"
- "get_filename_component(_realCurr \"${_IMPORT_PREFIX}\" REALPATH)\n"
- "get_filename_component(_realOrig \"" << absDest << "\" REALPATH)\n"
- "if(_realCurr STREQUAL _realOrig)\n"
- " set(_IMPORT_PREFIX \"" << absDest << "\")\n"
- "endif()\n"
- "unset(_realOrig)\n"
- "unset(_realCurr)\n";
- /* clang-format on */
- }
- std::string dest = expDest;
- while (!dest.empty()) {
- os << "get_filename_component(_IMPORT_PREFIX \"${_IMPORT_PREFIX}\" "
- "PATH)\n";
- dest = cmSystemTools::GetFilenamePath(dest);
- }
- os << "if(_IMPORT_PREFIX STREQUAL \"/\")\n"
- << " set(_IMPORT_PREFIX \"\")\n"
- << "endif()\n"
- << "\n";
- }
+ // Compute the relative import prefix for the file
+ this->GenerateImportPrefix(os);
std::vector<std::string> missingTargets;
@@ -204,24 +154,9 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
this->GenerateRequiredCMakeVersion(os, "2.8.12");
}
- // Now load per-configuration properties for them.
- /* clang-format off */
- os << "# Load information for each installed configuration.\n"
- << "get_filename_component(_DIR \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n"
- << "file(GLOB CONFIG_FILES \"${_DIR}/"
- << this->GetConfigImportFileGlob() << "\")\n"
- << "foreach(f ${CONFIG_FILES})\n"
- << " include(${f})\n"
- << "endforeach()\n"
- << "\n";
- /* clang-format on */
+ this->LoadConfigFiles(os);
- // Cleanup the import prefix variable.
- /* clang-format off */
- os << "# Cleanup temporary variables.\n"
- << "set(_IMPORT_PREFIX)\n"
- << "\n";
- /* clang-format on */
+ this->CleanupTemporaryVariables(os);
this->GenerateImportedFileCheckLoop(os);
bool result = true;
@@ -242,6 +177,86 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
return result;
}
+void cmExportInstallFileGenerator::GenerateImportPrefix(std::ostream& os)
+{
+ // Set an _IMPORT_PREFIX variable for import location properties
+ // to reference if they are relative to the install prefix.
+ std::string installPrefix =
+ this->IEGen->GetLocalGenerator()->GetMakefile()->GetSafeDefinition(
+ "CMAKE_INSTALL_PREFIX");
+ std::string const& expDest = this->IEGen->GetDestination();
+ if (cmSystemTools::FileIsFullPath(expDest)) {
+ // The export file is being installed to an absolute path so the
+ // package is not relocatable. Use the configured install prefix.
+ /* clang-format off */
+ os <<
+ "# The installation prefix configured by this project.\n"
+ "set(_IMPORT_PREFIX \"" << installPrefix << "\")\n"
+ "\n";
+ /* clang-format on */
+ } else {
+ // Add code to compute the installation prefix relative to the
+ // import file location.
+ std::string absDest = installPrefix + "/" + expDest;
+ std::string absDestS = absDest + "/";
+ os << "# Compute the installation prefix relative to this file.\n"
+ << "get_filename_component(_IMPORT_PREFIX"
+ << " \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n";
+ if (cmHasLiteralPrefix(absDestS.c_str(), "/lib/") ||
+ cmHasLiteralPrefix(absDestS.c_str(), "/lib64/") ||
+ cmHasLiteralPrefix(absDestS.c_str(), "/usr/lib/") ||
+ cmHasLiteralPrefix(absDestS.c_str(), "/usr/lib64/")) {
+ // Handle "/usr move" symlinks created by some Linux distros.
+ /* clang-format off */
+ os <<
+ "# Use original install prefix when loaded through a\n"
+ "# cross-prefix symbolic link such as /lib -> /usr/lib.\n"
+ "get_filename_component(_realCurr \"${_IMPORT_PREFIX}\" REALPATH)\n"
+ "get_filename_component(_realOrig \"" << absDest << "\" REALPATH)\n"
+ "if(_realCurr STREQUAL _realOrig)\n"
+ " set(_IMPORT_PREFIX \"" << absDest << "\")\n"
+ "endif()\n"
+ "unset(_realOrig)\n"
+ "unset(_realCurr)\n";
+ /* clang-format on */
+ }
+ std::string dest = expDest;
+ while (!dest.empty()) {
+ os << "get_filename_component(_IMPORT_PREFIX \"${_IMPORT_PREFIX}\" "
+ "PATH)\n";
+ dest = cmSystemTools::GetFilenamePath(dest);
+ }
+ os << "if(_IMPORT_PREFIX STREQUAL \"/\")\n"
+ << " set(_IMPORT_PREFIX \"\")\n"
+ << "endif()\n"
+ << "\n";
+ }
+}
+
+void cmExportInstallFileGenerator::CleanupTemporaryVariables(std::ostream& os)
+{
+ /* clang-format off */
+ os << "# Cleanup temporary variables.\n"
+ << "set(_IMPORT_PREFIX)\n"
+ << "\n";
+ /* clang-format on */
+}
+
+void cmExportInstallFileGenerator::LoadConfigFiles(std::ostream& os)
+{
+ // Now load per-configuration properties for them.
+ /* clang-format off */
+ os << "# Load information for each installed configuration.\n"
+ << "get_filename_component(_DIR \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n"
+ << "file(GLOB CONFIG_FILES \"${_DIR}/"
+ << this->GetConfigImportFileGlob() << "\")\n"
+ << "foreach(f ${CONFIG_FILES})\n"
+ << " include(${f})\n"
+ << "endforeach()\n"
+ << "\n";
+ /* clang-format on */
+}
+
void cmExportInstallFileGenerator::ReplaceInstallPrefix(std::string& input)
{
std::string::size_type pos = 0;
diff --git a/Source/cmExportInstallFileGenerator.h b/Source/cmExportInstallFileGenerator.h
index c693dc1..63f2d40 100644
--- a/Source/cmExportInstallFileGenerator.h
+++ b/Source/cmExportInstallFileGenerator.h
@@ -80,9 +80,17 @@ protected:
std::vector<std::string> FindNamespaces(cmGlobalGenerator* gg,
const std::string& name);
+ /** Generate the relative import prefix. */
+ virtual void GenerateImportPrefix(std::ostream&);
+
+ /** Generate the relative import prefix. */
+ virtual void LoadConfigFiles(std::ostream&);
+
+ virtual void CleanupTemporaryVariables(std::ostream&);
+
/** Generate a per-configuration file for the targets. */
- bool GenerateImportFileConfig(const std::string& config,
- std::vector<std::string>& missingTargets);
+ virtual bool GenerateImportFileConfig(
+ const std::string& config, std::vector<std::string>& missingTargets);
/** Fill in properties indicating installed file locations. */
void SetImportLocationProperty(const std::string& config,
diff --git a/Source/cmExportLibraryDependenciesCommand.cxx b/Source/cmExportLibraryDependenciesCommand.cxx
index b422a2c..350c855 100644
--- a/Source/cmExportLibraryDependenciesCommand.cxx
+++ b/Source/cmExportLibraryDependenciesCommand.cxx
@@ -27,7 +27,7 @@ bool cmExportLibraryDependenciesCommand::InitialPass(
"see CMP0033.")) {
return true;
}
- if (args.size() < 1) {
+ if (args.empty()) {
this->SetError("called with incorrect number of arguments");
return false;
}
@@ -64,7 +64,7 @@ void cmExportLibraryDependenciesCommand::ConstFinalPass() const
ap->SetCopyIfDifferent(true);
foutPtr = ap;
}
- std::ostream& fout = *foutPtr.get();
+ std::ostream& fout = *foutPtr;
if (!fout) {
cmSystemTools::Error("Error Writing ", this->Filename.c_str());
diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx
index a0aefb8..6c31481 100644
--- a/Source/cmExportTryCompileFileGenerator.cxx
+++ b/Source/cmExportTryCompileFileGenerator.cxx
@@ -77,9 +77,8 @@ std::string cmExportTryCompileFileGenerator::FindTargets(
CM_AUTO_PTR<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
- cmTarget dummyHead;
- dummyHead.SetType(cmState::EXECUTABLE, "try_compile_dummy_exe");
- dummyHead.SetMakefile(tgt->Target->GetMakefile());
+ cmTarget dummyHead("try_compile_dummy_exe", cmState::EXECUTABLE,
+ cmTarget::VisibilityNormal, tgt->Target->GetMakefile());
cmGeneratorTarget gDummyHead(&dummyHead, tgt->GetLocalGenerator());
diff --git a/Source/cmExternalMakefileProjectGenerator.h b/Source/cmExternalMakefileProjectGenerator.h
index b306f19..aa614fc 100644
--- a/Source/cmExternalMakefileProjectGenerator.h
+++ b/Source/cmExternalMakefileProjectGenerator.h
@@ -108,7 +108,7 @@ public:
}
cmExternalMakefileProjectGenerator* CreateExternalMakefileProjectGenerator()
- const
+ const CM_OVERRIDE
{
T* p = new T;
p->SetName(GetName());
diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx
index 5a98e34..61f2851 100644
--- a/Source/cmExtraEclipseCDT4Generator.cxx
+++ b/Source/cmExtraEclipseCDT4Generator.cxx
@@ -914,7 +914,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
const std::vector<cmGeneratorTarget*> targets =
(*it)->GetGeneratorTargets();
std::string subdir = (*it)->ConvertToRelativePath(
- (*it)->GetCurrentBinaryDirectory(), cmOutputConverter::HOME_OUTPUT);
+ this->HomeOutputDirectory, (*it)->GetCurrentBinaryDirectory());
if (subdir == ".") {
subdir = "";
}
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 835b118..a13309d 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -104,19 +104,25 @@ bool cmFileCommand::InitialPass(std::vector<std::string> const& args,
std::string subCommand = args[0];
if (subCommand == "WRITE") {
return this->HandleWriteCommand(args, false);
- } else if (subCommand == "APPEND") {
+ }
+ if (subCommand == "APPEND") {
return this->HandleWriteCommand(args, true);
- } else if (subCommand == "DOWNLOAD") {
+ }
+ if (subCommand == "DOWNLOAD") {
return this->HandleDownloadCommand(args);
- } else if (subCommand == "UPLOAD") {
+ }
+ if (subCommand == "UPLOAD") {
return this->HandleUploadCommand(args);
- } else if (subCommand == "READ") {
+ }
+ if (subCommand == "READ") {
return this->HandleReadCommand(args);
- } else if (subCommand == "MD5" || subCommand == "SHA1" ||
- subCommand == "SHA224" || subCommand == "SHA256" ||
- subCommand == "SHA384" || subCommand == "SHA512") {
+ }
+ if (subCommand == "MD5" || subCommand == "SHA1" || subCommand == "SHA224" ||
+ subCommand == "SHA256" || subCommand == "SHA384" ||
+ subCommand == "SHA512") {
return this->HandleHashCommand(args);
- } else if (subCommand == "STRINGS") {
+ }
+ if (subCommand == "STRINGS") {
return this->HandleStringsCommand(args);
} else if (subCommand == "GLOB") {
return this->HandleGlobCommand(args, false);
@@ -594,8 +600,9 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
// how many octets are there?
unsigned int num_utf8_bytes = 0;
for (unsigned int j = 0; num_utf8_bytes == 0 && j < 3; j++) {
- if ((c & utf8_check_table[j][0]) == utf8_check_table[j][1])
+ if ((c & utf8_check_table[j][0]) == utf8_check_table[j][1]) {
num_utf8_bytes = j + 2;
+ }
}
// get subsequent octets and check that they are valid
@@ -1408,11 +1415,14 @@ bool cmFileCopier::Install(const char* fromFile, const char* toFile)
if (cmSystemTools::SameFile(fromFile, toFile)) {
return true;
- } else if (cmSystemTools::FileIsSymlink(fromFile)) {
+ }
+ if (cmSystemTools::FileIsSymlink(fromFile)) {
return this->InstallSymlink(fromFile, toFile);
- } else if (cmSystemTools::FileIsDirectory(fromFile)) {
+ }
+ if (cmSystemTools::FileIsDirectory(fromFile)) {
return this->InstallDirectory(fromFile, toFile, match_properties);
- } else if (cmSystemTools::FileExists(fromFile)) {
+ }
+ if (cmSystemTools::FileExists(fromFile)) {
return this->InstallFile(fromFile, toFile, match_properties);
}
return this->ReportMissing(fromFile);
@@ -2481,6 +2491,9 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
std::string hashMatchMSG;
CM_AUTO_PTR<cmCryptoHash> hash;
bool showProgress = false;
+ std::string userpwd;
+
+ std::list<std::string> curl_headers;
while (i != args.end()) {
if (*i == "TIMEOUT") {
@@ -2564,6 +2577,25 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
return false;
}
hashMatchMSG = algo + " hash";
+ } else if (*i == "USERPWD") {
+ ++i;
+ if (i == args.end()) {
+ this->SetError("DOWNLOAD missing string for USERPWD.");
+ return false;
+ }
+ userpwd = *i;
+ } else if (*i == "HTTPHEADER") {
+ ++i;
+ if (i == args.end()) {
+ this->SetError("DOWNLOAD missing string for HTTPHEADER.");
+ return false;
+ }
+ curl_headers.push_back(*i);
+ } else {
+ // Do not return error for compatibility reason.
+ std::string err = "Unexpected argument: ";
+ err += *i;
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, err.c_str());
}
++i;
}
@@ -2698,8 +2730,22 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
check_curl_result(res, "DOWNLOAD cannot set progress data: ");
}
+ if (!userpwd.empty()) {
+ res = ::curl_easy_setopt(curl, CURLOPT_USERPWD, userpwd.c_str());
+ check_curl_result(res, "DOWNLOAD cannot set user password: ");
+ }
+
+ struct curl_slist* headers = CM_NULLPTR;
+ for (std::list<std::string>::const_iterator h = curl_headers.begin();
+ h != curl_headers.end(); ++h) {
+ headers = ::curl_slist_append(headers, h->c_str());
+ }
+ ::curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
+
res = ::curl_easy_perform(curl);
+ ::curl_slist_free_all(headers);
+
/* always cleanup */
g_curl.release();
::curl_easy_cleanup(curl);
@@ -2778,6 +2824,9 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
std::string logVar;
std::string statusVar;
bool showProgress = false;
+ std::string userpwd;
+
+ std::list<std::string> curl_headers;
while (i != args.end()) {
if (*i == "TIMEOUT") {
@@ -2812,6 +2861,25 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
statusVar = *i;
} else if (*i == "SHOW_PROGRESS") {
showProgress = true;
+ } else if (*i == "USERPWD") {
+ ++i;
+ if (i == args.end()) {
+ this->SetError("UPLOAD missing string for USERPWD.");
+ return false;
+ }
+ userpwd = *i;
+ } else if (*i == "HTTPHEADER") {
+ ++i;
+ if (i == args.end()) {
+ this->SetError("UPLOAD missing string for HTTPHEADER.");
+ return false;
+ }
+ curl_headers.push_back(*i);
+ } else {
+ // Do not return error for compatibility reason.
+ std::string err = "Unexpected argument: ";
+ err += *i;
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, err.c_str());
}
++i;
@@ -2920,8 +2988,22 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
::curl_easy_setopt(curl, CURLOPT_INFILESIZE, static_cast<long>(file_size));
check_curl_result(res, "UPLOAD cannot set input file size: ");
+ if (!userpwd.empty()) {
+ res = ::curl_easy_setopt(curl, CURLOPT_USERPWD, userpwd.c_str());
+ check_curl_result(res, "UPLOAD cannot set user password: ");
+ }
+
+ struct curl_slist* headers = CM_NULLPTR;
+ for (std::list<std::string>::const_iterator h = curl_headers.begin();
+ h != curl_headers.end(); ++h) {
+ headers = ::curl_slist_append(headers, h->c_str());
+ }
+ ::curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
+
res = ::curl_easy_perform(curl);
+ ::curl_slist_free_all(headers);
+
/* always cleanup */
g_curl.release();
::curl_easy_cleanup(curl);
@@ -3057,20 +3139,20 @@ bool cmFileCommand::HandleLockCommand(std::vector<std::string> const& args)
if (i >= args.size()) {
this->Makefile->IssueMessage(cmake::FATAL_ERROR, merr);
return false;
+ }
+ if (args[i] == "FUNCTION") {
+ guard = GUARD_FUNCTION;
+ } else if (args[i] == "FILE") {
+ guard = GUARD_FILE;
+ } else if (args[i] == "PROCESS") {
+ guard = GUARD_PROCESS;
} else {
- if (args[i] == "FUNCTION") {
- guard = GUARD_FUNCTION;
- } else if (args[i] == "FILE") {
- guard = GUARD_FILE;
- } else if (args[i] == "PROCESS") {
- guard = GUARD_PROCESS;
- } else {
- std::ostringstream e;
- e << merr << ", but got:\n \"" << args[i] << "\".";
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
- return false;
- }
+ std::ostringstream e;
+ e << merr << ", but got:\n \"" << args[i] << "\".";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
}
+
} else if (args[i] == "RESULT_VARIABLE") {
++i;
if (i >= args.size()) {
@@ -3187,7 +3269,8 @@ bool cmFileCommand::HandleTimestampCommand(
if (args.size() < 3) {
this->SetError("sub-command TIMESTAMP requires at least two arguments.");
return false;
- } else if (args.size() > 5) {
+ }
+ if (args.size() > 5) {
this->SetError("sub-command TIMESTAMP takes at most four arguments.");
return false;
}
diff --git a/Source/cmFileLockUnix.cxx b/Source/cmFileLockUnix.cxx
index 6be6abc..64ced9e 100644
--- a/Source/cmFileLockUnix.cxx
+++ b/Source/cmFileLockUnix.cxx
@@ -37,9 +37,8 @@ cmFileLockResult cmFileLock::Release()
if (lockResult == 0) {
return cmFileLockResult::MakeOk();
- } else {
- return cmFileLockResult::MakeSystem();
}
+ return cmFileLockResult::MakeSystem();
}
cmFileLockResult cmFileLock::OpenFile()
@@ -47,18 +46,16 @@ cmFileLockResult cmFileLock::OpenFile()
this->File = ::open(this->Filename.c_str(), O_RDWR);
if (this->File == -1) {
return cmFileLockResult::MakeSystem();
- } else {
- return cmFileLockResult::MakeOk();
}
+ return cmFileLockResult::MakeOk();
}
cmFileLockResult cmFileLock::LockWithoutTimeout()
{
if (this->LockFile(F_SETLKW, F_WRLCK) == -1) {
return cmFileLockResult::MakeSystem();
- } else {
- return cmFileLockResult::MakeOk();
}
+ return cmFileLockResult::MakeOk();
}
cmFileLockResult cmFileLock::LockWithTimeout(unsigned long seconds)
diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx
index c785e6c..fb95152 100644
--- a/Source/cmFindBase.cxx
+++ b/Source/cmFindBase.cxx
@@ -321,7 +321,8 @@ bool cmFindBase::CheckForVariableInCache()
this->AlreadyInCacheWithoutMetaInfo = true;
}
return true;
- } else if (cached) {
+ }
+ if (cached) {
const char* hs =
state->GetCacheEntryProperty(this->VariableName, "HELPSTRING");
this->VariableDocumentation = hs ? hs : "(none)";
diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx
index 3094fcf..0fd56b5 100644
--- a/Source/cmFindLibraryCommand.cxx
+++ b/Source/cmFindLibraryCommand.cxx
@@ -378,9 +378,8 @@ std::string cmFindLibraryCommand::FindNormalLibrary()
{
if (this->NamesPerDir) {
return this->FindNormalLibraryNamesPerDir();
- } else {
- return this->FindNormalLibraryDirsPerName();
}
+ return this->FindNormalLibraryDirsPerName();
}
std::string cmFindLibraryCommand::FindNormalLibraryNamesPerDir()
@@ -428,9 +427,8 @@ std::string cmFindLibraryCommand::FindFrameworkLibrary()
{
if (this->NamesPerDir) {
return this->FindFrameworkLibraryNamesPerDir();
- } else {
- return this->FindFrameworkLibraryDirsPerName();
}
+ return this->FindFrameworkLibraryDirsPerName();
}
std::string cmFindLibraryCommand::FindFrameworkLibraryNamesPerDir()
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 8338c2a..8b7bee2 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -12,6 +12,7 @@
#include "cmFindPackageCommand.h"
#include "cmAlgorithms.h"
+#include <cmSystemTools.h>
#include <cmsys/Directory.hxx>
#include <cmsys/Encoding.hxx>
#include <cmsys/RegularExpression.hxx>
@@ -33,6 +34,45 @@ cmFindPackageCommand::PathLabel cmFindPackageCommand::PathLabel::Builds(
cmFindPackageCommand::PathLabel
cmFindPackageCommand::PathLabel::SystemRegistry("SYSTEM_PACKAGE_REGISTRY");
+struct StrverscmpGreater
+{
+ bool operator()(const std::string& lhs, const std::string& rhs) const
+ {
+ return cmSystemTools::strverscmp(lhs, rhs) > 0;
+ }
+};
+
+struct StrverscmpLesser
+{
+ bool operator()(const std::string& lhs, const std::string& rhs) const
+ {
+ return cmSystemTools::strverscmp(lhs, rhs) < 0;
+ }
+};
+
+void cmFindPackageCommand::Sort(std::vector<std::string>::iterator begin,
+ std::vector<std::string>::iterator end,
+ SortOrderType order, SortDirectionType dir)
+{
+ if (order == Name_order) {
+ if (dir == Dec) {
+ std::sort(begin, end, std::greater<std::string>());
+ } else {
+ std::sort(begin, end);
+ }
+ } else if (order == Natural)
+ // natural order uses letters and numbers (contiguous numbers digit are
+ // compared such that e.g. 000 00 < 01 < 010 < 09 < 0 < 1 < 9 < 10
+ {
+ if (dir == Dec) {
+ std::sort(begin, end, StrverscmpGreater());
+ } else {
+ std::sort(begin, end, StrverscmpLesser());
+ }
+ }
+ // else do not sort
+}
+
cmFindPackageCommand::cmFindPackageCommand()
{
this->CMakePathName = "PACKAGE";
@@ -58,7 +98,8 @@ cmFindPackageCommand::cmFindPackageCommand()
this->VersionFoundTweak = 0;
this->VersionFoundCount = 0;
this->RequiredCMakeVersion = 0;
-
+ this->SortOrder = None;
+ this->SortDirection = Asc;
this->AppendSearchPathGroups();
}
@@ -89,7 +130,7 @@ void cmFindPackageCommand::AppendSearchPathGroups()
bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&)
{
- if (args.size() < 1) {
+ if (args.empty()) {
this->SetError("called with incorrect number of arguments");
return false;
}
@@ -135,6 +176,23 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args,
this->NoSystemRegistry = true;
}
+ // Check if Sorting should be enabled
+ if (const char* so =
+ this->Makefile->GetDefinition("CMAKE_FIND_PACKAGE_SORT_ORDER")) {
+
+ if (strcmp(so, "NAME") == 0) {
+ this->SortOrder = Name_order;
+ } else if (strcmp(so, "NATURAL") == 0) {
+ this->SortOrder = Natural;
+ } else {
+ this->SortOrder = None;
+ }
+ }
+ if (const char* sd =
+ this->Makefile->GetDefinition("CMAKE_FIND_PACKAGE_SORT_DIRECTION")) {
+ this->SortDirection = strcmp(sd, "ASC") == 0 ? Asc : Dec;
+ }
+
// Find the current root path mode.
this->SelectDefaultRootPathMode();
@@ -1250,18 +1308,16 @@ bool cmFindPackageCommand::CheckPackageRegistryEntry(const std::string& fname,
outPaths.AddPath(fname);
}
return true;
- } else {
- // The path does not exist. Assume the stream content is
- // associated with an old package that no longer exists, and
- // delete it to keep the package registry clean.
- return false;
}
- } else {
- // The first line in the stream is not the full path to a file or
- // directory. Assume the stream content was created by a future
- // version of CMake that uses a different format, and leave it.
- return true;
+ // The path does not exist. Assume the stream content is
+ // associated with an old package that no longer exists, and
+ // delete it to keep the package registry clean.
+ return false;
}
+ // The first line in the stream is not the full path to a file or
+ // directory. Assume the stream content was created by a future
+ // version of CMake that uses a different format, and leave it.
+ return true;
}
void cmFindPackageCommand::FillPrefixesCMakeSystemVariable()
@@ -1570,9 +1626,8 @@ private:
{
if (this->UseSuffixes) {
return this->FPC->SearchDirectory(fullPath);
- } else {
- return this->FPC->CheckDirectory(fullPath);
}
+ return this->FPC->CheckDirectory(fullPath);
}
cmFindPackageCommand* FPC;
bool UseSuffixes;
@@ -1595,9 +1650,8 @@ bool cmFileListGeneratorBase::Consider(std::string const& fullPath,
{
if (this->Next.get()) {
return this->Next->Search(fullPath + "/", listing);
- } else {
- return listing.Visit(fullPath + "/");
}
+ return listing.Visit(fullPath + "/");
}
class cmFileListGeneratorFixed : public cmFileListGeneratorBase
@@ -1666,17 +1720,33 @@ private:
class cmFileListGeneratorProject : public cmFileListGeneratorBase
{
public:
- cmFileListGeneratorProject(std::vector<std::string> const& names)
+ cmFileListGeneratorProject(std::vector<std::string> const& names,
+ cmFindPackageCommand::SortOrderType so,
+ cmFindPackageCommand::SortDirectionType sd)
: cmFileListGeneratorBase()
, Names(names)
{
+ this->SetSort(so, sd);
}
cmFileListGeneratorProject(cmFileListGeneratorProject const& r)
: cmFileListGeneratorBase()
, Names(r.Names)
{
+ this->SetSort(r.SortOrder, r.SortDirection);
+ }
+
+ void SetSort(cmFindPackageCommand::SortOrderType o,
+ cmFindPackageCommand::SortDirectionType d)
+ {
+ SortOrder = o;
+ SortDirection = d;
}
+protected:
+ // sort parameters
+ cmFindPackageCommand::SortOrderType SortOrder;
+ cmFindPackageCommand::SortDirectionType SortDirection;
+
private:
std::vector<std::string> const& Names;
bool Search(std::string const& parent, cmFileList& lister) CM_OVERRIDE
@@ -1698,6 +1768,13 @@ private:
}
}
+ // before testing the matches check if there is a specific sorting order to
+ // perform
+ if (this->SortOrder != cmFindPackageCommand::None) {
+ cmFindPackageCommand::Sort(matches.begin(), matches.end(), SortOrder,
+ SortDirection);
+ }
+
for (std::vector<std::string>::const_iterator i = matches.begin();
i != matches.end(); ++i) {
if (this->Consider(parent + *i, lister)) {
@@ -1895,7 +1972,8 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
{
cmFindPackageFileList lister(this);
lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorProject(this->Names);
+ cmFileListGeneratorProject(this->Names, this->SortOrder,
+ this->SortDirection);
if (lister.Search()) {
return true;
}
@@ -1905,7 +1983,8 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
{
cmFindPackageFileList lister(this);
lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorProject(this->Names) /
+ cmFileListGeneratorProject(this->Names, this->SortOrder,
+ this->SortDirection) /
cmFileListGeneratorCaseInsensitive("cmake");
if (lister.Search()) {
return true;
@@ -1932,7 +2011,8 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
lister / cmFileListGeneratorFixed(prefix) /
cmFileListGeneratorEnumerate(common) /
cmFileListGeneratorFixed("cmake") /
- cmFileListGeneratorProject(this->Names);
+ cmFileListGeneratorProject(this->Names, this->SortOrder,
+ this->SortDirection);
if (lister.Search()) {
return true;
}
@@ -1943,7 +2023,8 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
cmFindPackageFileList lister(this);
lister / cmFileListGeneratorFixed(prefix) /
cmFileListGeneratorEnumerate(common) /
- cmFileListGeneratorProject(this->Names);
+ cmFileListGeneratorProject(this->Names, this->SortOrder,
+ this->SortDirection);
if (lister.Search()) {
return true;
}
@@ -1954,7 +2035,8 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
cmFindPackageFileList lister(this);
lister / cmFileListGeneratorFixed(prefix) /
cmFileListGeneratorEnumerate(common) /
- cmFileListGeneratorProject(this->Names) /
+ cmFileListGeneratorProject(this->Names, this->SortOrder,
+ this->SortDirection) /
cmFileListGeneratorCaseInsensitive("cmake");
if (lister.Search()) {
return true;
@@ -1965,10 +2047,12 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
{
cmFindPackageFileList lister(this);
lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorProject(this->Names) /
+ cmFileListGeneratorProject(this->Names, this->SortOrder,
+ this->SortDirection) /
cmFileListGeneratorEnumerate(common) /
cmFileListGeneratorFixed("cmake") /
- cmFileListGeneratorProject(this->Names);
+ cmFileListGeneratorProject(this->Names, this->SortOrder,
+ this->SortDirection);
if (lister.Search()) {
return true;
}
@@ -1978,9 +2062,11 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
{
cmFindPackageFileList lister(this);
lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorProject(this->Names) /
+ cmFileListGeneratorProject(this->Names, this->SortOrder,
+ this->SortDirection) /
cmFileListGeneratorEnumerate(common) /
- cmFileListGeneratorProject(this->Names);
+ cmFileListGeneratorProject(this->Names, this->SortOrder,
+ this->SortDirection);
if (lister.Search()) {
return true;
}
@@ -1990,9 +2076,11 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
{
cmFindPackageFileList lister(this);
lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorProject(this->Names) /
+ cmFileListGeneratorProject(this->Names, this->SortOrder,
+ this->SortDirection) /
cmFileListGeneratorEnumerate(common) /
- cmFileListGeneratorProject(this->Names) /
+ cmFileListGeneratorProject(this->Names, this->SortOrder,
+ this->SortDirection) /
cmFileListGeneratorCaseInsensitive("cmake");
if (lister.Search()) {
return true;
diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h
index 087107e..babdd5a 100644
--- a/Source/cmFindPackageCommand.h
+++ b/Source/cmFindPackageCommand.h
@@ -24,6 +24,27 @@ class cmFindPackageFileList;
class cmFindPackageCommand : public cmFindCommon
{
public:
+ /*! A sorting order strategy to be applied to recovered package folders (see
+ * FIND_PACKAGE_SORT_ORDER)*/
+ enum /*class*/ SortOrderType
+ {
+ None,
+ Name_order,
+ Natural
+ };
+ /*! A sorting direction to be applied to recovered package folders (see
+ * FIND_PACKAGE_SORT_DIRECTION)*/
+ enum /*class*/ SortDirectionType
+ {
+ Asc,
+ Dec
+ };
+
+ /*! sorts a given list of string based on the input sort parameters */
+ static void Sort(std::vector<std::string>::iterator begin,
+ std::vector<std::string>::iterator end, SortOrderType order,
+ SortDirectionType dir);
+
cmFindPackageCommand();
/**
@@ -156,6 +177,11 @@ private:
std::vector<std::string> Configs;
std::set<std::string> IgnoredPaths;
+ /*! the selected sortOrder (None by default)*/
+ SortOrderType SortOrder;
+ /*! the selected sortDirection (Asc by default)*/
+ SortDirectionType SortDirection;
+
struct ConfigFileInfo
{
std::string filename;
diff --git a/Source/cmFindPathCommand.cxx b/Source/cmFindPathCommand.cxx
index d71fc1a..d8f8795 100644
--- a/Source/cmFindPathCommand.cxx
+++ b/Source/cmFindPathCommand.cxx
@@ -136,9 +136,8 @@ std::string cmFindPathCommand::FindNormalHeader()
if (cmSystemTools::FileExists(tryPath.c_str())) {
if (this->IncludeFileInPath) {
return tryPath;
- } else {
- return *p;
}
+ return *p;
}
}
}
diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx
index 8d142c9..2cdda4c 100644
--- a/Source/cmFindProgramCommand.cxx
+++ b/Source/cmFindProgramCommand.cxx
@@ -140,9 +140,8 @@ std::string cmFindProgramCommand::FindNormalProgram()
{
if (this->NamesPerDir) {
return this->FindNormalProgramNamesPerDir();
- } else {
- return this->FindNormalProgramDirsPerName();
}
+ return this->FindNormalProgramDirsPerName();
}
std::string cmFindProgramCommand::FindNormalProgramNamesPerDir()
diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx
index c6e5f06..4dbbd2c 100644
--- a/Source/cmForEachCommand.cxx
+++ b/Source/cmForEachCommand.cxx
@@ -81,10 +81,9 @@ bool cmForEachFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff,
// restore the variable to its prior value
mf.AddDefinition(this->Args[0], oldDef.c_str());
return true;
- } else {
- // close out a nested foreach
- this->Depth--;
}
+ // close out a nested foreach
+ this->Depth--;
}
// record the command
@@ -113,7 +112,7 @@ bool cmForEachFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
bool cmForEachCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&)
{
- if (args.size() < 1) {
+ if (args.empty()) {
this->SetError("called with incorrect number of arguments");
return false;
}
diff --git a/Source/cmFortranLexer.cxx b/Source/cmFortranLexer.cxx
index 7bcd993..60d5591 100644
--- a/Source/cmFortranLexer.cxx
+++ b/Source/cmFortranLexer.cxx
@@ -347,8 +347,8 @@ static void yynoreturn yy_fatal_error (yyconst char* msg ,yyscan_t yyscanner );
*yy_cp = '\0'; \
yyg->yy_c_buf_p = yy_cp;
-#define YY_NUM_RULES 50
-#define YY_END_OF_BUFFER 51
+#define YY_NUM_RULES 54
+#define YY_END_OF_BUFFER 55
/* This struct is not used in this scanner,
but its presence is necessary. */
struct yy_trans_info
@@ -356,30 +356,31 @@ struct yy_trans_info
flex_int32_t yy_verify;
flex_int32_t yy_nxt;
};
-static yyconst flex_int16_t yy_accept[199] =
+static yyconst flex_int16_t yy_accept[210] =
{ 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 51, 45, 47, 46, 49, 1, 45, 33, 2, 35,
- 45, 46, 38, 45, 44, 44, 44, 44, 44, 45,
- 44, 47, 45, 46, 45, 44, 9, 8, 9, 4,
- 3, 45, 0, 10, 0, 0, 0, 0, 0, 33,
- 33, 34, 36, 38, 45, 44, 44, 44, 44, 44,
- 0, 48, 44, 0, 0, 0, 12, 0, 0, 0,
- 0, 0, 0, 45, 0, 11, 44, 0, 0, 5,
- 0, 0, 0, 29, 0, 0, 33, 33, 33, 33,
- 0, 0, 39, 44, 44, 44, 43, 12, 12, 0,
-
- 0, 0, 23, 0, 0, 0, 0, 0, 0, 6,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 44,
- 44, 44, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 30, 31, 0, 0, 0, 0,
- 0, 0, 44, 44, 44, 0, 24, 25, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 32, 27, 0,
- 0, 20, 0, 44, 44, 42, 0, 26, 21, 0,
- 0, 0, 19, 0, 0, 18, 28, 0, 0, 40,
- 44, 17, 22, 0, 7, 37, 7, 15, 0, 44,
- 14, 16, 41, 0, 0, 0, 13, 0
-
+ 55, 49, 51, 50, 53, 1, 49, 33, 2, 47,
+ 48, 35, 37, 50, 39, 49, 46, 46, 46, 46,
+ 46, 46, 49, 46, 51, 49, 50, 49, 46, 9,
+ 8, 9, 4, 3, 49, 0, 10, 0, 0, 0,
+ 0, 0, 33, 33, 34, 36, 39, 49, 46, 46,
+ 46, 46, 46, 46, 0, 52, 46, 0, 0, 0,
+ 12, 0, 0, 0, 0, 0, 0, 49, 0, 11,
+ 46, 0, 0, 5, 0, 0, 0, 29, 0, 0,
+ 33, 33, 33, 33, 0, 0, 40, 46, 46, 46,
+
+ 46, 45, 12, 12, 0, 0, 0, 23, 0, 0,
+ 0, 0, 0, 0, 6, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 46, 46, 46, 46, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 30, 31, 0, 0, 0, 0, 0, 0, 46, 46,
+ 46, 46, 0, 24, 25, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 32, 27, 0, 0, 20, 0,
+ 46, 46, 43, 46, 0, 26, 21, 0, 0, 0,
+ 19, 0, 0, 18, 28, 0, 0, 41, 46, 46,
+ 17, 22, 0, 7, 38, 7, 15, 0, 46, 46,
+
+ 14, 16, 42, 44, 0, 0, 0, 13, 0
} ;
static yyconst YY_CHAR yy_ec[256] =
@@ -387,17 +388,17 @@ static yyconst YY_CHAR yy_ec[256] =
1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
1, 1, 4, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 5, 6, 7, 8, 9, 1, 10, 11, 1,
- 1, 12, 1, 13, 1, 1, 1, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 15, 16, 17,
- 18, 19, 20, 1, 21, 22, 23, 24, 25, 26,
- 22, 22, 27, 22, 22, 28, 29, 30, 31, 22,
- 22, 32, 33, 34, 35, 22, 22, 22, 22, 22,
- 1, 36, 1, 1, 37, 1, 21, 22, 38, 39,
-
- 40, 41, 22, 22, 42, 22, 22, 43, 29, 44,
- 31, 22, 22, 32, 45, 34, 46, 22, 22, 22,
- 22, 22, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 5, 6, 7, 8, 9, 1, 10, 11, 12,
+ 13, 14, 1, 15, 1, 1, 1, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 17, 18, 19,
+ 20, 21, 22, 1, 23, 24, 25, 26, 27, 28,
+ 29, 29, 30, 29, 29, 31, 32, 33, 34, 29,
+ 29, 35, 36, 37, 38, 29, 29, 29, 29, 29,
+ 1, 39, 1, 1, 40, 1, 23, 24, 41, 42,
+
+ 43, 44, 29, 29, 45, 29, 29, 46, 32, 47,
+ 34, 29, 29, 35, 48, 37, 49, 29, 29, 29,
+ 29, 29, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -414,211 +415,217 @@ static yyconst YY_CHAR yy_ec[256] =
1, 1, 1, 1, 1
} ;
-static yyconst YY_CHAR yy_meta[47] =
+static yyconst YY_CHAR yy_meta[50] =
{ 0,
1, 2, 2, 3, 4, 3, 3, 1, 1, 3,
- 3, 1, 3, 5, 1, 3, 1, 3, 6, 1,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 1, 5, 7, 7, 7,
- 7, 7, 7, 7, 7, 7
+ 3, 3, 3, 1, 3, 5, 3, 3, 1, 3,
+ 6, 1, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 1, 5,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7
} ;
-static yyconst flex_uint16_t yy_base[208] =
+static yyconst flex_uint16_t yy_base[219] =
{ 0,
- 0, 45, 0, 46, 392, 53, 49, 59, 61, 71,
- 392, 0, 572, 572, 364, 572, 91, 77, 572, 572,
- 342, 572, 317, 232, 0, 19, 42, 218, 40, 92,
- 137, 96, 174, 240, 220, 257, 572, 238, 97, 572,
- 572, 0, 205, 572, 302, 50, 77, 83, 59, 137,
- 156, 572, 0, 572, 123, 0, 84, 130, 90, 92,
- 167, 572, 0, 176, 347, 0, 190, 94, 175, 200,
- 121, 92, 201, 393, 193, 572, 0, 162, 222, 175,
- 171, 209, 176, 281, 184, 207, 307, 313, 328, 348,
- 338, 111, 0, 205, 213, 125, 0, 354, 185, 280,
-
- 336, 300, 340, 309, 278, 321, 139, 130, 245, 572,
- 335, 347, 351, 356, 360, 375, 375, 379, 383, 300,
- 80, 381, 384, 390, 392, 393, 397, 399, 397, 402,
- 403, 106, 105, 284, 572, 572, 407, 408, 411, 320,
- 413, 413, 420, 419, 421, 420, 572, 572, 421, 426,
- 428, 420, 467, 432, 101, 83, 438, 572, 572, 439,
- 446, 572, 436, 449, 63, 0, 450, 572, 572, 450,
- 453, 481, 572, 64, 0, 572, 572, 454, 460, 0,
- 464, 572, 572, 463, 572, 572, 572, 572, 468, 471,
- 495, 572, 0, 496, 0, 38, 572, 572, 513, 520,
-
- 526, 529, 536, 543, 550, 557, 564
+ 0, 48, 0, 49, 513, 56, 52, 57, 62, 68,
+ 515, 0, 583, 583, 509, 583, 97, 74, 583, 583,
+ 583, 583, 491, 583, 423, 421, 0, 19, 40, 392,
+ 36, 47, 86, 146, 88, 186, 413, 235, 275, 583,
+ 407, 98, 583, 583, 0, 386, 583, 323, 65, 73,
+ 81, 74, 127, 146, 583, 583, 583, 108, 0, 89,
+ 120, 92, 362, 116, 161, 583, 0, 167, 371, 0,
+ 168, 131, 146, 171, 81, 89, 352, 420, 353, 583,
+ 0, 349, 178, 196, 175, 197, 188, 208, 196, 197,
+ 256, 262, 324, 330, 337, 143, 0, 151, 220, 56,
+
+ 305, 0, 336, 139, 225, 315, 305, 322, 318, 163,
+ 320, 268, 266, 369, 583, 340, 347, 350, 350, 351,
+ 357, 350, 357, 363, 140, 235, 359, 218, 362, 375,
+ 379, 380, 381, 385, 384, 404, 405, 243, 235, 213,
+ 583, 583, 405, 407, 410, 171, 410, 409, 419, 418,
+ 423, 426, 311, 583, 583, 428, 429, 431, 173, 462,
+ 435, 166, 145, 438, 583, 583, 441, 444, 583, 433,
+ 448, 89, 0, 438, 450, 583, 583, 452, 457, 487,
+ 583, 114, 0, 583, 583, 457, 462, 0, 465, 463,
+ 583, 583, 468, 583, 583, 583, 583, 470, 471, 474,
+
+ 500, 583, 0, 0, 505, 0, 65, 583, 583, 524,
+ 531, 537, 540, 547, 554, 561, 568, 575
} ;
-static yyconst flex_int16_t yy_def[208] =
+static yyconst flex_int16_t yy_def[219] =
{ 0,
- 198, 1, 1, 1, 1, 1, 199, 199, 199, 199,
- 198, 200, 198, 198, 201, 198, 200, 198, 198, 198,
- 200, 198, 198, 200, 202, 202, 202, 202, 202, 200,
- 202, 198, 198, 198, 203, 198, 198, 198, 198, 198,
- 198, 200, 201, 198, 198, 198, 198, 198, 198, 198,
- 204, 198, 200, 198, 200, 202, 202, 202, 202, 202,
- 198, 198, 31, 198, 198, 65, 200, 198, 198, 198,
- 198, 198, 198, 203, 203, 198, 36, 198, 198, 198,
- 198, 198, 198, 198, 198, 198, 204, 204, 204, 204,
- 198, 198, 202, 202, 202, 202, 202, 198, 198, 198,
-
- 198, 198, 198, 198, 198, 198, 198, 198, 198, 198,
- 198, 198, 198, 198, 198, 198, 198, 198, 198, 202,
- 202, 202, 198, 198, 198, 198, 198, 198, 198, 198,
- 198, 198, 198, 198, 198, 198, 198, 198, 198, 198,
- 198, 198, 202, 202, 202, 198, 198, 198, 198, 198,
- 198, 198, 198, 198, 198, 198, 198, 198, 198, 198,
- 198, 198, 198, 202, 202, 202, 198, 198, 198, 198,
- 198, 198, 198, 205, 206, 198, 198, 198, 198, 202,
- 202, 198, 198, 198, 198, 198, 198, 198, 198, 202,
- 198, 198, 202, 198, 207, 207, 198, 0, 198, 198,
-
- 198, 198, 198, 198, 198, 198, 198
+ 209, 1, 1, 1, 1, 1, 210, 210, 210, 210,
+ 209, 211, 209, 209, 212, 209, 211, 209, 209, 209,
+ 209, 209, 209, 209, 209, 211, 213, 213, 213, 213,
+ 213, 213, 211, 213, 209, 209, 209, 214, 209, 209,
+ 209, 209, 209, 209, 211, 212, 209, 209, 209, 209,
+ 209, 209, 209, 215, 209, 209, 209, 211, 213, 213,
+ 213, 213, 213, 213, 209, 209, 34, 209, 209, 69,
+ 211, 209, 209, 209, 209, 209, 209, 214, 214, 209,
+ 39, 209, 209, 209, 209, 209, 209, 209, 209, 209,
+ 215, 215, 215, 215, 209, 209, 213, 213, 213, 213,
+
+ 213, 213, 209, 209, 209, 209, 209, 209, 209, 209,
+ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
+ 209, 209, 209, 209, 213, 213, 213, 213, 209, 209,
+ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
+ 209, 209, 209, 209, 209, 209, 209, 209, 213, 213,
+ 213, 213, 209, 209, 209, 209, 209, 209, 209, 209,
+ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
+ 213, 213, 213, 213, 209, 209, 209, 209, 209, 209,
+ 209, 216, 217, 209, 209, 209, 209, 213, 213, 213,
+ 209, 209, 209, 209, 209, 209, 209, 209, 213, 213,
+
+ 209, 209, 213, 213, 209, 218, 218, 209, 0, 209,
+ 209, 209, 209, 209, 209, 209, 209, 209
} ;
-static yyconst flex_uint16_t yy_nxt[619] =
+static yyconst flex_uint16_t yy_nxt[633] =
{ 0,
12, 13, 14, 13, 13, 15, 16, 12, 17, 18,
- 19, 12, 20, 12, 21, 22, 12, 23, 12, 24,
- 25, 25, 25, 25, 26, 25, 27, 25, 28, 25,
- 25, 25, 25, 25, 29, 30, 31, 25, 25, 26,
- 25, 27, 25, 25, 25, 29, 32, 32, 57, 32,
- 32, 38, 33, 33, 32, 34, 197, 32, 39, 40,
- 33, 38, 57, 38, 35, 186, 186, 41, 39, 40,
- 39, 58, 60, 38, 81, 36, 36, 41, 50, 50,
- 39, 50, 51, 181, 60, 58, 52, 175, 86, 81,
- 36, 36, 45, 61, 62, 45, 61, 64, 79, 80,
-
- 64, 79, 86, 65, 82, 174, 83, 93, 84, 156,
- 155, 144, 85, 96, 46, 47, 97, 48, 100, 82,
- 83, 106, 93, 84, 91, 49, 85, 91, 96, 46,
- 47, 97, 48, 100, 133, 106, 49, 42, 50, 50,
- 119, 50, 51, 132, 42, 42, 52, 105, 42, 92,
- 63, 42, 94, 42, 119, 42, 42, 88, 50, 122,
- 88, 89, 105, 95, 92, 90, 108, 94, 61, 62,
- 122, 61, 42, 63, 42, 66, 109, 64, 66, 109,
- 64, 42, 42, 65, 110, 42, 99, 67, 42, 99,
- 42, 99, 42, 42, 99, 76, 111, 68, 69, 114,
-
- 70, 71, 101, 67, 102, 107, 117, 44, 72, 42,
- 42, 111, 68, 69, 114, 70, 71, 101, 102, 72,
- 74, 117, 76, 79, 80, 103, 79, 74, 74, 104,
- 118, 74, 120, 74, 74, 112, 74, 121, 74, 74,
- 103, 113, 78, 104, 73, 118, 109, 120, 59, 109,
- 112, 55, 121, 113, 110, 74, 74, 75, 75, 76,
- 75, 75, 75, 75, 75, 75, 75, 75, 75, 75,
- 77, 75, 75, 75, 75, 75, 75, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 75, 77, 77, 77, 77, 77, 77, 77,
-
- 77, 77, 77, 45, 115, 123, 45, 130, 88, 50,
- 116, 88, 89, 157, 88, 50, 90, 88, 89, 115,
- 123, 130, 90, 126, 116, 46, 47, 157, 48, 88,
- 50, 129, 88, 89, 143, 54, 49, 90, 126, 91,
- 46, 47, 91, 48, 131, 143, 129, 49, 66, 88,
- 50, 66, 88, 89, 161, 99, 53, 90, 99, 131,
- 98, 134, 124, 127, 92, 161, 44, 98, 125, 128,
- 68, 69, 135, 70, 71, 136, 134, 124, 127, 92,
- 125, 72, 137, 128, 138, 68, 69, 135, 70, 71,
- 136, 198, 72, 74, 34, 76, 198, 137, 139, 138,
-
- 74, 74, 140, 141, 74, 142, 74, 74, 145, 74,
- 146, 74, 74, 139, 198, 147, 148, 140, 141, 149,
- 142, 150, 151, 145, 152, 146, 153, 154, 74, 74,
- 147, 148, 158, 159, 149, 160, 150, 151, 162, 152,
- 163, 153, 154, 164, 165, 166, 168, 158, 159, 167,
- 160, 169, 170, 162, 171, 163, 198, 173, 164, 165,
- 166, 168, 176, 167, 177, 171, 169, 170, 172, 178,
- 179, 172, 173, 180, 182, 183, 184, 176, 188, 177,
- 98, 179, 172, 189, 178, 172, 190, 191, 180, 182,
- 183, 184, 192, 188, 98, 193, 194, 194, 189, 194,
-
- 194, 190, 191, 198, 198, 198, 198, 192, 198, 198,
- 193, 195, 195, 37, 37, 37, 37, 37, 37, 37,
- 42, 198, 198, 198, 42, 42, 43, 43, 43, 43,
- 43, 43, 43, 56, 198, 56, 75, 75, 75, 75,
- 75, 75, 75, 87, 87, 87, 87, 87, 87, 87,
- 185, 185, 185, 198, 185, 185, 185, 187, 198, 187,
- 198, 187, 187, 187, 196, 196, 196, 196, 196, 198,
- 196, 11, 198, 198, 198, 198, 198, 198, 198, 198,
- 198, 198, 198, 198, 198, 198, 198, 198, 198, 198,
- 198, 198, 198, 198, 198, 198, 198, 198, 198, 198,
-
- 198, 198, 198, 198, 198, 198, 198, 198, 198, 198,
- 198, 198, 198, 198, 198, 198, 198, 198
+ 19, 20, 21, 12, 22, 12, 23, 24, 12, 25,
+ 12, 26, 27, 27, 27, 27, 28, 27, 27, 29,
+ 27, 30, 27, 27, 27, 31, 27, 32, 33, 34,
+ 27, 27, 28, 27, 29, 27, 27, 31, 32, 35,
+ 35, 60, 35, 35, 41, 36, 36, 35, 37, 41,
+ 35, 42, 43, 36, 41, 60, 42, 43, 44, 38,
+ 41, 42, 61, 63, 44, 53, 53, 42, 53, 54,
+ 39, 39, 64, 55, 63, 208, 61, 65, 66, 68,
+ 65, 85, 68, 127, 64, 69, 39, 39, 48, 83,
+
+ 84, 48, 83, 86, 127, 87, 90, 85, 88, 95,
+ 110, 189, 95, 89, 97, 195, 195, 100, 86, 87,
+ 90, 111, 49, 50, 88, 110, 51, 89, 53, 53,
+ 97, 53, 54, 100, 52, 111, 55, 96, 49, 50,
+ 104, 51, 102, 104, 98, 52, 45, 92, 53, 183,
+ 92, 93, 96, 45, 45, 94, 99, 105, 102, 45,
+ 98, 67, 65, 66, 45, 65, 45, 45, 68, 104,
+ 182, 68, 104, 105, 69, 124, 106, 149, 107, 83,
+ 84, 125, 83, 71, 45, 67, 45, 70, 149, 124,
+ 70, 106, 107, 45, 45, 136, 125, 114, 108, 45,
+
+ 114, 71, 116, 109, 45, 115, 45, 45, 168, 136,
+ 179, 72, 73, 119, 108, 74, 75, 109, 116, 168,
+ 122, 179, 123, 76, 45, 45, 117, 72, 73, 119,
+ 74, 75, 118, 120, 76, 78, 122, 80, 123, 163,
+ 121, 117, 78, 78, 118, 164, 126, 162, 78, 120,
+ 78, 152, 129, 78, 121, 78, 78, 92, 53, 164,
+ 92, 93, 126, 92, 53, 94, 92, 93, 129, 150,
+ 139, 94, 138, 78, 78, 79, 79, 80, 79, 79,
+ 79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
+ 81, 79, 79, 79, 79, 79, 79, 81, 81, 81,
+
+ 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
+ 81, 81, 81, 79, 81, 81, 81, 81, 81, 81,
+ 81, 81, 81, 81, 48, 92, 53, 48, 92, 93,
+ 132, 92, 53, 94, 92, 93, 128, 104, 95, 94,
+ 104, 95, 135, 175, 130, 137, 132, 133, 49, 50,
+ 131, 103, 51, 113, 134, 80, 112, 175, 135, 130,
+ 52, 137, 131, 133, 49, 50, 96, 51, 134, 140,
+ 114, 52, 70, 114, 141, 70, 142, 144, 115, 143,
+ 146, 96, 145, 147, 140, 101, 103, 148, 47, 151,
+ 141, 153, 142, 144, 143, 146, 72, 73, 145, 147,
+
+ 74, 75, 154, 148, 151, 155, 153, 157, 76, 156,
+ 158, 82, 72, 73, 159, 74, 75, 77, 154, 76,
+ 78, 155, 80, 157, 156, 62, 158, 78, 78, 159,
+ 160, 161, 165, 78, 166, 78, 167, 169, 78, 170,
+ 78, 78, 58, 57, 171, 172, 160, 161, 165, 173,
+ 166, 174, 167, 169, 170, 176, 177, 178, 78, 78,
+ 171, 172, 181, 180, 184, 173, 180, 174, 185, 186,
+ 187, 176, 177, 178, 188, 190, 191, 103, 181, 192,
+ 184, 187, 193, 197, 185, 186, 190, 198, 180, 199,
+ 188, 180, 191, 200, 201, 192, 202, 203, 193, 197,
+
+ 204, 205, 103, 198, 205, 199, 205, 56, 200, 205,
+ 201, 47, 202, 203, 209, 37, 204, 209, 206, 209,
+ 209, 209, 209, 206, 40, 40, 40, 40, 40, 40,
+ 40, 45, 209, 209, 209, 45, 45, 46, 46, 46,
+ 46, 46, 46, 46, 59, 209, 59, 79, 79, 79,
+ 79, 79, 79, 79, 91, 91, 91, 91, 91, 91,
+ 91, 194, 194, 194, 209, 194, 194, 194, 196, 209,
+ 196, 209, 196, 196, 196, 207, 207, 207, 207, 207,
+ 209, 207, 11, 209, 209, 209, 209, 209, 209, 209,
+ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
+
+ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
+ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
+ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
+ 209, 209
} ;
-static yyconst flex_int16_t yy_chk[619] =
+static yyconst flex_int16_t yy_chk[633] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 2, 4, 26, 2,
- 4, 7, 2, 4, 6, 6, 196, 6, 7, 7,
- 6, 8, 26, 9, 6, 174, 174, 9, 8, 8,
- 9, 27, 29, 10, 46, 6, 6, 10, 18, 18,
- 10, 18, 18, 165, 29, 27, 18, 156, 49, 46,
- 6, 6, 17, 30, 30, 17, 30, 32, 39, 39,
-
- 32, 39, 49, 32, 47, 155, 47, 57, 48, 133,
- 132, 121, 48, 59, 17, 17, 60, 17, 68, 47,
- 47, 72, 57, 48, 55, 17, 48, 55, 59, 17,
- 17, 60, 17, 68, 108, 72, 17, 31, 50, 50,
- 92, 50, 50, 107, 31, 31, 50, 71, 31, 55,
- 31, 31, 58, 31, 92, 31, 31, 51, 51, 96,
- 51, 51, 71, 58, 55, 51, 78, 58, 61, 61,
- 96, 61, 31, 31, 33, 33, 80, 64, 33, 80,
- 64, 33, 33, 64, 80, 33, 99, 33, 33, 99,
- 33, 67, 33, 33, 67, 75, 81, 33, 33, 83,
-
- 33, 33, 69, 67, 69, 73, 85, 43, 33, 33,
- 33, 81, 33, 33, 83, 33, 33, 69, 69, 33,
- 35, 85, 35, 79, 79, 70, 79, 35, 35, 70,
- 86, 35, 94, 35, 35, 82, 35, 95, 35, 35,
- 70, 82, 38, 70, 34, 86, 109, 94, 28, 109,
- 82, 24, 95, 82, 109, 35, 35, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
-
- 36, 36, 36, 45, 84, 100, 45, 105, 87, 87,
- 84, 87, 87, 134, 88, 88, 87, 88, 88, 84,
- 100, 105, 88, 102, 84, 45, 45, 134, 45, 89,
- 89, 104, 89, 89, 120, 23, 45, 89, 102, 91,
- 45, 45, 91, 45, 106, 120, 104, 45, 65, 90,
- 90, 65, 90, 90, 140, 98, 21, 90, 98, 106,
- 65, 111, 101, 103, 91, 140, 15, 98, 101, 103,
- 65, 65, 112, 65, 65, 113, 111, 101, 103, 91,
- 101, 65, 114, 103, 115, 65, 65, 112, 65, 65,
- 113, 11, 65, 74, 5, 74, 0, 114, 116, 115,
-
- 74, 74, 117, 118, 74, 119, 74, 74, 122, 74,
- 123, 74, 74, 116, 0, 124, 125, 117, 118, 126,
- 119, 127, 128, 122, 129, 123, 130, 131, 74, 74,
- 124, 125, 137, 138, 126, 139, 127, 128, 141, 129,
- 142, 130, 131, 143, 144, 145, 149, 137, 138, 146,
- 139, 150, 151, 141, 152, 142, 0, 154, 143, 144,
- 145, 149, 157, 146, 160, 152, 150, 151, 153, 161,
- 163, 153, 154, 164, 167, 170, 171, 157, 178, 160,
- 153, 163, 172, 179, 161, 172, 181, 184, 164, 167,
- 170, 171, 189, 178, 172, 190, 191, 194, 179, 191,
-
- 194, 181, 184, 0, 0, 0, 0, 189, 0, 0,
- 190, 191, 194, 199, 199, 199, 199, 199, 199, 199,
- 200, 0, 0, 0, 200, 200, 201, 201, 201, 201,
- 201, 201, 201, 202, 0, 202, 203, 203, 203, 203,
- 203, 203, 203, 204, 204, 204, 204, 204, 204, 204,
- 205, 205, 205, 0, 205, 205, 205, 206, 0, 206,
- 0, 206, 206, 206, 207, 207, 207, 207, 207, 0,
- 207, 198, 198, 198, 198, 198, 198, 198, 198, 198,
- 198, 198, 198, 198, 198, 198, 198, 198, 198, 198,
- 198, 198, 198, 198, 198, 198, 198, 198, 198, 198,
-
- 198, 198, 198, 198, 198, 198, 198, 198, 198, 198,
- 198, 198, 198, 198, 198, 198, 198, 198
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
+ 4, 28, 2, 4, 7, 2, 4, 6, 6, 8,
+ 6, 7, 7, 6, 9, 28, 8, 8, 9, 6,
+ 10, 9, 29, 31, 10, 18, 18, 10, 18, 18,
+ 6, 6, 32, 18, 31, 207, 29, 33, 33, 35,
+ 33, 49, 35, 100, 32, 35, 6, 6, 17, 42,
+
+ 42, 17, 42, 50, 100, 50, 52, 49, 51, 58,
+ 75, 172, 58, 51, 60, 182, 182, 62, 50, 50,
+ 52, 76, 17, 17, 51, 75, 17, 51, 53, 53,
+ 60, 53, 53, 62, 17, 76, 53, 58, 17, 17,
+ 104, 17, 64, 104, 61, 17, 34, 54, 54, 163,
+ 54, 54, 58, 34, 34, 54, 61, 72, 64, 34,
+ 61, 34, 65, 65, 34, 65, 34, 34, 68, 71,
+ 162, 68, 71, 72, 68, 96, 73, 125, 73, 83,
+ 83, 98, 83, 71, 34, 34, 36, 36, 125, 96,
+ 36, 73, 73, 36, 36, 110, 98, 84, 74, 36,
+
+ 84, 36, 85, 74, 36, 84, 36, 36, 146, 110,
+ 159, 36, 36, 87, 74, 36, 36, 74, 85, 146,
+ 89, 159, 90, 36, 36, 36, 86, 36, 36, 87,
+ 36, 36, 86, 88, 36, 38, 89, 38, 90, 139,
+ 88, 86, 38, 38, 86, 140, 99, 138, 38, 88,
+ 38, 128, 105, 38, 88, 38, 38, 91, 91, 140,
+ 91, 91, 99, 92, 92, 91, 92, 92, 105, 126,
+ 113, 92, 112, 38, 38, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 48, 93, 93, 48, 93, 93,
+ 107, 94, 94, 93, 94, 94, 101, 103, 95, 94,
+ 103, 95, 109, 153, 106, 111, 107, 108, 48, 48,
+ 106, 103, 48, 82, 108, 79, 77, 153, 109, 106,
+ 48, 111, 106, 108, 48, 48, 95, 48, 108, 116,
+ 114, 48, 69, 114, 117, 69, 118, 120, 114, 119,
+ 122, 95, 121, 123, 116, 63, 69, 124, 46, 127,
+ 117, 129, 118, 120, 119, 122, 69, 69, 121, 123,
+
+ 69, 69, 130, 124, 127, 131, 129, 133, 69, 132,
+ 134, 41, 69, 69, 135, 69, 69, 37, 130, 69,
+ 78, 131, 78, 133, 132, 30, 134, 78, 78, 135,
+ 136, 137, 143, 78, 144, 78, 145, 147, 78, 148,
+ 78, 78, 26, 25, 149, 150, 136, 137, 143, 151,
+ 144, 152, 145, 147, 148, 156, 157, 158, 78, 78,
+ 149, 150, 161, 160, 164, 151, 160, 152, 167, 168,
+ 170, 156, 157, 158, 171, 174, 175, 160, 161, 178,
+ 164, 170, 179, 186, 167, 168, 174, 187, 180, 189,
+ 171, 180, 175, 190, 193, 178, 198, 199, 179, 186,
+
+ 200, 201, 180, 187, 201, 189, 205, 23, 190, 205,
+ 193, 15, 198, 199, 11, 5, 200, 0, 201, 0,
+ 0, 0, 0, 205, 210, 210, 210, 210, 210, 210,
+ 210, 211, 0, 0, 0, 211, 211, 212, 212, 212,
+ 212, 212, 212, 212, 213, 0, 213, 214, 214, 214,
+ 214, 214, 214, 214, 215, 215, 215, 215, 215, 215,
+ 215, 216, 216, 216, 0, 216, 216, 216, 217, 0,
+ 217, 0, 217, 217, 217, 218, 218, 218, 218, 218,
+ 0, 218, 209, 209, 209, 209, 209, 209, 209, 209,
+ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
+
+ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
+ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
+ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
+ 209, 209
} ;
/* The intent behind this definition is that it'll catch
@@ -685,7 +692,7 @@ Modify cmFortranLexer.cxx:
/*--------------------------------------------------------------------------*/
-#line 689 "cmFortranLexer.cxx"
+#line 696 "cmFortranLexer.cxx"
#define INITIAL 0
#define free_fmt 1
@@ -956,7 +963,7 @@ YY_DECL
#line 65 "cmFortranLexer.in.l"
-#line 960 "cmFortranLexer.cxx"
+#line 967 "cmFortranLexer.cxx"
while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
{
@@ -984,13 +991,13 @@ yy_match:
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 199 )
+ if ( yy_current_state >= 210 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
++yy_cp;
}
- while ( yy_base[yy_current_state] != 572 );
+ while ( yy_base[yy_current_state] != 583 );
yy_find_action:
yy_act = yy_accept[yy_current_state];
@@ -1201,71 +1208,87 @@ YY_RULE_SETUP
#line 148 "cmFortranLexer.in.l"
{ return DCOLON; }
case 37:
-/* rule 37 can match eol */
YY_RULE_SETUP
-#line 150 "cmFortranLexer.in.l"
-{ return GARBAGE; }
+#line 149 "cmFortranLexer.in.l"
+{ return COLON; }
case 38:
+/* rule 38 can match eol */
YY_RULE_SETUP
-#line 152 "cmFortranLexer.in.l"
-{ return ASSIGNMENT_OP; }
+#line 151 "cmFortranLexer.in.l"
+{ return GARBAGE; }
case 39:
YY_RULE_SETUP
-#line 154 "cmFortranLexer.in.l"
-{ return END; }
+#line 153 "cmFortranLexer.in.l"
+{ return ASSIGNMENT_OP; }
case 40:
YY_RULE_SETUP
#line 155 "cmFortranLexer.in.l"
-{ return INCLUDE; }
+{ return END; }
case 41:
YY_RULE_SETUP
#line 156 "cmFortranLexer.in.l"
-{ return INTERFACE; }
+{ return INCLUDE; }
case 42:
YY_RULE_SETUP
#line 157 "cmFortranLexer.in.l"
-{ return MODULE; }
+{ return INTERFACE; }
case 43:
YY_RULE_SETUP
#line 158 "cmFortranLexer.in.l"
-{ return USE; }
+{ return MODULE; }
case 44:
YY_RULE_SETUP
+#line 159 "cmFortranLexer.in.l"
+{ return SUBMODULE; }
+case 45:
+YY_RULE_SETUP
#line 160 "cmFortranLexer.in.l"
+{ return USE; }
+case 46:
+YY_RULE_SETUP
+#line 162 "cmFortranLexer.in.l"
{
yylvalp->string = strdup(yytext);
return WORD;
}
-case 45:
+case 47:
+YY_RULE_SETUP
+#line 167 "cmFortranLexer.in.l"
+{ return LPAREN; }
+case 48:
+YY_RULE_SETUP
+#line 168 "cmFortranLexer.in.l"
+{ return RPAREN; }
+case 49:
YY_RULE_SETUP
-#line 165 "cmFortranLexer.in.l"
+#line 170 "cmFortranLexer.in.l"
{ return GARBAGE; }
-case 46:
-/* rule 46 can match eol */
+case 50:
+/* rule 50 can match eol */
YY_RULE_SETUP
-#line 167 "cmFortranLexer.in.l"
+#line 172 "cmFortranLexer.in.l"
{ return EOSTMT; }
-case 47:
+case 51:
YY_RULE_SETUP
-#line 170 "cmFortranLexer.in.l"
+#line 175 "cmFortranLexer.in.l"
/* Ignore */
YY_BREAK
-case 48:
-/* rule 48 can match eol */
+case 52:
+/* rule 52 can match eol */
YY_RULE_SETUP
-#line 171 "cmFortranLexer.in.l"
+#line 176 "cmFortranLexer.in.l"
/* Ignore line-endings preceded by \ */
YY_BREAK
-case 49:
+case 53:
YY_RULE_SETUP
-#line 173 "cmFortranLexer.in.l"
+#line 178 "cmFortranLexer.in.l"
{ return *yytext; }
case YY_STATE_EOF(INITIAL):
case YY_STATE_EOF(free_fmt):
case YY_STATE_EOF(fixed_fmt):
case YY_STATE_EOF(str_sq):
case YY_STATE_EOF(str_dq):
-#line 175 "cmFortranLexer.in.l"
+#line 180 "cmFortranLexer.in.l"
{
if(!cmFortranParser_FilePop(yyextra) )
{
@@ -1273,12 +1296,12 @@ case YY_STATE_EOF(str_dq):
}
}
YY_BREAK
-case 50:
+case 54:
YY_RULE_SETUP
-#line 182 "cmFortranLexer.in.l"
+#line 187 "cmFortranLexer.in.l"
ECHO;
YY_BREAK
-#line 1320 "cmFortranLexer.cxx"
+#line 1347 "cmFortranLexer.cxx"
case YY_END_OF_BUFFER:
{
@@ -1572,7 +1595,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 199 )
+ if ( yy_current_state >= 210 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
@@ -1601,11 +1624,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 199 )
+ if ( yy_current_state >= 210 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
- yy_is_jam = (yy_current_state == 198);
+ yy_is_jam = (yy_current_state == 209);
(void)yyg;
return yy_is_jam ? 0 : yy_current_state;
@@ -2447,7 +2470,7 @@ void cmFortran_yyfree (void * ptr , yyscan_t yyscanner)
#define YYTABLES_NAME "yytables"
-#line 182 "cmFortranLexer.in.l"
+#line 187 "cmFortranLexer.in.l"
diff --git a/Source/cmFortranLexer.h b/Source/cmFortranLexer.h
index cb175ec..851f37f 100644
--- a/Source/cmFortranLexer.h
+++ b/Source/cmFortranLexer.h
@@ -337,7 +337,7 @@ extern int cmFortran_yylex (yyscan_t yyscanner);
#undef YY_DECL
#endif
-#line 182 "cmFortranLexer.in.l"
+#line 187 "cmFortranLexer.in.l"
#line 344 "cmFortranLexer.h"
diff --git a/Source/cmFortranLexer.in.l b/Source/cmFortranLexer.in.l
index 6870f7c..ea3c132 100644
--- a/Source/cmFortranLexer.in.l
+++ b/Source/cmFortranLexer.in.l
@@ -146,6 +146,7 @@ $[ \t]*endif { return F90PPR_ENDIF; }
, { return COMMA; }
:: { return DCOLON; }
+: { return COLON; }
<fixed_fmt>\n[ ]{5}[^ ] { return GARBAGE; }
@@ -155,6 +156,7 @@ $[ \t]*endif { return F90PPR_ENDIF; }
[Ii][Nn][Cc][Ll][Uu][Dd][Ee] { return INCLUDE; }
[Ii][Nn][Tt][Ee][Rr][Ff][Aa][Cc][Ee] { return INTERFACE; }
[Mm][Oo][Dd][Uu][Ll][Ee] { return MODULE; }
+[Ss][Uu][bb][Mm][Oo][Dd][Uu][Ll][Ee] { return SUBMODULE; }
[Uu][Ss][Ee] { return USE; }
[a-zA-Z_][a-zA-Z_0-9]* {
@@ -162,7 +164,10 @@ $[ \t]*endif { return F90PPR_ENDIF; }
return WORD;
}
-[^ \t\n\r;,!'"a-zA-Z=&]+ { return GARBAGE; }
+\( { return LPAREN; }
+\) { return RPAREN; }
+
+[^ \t\n\r:;,!'"a-zA-Z=&()]+ { return GARBAGE; }
;|\n { return EOSTMT; }
diff --git a/Source/cmFortranParser.cxx b/Source/cmFortranParser.cxx
index bf4e7c4..2b3e22d 100644
--- a/Source/cmFortranParser.cxx
+++ b/Source/cmFortranParser.cxx
@@ -192,16 +192,20 @@ extern int cmFortran_yydebug;
F90PPR_ELIF = 279,
F90PPR_ENDIF = 280,
COMMA = 281,
- DCOLON = 282,
- UNTERMINATED_STRING = 283,
- STRING = 284,
- WORD = 285,
- CPP_INCLUDE_ANGLE = 286,
- END = 287,
- INCLUDE = 288,
- INTERFACE = 289,
- MODULE = 290,
- USE = 291
+ COLON = 282,
+ DCOLON = 283,
+ LPAREN = 284,
+ RPAREN = 285,
+ UNTERMINATED_STRING = 286,
+ STRING = 287,
+ WORD = 288,
+ CPP_INCLUDE_ANGLE = 289,
+ END = 290,
+ INCLUDE = 291,
+ INTERFACE = 292,
+ MODULE = 293,
+ SUBMODULE = 294,
+ USE = 295
};
#endif
/* Tokens. */
@@ -229,16 +233,20 @@ extern int cmFortran_yydebug;
#define F90PPR_ELIF 279
#define F90PPR_ENDIF 280
#define COMMA 281
-#define DCOLON 282
-#define UNTERMINATED_STRING 283
-#define STRING 284
-#define WORD 285
-#define CPP_INCLUDE_ANGLE 286
-#define END 287
-#define INCLUDE 288
-#define INTERFACE 289
-#define MODULE 290
-#define USE 291
+#define COLON 282
+#define DCOLON 283
+#define LPAREN 284
+#define RPAREN 285
+#define UNTERMINATED_STRING 286
+#define STRING 287
+#define WORD 288
+#define CPP_INCLUDE_ANGLE 289
+#define END 290
+#define INCLUDE 291
+#define INTERFACE 292
+#define MODULE 293
+#define SUBMODULE 294
+#define USE 295
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
@@ -249,7 +257,7 @@ union YYSTYPE
char* string;
-#line 253 "cmFortranParser.cxx" /* yacc.c:355 */
+#line 261 "cmFortranParser.cxx" /* yacc.c:355 */
};
typedef union YYSTYPE YYSTYPE;
@@ -265,7 +273,7 @@ int cmFortran_yyparse (yyscan_t yyscanner);
/* Copy the second part of user declarations. */
-#line 269 "cmFortranParser.cxx" /* yacc.c:358 */
+#line 277 "cmFortranParser.cxx" /* yacc.c:358 */
#ifdef short
# undef short
@@ -507,21 +515,21 @@ union yyalloc
/* YYFINAL -- State number of the termination state. */
#define YYFINAL 2
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 469
+#define YYLAST 593
/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 37
+#define YYNTOKENS 41
/* YYNNTS -- Number of nonterminals. */
#define YYNNTS 14
/* YYNRULES -- Number of rules. */
-#define YYNRULES 57
+#define YYNRULES 63
/* YYNSTATES -- Number of states. */
-#define YYNSTATES 109
+#define YYNSTATES 126
/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
by yylex, with out-of-bounds checking. */
#define YYUNDEFTOK 2
-#define YYMAXUTOK 291
+#define YYMAXUTOK 295
#define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -559,19 +567,20 @@ static const yytype_uint8 yytranslate[] =
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
- 35, 36
+ 35, 36, 37, 38, 39, 40
};
#if YYDEBUG
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_uint8 yyrline[] =
{
- 0, 102, 102, 102, 105, 109, 114, 119, 124, 128,
- 133, 141, 146, 151, 156, 161, 166, 171, 176, 181,
- 185, 189, 193, 197, 198, 203, 203, 203, 204, 204,
- 205, 205, 206, 206, 207, 207, 208, 208, 209, 209,
- 210, 210, 211, 211, 212, 212, 215, 216, 217, 218,
- 219, 220, 221, 222, 223, 224, 225, 226
+ 0, 103, 103, 103, 106, 110, 115, 124, 130, 137,
+ 142, 146, 151, 159, 164, 169, 174, 179, 184, 189,
+ 194, 199, 203, 207, 211, 215, 216, 221, 221, 221,
+ 222, 222, 223, 223, 224, 224, 225, 225, 226, 226,
+ 227, 227, 228, 228, 229, 229, 230, 230, 233, 234,
+ 235, 236, 237, 238, 239, 240, 241, 242, 243, 244,
+ 245, 246, 247, 248
};
#endif
@@ -585,10 +594,11 @@ static const char *const yytname[] =
"F90PPR_DEFINE", "CPP_DEFINE", "F90PPR_UNDEF", "CPP_UNDEF", "CPP_IFDEF",
"CPP_IFNDEF", "CPP_IF", "CPP_ELSE", "CPP_ELIF", "CPP_ENDIF",
"F90PPR_IFDEF", "F90PPR_IFNDEF", "F90PPR_IF", "F90PPR_ELSE",
- "F90PPR_ELIF", "F90PPR_ENDIF", "COMMA", "DCOLON", "UNTERMINATED_STRING",
- "STRING", "WORD", "CPP_INCLUDE_ANGLE", "END", "INCLUDE", "INTERFACE",
- "MODULE", "USE", "$accept", "code", "stmt", "include", "define", "undef",
- "ifdef", "ifndef", "if", "elif", "else", "endif", "other", "misc_code", YY_NULLPTR
+ "F90PPR_ELIF", "F90PPR_ENDIF", "COMMA", "COLON", "DCOLON", "LPAREN",
+ "RPAREN", "UNTERMINATED_STRING", "STRING", "WORD", "CPP_INCLUDE_ANGLE",
+ "END", "INCLUDE", "INTERFACE", "MODULE", "SUBMODULE", "USE", "$accept",
+ "code", "stmt", "include", "define", "undef", "ifdef", "ifndef", "if",
+ "elif", "else", "endif", "other", "misc_code", YY_NULLPTR
};
#endif
@@ -600,14 +610,15 @@ static const yytype_uint16 yytoknum[] =
0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
- 285, 286, 287, 288, 289, 290, 291
+ 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
+ 295
};
# endif
-#define YYPACT_NINF -38
+#define YYPACT_NINF -39
#define yypact_value_is_default(Yystate) \
- (!!((Yystate) == (-38)))
+ (!!((Yystate) == (-39)))
#define YYTABLE_NINF -1
@@ -618,17 +629,19 @@ static const yytype_uint16 yytoknum[] =
STATE-NUM. */
static const yytype_int16 yypact[] =
{
- -38, 39, -38, 3, -38, -20, -38, -38, -38, -38,
- -38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
- -38, -38, -38, -38, -38, -38, -22, -16, 1, -8,
- -6, -38, -4, -7, -3, -2, -1, -38, -38, -38,
- -38, -38, -38, 62, -38, -38, -38, -38, -38, 0,
- 2, -38, -38, -38, -38, -38, -38, 73, 107, 118,
- 152, 163, -38, -38, -38, -38, -38, -38, -38, -38,
- -38, -38, -38, -38, -38, -38, 197, 208, 242, 253,
- 6, -38, 287, 298, 332, 343, 377, 388, -38, -38,
- -38, -38, -38, -38, -38, -38, -38, 4, 422, -38,
- -38, -38, -38, -38, -38, -38, -38, 433, -38
+ -39, 21, -39, 1, -39, -20, -39, -39, -39, -39,
+ -39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
+ -39, -39, -39, -39, -39, -39, -24, -18, 20, -8,
+ -3, 39, -39, 15, 16, 18, 19, 33, -39, -39,
+ -39, -39, -39, -39, 59, -39, -39, -39, -39, -39,
+ 35, 36, 37, -39, -39, -39, -39, -39, -39, 76,
+ 114, 129, 167, 182, -39, -39, -39, -39, -39, -39,
+ -39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
+ -39, -39, 220, 235, 273, 288, -21, 26, -39, 326,
+ 341, 379, 394, 432, 447, -39, -39, -39, -39, -39,
+ -39, -39, -39, -39, 38, 40, 41, 485, -39, -39,
+ -39, -39, -39, -39, 45, -39, -39, -39, 43, 500,
+ 538, -39, -39, -39, 553, -39
};
/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -636,31 +649,33 @@ static const yytype_int16 yypact[] =
means the default is an error. */
static const yytype_uint8 yydefact[] =
{
- 2, 0, 1, 0, 23, 0, 25, 26, 27, 29,
- 28, 31, 30, 32, 34, 36, 40, 38, 42, 33,
- 35, 37, 41, 39, 43, 44, 0, 0, 0, 0,
- 0, 3, 0, 0, 0, 0, 0, 44, 44, 44,
- 44, 24, 44, 0, 44, 44, 4, 44, 44, 0,
- 0, 44, 44, 44, 44, 44, 44, 0, 0, 0,
- 0, 0, 13, 54, 53, 56, 55, 57, 52, 46,
- 47, 48, 49, 50, 51, 45, 0, 0, 0, 0,
- 0, 44, 0, 0, 0, 0, 0, 0, 19, 20,
- 21, 22, 12, 8, 11, 7, 6, 0, 0, 5,
- 14, 15, 16, 17, 18, 44, 9, 0, 10
+ 2, 0, 1, 0, 25, 0, 27, 28, 29, 31,
+ 30, 33, 32, 34, 36, 38, 42, 40, 44, 35,
+ 37, 39, 43, 41, 45, 46, 0, 0, 0, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0, 46, 46,
+ 46, 46, 26, 46, 0, 46, 46, 4, 46, 46,
+ 0, 0, 0, 46, 46, 46, 46, 46, 46, 0,
+ 0, 0, 0, 0, 15, 57, 56, 62, 58, 59,
+ 60, 61, 63, 55, 48, 49, 50, 51, 52, 53,
+ 54, 47, 0, 0, 0, 0, 0, 0, 46, 0,
+ 0, 0, 0, 0, 0, 21, 22, 23, 24, 14,
+ 10, 13, 9, 6, 0, 0, 0, 0, 5, 16,
+ 17, 18, 19, 20, 0, 46, 46, 11, 0, 0,
+ 0, 46, 7, 12, 0, 8
};
/* YYPGOTO[NTERM-NUM]. */
static const yytype_int8 yypgoto[] =
{
- -38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
- -38, -38, -37, -38
+ -39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
+ -39, -39, -38, -39
};
/* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int8 yydefgoto[] =
{
- -1, 1, 31, 32, 33, 34, 35, 36, 37, 38,
- 39, 40, 43, 75
+ -1, 1, 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 44, 81
};
/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
@@ -668,143 +683,173 @@ static const yytype_int8 yydefgoto[] =
number is the opposite. If YYTABLE_NINF, syntax error. */
static const yytype_uint8 yytable[] =
{
- 57, 58, 59, 60, 46, 61, 41, 76, 77, 42,
- 78, 79, 44, 45, 82, 83, 84, 85, 86, 87,
- 49, 50, 48, 53, 51, 52, 0, 54, 55, 56,
- 80, 47, 81, 97, 105, 0, 0, 0, 0, 2,
- 3, 0, 4, 0, 98, 5, 6, 7, 8, 9,
- 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
- 20, 21, 22, 23, 24, 62, 63, 64, 107, 0,
- 25, 26, 27, 28, 29, 30, 88, 63, 64, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 65, 66,
- 67, 68, 69, 0, 70, 71, 72, 73, 74, 65,
- 66, 67, 68, 69, 0, 70, 71, 72, 73, 74,
- 89, 63, 64, 0, 0, 0, 0, 0, 0, 0,
- 0, 90, 63, 64, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 65, 66, 67, 68, 69, 0, 70,
- 71, 72, 73, 74, 65, 66, 67, 68, 69, 0,
- 70, 71, 72, 73, 74, 91, 63, 64, 0, 0,
- 0, 0, 0, 0, 0, 0, 92, 63, 64, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 65, 66,
- 67, 68, 69, 0, 70, 71, 72, 73, 74, 65,
- 66, 67, 68, 69, 0, 70, 71, 72, 73, 74,
- 93, 63, 64, 0, 0, 0, 0, 0, 0, 0,
- 0, 94, 63, 64, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 65, 66, 67, 68, 69, 0, 70,
- 71, 72, 73, 74, 65, 66, 67, 68, 69, 0,
- 70, 71, 72, 73, 74, 95, 63, 64, 0, 0,
- 0, 0, 0, 0, 0, 0, 96, 63, 64, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 65, 66,
- 67, 68, 69, 0, 70, 71, 72, 73, 74, 65,
- 66, 67, 68, 69, 0, 70, 71, 72, 73, 74,
- 99, 63, 64, 0, 0, 0, 0, 0, 0, 0,
- 0, 100, 63, 64, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 65, 66, 67, 68, 69, 0, 70,
- 71, 72, 73, 74, 65, 66, 67, 68, 69, 0,
- 70, 71, 72, 73, 74, 101, 63, 64, 0, 0,
- 0, 0, 0, 0, 0, 0, 102, 63, 64, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 65, 66,
- 67, 68, 69, 0, 70, 71, 72, 73, 74, 65,
- 66, 67, 68, 69, 0, 70, 71, 72, 73, 74,
- 103, 63, 64, 0, 0, 0, 0, 0, 0, 0,
- 0, 104, 63, 64, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 65, 66, 67, 68, 69, 0, 70,
- 71, 72, 73, 74, 65, 66, 67, 68, 69, 0,
- 70, 71, 72, 73, 74, 106, 63, 64, 0, 0,
- 0, 0, 0, 0, 0, 0, 108, 63, 64, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 65, 66,
- 67, 68, 69, 0, 70, 71, 72, 73, 74, 65,
- 66, 67, 68, 69, 0, 70, 71, 72, 73, 74
+ 59, 60, 61, 62, 42, 63, 104, 82, 83, 105,
+ 84, 85, 43, 45, 46, 89, 90, 91, 92, 93,
+ 94, 2, 3, 47, 4, 49, 50, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 54, 0, 55,
+ 107, 56, 57, 48, 106, 25, 26, 27, 28, 29,
+ 30, 31, 64, 65, 66, 51, 58, 52, 86, 87,
+ 88, 114, 53, 115, 116, 118, 121, 119, 120, 95,
+ 65, 66, 0, 124, 0, 67, 68, 69, 70, 71,
+ 72, 73, 74, 0, 75, 76, 77, 78, 79, 80,
+ 0, 0, 67, 68, 69, 70, 71, 72, 73, 74,
+ 0, 75, 76, 77, 78, 79, 80, 96, 65, 66,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 97, 65, 66, 0, 0, 0, 0, 0,
+ 67, 68, 69, 70, 71, 72, 73, 74, 0, 75,
+ 76, 77, 78, 79, 80, 67, 68, 69, 70, 71,
+ 72, 73, 74, 0, 75, 76, 77, 78, 79, 80,
+ 98, 65, 66, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 99, 65, 66, 0, 0,
+ 0, 0, 0, 67, 68, 69, 70, 71, 72, 73,
+ 74, 0, 75, 76, 77, 78, 79, 80, 67, 68,
+ 69, 70, 71, 72, 73, 74, 0, 75, 76, 77,
+ 78, 79, 80, 100, 65, 66, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 101, 65,
+ 66, 0, 0, 0, 0, 0, 67, 68, 69, 70,
+ 71, 72, 73, 74, 0, 75, 76, 77, 78, 79,
+ 80, 67, 68, 69, 70, 71, 72, 73, 74, 0,
+ 75, 76, 77, 78, 79, 80, 102, 65, 66, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 103, 65, 66, 0, 0, 0, 0, 0, 67,
+ 68, 69, 70, 71, 72, 73, 74, 0, 75, 76,
+ 77, 78, 79, 80, 67, 68, 69, 70, 71, 72,
+ 73, 74, 0, 75, 76, 77, 78, 79, 80, 108,
+ 65, 66, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 109, 65, 66, 0, 0, 0,
+ 0, 0, 67, 68, 69, 70, 71, 72, 73, 74,
+ 0, 75, 76, 77, 78, 79, 80, 67, 68, 69,
+ 70, 71, 72, 73, 74, 0, 75, 76, 77, 78,
+ 79, 80, 110, 65, 66, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 111, 65, 66,
+ 0, 0, 0, 0, 0, 67, 68, 69, 70, 71,
+ 72, 73, 74, 0, 75, 76, 77, 78, 79, 80,
+ 67, 68, 69, 70, 71, 72, 73, 74, 0, 75,
+ 76, 77, 78, 79, 80, 112, 65, 66, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 113, 65, 66, 0, 0, 0, 0, 0, 67, 68,
+ 69, 70, 71, 72, 73, 74, 0, 75, 76, 77,
+ 78, 79, 80, 67, 68, 69, 70, 71, 72, 73,
+ 74, 0, 75, 76, 77, 78, 79, 80, 117, 65,
+ 66, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 122, 65, 66, 0, 0, 0, 0,
+ 0, 67, 68, 69, 70, 71, 72, 73, 74, 0,
+ 75, 76, 77, 78, 79, 80, 67, 68, 69, 70,
+ 71, 72, 73, 74, 0, 75, 76, 77, 78, 79,
+ 80, 123, 65, 66, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 125, 65, 66, 0,
+ 0, 0, 0, 0, 67, 68, 69, 70, 71, 72,
+ 73, 74, 0, 75, 76, 77, 78, 79, 80, 67,
+ 68, 69, 70, 71, 72, 73, 74, 0, 75, 76,
+ 77, 78, 79, 80
};
static const yytype_int8 yycheck[] =
{
- 37, 38, 39, 40, 3, 42, 3, 44, 45, 29,
- 47, 48, 34, 29, 51, 52, 53, 54, 55, 56,
- 26, 27, 30, 30, 30, 29, -1, 30, 30, 30,
- 30, 30, 30, 27, 30, -1, -1, -1, -1, 0,
- 1, -1, 3, -1, 81, 6, 7, 8, 9, 10,
- 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
- 21, 22, 23, 24, 25, 3, 4, 5, 105, -1,
- 31, 32, 33, 34, 35, 36, 3, 4, 5, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 26, 27,
- 28, 29, 30, -1, 32, 33, 34, 35, 36, 26,
- 27, 28, 29, 30, -1, 32, 33, 34, 35, 36,
- 3, 4, 5, -1, -1, -1, -1, -1, -1, -1,
- -1, 3, 4, 5, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 26, 27, 28, 29, 30, -1, 32,
- 33, 34, 35, 36, 26, 27, 28, 29, 30, -1,
- 32, 33, 34, 35, 36, 3, 4, 5, -1, -1,
- -1, -1, -1, -1, -1, -1, 3, 4, 5, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 26, 27,
- 28, 29, 30, -1, 32, 33, 34, 35, 36, 26,
- 27, 28, 29, 30, -1, 32, 33, 34, 35, 36,
- 3, 4, 5, -1, -1, -1, -1, -1, -1, -1,
- -1, 3, 4, 5, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 26, 27, 28, 29, 30, -1, 32,
- 33, 34, 35, 36, 26, 27, 28, 29, 30, -1,
- 32, 33, 34, 35, 36, 3, 4, 5, -1, -1,
- -1, -1, -1, -1, -1, -1, 3, 4, 5, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 26, 27,
- 28, 29, 30, -1, 32, 33, 34, 35, 36, 26,
- 27, 28, 29, 30, -1, 32, 33, 34, 35, 36,
+ 38, 39, 40, 41, 3, 43, 27, 45, 46, 30,
+ 48, 49, 32, 37, 32, 53, 54, 55, 56, 57,
+ 58, 0, 1, 3, 3, 33, 29, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 32, -1, 33,
+ 88, 33, 33, 33, 28, 34, 35, 36, 37, 38,
+ 39, 40, 3, 4, 5, 26, 33, 28, 33, 33,
+ 33, 33, 33, 33, 33, 30, 33, 115, 116, 3,
+ 4, 5, -1, 121, -1, 26, 27, 28, 29, 30,
+ 31, 32, 33, -1, 35, 36, 37, 38, 39, 40,
+ -1, -1, 26, 27, 28, 29, 30, 31, 32, 33,
+ -1, 35, 36, 37, 38, 39, 40, 3, 4, 5,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 3, 4, 5, -1, -1, -1, -1, -1,
+ 26, 27, 28, 29, 30, 31, 32, 33, -1, 35,
+ 36, 37, 38, 39, 40, 26, 27, 28, 29, 30,
+ 31, 32, 33, -1, 35, 36, 37, 38, 39, 40,
3, 4, 5, -1, -1, -1, -1, -1, -1, -1,
- -1, 3, 4, 5, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 26, 27, 28, 29, 30, -1, 32,
- 33, 34, 35, 36, 26, 27, 28, 29, 30, -1,
- 32, 33, 34, 35, 36, 3, 4, 5, -1, -1,
+ -1, -1, -1, -1, -1, 3, 4, 5, -1, -1,
+ -1, -1, -1, 26, 27, 28, 29, 30, 31, 32,
+ 33, -1, 35, 36, 37, 38, 39, 40, 26, 27,
+ 28, 29, 30, 31, 32, 33, -1, 35, 36, 37,
+ 38, 39, 40, 3, 4, 5, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 3, 4,
+ 5, -1, -1, -1, -1, -1, 26, 27, 28, 29,
+ 30, 31, 32, 33, -1, 35, 36, 37, 38, 39,
+ 40, 26, 27, 28, 29, 30, 31, 32, 33, -1,
+ 35, 36, 37, 38, 39, 40, 3, 4, 5, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 3, 4, 5, -1, -1, -1, -1, -1, 26,
+ 27, 28, 29, 30, 31, 32, 33, -1, 35, 36,
+ 37, 38, 39, 40, 26, 27, 28, 29, 30, 31,
+ 32, 33, -1, 35, 36, 37, 38, 39, 40, 3,
+ 4, 5, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 3, 4, 5, -1, -1, -1,
+ -1, -1, 26, 27, 28, 29, 30, 31, 32, 33,
+ -1, 35, 36, 37, 38, 39, 40, 26, 27, 28,
+ 29, 30, 31, 32, 33, -1, 35, 36, 37, 38,
+ 39, 40, 3, 4, 5, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 3, 4, 5,
+ -1, -1, -1, -1, -1, 26, 27, 28, 29, 30,
+ 31, 32, 33, -1, 35, 36, 37, 38, 39, 40,
+ 26, 27, 28, 29, 30, 31, 32, 33, -1, 35,
+ 36, 37, 38, 39, 40, 3, 4, 5, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 3, 4, 5, -1, -1, -1, -1, -1, 26, 27,
+ 28, 29, 30, 31, 32, 33, -1, 35, 36, 37,
+ 38, 39, 40, 26, 27, 28, 29, 30, 31, 32,
+ 33, -1, 35, 36, 37, 38, 39, 40, 3, 4,
+ 5, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 3, 4, 5, -1, -1, -1, -1,
+ -1, 26, 27, 28, 29, 30, 31, 32, 33, -1,
+ 35, 36, 37, 38, 39, 40, 26, 27, 28, 29,
+ 30, 31, 32, 33, -1, 35, 36, 37, 38, 39,
+ 40, 3, 4, 5, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, 3, 4, 5, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 26, 27,
- 28, 29, 30, -1, 32, 33, 34, 35, 36, 26,
- 27, 28, 29, 30, -1, 32, 33, 34, 35, 36,
- 3, 4, 5, -1, -1, -1, -1, -1, -1, -1,
- -1, 3, 4, 5, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 26, 27, 28, 29, 30, -1, 32,
- 33, 34, 35, 36, 26, 27, 28, 29, 30, -1,
- 32, 33, 34, 35, 36, 3, 4, 5, -1, -1,
- -1, -1, -1, -1, -1, -1, 3, 4, 5, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 26, 27,
- 28, 29, 30, -1, 32, 33, 34, 35, 36, 26,
- 27, 28, 29, 30, -1, 32, 33, 34, 35, 36
+ -1, -1, -1, -1, 26, 27, 28, 29, 30, 31,
+ 32, 33, -1, 35, 36, 37, 38, 39, 40, 26,
+ 27, 28, 29, 30, 31, 32, 33, -1, 35, 36,
+ 37, 38, 39, 40
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */
static const yytype_uint8 yystos[] =
{
- 0, 38, 0, 1, 3, 6, 7, 8, 9, 10,
+ 0, 42, 0, 1, 3, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
- 21, 22, 23, 24, 25, 31, 32, 33, 34, 35,
- 36, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 3, 29, 49, 34, 29, 3, 30, 30, 26,
- 27, 30, 29, 30, 30, 30, 30, 49, 49, 49,
- 49, 49, 3, 4, 5, 26, 27, 28, 29, 30,
- 32, 33, 34, 35, 36, 50, 49, 49, 49, 49,
- 30, 30, 49, 49, 49, 49, 49, 49, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 27, 49, 3,
- 3, 3, 3, 3, 3, 30, 3, 49, 3
+ 21, 22, 23, 24, 25, 34, 35, 36, 37, 38,
+ 39, 40, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 3, 32, 53, 37, 32, 3, 33, 33,
+ 29, 26, 28, 33, 32, 33, 33, 33, 33, 53,
+ 53, 53, 53, 53, 3, 4, 5, 26, 27, 28,
+ 29, 30, 31, 32, 33, 35, 36, 37, 38, 39,
+ 40, 54, 53, 53, 53, 53, 33, 33, 33, 53,
+ 53, 53, 53, 53, 53, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 27, 30, 28, 53, 3, 3,
+ 3, 3, 3, 3, 33, 33, 33, 3, 30, 53,
+ 53, 33, 3, 3, 53, 3
};
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
static const yytype_uint8 yyr1[] =
{
- 0, 37, 38, 38, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 40, 40, 40, 41, 41,
- 42, 42, 43, 43, 44, 44, 45, 45, 46, 46,
- 47, 47, 48, 48, 49, 49, 50, 50, 50, 50,
- 50, 50, 50, 50, 50, 50, 50, 50
+ 0, 41, 42, 42, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 44, 44, 44,
+ 45, 45, 46, 46, 47, 47, 48, 48, 49, 49,
+ 50, 50, 51, 51, 52, 52, 53, 53, 54, 54,
+ 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+ 54, 54, 54, 54
};
/* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
static const yytype_uint8 yyr2[] =
{
- 0, 2, 0, 2, 2, 4, 4, 4, 4, 5,
- 7, 4, 4, 3, 4, 4, 4, 4, 4, 3,
- 3, 3, 3, 1, 2, 1, 1, 1, 1, 1,
+ 0, 2, 0, 2, 2, 4, 4, 7, 9, 4,
+ 4, 5, 7, 4, 4, 3, 4, 4, 4, 4,
+ 4, 3, 3, 3, 3, 1, 2, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 0, 2, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1
+ 1, 1, 1, 1, 1, 1, 0, 2, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1
};
@@ -1487,65 +1532,92 @@ yyreduce:
switch (yyn)
{
case 4:
-#line 105 "cmFortranParser.y" /* yacc.c:1646 */
+#line 106 "cmFortranParser.y" /* yacc.c:1646 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_SetInInterface(parser, true);
}
-#line 1496 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1541 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
case 5:
-#line 109 "cmFortranParser.y" /* yacc.c:1646 */
+#line 110 "cmFortranParser.y" /* yacc.c:1646 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleUse(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1506 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1551 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
case 6:
-#line 114 "cmFortranParser.y" /* yacc.c:1646 */
+#line 115 "cmFortranParser.y" /* yacc.c:1646 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
- cmFortranParser_RuleModule(parser, (yyvsp[-2].string));
+ if (cmsysString_strcasecmp((yyvsp[-2].string), "function") != 0 &&
+ cmsysString_strcasecmp((yyvsp[-2].string), "procedure") != 0 &&
+ cmsysString_strcasecmp((yyvsp[-2].string), "subroutine") != 0) {
+ cmFortranParser_RuleModule(parser, (yyvsp[-2].string));
+ }
free((yyvsp[-2].string));
}
-#line 1516 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1565 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
case 7:
-#line 119 "cmFortranParser.y" /* yacc.c:1646 */
+#line 124 "cmFortranParser.y" /* yacc.c:1646 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
- cmFortranParser_SetInInterface(parser, true);
+ cmFortranParser_RuleUse(parser, (yyvsp[-4].string));
+ free((yyvsp[-4].string));
free((yyvsp[-2].string));
}
-#line 1526 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1576 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
case 8:
-#line 124 "cmFortranParser.y" /* yacc.c:1646 */
+#line 130 "cmFortranParser.y" /* yacc.c:1646 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
- cmFortranParser_SetInInterface(parser, false);
+ cmFortranParser_RuleUse(parser, (yyvsp[-6].string));
+ free((yyvsp[-6].string));
+ free((yyvsp[-4].string));
+ free((yyvsp[-2].string));
}
-#line 1535 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1588 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
case 9:
-#line 128 "cmFortranParser.y" /* yacc.c:1646 */
+#line 137 "cmFortranParser.y" /* yacc.c:1646 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
- cmFortranParser_RuleUse(parser, (yyvsp[-2].string));
+ cmFortranParser_SetInInterface(parser, true);
free((yyvsp[-2].string));
}
-#line 1545 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1598 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
case 10:
-#line 133 "cmFortranParser.y" /* yacc.c:1646 */
+#line 142 "cmFortranParser.y" /* yacc.c:1646 */
+ {
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_SetInInterface(parser, false);
+ }
+#line 1607 "cmFortranParser.cxx" /* yacc.c:1646 */
+ break;
+
+ case 11:
+#line 146 "cmFortranParser.y" /* yacc.c:1646 */
+ {
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleUse(parser, (yyvsp[-2].string));
+ free((yyvsp[-2].string));
+ }
+#line 1617 "cmFortranParser.cxx" /* yacc.c:1646 */
+ break;
+
+ case 12:
+#line 151 "cmFortranParser.y" /* yacc.c:1646 */
{
if (cmsysString_strcasecmp((yyvsp[-4].string), "non_intrinsic") == 0) {
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
@@ -1554,139 +1626,139 @@ yyreduce:
free((yyvsp[-4].string));
free((yyvsp[-2].string));
}
-#line 1558 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1630 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
- case 11:
-#line 141 "cmFortranParser.y" /* yacc.c:1646 */
+ case 13:
+#line 159 "cmFortranParser.y" /* yacc.c:1646 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1568 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1640 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
- case 12:
-#line 146 "cmFortranParser.y" /* yacc.c:1646 */
+ case 14:
+#line 164 "cmFortranParser.y" /* yacc.c:1646 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleLineDirective(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1578 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1650 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
- case 13:
-#line 151 "cmFortranParser.y" /* yacc.c:1646 */
+ case 15:
+#line 169 "cmFortranParser.y" /* yacc.c:1646 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1588 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1660 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
- case 14:
-#line 156 "cmFortranParser.y" /* yacc.c:1646 */
+ case 16:
+#line 174 "cmFortranParser.y" /* yacc.c:1646 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1598 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1670 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
- case 15:
-#line 161 "cmFortranParser.y" /* yacc.c:1646 */
+ case 17:
+#line 179 "cmFortranParser.y" /* yacc.c:1646 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleDefine(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1608 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1680 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
- case 16:
-#line 166 "cmFortranParser.y" /* yacc.c:1646 */
+ case 18:
+#line 184 "cmFortranParser.y" /* yacc.c:1646 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleUndef(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1618 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1690 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
- case 17:
-#line 171 "cmFortranParser.y" /* yacc.c:1646 */
+ case 19:
+#line 189 "cmFortranParser.y" /* yacc.c:1646 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleIfdef(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1628 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1700 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
- case 18:
-#line 176 "cmFortranParser.y" /* yacc.c:1646 */
+ case 20:
+#line 194 "cmFortranParser.y" /* yacc.c:1646 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleIfndef(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1638 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1710 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
- case 19:
-#line 181 "cmFortranParser.y" /* yacc.c:1646 */
+ case 21:
+#line 199 "cmFortranParser.y" /* yacc.c:1646 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleIf(parser);
}
-#line 1647 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1719 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
- case 20:
-#line 185 "cmFortranParser.y" /* yacc.c:1646 */
+ case 22:
+#line 203 "cmFortranParser.y" /* yacc.c:1646 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleElif(parser);
}
-#line 1656 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1728 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
- case 21:
-#line 189 "cmFortranParser.y" /* yacc.c:1646 */
+ case 23:
+#line 207 "cmFortranParser.y" /* yacc.c:1646 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleElse(parser);
}
-#line 1665 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1737 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
- case 22:
-#line 193 "cmFortranParser.y" /* yacc.c:1646 */
+ case 24:
+#line 211 "cmFortranParser.y" /* yacc.c:1646 */
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleEndif(parser);
}
-#line 1674 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1746 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
- case 46:
-#line 215 "cmFortranParser.y" /* yacc.c:1646 */
+ case 48:
+#line 233 "cmFortranParser.y" /* yacc.c:1646 */
{ free ((yyvsp[0].string)); }
-#line 1680 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1752 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
- case 52:
-#line 221 "cmFortranParser.y" /* yacc.c:1646 */
+ case 55:
+#line 240 "cmFortranParser.y" /* yacc.c:1646 */
{ free ((yyvsp[0].string)); }
-#line 1686 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1758 "cmFortranParser.cxx" /* yacc.c:1646 */
break;
-#line 1690 "cmFortranParser.cxx" /* yacc.c:1646 */
+#line 1762 "cmFortranParser.cxx" /* yacc.c:1646 */
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -1916,6 +1988,6 @@ yyreturn:
#endif
return yyresult;
}
-#line 229 "cmFortranParser.y" /* yacc.c:1906 */
+#line 251 "cmFortranParser.y" /* yacc.c:1906 */
/* End of grammar */
diff --git a/Source/cmFortranParser.y b/Source/cmFortranParser.y
index b856a1a..d3327e9 100644
--- a/Source/cmFortranParser.y
+++ b/Source/cmFortranParser.y
@@ -85,7 +85,7 @@ static void cmFortran_yyerror(yyscan_t yyscanner, const char* message)
%token CPP_IFDEF CPP_IFNDEF CPP_IF CPP_ELSE CPP_ELIF CPP_ENDIF
%token F90PPR_IFDEF F90PPR_IFNDEF F90PPR_IF
%token F90PPR_ELSE F90PPR_ELIF F90PPR_ENDIF
-%token COMMA DCOLON
+%token COMMA COLON DCOLON LPAREN RPAREN
%token <number> UNTERMINATED_STRING
%token <string> STRING WORD
%token <string> CPP_INCLUDE_ANGLE
@@ -93,6 +93,7 @@ static void cmFortran_yyerror(yyscan_t yyscanner, const char* message)
%token INCLUDE
%token INTERFACE
%token MODULE
+%token SUBMODULE
%token USE
/*-------------------------------------------------------------------------*/
@@ -113,9 +114,26 @@ stmt:
}
| MODULE WORD other EOSTMT {
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
- cmFortranParser_RuleModule(parser, $2);
+ if (cmsysString_strcasecmp($2, "function") != 0 &&
+ cmsysString_strcasecmp($2, "procedure") != 0 &&
+ cmsysString_strcasecmp($2, "subroutine") != 0) {
+ cmFortranParser_RuleModule(parser, $2);
+ }
free($2);
}
+| SUBMODULE LPAREN WORD RPAREN WORD other EOSTMT {
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleUse(parser, $3);
+ free($3);
+ free($5);
+ }
+| SUBMODULE LPAREN WORD COLON WORD RPAREN WORD other EOSTMT {
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleUse(parser, $3);
+ free($3);
+ free($5);
+ free($7);
+ }
| INTERFACE WORD other EOSTMT {
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_SetInInterface(parser, true);
@@ -217,11 +235,15 @@ misc_code:
| INCLUDE
| INTERFACE
| MODULE
+| SUBMODULE
| USE
| STRING { free ($1); }
| GARBAGE
| ASSIGNMENT_OP
+| COLON
| DCOLON
+| LPAREN
+| RPAREN
| COMMA
| UNTERMINATED_STRING
;
diff --git a/Source/cmFortranParserTokens.h b/Source/cmFortranParserTokens.h
index e988df4..18b9e0a 100644
--- a/Source/cmFortranParserTokens.h
+++ b/Source/cmFortranParserTokens.h
@@ -69,16 +69,20 @@ extern int cmFortran_yydebug;
F90PPR_ELIF = 279,
F90PPR_ENDIF = 280,
COMMA = 281,
- DCOLON = 282,
- UNTERMINATED_STRING = 283,
- STRING = 284,
- WORD = 285,
- CPP_INCLUDE_ANGLE = 286,
- END = 287,
- INCLUDE = 288,
- INTERFACE = 289,
- MODULE = 290,
- USE = 291
+ COLON = 282,
+ DCOLON = 283,
+ LPAREN = 284,
+ RPAREN = 285,
+ UNTERMINATED_STRING = 286,
+ STRING = 287,
+ WORD = 288,
+ CPP_INCLUDE_ANGLE = 289,
+ END = 290,
+ INCLUDE = 291,
+ INTERFACE = 292,
+ MODULE = 293,
+ SUBMODULE = 294,
+ USE = 295
};
#endif
/* Tokens. */
@@ -106,16 +110,20 @@ extern int cmFortran_yydebug;
#define F90PPR_ELIF 279
#define F90PPR_ENDIF 280
#define COMMA 281
-#define DCOLON 282
-#define UNTERMINATED_STRING 283
-#define STRING 284
-#define WORD 285
-#define CPP_INCLUDE_ANGLE 286
-#define END 287
-#define INCLUDE 288
-#define INTERFACE 289
-#define MODULE 290
-#define USE 291
+#define COLON 282
+#define DCOLON 283
+#define LPAREN 284
+#define RPAREN 285
+#define UNTERMINATED_STRING 286
+#define STRING 287
+#define WORD 288
+#define CPP_INCLUDE_ANGLE 289
+#define END 290
+#define INCLUDE 291
+#define INTERFACE 292
+#define MODULE 293
+#define SUBMODULE 294
+#define USE 295
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
@@ -126,7 +134,7 @@ union YYSTYPE
char* string;
-#line 130 "cmFortranParserTokens.h" /* yacc.c:1909 */
+#line 138 "cmFortranParserTokens.h" /* yacc.c:1909 */
};
typedef union YYSTYPE YYSTYPE;
diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx
index 40c54db..8aa1b77 100644
--- a/Source/cmFunctionCommand.cxx
+++ b/Source/cmFunctionCommand.cxx
@@ -169,10 +169,9 @@ bool cmFunctionFunctionBlocker::IsFunctionBlocked(
// remove the function blocker now that the function is defined
mf.RemoveFunctionBlocker(this, lff);
return true;
- } else {
- // decrement for each nested function that ends
- this->Depth--;
}
+ // decrement for each nested function that ends
+ this->Depth--;
}
// if it wasn't an endfunction and we are not executing then we must be
@@ -202,7 +201,7 @@ bool cmFunctionFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
bool cmFunctionCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&)
{
- if (args.size() < 1) {
+ if (args.empty()) {
this->SetError("called with incorrect number of arguments");
return false;
}
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 7dd8e7f..f181cf6 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -1162,7 +1162,28 @@ bool cmGeneratorTarget::NeedRelinkBeforeInstall(
// If either a build or install tree rpath is set then the rpath
// will likely change between the build tree and install tree and
// this target must be relinked.
- return this->HaveBuildTreeRPATH(config) || this->HaveInstallTreeRPATH();
+ bool have_rpath =
+ this->HaveBuildTreeRPATH(config) || this->HaveInstallTreeRPATH();
+ bool is_ninja =
+ this->LocalGenerator->GetGlobalGenerator()->GetName() == "Ninja";
+
+ if (have_rpath && is_ninja) {
+ std::ostringstream w;
+ /* clang-format off */
+ w <<
+ "The install of the " << this->GetName() << " target requires "
+ "changing an RPATH from the build tree, but this is not supported "
+ "with the Ninja generator unless on an ELF-based platform. The "
+ "CMAKE_BUILD_WITH_INSTALL_RPATH variable may be set to avoid this "
+ "relinking step."
+ ;
+ /* clang-format on */
+
+ cmake* cm = this->LocalGenerator->GetCMakeInstance();
+ cm->IssueMessage(cmake::FATAL_ERROR, w.str(), this->GetBacktrace());
+ }
+
+ return have_rpath;
}
bool cmGeneratorTarget::IsChrpathUsed(const std::string& config) const
@@ -1280,11 +1301,11 @@ bool cmGeneratorTarget::HasMacOSXRpathInstallNameDir(
if (!this->Makefile->IsSet("CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG")) {
std::ostringstream w;
- w << "Attempting to use";
+ w << "Attempting to use ";
if (macosx_rpath) {
- w << " MACOSX_RPATH";
+ w << "MACOSX_RPATH";
} else {
- w << " @rpath";
+ w << "@rpath";
}
w << " without CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG being set.";
w << " This could be because you are using a Mac OS X version";
@@ -3862,23 +3883,35 @@ void cmGeneratorTarget::GetTargetVersion(bool soversion, int& major,
}
}
-std::string cmGeneratorTarget::GetFortranModuleDirectory() const
+std::string cmGeneratorTarget::GetFortranModuleDirectory(
+ std::string const& working_dir) const
{
if (!this->FortranModuleDirectoryCreated) {
this->FortranModuleDirectory = true;
- this->FortranModuleDirectory = this->CreateFortranModuleDirectory();
+ this->FortranModuleDirectory =
+ this->CreateFortranModuleDirectory(working_dir);
}
return this->FortranModuleDirectory;
}
-std::string cmGeneratorTarget::CreateFortranModuleDirectory() const
+std::string cmGeneratorTarget::CreateFortranModuleDirectory(
+ std::string const& working_dir) const
{
std::string mod_dir;
- const char* target_mod_dir = this->GetProperty("Fortran_MODULE_DIRECTORY");
+ std::string target_mod_dir;
+ if (const char* prop = this->GetProperty("Fortran_MODULE_DIRECTORY")) {
+ target_mod_dir = prop;
+ } else {
+ std::string const& default_mod_dir =
+ this->LocalGenerator->GetCurrentBinaryDirectory();
+ if (default_mod_dir != working_dir) {
+ target_mod_dir = default_mod_dir;
+ }
+ }
const char* moddir_flag =
this->Makefile->GetDefinition("CMAKE_Fortran_MODDIR_FLAG");
- if (target_mod_dir && moddir_flag) {
+ if (!target_mod_dir.empty() && moddir_flag) {
// Compute the full path to the module directory.
if (cmSystemTools::FileIsFullPath(target_mod_dir)) {
// Already a full path.
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 715220e..8e17b8f 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -537,12 +537,13 @@ public:
void GetTargetVersion(bool soversion, int& major, int& minor,
int& patch) const;
- std::string GetFortranModuleDirectory() const;
+ std::string GetFortranModuleDirectory(std::string const& working_dir) const;
private:
void AddSourceCommon(const std::string& src);
- std::string CreateFortranModuleDirectory() const;
+ std::string CreateFortranModuleDirectory(
+ std::string const& working_dir) const;
mutable bool FortranModuleDirectoryCreated;
mutable std::string FortranModuleDirectory;
diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx
index 2307e08..8063328 100644
--- a/Source/cmGetPropertyCommand.cxx
+++ b/Source/cmGetPropertyCommand.cxx
@@ -252,19 +252,17 @@ bool cmGetPropertyCommand::HandleTargetMode()
if (this->PropertyName == "ALIASED_TARGET") {
if (this->Makefile->IsAlias(this->Name)) {
return this->StoreResult(target->GetName().c_str());
- } else {
- return this->StoreResult(NULL);
}
+ return this->StoreResult(CM_NULLPTR);
}
return this->StoreResult(
target->GetProperty(this->PropertyName, this->Makefile));
- } else {
- std::ostringstream e;
- e << "could not find TARGET " << this->Name
- << ". Perhaps it has not yet been created.";
- this->SetError(e.str());
- return false;
}
+ std::ostringstream e;
+ e << "could not find TARGET " << this->Name
+ << ". Perhaps it has not yet been created.";
+ this->SetError(e.str());
+ return false;
}
bool cmGetPropertyCommand::HandleSourceMode()
@@ -277,13 +275,11 @@ bool cmGetPropertyCommand::HandleSourceMode()
// Get the source file.
if (cmSourceFile* sf = this->Makefile->GetOrCreateSource(this->Name)) {
return this->StoreResult(sf->GetPropertyForUser(this->PropertyName));
- } else {
- std::ostringstream e;
- e << "given SOURCE name that could not be found or created: "
- << this->Name;
- this->SetError(e.str());
- return false;
}
+ std::ostringstream e;
+ e << "given SOURCE name that could not be found or created: " << this->Name;
+ this->SetError(e.str());
+ return false;
}
bool cmGetPropertyCommand::HandleTestMode()
@@ -347,11 +343,9 @@ bool cmGetPropertyCommand::HandleInstallMode()
bool isSet = file->GetProperty(this->PropertyName, value);
return this->StoreResult(isSet ? value.c_str() : CM_NULLPTR);
- } else {
- std::ostringstream e;
- e << "given INSTALL name that could not be found or created: "
- << this->Name;
- this->SetError(e.str());
- return false;
}
+ std::ostringstream e;
+ e << "given INSTALL name that could not be found or created: " << this->Name;
+ this->SetError(e.str());
+ return false;
}
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index ef8266f..4772474 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -94,6 +94,7 @@ cmGlobalGenerator::cmGlobalGenerator(cmake* cm)
this->TryCompileOuterMakefile = CM_NULLPTR;
this->ConfigureDoneCMP0026AndCMP0024 = false;
+ this->FirstTimeProgress = 0.0f;
cm->GetState()->SetMinGWMake(false);
cm->GetState()->SetMSYSShell(false);
@@ -1060,16 +1061,16 @@ void cmGlobalGenerator::Configure()
this->ConfigureDoneCMP0026AndCMP0024 = true;
// Put a copy of each global target in every directory.
- cmTargets globalTargets;
- this->CreateDefaultGlobalTargets(&globalTargets);
+ std::vector<GlobalTargetInfo> globalTargets;
+ this->CreateDefaultGlobalTargets(globalTargets);
for (unsigned int i = 0; i < this->Makefiles.size(); ++i) {
cmMakefile* mf = this->Makefiles[i];
cmTargets* targets = &(mf->GetTargets());
- cmTargets::iterator tit;
- for (tit = globalTargets.begin(); tit != globalTargets.end(); ++tit) {
- (*targets)[tit->first] = tit->second;
- (*targets)[tit->first].SetMakefile(mf);
+ for (std::vector<GlobalTargetInfo>::iterator gti = globalTargets.begin();
+ gti != globalTargets.end(); ++gti) {
+ targets->insert(
+ cmTargets::value_type(gti->Name, this->CreateGlobalTarget(*gti, mf)));
}
}
@@ -2069,15 +2070,27 @@ inline std::string removeQuotes(const std::string& s)
return s;
}
-void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
+void cmGlobalGenerator::CreateDefaultGlobalTargets(
+ std::vector<GlobalTargetInfo>& targets)
+{
+ this->AddGlobalTarget_Package(targets);
+ this->AddGlobalTarget_PackageSource(targets);
+ this->AddGlobalTarget_Test(targets);
+ this->AddGlobalTarget_EditCache(targets);
+ this->AddGlobalTarget_RebuildCache(targets);
+ this->AddGlobalTarget_Install(targets);
+}
+
+void cmGlobalGenerator::AddGlobalTarget_Package(
+ std::vector<GlobalTargetInfo>& targets)
{
cmMakefile* mf = this->Makefiles[0];
const char* cmakeCfgIntDir = this->GetCMakeCFGIntDir();
-
- // CPack
- std::string workingDir = mf->GetCurrentBinaryDirectory();
- cmCustomCommandLines cpackCommandLines;
- std::vector<std::string> depends;
+ GlobalTargetInfo gti;
+ gti.Name = this->GetPackageTargetName();
+ gti.Message = "Run CPack packaging tool...";
+ gti.UsesTerminal = true;
+ gti.WorkingDir = mf->GetCurrentBinaryDirectory();
cmCustomCommandLine singleLine;
singleLine.push_back(cmSystemTools::GetCPackCommand());
if (cmakeCfgIntDir && *cmakeCfgIntDir && cmakeCfgIntDir[0] != '.') {
@@ -2086,55 +2099,61 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
}
singleLine.push_back("--config");
std::string configFile = mf->GetCurrentBinaryDirectory();
- ;
configFile += "/CPackConfig.cmake";
std::string relConfigFile = "./CPackConfig.cmake";
singleLine.push_back(relConfigFile);
- cpackCommandLines.push_back(singleLine);
+ gti.CommandLines.push_back(singleLine);
if (this->GetPreinstallTargetName()) {
- depends.push_back(this->GetPreinstallTargetName());
+ gti.Depends.push_back(this->GetPreinstallTargetName());
} else {
const char* noPackageAll =
mf->GetDefinition("CMAKE_SKIP_PACKAGE_ALL_DEPENDENCY");
if (!noPackageAll || cmSystemTools::IsOff(noPackageAll)) {
- depends.push_back(this->GetAllTargetName());
+ gti.Depends.push_back(this->GetAllTargetName());
}
}
if (cmSystemTools::FileExists(configFile.c_str())) {
- (*targets)[this->GetPackageTargetName()] = this->CreateGlobalTarget(
- this->GetPackageTargetName(), "Run CPack packaging tool...",
- &cpackCommandLines, depends, workingDir.c_str(), /*uses_terminal*/ true);
+ targets.push_back(gti);
}
- // CPack source
+}
+
+void cmGlobalGenerator::AddGlobalTarget_PackageSource(
+ std::vector<GlobalTargetInfo>& targets)
+{
+ cmMakefile* mf = this->Makefiles[0];
const char* packageSourceTargetName = this->GetPackageSourceTargetName();
if (packageSourceTargetName) {
- cpackCommandLines.erase(cpackCommandLines.begin(),
- cpackCommandLines.end());
- singleLine.erase(singleLine.begin(), singleLine.end());
- depends.erase(depends.begin(), depends.end());
+ GlobalTargetInfo gti;
+ gti.Name = packageSourceTargetName;
+ gti.Message = "Run CPack packaging tool for source...";
+ gti.WorkingDir = mf->GetCurrentBinaryDirectory();
+ gti.UsesTerminal = true;
+ cmCustomCommandLine singleLine;
singleLine.push_back(cmSystemTools::GetCPackCommand());
singleLine.push_back("--config");
- configFile = mf->GetCurrentBinaryDirectory();
- ;
+ std::string configFile = mf->GetCurrentBinaryDirectory();
configFile += "/CPackSourceConfig.cmake";
- relConfigFile = "./CPackSourceConfig.cmake";
+ std::string relConfigFile = "./CPackSourceConfig.cmake";
singleLine.push_back(relConfigFile);
if (cmSystemTools::FileExists(configFile.c_str())) {
singleLine.push_back(configFile);
- cpackCommandLines.push_back(singleLine);
- (*targets)[packageSourceTargetName] = this->CreateGlobalTarget(
- packageSourceTargetName, "Run CPack packaging tool for source...",
- &cpackCommandLines, depends, workingDir.c_str(),
- /*uses_terminal*/ true);
+ gti.CommandLines.push_back(singleLine);
+ targets.push_back(gti);
}
}
+}
- // Test
+void cmGlobalGenerator::AddGlobalTarget_Test(
+ std::vector<GlobalTargetInfo>& targets)
+{
+ cmMakefile* mf = this->Makefiles[0];
+ const char* cmakeCfgIntDir = this->GetCMakeCFGIntDir();
if (mf->IsOn("CMAKE_TESTING_ENABLED")) {
- cpackCommandLines.erase(cpackCommandLines.begin(),
- cpackCommandLines.end());
- singleLine.erase(singleLine.begin(), singleLine.end());
- depends.erase(depends.begin(), depends.end());
+ GlobalTargetInfo gti;
+ gti.Name = this->GetTestTargetName();
+ gti.Message = "Running tests...";
+ gti.UsesTerminal = true;
+ cmCustomCommandLine singleLine;
singleLine.push_back(cmSystemTools::GetCTestCommand());
singleLine.push_back("--force-new-ctest-process");
if (cmakeCfgIntDir && *cmakeCfgIntDir && cmakeCfgIntDir[0] != '.') {
@@ -2145,20 +2164,19 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
{
singleLine.push_back("$(ARGS)");
}
- cpackCommandLines.push_back(singleLine);
- (*targets)[this->GetTestTargetName()] =
- this->CreateGlobalTarget(this->GetTestTargetName(), "Running tests...",
- &cpackCommandLines, depends, CM_NULLPTR,
- /*uses_terminal*/ true);
+ gti.CommandLines.push_back(singleLine);
+ targets.push_back(gti);
}
+}
- // Edit Cache
+void cmGlobalGenerator::AddGlobalTarget_EditCache(
+ std::vector<GlobalTargetInfo>& targets)
+{
const char* editCacheTargetName = this->GetEditCacheTargetName();
if (editCacheTargetName) {
- cpackCommandLines.erase(cpackCommandLines.begin(),
- cpackCommandLines.end());
- singleLine.erase(singleLine.begin(), singleLine.end());
- depends.erase(depends.begin(), depends.end());
+ GlobalTargetInfo gti;
+ gti.Name = editCacheTargetName;
+ cmCustomCommandLine singleLine;
// Use generator preference for the edit_cache rule if it is defined.
std::string edit_cmd = this->GetEditCacheCommand();
@@ -2166,39 +2184,46 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
singleLine.push_back(edit_cmd);
singleLine.push_back("-H$(CMAKE_SOURCE_DIR)");
singleLine.push_back("-B$(CMAKE_BINARY_DIR)");
- cpackCommandLines.push_back(singleLine);
- (*targets)[editCacheTargetName] = this->CreateGlobalTarget(
- editCacheTargetName, "Running CMake cache editor...",
- &cpackCommandLines, depends, CM_NULLPTR, /*uses_terminal*/ true);
+ gti.Message = "Running CMake cache editor...";
+ gti.UsesTerminal = true;
+ gti.CommandLines.push_back(singleLine);
} else {
singleLine.push_back(cmSystemTools::GetCMakeCommand());
singleLine.push_back("-E");
singleLine.push_back("echo");
singleLine.push_back("No interactive CMake dialog available.");
- cpackCommandLines.push_back(singleLine);
- (*targets)[editCacheTargetName] = this->CreateGlobalTarget(
- editCacheTargetName, "No interactive CMake dialog available...",
- &cpackCommandLines, depends, CM_NULLPTR, /*uses_terminal*/ false);
+ gti.Message = "No interactive CMake dialog available...";
+ gti.UsesTerminal = false;
+ gti.CommandLines.push_back(singleLine);
}
+
+ targets.push_back(gti);
}
+}
- // Rebuild Cache
+void cmGlobalGenerator::AddGlobalTarget_RebuildCache(
+ std::vector<GlobalTargetInfo>& targets)
+{
const char* rebuildCacheTargetName = this->GetRebuildCacheTargetName();
if (rebuildCacheTargetName) {
- cpackCommandLines.erase(cpackCommandLines.begin(),
- cpackCommandLines.end());
- singleLine.erase(singleLine.begin(), singleLine.end());
- depends.erase(depends.begin(), depends.end());
+ GlobalTargetInfo gti;
+ gti.Name = rebuildCacheTargetName;
+ gti.Message = "Running CMake to regenerate build system...";
+ gti.UsesTerminal = true;
+ cmCustomCommandLine singleLine;
singleLine.push_back(cmSystemTools::GetCMakeCommand());
singleLine.push_back("-H$(CMAKE_SOURCE_DIR)");
singleLine.push_back("-B$(CMAKE_BINARY_DIR)");
- cpackCommandLines.push_back(singleLine);
- (*targets)[rebuildCacheTargetName] = this->CreateGlobalTarget(
- rebuildCacheTargetName, "Running CMake to regenerate build system...",
- &cpackCommandLines, depends, CM_NULLPTR, /*uses_terminal*/ true);
+ gti.CommandLines.push_back(singleLine);
+ targets.push_back(gti);
}
+}
- // Install
+void cmGlobalGenerator::AddGlobalTarget_Install(
+ std::vector<GlobalTargetInfo>& targets)
+{
+ cmMakefile* mf = this->Makefiles[0];
+ const char* cmakeCfgIntDir = this->GetCMakeCFGIntDir();
bool skipInstallRules = mf->IsOn("CMAKE_SKIP_INSTALL_RULES");
if (this->InstallTargetEnabled && skipInstallRules) {
this->CMakeInstance->IssueMessage(
@@ -2208,9 +2233,6 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
} else if (this->InstallTargetEnabled && !skipInstallRules) {
if (!cmakeCfgIntDir || !*cmakeCfgIntDir || cmakeCfgIntDir[0] == '.') {
std::set<std::string>* componentsSet = &this->InstallComponents;
- cpackCommandLines.erase(cpackCommandLines.begin(),
- cpackCommandLines.end());
- depends.erase(depends.begin(), depends.end());
std::ostringstream ostr;
if (!componentsSet->empty()) {
ostr << "Available install components are: ";
@@ -2218,23 +2240,25 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
} else {
ostr << "Only default component available";
}
- singleLine.push_back(ostr.str());
- (*targets)["list_install_components"] = this->CreateGlobalTarget(
- "list_install_components", ostr.str().c_str(), &cpackCommandLines,
- depends, CM_NULLPTR, /*uses_terminal*/ false);
+ GlobalTargetInfo gti;
+ gti.Name = "list_install_components";
+ gti.Message = ostr.str();
+ gti.UsesTerminal = false;
+ targets.push_back(gti);
}
std::string cmd = cmSystemTools::GetCMakeCommand();
- cpackCommandLines.erase(cpackCommandLines.begin(),
- cpackCommandLines.end());
- singleLine.erase(singleLine.begin(), singleLine.end());
- depends.erase(depends.begin(), depends.end());
+ GlobalTargetInfo gti;
+ gti.Name = this->GetInstallTargetName();
+ gti.Message = "Install the project...";
+ gti.UsesTerminal = true;
+ cmCustomCommandLine singleLine;
if (this->GetPreinstallTargetName()) {
- depends.push_back(this->GetPreinstallTargetName());
+ gti.Depends.push_back(this->GetPreinstallTargetName());
} else {
const char* noall =
mf->GetDefinition("CMAKE_SKIP_INSTALL_ALL_DEPENDENCY");
if (!noall || cmSystemTools::IsOff(noall)) {
- depends.push_back(this->GetAllTargetName());
+ gti.Depends.push_back(this->GetAllTargetName());
}
}
if (mf->GetDefinition("CMake_BINARY_DIR") &&
@@ -2259,40 +2283,39 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
}
singleLine.push_back("-P");
singleLine.push_back("cmake_install.cmake");
- cpackCommandLines.push_back(singleLine);
- (*targets)[this->GetInstallTargetName()] = this->CreateGlobalTarget(
- this->GetInstallTargetName(), "Install the project...",
- &cpackCommandLines, depends, CM_NULLPTR, /*uses_terminal*/ true);
+ gti.CommandLines.push_back(singleLine);
+ targets.push_back(gti);
// install_local
if (const char* install_local = this->GetInstallLocalTargetName()) {
+ gti.Name = install_local;
+ gti.Message = "Installing only the local directory...";
+ gti.UsesTerminal = true;
+ gti.CommandLines.clear();
+
cmCustomCommandLine localCmdLine = singleLine;
localCmdLine.insert(localCmdLine.begin() + 1,
"-DCMAKE_INSTALL_LOCAL_ONLY=1");
- cpackCommandLines.erase(cpackCommandLines.begin(),
- cpackCommandLines.end());
- cpackCommandLines.push_back(localCmdLine);
- (*targets)[install_local] = this->CreateGlobalTarget(
- install_local, "Installing only the local directory...",
- &cpackCommandLines, depends, CM_NULLPTR, /*uses_terminal*/ true);
+ gti.CommandLines.push_back(localCmdLine);
+ targets.push_back(gti);
}
// install_strip
const char* install_strip = this->GetInstallStripTargetName();
if ((install_strip != CM_NULLPTR) && (mf->IsSet("CMAKE_STRIP"))) {
+ gti.Name = install_strip;
+ gti.Message = "Installing the project stripped...";
+ gti.UsesTerminal = true;
+ gti.CommandLines.clear();
+
cmCustomCommandLine stripCmdLine = singleLine;
stripCmdLine.insert(stripCmdLine.begin() + 1,
"-DCMAKE_INSTALL_DO_STRIP=1");
- cpackCommandLines.erase(cpackCommandLines.begin(),
- cpackCommandLines.end());
- cpackCommandLines.push_back(stripCmdLine);
-
- (*targets)[install_strip] = this->CreateGlobalTarget(
- install_strip, "Installing the project stripped...",
- &cpackCommandLines, depends, CM_NULLPTR, /*uses_terminal*/ true);
+ gti.CommandLines.push_back(stripCmdLine);
+ targets.push_back(gti);
}
}
}
@@ -2326,14 +2349,12 @@ bool cmGlobalGenerator::UseFolderProperty()
return false;
}
-cmTarget cmGlobalGenerator::CreateGlobalTarget(
- const std::string& name, const char* message,
- const cmCustomCommandLines* commandLines, std::vector<std::string> depends,
- const char* workingDirectory, bool uses_terminal)
+cmTarget cmGlobalGenerator::CreateGlobalTarget(GlobalTargetInfo const& gti,
+ cmMakefile* mf)
{
// Package
- cmTarget target;
- target.SetType(cmState::GLOBAL_TARGET, name);
+ cmTarget target(gti.Name, cmState::GLOBAL_TARGET, cmTarget::VisibilityNormal,
+ mf);
target.SetProperty("EXCLUDE_FROM_ALL", "TRUE");
std::vector<std::string> no_outputs;
@@ -2341,12 +2362,14 @@ cmTarget cmGlobalGenerator::CreateGlobalTarget(
std::vector<std::string> no_depends;
// Store the custom command in the target.
cmCustomCommand cc(CM_NULLPTR, no_outputs, no_byproducts, no_depends,
- *commandLines, CM_NULLPTR, workingDirectory);
- cc.SetUsesTerminal(uses_terminal);
+ gti.CommandLines, CM_NULLPTR, gti.WorkingDir.c_str());
+ cc.SetUsesTerminal(gti.UsesTerminal);
target.AddPostBuildCommand(cc);
- target.SetProperty("EchoString", message);
- std::vector<std::string>::iterator dit;
- for (dit = depends.begin(); dit != depends.end(); ++dit) {
+ if (!gti.Message.empty()) {
+ target.SetProperty("EchoString", gti.Message.c_str());
+ }
+ for (std::vector<std::string>::const_iterator dit = gti.Depends.begin();
+ dit != gti.Depends.end(); ++dit) {
target.AddUtility(*dit);
}
@@ -2556,7 +2579,7 @@ void cmGlobalGenerator::AddRuleHash(const std::vector<std::string>& outputs,
// Shorten the output name (in expected use case).
cmOutputConverter converter(this->GetMakefiles()[0]->GetStateSnapshot());
std::string fname = converter.ConvertToRelativePath(
- outputs[0], cmOutputConverter::HOME_OUTPUT);
+ this->GetMakefiles()[0]->GetState()->GetBinaryDirectory(), outputs[0]);
// Associate the hash with this output.
this->RuleHashes[fname] = hash;
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 1e1479a..f7b2e59 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -402,11 +402,30 @@ protected:
bool IsExcluded(cmLocalGenerator* root, cmLocalGenerator* gen) const;
bool IsExcluded(cmLocalGenerator* root, cmGeneratorTarget* target) const;
virtual void InitializeProgressMarks() {}
- void CreateDefaultGlobalTargets(cmTargets* targets);
- cmTarget CreateGlobalTarget(const std::string& name, const char* message,
- const cmCustomCommandLines* commandLines,
- std::vector<std::string> depends,
- const char* workingDir, bool uses_terminal);
+
+ struct GlobalTargetInfo
+ {
+ std::string Name;
+ std::string Message;
+ cmCustomCommandLines CommandLines;
+ std::vector<std::string> Depends;
+ std::string WorkingDir;
+ bool UsesTerminal;
+ GlobalTargetInfo()
+ : UsesTerminal(false)
+ {
+ }
+ };
+
+ void CreateDefaultGlobalTargets(std::vector<GlobalTargetInfo>& targets);
+
+ void AddGlobalTarget_Package(std::vector<GlobalTargetInfo>& targets);
+ void AddGlobalTarget_PackageSource(std::vector<GlobalTargetInfo>& targets);
+ void AddGlobalTarget_Test(std::vector<GlobalTargetInfo>& targets);
+ void AddGlobalTarget_EditCache(std::vector<GlobalTargetInfo>& targets);
+ void AddGlobalTarget_RebuildCache(std::vector<GlobalTargetInfo>& targets);
+ void AddGlobalTarget_Install(std::vector<GlobalTargetInfo>& targets);
+ cmTarget CreateGlobalTarget(GlobalTargetInfo const& gti, cmMakefile* mf);
std::string FindMakeProgramFile;
std::string ConfiguredFilesPath;
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 30a05a0..b913621 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -140,10 +140,10 @@ std::string cmGlobalNinjaGenerator::EncodeDepfileSpace(const std::string& path)
void cmGlobalNinjaGenerator::WriteBuild(
std::ostream& os, const std::string& comment, const std::string& rule,
- const cmNinjaDeps& outputs, const cmNinjaDeps& explicitDeps,
- const cmNinjaDeps& implicitDeps, const cmNinjaDeps& orderOnlyDeps,
- const cmNinjaVars& variables, const std::string& rspfile, int cmdLineLimit,
- bool* usedResponseFile)
+ const cmNinjaDeps& outputs, const cmNinjaDeps& implicitOuts,
+ const cmNinjaDeps& explicitDeps, const cmNinjaDeps& implicitDeps,
+ const cmNinjaDeps& orderOnlyDeps, const cmNinjaVars& variables,
+ const std::string& rspfile, int cmdLineLimit, bool* usedResponseFile)
{
// Make sure there is a rule.
if (rule.empty()) {
@@ -204,6 +204,13 @@ void cmGlobalNinjaGenerator::WriteBuild(
this->CombinedBuildOutputs.insert(EncodePath(*i));
}
}
+ if (!implicitOuts.empty()) {
+ build += " |";
+ for (cmNinjaDeps::const_iterator i = implicitOuts.begin();
+ i != implicitOuts.end(); ++i) {
+ build += " " + EncodeIdent(EncodePath(*i), os);
+ }
+ }
build += ":";
// Write the rule.
@@ -244,7 +251,8 @@ void cmGlobalNinjaGenerator::WritePhonyBuild(
const cmNinjaDeps& explicitDeps, const cmNinjaDeps& implicitDeps,
const cmNinjaDeps& orderOnlyDeps, const cmNinjaVars& variables)
{
- this->WriteBuild(os, comment, "phony", outputs, explicitDeps, implicitDeps,
+ this->WriteBuild(os, comment, "phony", outputs,
+ /*implicitOuts=*/cmNinjaDeps(), explicitDeps, implicitDeps,
orderOnlyDeps, variables);
}
@@ -288,7 +296,8 @@ void cmGlobalNinjaGenerator::WriteCustomCommandBuild(
vars["depfile"] = depfile;
}
this->WriteBuild(*this->BuildFileStream, comment, "CUSTOM_COMMAND", outputs,
- deps, cmNinjaDeps(), orderOnly, vars);
+ /*implicitOuts=*/cmNinjaDeps(), deps, cmNinjaDeps(),
+ orderOnly, vars);
if (this->ComputingUnknownDependencies) {
// we need to track every dependency that comes in, since we are trying
@@ -330,7 +339,8 @@ void cmGlobalNinjaGenerator::WriteMacOSXContentBuild(const std::string& input,
cmNinjaVars vars;
this->WriteBuild(*this->BuildFileStream, "", "COPY_OSX_CONTENT", outputs,
- deps, cmNinjaDeps(), cmNinjaDeps(), cmNinjaVars());
+ /*implicitOuts=*/cmNinjaDeps(), deps, cmNinjaDeps(),
+ cmNinjaDeps(), cmNinjaVars());
}
void cmGlobalNinjaGenerator::WriteRule(
@@ -760,8 +770,8 @@ std::string cmGlobalNinjaGenerator::ConvertToNinjaPath(const std::string& path)
{
cmLocalNinjaGenerator* ng =
static_cast<cmLocalNinjaGenerator*>(this->LocalGenerators[0]);
- std::string convPath =
- ng->ConvertToRelativePath(path, cmOutputConverter::HOME_OUTPUT);
+ std::string convPath = ng->ConvertToRelativePath(
+ this->LocalGenerators[0]->GetState()->GetBinaryDirectory(), path);
convPath = this->NinjaOutputPath(convPath);
#ifdef _WIN32
std::replace(convPath.begin(), convPath.end(), '/', '\\');
@@ -774,8 +784,8 @@ std::string cmGlobalNinjaGenerator::ConvertToNinjaFolderRule(
{
cmLocalNinjaGenerator* ng =
static_cast<cmLocalNinjaGenerator*>(this->LocalGenerators[0]);
- std::string convPath =
- ng->ConvertToRelativePath(path + "/all", cmOutputConverter::HOME);
+ std::string convPath = ng->ConvertToRelativePath(
+ this->LocalGenerators[0]->GetState()->GetSourceDirectory(), path + "/all");
convPath = this->NinjaOutputPath(convPath);
#ifdef _WIN32
std::replace(convPath.begin(), convPath.end(), '/', '\\');
@@ -1271,6 +1281,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
this->WriteBuild(os, "Re-run CMake if any of its inputs changed.",
"RERUN_CMAKE",
/*outputs=*/cmNinjaDeps(1, ninjaBuildFile),
+ /*implicitOuts=*/cmNinjaDeps(),
/*explicitDeps=*/cmNinjaDeps(), implicitDeps,
/*orderOnlyDeps=*/cmNinjaDeps(), variables);
@@ -1295,6 +1306,13 @@ bool cmGlobalNinjaGenerator::SupportsConsolePool() const
RequiredNinjaVersionForConsolePool().c_str());
}
+bool cmGlobalNinjaGenerator::SupportsImplicitOuts() const
+{
+ return !cmSystemTools::VersionCompare(
+ cmSystemTools::OP_LESS, this->NinjaVersion.c_str(),
+ this->RequiredNinjaVersionForImplicitOuts().c_str());
+}
+
void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
{
WriteRule(*this->RulesFileStream, "CLEAN", ninjaCmd() + " -t clean",
@@ -1308,6 +1326,7 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
/*generator=*/false);
WriteBuild(os, "Clean all the built files.", "CLEAN",
/*outputs=*/cmNinjaDeps(1, this->NinjaOutputPath("clean")),
+ /*implicitOuts=*/cmNinjaDeps(),
/*explicitDeps=*/cmNinjaDeps(),
/*implicitDeps=*/cmNinjaDeps(),
/*orderOnlyDeps=*/cmNinjaDeps(),
@@ -1327,6 +1346,7 @@ void cmGlobalNinjaGenerator::WriteTargetHelp(std::ostream& os)
/*generator=*/false);
WriteBuild(os, "Print all primary targets available.", "HELP",
/*outputs=*/cmNinjaDeps(1, this->NinjaOutputPath("help")),
+ /*implicitOuts=*/cmNinjaDeps(),
/*explicitDeps=*/cmNinjaDeps(),
/*implicitDeps=*/cmNinjaDeps(),
/*orderOnlyDeps=*/cmNinjaDeps(),
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index a0fad64..0201685 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -106,6 +106,7 @@ public:
*/
void WriteBuild(std::ostream& os, const std::string& comment,
const std::string& rule, const cmNinjaDeps& outputs,
+ const cmNinjaDeps& implicitOuts,
const cmNinjaDeps& explicitDeps,
const cmNinjaDeps& implicitDeps,
const cmNinjaDeps& orderOnlyDeps,
@@ -338,7 +339,9 @@ public:
// Ninja generator uses 'deps' and 'msvc_deps_prefix' introduced in 1.3
static std::string RequiredNinjaVersion() { return "1.3"; }
static std::string RequiredNinjaVersionForConsolePool() { return "1.5"; }
+ static std::string RequiredNinjaVersionForImplicitOuts() { return "1.7"; }
bool SupportsConsolePool() const;
+ bool SupportsImplicitOuts() const;
std::string NinjaOutputPath(std::string const& path);
bool HasOutputPathPrefix() const { return !this->OutputPathPrefix.empty(); }
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index d90ebf0..52ae469 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -319,18 +319,15 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
std::string cache = this->GetCMakeInstance()->GetHomeOutputDirectory();
cache += "/CMakeCache.txt";
+ std::string currentBinDir = lg->GetCurrentBinaryDirectory();
// Save the list to the cmake file.
cmakefileStream
<< "# The top level Makefile was generated from the following files:\n"
<< "set(CMAKE_MAKEFILE_DEPENDS\n"
- << " \""
- << lg->ConvertToRelativePath(cache, cmOutputConverter::START_OUTPUT)
- << "\"\n";
+ << " \"" << lg->ConvertToRelativePath(currentBinDir, cache) << "\"\n";
for (std::vector<std::string>::const_iterator i = lfiles.begin();
i != lfiles.end(); ++i) {
- cmakefileStream << " \""
- << lg->ConvertToRelativePath(
- *i, cmOutputConverter::START_OUTPUT)
+ cmakefileStream << " \"" << lg->ConvertToRelativePath(currentBinDir, *i)
<< "\"\n";
}
cmakefileStream << " )\n\n";
@@ -344,15 +341,14 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
cmakefileStream << "# The corresponding makefile is:\n"
<< "set(CMAKE_MAKEFILE_OUTPUTS\n"
<< " \""
- << lg->ConvertToRelativePath(makefileName,
- cmOutputConverter::START_OUTPUT)
+ << lg->ConvertToRelativePath(currentBinDir, makefileName)
<< "\"\n"
- << " \""
- << lg->ConvertToRelativePath(check,
- cmOutputConverter::START_OUTPUT)
+ << " \"" << lg->ConvertToRelativePath(currentBinDir, check)
<< "\"\n";
cmakefileStream << " )\n\n";
+ const std::string binDir = lg->GetBinaryDirectory();
+
// CMake must rerun if a byproduct is missing.
{
cmakefileStream << "# Byproducts of CMake generate step:\n"
@@ -361,9 +357,7 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
lg->GetMakefile()->GetOutputFiles();
for (std::vector<std::string>::const_iterator k = outfiles.begin();
k != outfiles.end(); ++k) {
- cmakefileStream << " \""
- << lg->ConvertToRelativePath(
- *k, cmOutputConverter::HOME_OUTPUT)
+ cmakefileStream << " \"" << lg->ConvertToRelativePath(binDir, *k)
<< "\"\n";
}
@@ -375,9 +369,7 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
tmpStr = lg->GetCurrentBinaryDirectory();
tmpStr += cmake::GetCMakeFilesDirectory();
tmpStr += "/CMakeDirectoryInformation.cmake";
- cmakefileStream << " \""
- << lg->ConvertToRelativePath(
- tmpStr, cmOutputConverter::HOME_OUTPUT)
+ cmakefileStream << " \"" << lg->ConvertToRelativePath(binDir, tmpStr)
<< "\"\n";
}
cmakefileStream << " )\n\n";
@@ -488,9 +480,10 @@ void cmGlobalUnixMakefileGenerator3::WriteDirectoryRules2(
}
// Begin the directory-level rules section.
- std::string dir = lg->GetCurrentBinaryDirectory();
- dir = lg->Convert(dir, cmOutputConverter::HOME_OUTPUT,
- cmOutputConverter::MAKERULE);
+ std::string dir = cmSystemTools::ConvertToOutputPath(
+ lg->ConvertToRelativePath(lg->GetBinaryDirectory(),
+ lg->GetCurrentBinaryDirectory())
+ .c_str());
lg->WriteDivider(ruleFileStream);
ruleFileStream << "# Directory level rules for directory " << dir << "\n\n";
@@ -538,7 +531,8 @@ void cmGlobalUnixMakefileGenerator3::GenerateBuildCommand(
tname += "/fast";
}
cmOutputConverter conv(mf->GetStateSnapshot());
- tname = conv.ConvertToRelativePath(tname, cmOutputConverter::HOME_OUTPUT);
+ tname =
+ conv.ConvertToRelativePath(mf->GetState()->GetBinaryDirectory(), tname);
cmSystemTools::ConvertToOutputSlashes(tname);
makeCommand.push_back(tname);
if (this->Makefiles.empty()) {
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index 0dc4497..7664b02 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -382,6 +382,7 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
{
VisualStudioFolders.clear();
+ std::string rootBinaryDir = root->GetCurrentBinaryDirectory();
for (OrderedTargetDependSet::const_iterator tt = projectTargets.begin();
tt != projectTargets.end(); ++tt) {
cmGeneratorTarget const* target = *tt;
@@ -405,8 +406,7 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
if (vcprojName) {
cmLocalGenerator* lg = target->GetLocalGenerator();
std::string dir = lg->GetCurrentBinaryDirectory();
- dir = root->ConvertToRelativePath(dir.c_str(),
- cmOutputConverter::START_OUTPUT);
+ dir = root->ConvertToRelativePath(rootBinaryDir, dir.c_str());
if (dir == ".") {
dir = ""; // msbuild cannot handle ".\" prefix
}
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 5653820..997f46c 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -896,9 +896,6 @@ void cmGlobalXCodeGenerator::SetCurrentLocalGenerator(cmLocalGenerator* gen)
{
this->CurrentLocalGenerator = gen;
this->CurrentMakefile = gen->GetMakefile();
- std::string outdir = cmSystemTools::CollapseFullPath(
- this->CurrentLocalGenerator->GetCurrentBinaryDirectory());
- cmSystemTools::SplitPath(outdir, this->CurrentOutputDirectoryComponents);
// Select the current set of configuration types.
this->CurrentConfigurationTypes.clear();
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index 303dfa0..ebdba3e 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -241,7 +241,6 @@ private:
std::string CurrentXCodeHackMakefile;
std::string CurrentProject;
std::set<std::string> TargetDoneSet;
- std::vector<std::string> CurrentOutputDirectoryComponents;
std::vector<std::string> ProjectSourceDirectoryComponents;
std::vector<std::string> ProjectOutputDirectoryComponents;
std::map<std::string, cmXCodeObject*> GroupMap;
diff --git a/Source/cmHexFileConverter.cxx b/Source/cmHexFileConverter.cxx
index 34fd626..64ece2d 100644
--- a/Source/cmHexFileConverter.cxx
+++ b/Source/cmHexFileConverter.cxx
@@ -89,7 +89,8 @@ static bool ConvertMotorolaSrecLine(const char* buf, FILE* outFile)
if ((buf[1] == '5') || (buf[1] == '7') || (buf[1] == '8') ||
(buf[1] == '9')) {
return true;
- } else if (buf[1] == '1') {
+ }
+ if (buf[1] == '1') {
dataStart = 8;
} else if (buf[1] == '2') {
dataStart = 10;
diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx
index dd04136..f0143e7 100644
--- a/Source/cmIfCommand.cxx
+++ b/Source/cmIfCommand.cxx
@@ -190,9 +190,8 @@ bool cmIfCommand::InvokeInitialPass(
this->Makefile->IssueMessage(cmake::FATAL_ERROR, err);
cmSystemTools::SetFatalErrorOccured();
return true;
- } else {
- this->Makefile->IssueMessage(status, err);
}
+ this->Makefile->IssueMessage(status, err);
}
cmIfFunctionBlocker* f = new cmIfFunctionBlocker();
diff --git a/Source/cmIncludeCommand.cxx b/Source/cmIncludeCommand.cxx
index 360ebeb..c90314e 100644
--- a/Source/cmIncludeCommand.cxx
+++ b/Source/cmIncludeCommand.cxx
@@ -15,7 +15,7 @@
bool cmIncludeCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&)
{
- if (args.size() < 1 || args.size() > 4) {
+ if (args.empty() || args.size() > 4) {
this->SetError("called with wrong number of arguments. "
"include() only takes one file.");
return false;
diff --git a/Source/cmIncludeDirectoryCommand.cxx b/Source/cmIncludeDirectoryCommand.cxx
index cafdba7..904fcca 100644
--- a/Source/cmIncludeDirectoryCommand.cxx
+++ b/Source/cmIncludeDirectoryCommand.cxx
@@ -15,7 +15,7 @@
bool cmIncludeDirectoryCommand::InitialPass(
std::vector<std::string> const& args, cmExecutionStatus&)
{
- if (args.size() < 1) {
+ if (args.empty()) {
return true;
}
diff --git a/Source/cmIncludeRegularExpressionCommand.cxx b/Source/cmIncludeRegularExpressionCommand.cxx
index 2473dff..bd26d93 100644
--- a/Source/cmIncludeRegularExpressionCommand.cxx
+++ b/Source/cmIncludeRegularExpressionCommand.cxx
@@ -15,7 +15,7 @@
bool cmIncludeRegularExpressionCommand::InitialPass(
std::vector<std::string> const& args, cmExecutionStatus&)
{
- if ((args.size() < 1) || (args.size() > 2)) {
+ if ((args.empty()) || (args.size() > 2)) {
this->SetError("called with incorrect number of arguments");
return false;
}
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index 4912eac..8450360 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -71,19 +71,28 @@ bool cmInstallCommand::InitialPass(std::vector<std::string> const& args,
// Switch among the command modes.
if (args[0] == "SCRIPT") {
return this->HandleScriptMode(args);
- } else if (args[0] == "CODE") {
+ }
+ if (args[0] == "CODE") {
return this->HandleScriptMode(args);
- } else if (args[0] == "TARGETS") {
+ }
+ if (args[0] == "TARGETS") {
return this->HandleTargetsMode(args);
- } else if (args[0] == "FILES") {
+ }
+ if (args[0] == "FILES") {
return this->HandleFilesMode(args);
- } else if (args[0] == "PROGRAMS") {
+ }
+ if (args[0] == "PROGRAMS") {
return this->HandleFilesMode(args);
- } else if (args[0] == "DIRECTORY") {
+ }
+ if (args[0] == "DIRECTORY") {
return this->HandleDirectoryMode(args);
- } else if (args[0] == "EXPORT") {
+ }
+ if (args[0] == "EXPORT") {
return this->HandleExportMode(args);
}
+ if (args[0] == "EXPORT_ANDROID_MK") {
+ return this->HandleExportAndroidMKMode(args);
+ }
// Unknown mode.
std::string e = "called with unknown mode ";
@@ -338,7 +347,8 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
<< "\" which is not an executable, library, or module.";
this->SetError(e.str());
return false;
- } else if (target->GetType() == cmState::OBJECT_LIBRARY) {
+ }
+ if (target->GetType() == cmState::OBJECT_LIBRARY) {
std::ostringstream e;
e << "TARGETS given OBJECT library \"" << (*targetIt)
<< "\" which may not be installed.";
@@ -1097,6 +1107,100 @@ bool cmInstallCommand::HandleDirectoryMode(
return true;
}
+bool cmInstallCommand::HandleExportAndroidMKMode(
+ std::vector<std::string> const& args)
+{
+#ifdef CMAKE_BUILD_WITH_CMAKE
+ // This is the EXPORT mode.
+ cmInstallCommandArguments ica(this->DefaultComponentName);
+ cmCAString exp(&ica.Parser, "EXPORT_ANDROID_MK");
+ cmCAString name_space(&ica.Parser, "NAMESPACE", &ica.ArgumentGroup);
+ cmCAEnabler exportOld(&ica.Parser, "EXPORT_LINK_INTERFACE_LIBRARIES",
+ &ica.ArgumentGroup);
+ cmCAString filename(&ica.Parser, "FILE", &ica.ArgumentGroup);
+ exp.Follows(CM_NULLPTR);
+
+ ica.ArgumentGroup.Follows(&exp);
+ std::vector<std::string> unknownArgs;
+ ica.Parse(&args, &unknownArgs);
+
+ if (!unknownArgs.empty()) {
+ // Unknown argument.
+ std::ostringstream e;
+ e << args[0] << " given unknown argument \"" << unknownArgs[0] << "\".";
+ this->SetError(e.str());
+ return false;
+ }
+
+ if (!ica.Finalize()) {
+ return false;
+ }
+
+ // Make sure there is a destination.
+ if (ica.GetDestination().empty()) {
+ // A destination is required.
+ std::ostringstream e;
+ e << args[0] << " given no DESTINATION!";
+ this->SetError(e.str());
+ return false;
+ }
+
+ // Check the file name.
+ std::string fname = filename.GetString();
+ if (fname.find_first_of(":/\\") != fname.npos) {
+ std::ostringstream e;
+ e << args[0] << " given invalid export file name \"" << fname << "\". "
+ << "The FILE argument may not contain a path. "
+ << "Specify the path in the DESTINATION argument.";
+ this->SetError(e.str());
+ return false;
+ }
+
+ // Check the file extension.
+ if (!fname.empty() &&
+ cmSystemTools::GetFilenameLastExtension(fname) != ".mk") {
+ std::ostringstream e;
+ e << args[0] << " given invalid export file name \"" << fname << "\". "
+ << "The FILE argument must specify a name ending in \".mk\".";
+ this->SetError(e.str());
+ return false;
+ }
+ if (fname.find_first_of(":/\\") != fname.npos) {
+ std::ostringstream e;
+ e << args[0] << " given export name \"" << exp.GetString() << "\". "
+ << "This name cannot be safely converted to a file name. "
+ << "Specify a different export name or use the FILE option to set "
+ << "a file name explicitly.";
+ this->SetError(e.str());
+ return false;
+ }
+ // Use the default name
+ if (fname.empty()) {
+ fname = "Android.mk";
+ }
+
+ cmExportSet* exportSet =
+ this->Makefile->GetGlobalGenerator()->GetExportSets()[exp.GetString()];
+
+ cmInstallGenerator::MessageLevel message =
+ cmInstallGenerator::SelectMessageLevel(this->Makefile);
+
+ // Create the export install generator.
+ cmInstallExportGenerator* exportGenerator = new cmInstallExportGenerator(
+ exportSet, ica.GetDestination().c_str(), ica.GetPermissions().c_str(),
+ ica.GetConfigurations(), ica.GetComponent().c_str(), message,
+ ica.GetExcludeFromAll(), fname.c_str(), name_space.GetCString(),
+ exportOld.IsEnabled(), true);
+ this->Makefile->AddInstallGenerator(exportGenerator);
+
+ return true;
+#else
+ static_cast<void>(args);
+ this->SetError("EXPORT_ANDROID_MK not supported in bootstrap cmake");
+ return false;
+#endif
+}
+
bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args)
{
// This is the EXPORT mode.
@@ -1203,7 +1307,7 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args)
exportSet, ica.GetDestination().c_str(), ica.GetPermissions().c_str(),
ica.GetConfigurations(), ica.GetComponent().c_str(), message,
ica.GetExcludeFromAll(), fname.c_str(), name_space.GetCString(),
- exportOld.IsEnabled());
+ exportOld.IsEnabled(), false);
this->Makefile->AddInstallGenerator(exportGenerator);
return true;
diff --git a/Source/cmInstallCommand.h b/Source/cmInstallCommand.h
index 3718ad5..7bc974c 100644
--- a/Source/cmInstallCommand.h
+++ b/Source/cmInstallCommand.h
@@ -48,6 +48,7 @@ private:
bool HandleFilesMode(std::vector<std::string> const& args);
bool HandleDirectoryMode(std::vector<std::string> const& args);
bool HandleExportMode(std::vector<std::string> const& args);
+ bool HandleExportAndroidMKMode(std::vector<std::string> const& args);
bool MakeFilesFullPath(const char* modeName,
const std::vector<std::string>& relFiles,
std::vector<std::string>& absFiles);
diff --git a/Source/cmInstallExportAndroidMKGenerator.cxx b/Source/cmInstallExportAndroidMKGenerator.cxx
new file mode 100644
index 0000000..43bdc01
--- /dev/null
+++ b/Source/cmInstallExportAndroidMKGenerator.cxx
@@ -0,0 +1,149 @@
+
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmInstallExportAndroidMKGenerator.h"
+
+#include <stdio.h>
+
+#include "cmExportInstallFileGenerator.h"
+#include "cmExportSet.h"
+#include "cmGeneratedFileStream.h"
+#include "cmGlobalGenerator.h"
+#include "cmInstallFilesGenerator.h"
+#include "cmInstallTargetGenerator.h"
+#include "cmLocalGenerator.h"
+#include "cmMakefile.h"
+#include "cmake.h"
+
+cmInstallExportAndroidMKGenerator::cmInstallExportAndroidMKGenerator(
+ cmExportSet* exportSet, const char* destination,
+ const char* file_permissions, std::vector<std::string> const& configurations,
+ const char* component, MessageLevel message, bool exclude_from_all,
+ const char* filename, const char* name_space, bool exportOld)
+ : cmInstallExportGenerator(exportSet, destination, file_permissions,
+ configurations, component, message,
+ exclude_from_all, filename, name_space, exportOld)
+{
+}
+
+cmInstallExportAndroidMKGenerator::~cmInstallExportAndroidMKGenerator()
+{
+}
+
+void cmInstallExportAndroidMKGenerator::Compute(cmLocalGenerator* lg)
+{
+ this->LocalGenerator = lg;
+ this->ExportSet->Compute(lg);
+}
+
+void cmInstallExportAndroidMKGenerator::GenerateScript(std::ostream& os)
+{
+ // Skip empty sets.
+ if (ExportSet->GetTargetExports()->empty()) {
+ std::ostringstream e;
+ e << "INSTALL(EXPORT) given unknown export \"" << ExportSet->GetName()
+ << "\"";
+ cmSystemTools::Error(e.str().c_str());
+ return;
+ }
+
+ // Create the temporary directory in which to store the files.
+ this->ComputeTempDir();
+ cmSystemTools::MakeDirectory(this->TempDir.c_str());
+
+ // Construct a temporary location for the file.
+ this->MainImportFile = this->TempDir;
+ this->MainImportFile += "/";
+ this->MainImportFile += this->FileName;
+
+ // Generate the import file for this export set.
+ this->EFGen->SetExportFile(this->MainImportFile.c_str());
+ this->EFGen->SetNamespace(this->Namespace);
+ this->EFGen->SetExportOld(this->ExportOld);
+ if (this->ConfigurationTypes->empty()) {
+ if (!this->ConfigurationName.empty()) {
+ this->EFGen->AddConfiguration(this->ConfigurationName);
+ } else {
+ this->EFGen->AddConfiguration("");
+ }
+ } else {
+ for (std::vector<std::string>::const_iterator ci =
+ this->ConfigurationTypes->begin();
+ ci != this->ConfigurationTypes->end(); ++ci) {
+ this->EFGen->AddConfiguration(*ci);
+ }
+ }
+ this->EFGen->GenerateImportFile();
+
+ // Perform the main install script generation.
+ this->cmInstallGenerator::GenerateScript(os);
+}
+
+void cmInstallExportAndroidMKGenerator::GenerateScriptConfigs(
+ std::ostream& os, Indent const& indent)
+{
+ // Create the main install rules first.
+ this->cmInstallGenerator::GenerateScriptConfigs(os, indent);
+
+ // Now create a configuration-specific install rule for the import
+ // file of each configuration.
+ std::vector<std::string> files;
+ for (std::map<std::string, std::string>::const_iterator i =
+ this->EFGen->GetConfigImportFiles().begin();
+ i != this->EFGen->GetConfigImportFiles().end(); ++i) {
+ files.push_back(i->second);
+ std::string config_test = this->CreateConfigTest(i->first);
+ os << indent << "if(" << config_test << ")\n";
+ this->AddInstallRule(os, this->Destination, cmInstallType_FILES, files,
+ false, this->FilePermissions.c_str(), CM_NULLPTR,
+ CM_NULLPTR, CM_NULLPTR, indent.Next());
+ os << indent << "endif()\n";
+ files.clear();
+ }
+}
+
+void cmInstallExportAndroidMKGenerator::GenerateScriptActions(
+ std::ostream& os, Indent const& indent)
+{
+ // Remove old per-configuration export files if the main changes.
+ std::string installedDir = "$ENV{DESTDIR}";
+ installedDir += this->ConvertToAbsoluteDestination(this->Destination);
+ installedDir += "/";
+ std::string installedFile = installedDir;
+ installedFile += this->FileName;
+ os << indent << "if(EXISTS \"" << installedFile << "\")\n";
+ Indent indentN = indent.Next();
+ Indent indentNN = indentN.Next();
+ Indent indentNNN = indentNN.Next();
+ /* clang-format off */
+ os << indentN << "file(DIFFERENT EXPORT_FILE_CHANGED FILES\n"
+ << indentN << " \"" << installedFile << "\"\n"
+ << indentN << " \"" << this->MainImportFile << "\")\n";
+ os << indentN << "if(EXPORT_FILE_CHANGED)\n";
+ os << indentNN << "file(GLOB OLD_CONFIG_FILES \"" << installedDir
+ << this->EFGen->GetConfigImportFileGlob() << "\")\n";
+ os << indentNN << "if(OLD_CONFIG_FILES)\n";
+ os << indentNNN << "message(STATUS \"Old export file \\\"" << installedFile
+ << "\\\" will be replaced. Removing files [${OLD_CONFIG_FILES}].\")\n";
+ os << indentNNN << "file(REMOVE ${OLD_CONFIG_FILES})\n";
+ os << indentNN << "endif()\n";
+ os << indentN << "endif()\n";
+ os << indent << "endif()\n";
+ /* clang-format on */
+
+ // Install the main export file.
+ std::vector<std::string> files;
+ files.push_back(this->MainImportFile);
+ this->AddInstallRule(os, this->Destination, cmInstallType_FILES, files,
+ false, this->FilePermissions.c_str(), CM_NULLPTR,
+ CM_NULLPTR, CM_NULLPTR, indent);
+}
diff --git a/Source/cmInstallExportAndroidMKGenerator.h b/Source/cmInstallExportAndroidMKGenerator.h
new file mode 100644
index 0000000..158972d
--- /dev/null
+++ b/Source/cmInstallExportAndroidMKGenerator.h
@@ -0,0 +1,46 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef cmInstallExportAndroidMKGenerator_h
+#define cmInstallExportAndroidMKGenerator_h
+
+#include "cmInstallExportGenerator.h"
+
+class cmExportInstallFileGenerator;
+class cmInstallFilesGenerator;
+class cmInstallTargetGenerator;
+class cmExportSet;
+class cmMakefile;
+
+/** \class cmInstallExportAndroidMKGenerator
+ * \brief Generate rules for creating an export files.
+ */
+class cmInstallExportAndroidMKGenerator : public cmInstallExportGenerator
+{
+public:
+ cmInstallExportAndroidMKGenerator(
+ cmExportSet* exportSet, const char* dest, const char* file_permissions,
+ const std::vector<std::string>& configurations, const char* component,
+ MessageLevel message, bool exclude_from_all, const char* filename,
+ const char* name_space, bool exportOld);
+ ~cmInstallExportAndroidMKGenerator();
+
+ void Compute(cmLocalGenerator* lg);
+
+protected:
+ virtual void GenerateScript(std::ostream& os);
+ virtual void GenerateScriptConfigs(std::ostream& os, Indent const& indent);
+ virtual void GenerateScriptActions(std::ostream& os, Indent const& indent);
+ void GenerateImportFile(cmExportSet const* exportSet);
+ void GenerateImportFile(const char* config, cmExportSet const* exportSet);
+};
+
+#endif
diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx
index 27628f4..5ea7faf 100644
--- a/Source/cmInstallExportGenerator.cxx
+++ b/Source/cmInstallExportGenerator.cxx
@@ -16,6 +16,9 @@
#include <sstream>
#include <utility>
+#ifdef CMAKE_BUILD_WITH_CMAKE
+#include "cmExportInstallAndroidMKGenerator.h"
+#endif
#include "cmExportInstallFileGenerator.h"
#include "cmExportSet.h"
#include "cmInstallType.h"
@@ -27,7 +30,7 @@ cmInstallExportGenerator::cmInstallExportGenerator(
cmExportSet* exportSet, const char* destination,
const char* file_permissions, std::vector<std::string> const& configurations,
const char* component, MessageLevel message, bool exclude_from_all,
- const char* filename, const char* name_space, bool exportOld)
+ const char* filename, const char* name_space, bool exportOld, bool android)
: cmInstallGenerator(destination, configurations, component, message,
exclude_from_all)
, ExportSet(exportSet)
@@ -37,7 +40,13 @@ cmInstallExportGenerator::cmInstallExportGenerator(
, ExportOld(exportOld)
, LocalGenerator(CM_NULLPTR)
{
- this->EFGen = new cmExportInstallFileGenerator(this);
+ if (android) {
+#ifdef CMAKE_BUILD_WITH_CMAKE
+ this->EFGen = new cmExportInstallAndroidMKGenerator(this);
+#endif
+ } else {
+ this->EFGen = new cmExportInstallFileGenerator(this);
+ }
exportSet->AddInstallation(this);
}
diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h
index 5539827..ac02386 100644
--- a/Source/cmInstallExportGenerator.h
+++ b/Source/cmInstallExportGenerator.h
@@ -37,7 +37,8 @@ public:
const std::vector<std::string>& configurations,
const char* component, MessageLevel message,
bool exclude_from_all, const char* filename,
- const char* name_space, bool exportOld);
+ const char* name_space, bool exportOld,
+ bool android);
~cmInstallExportGenerator() CM_OVERRIDE;
cmExportSet* GetExportSet() { return this->ExportSet; }
diff --git a/Source/cmInstallFilesCommand.cxx b/Source/cmInstallFilesCommand.cxx
index 64efe61..9d0db02 100644
--- a/Source/cmInstallFilesCommand.cxx
+++ b/Source/cmInstallFilesCommand.cxx
@@ -143,12 +143,12 @@ std::string cmInstallFilesCommand::FindInstallSource(const char* name) const
if (cmSystemTools::FileExists(tb.c_str())) {
// The file exists in the binary tree. Use it.
return tb;
- } else if (cmSystemTools::FileExists(ts.c_str())) {
+ }
+ if (cmSystemTools::FileExists(ts.c_str())) {
// The file exists in the source tree. Use it.
return ts;
- } else {
- // The file doesn't exist. Assume it will be present in the
- // binary tree when the install occurs.
- return tb;
}
+ // The file doesn't exist. Assume it will be present in the
+ // binary tree when the install occurs.
+ return tb;
}
diff --git a/Source/cmInstallProgramsCommand.cxx b/Source/cmInstallProgramsCommand.cxx
index 2e5fc1f..93e7f6c 100644
--- a/Source/cmInstallProgramsCommand.cxx
+++ b/Source/cmInstallProgramsCommand.cxx
@@ -113,12 +113,12 @@ std::string cmInstallProgramsCommand::FindInstallSource(const char* name) const
if (cmSystemTools::FileExists(tb.c_str())) {
// The file exists in the binary tree. Use it.
return tb;
- } else if (cmSystemTools::FileExists(ts.c_str())) {
+ }
+ if (cmSystemTools::FileExists(ts.c_str())) {
// The file exists in the source tree. Use it.
return ts;
- } else {
- // The file doesn't exist. Assume it will be present in the
- // binary tree when the install occurs.
- return tb;
}
+ // The file doesn't exist. Assume it will be present in the
+ // binary tree when the install occurs.
+ return tb;
}
diff --git a/Source/cmInstallTargetsCommand.cxx b/Source/cmInstallTargetsCommand.cxx
index 056ea24..6b594b6 100644
--- a/Source/cmInstallTargetsCommand.cxx
+++ b/Source/cmInstallTargetsCommand.cxx
@@ -37,14 +37,17 @@ bool cmInstallTargetsCommand::InitialPass(std::vector<std::string> const& args,
}
runtime_dir = *s;
- } else if (tgts.find(*s) != tgts.end()) {
- tgts[*s].SetInstallPath(args[0].c_str());
- tgts[*s].SetRuntimeInstallPath(runtime_dir.c_str());
- tgts[*s].SetHaveInstallRule(true);
} else {
- std::string str = "Cannot find target: \"" + *s + "\" to install.";
- this->SetError(str);
- return false;
+ cmTargets::iterator ti = tgts.find(*s);
+ if (ti != tgts.end()) {
+ ti->second.SetInstallPath(args[0].c_str());
+ ti->second.SetRuntimeInstallPath(runtime_dir.c_str());
+ ti->second.SetHaveInstallRule(true);
+ } else {
+ std::string str = "Cannot find target: \"" + *s + "\" to install.";
+ this->SetError(str);
+ return false;
+ }
}
}
diff --git a/Source/cmLinkDirectoriesCommand.cxx b/Source/cmLinkDirectoriesCommand.cxx
index a33b429..9b5d54a 100644
--- a/Source/cmLinkDirectoriesCommand.cxx
+++ b/Source/cmLinkDirectoriesCommand.cxx
@@ -15,7 +15,7 @@
bool cmLinkDirectoriesCommand::InitialPass(
std::vector<std::string> const& args, cmExecutionStatus&)
{
- if (args.size() < 1) {
+ if (args.empty()) {
return true;
}
diff --git a/Source/cmLinkLibrariesCommand.cxx b/Source/cmLinkLibrariesCommand.cxx
index 5d23d6a..bef234e 100644
--- a/Source/cmLinkLibrariesCommand.cxx
+++ b/Source/cmLinkLibrariesCommand.cxx
@@ -15,7 +15,7 @@
bool cmLinkLibrariesCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&)
{
- if (args.size() < 1) {
+ if (args.empty()) {
return true;
}
// add libraries, nothe that there is an optional prefix
diff --git a/Source/cmLinkedTree.h b/Source/cmLinkedTree.h
index 466aaa7..025c0a3 100644
--- a/Source/cmLinkedTree.h
+++ b/Source/cmLinkedTree.h
@@ -167,10 +167,10 @@ public:
iterator Truncate()
{
- assert(this->UpPositions.size() > 0);
+ assert(!this->UpPositions.empty());
this->UpPositions.erase(this->UpPositions.begin() + 1,
this->UpPositions.end());
- assert(this->Data.size() > 0);
+ assert(!this->Data.empty());
this->Data.erase(this->Data.begin() + 1, this->Data.end());
return iterator(this, 1);
}
diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx
index 14bb81e..7ab7de1 100644
--- a/Source/cmListFileCache.cxx
+++ b/Source/cmListFileCache.cxx
@@ -404,8 +404,8 @@ void cmListFileBacktrace::PrintTitle(std::ostream& out) const
cmOutputConverter converter(this->Bottom);
cmListFileContext lfc = *this->Cur;
if (!this->Bottom.GetState()->GetIsInTryCompile()) {
- lfc.FilePath =
- converter.ConvertToRelativePath(lfc.FilePath, cmOutputConverter::HOME);
+ lfc.FilePath = converter.ConvertToRelativePath(
+ this->Bottom.GetState()->GetSourceDirectory(), lfc.FilePath);
}
out << (lfc.Line ? " at " : " in ") << lfc;
}
@@ -430,8 +430,8 @@ void cmListFileBacktrace::PrintCallStack(std::ostream& out) const
}
cmListFileContext lfc = *i;
if (!this->Bottom.GetState()->GetIsInTryCompile()) {
- lfc.FilePath =
- converter.ConvertToRelativePath(lfc.FilePath, cmOutputConverter::HOME);
+ lfc.FilePath = converter.ConvertToRelativePath(
+ this->Bottom.GetState()->GetSourceDirectory(), lfc.FilePath);
}
out << " " << lfc << "\n";
}
diff --git a/Source/cmLoadCacheCommand.cxx b/Source/cmLoadCacheCommand.cxx
index 85188d1..6d9cf8e 100644
--- a/Source/cmLoadCacheCommand.cxx
+++ b/Source/cmLoadCacheCommand.cxx
@@ -18,7 +18,7 @@
bool cmLoadCacheCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&)
{
- if (args.size() < 1) {
+ if (args.empty()) {
this->SetError("called with wrong number of arguments.");
}
diff --git a/Source/cmLoadCommandCommand.cxx b/Source/cmLoadCommandCommand.cxx
index ddf6ce6..4d8a4e3 100644
--- a/Source/cmLoadCommandCommand.cxx
+++ b/Source/cmLoadCommandCommand.cxx
@@ -183,7 +183,7 @@ bool cmLoadCommandCommand::InitialPass(std::vector<std::string> const& args,
"The load_command command should not be called; see CMP0031.")) {
return true;
}
- if (args.size() < 1) {
+ if (args.empty()) {
return true;
}
diff --git a/Source/cmLocalCommonGenerator.cxx b/Source/cmLocalCommonGenerator.cxx
index 0e79293..b75ce62 100644
--- a/Source/cmLocalCommonGenerator.cxx
+++ b/Source/cmLocalCommonGenerator.cxx
@@ -18,8 +18,9 @@
class cmGlobalGenerator;
-cmLocalCommonGenerator::cmLocalCommonGenerator(
- cmGlobalGenerator* gg, cmMakefile* mf, cmOutputConverter::RelativeRoot wd)
+cmLocalCommonGenerator::cmLocalCommonGenerator(cmGlobalGenerator* gg,
+ cmMakefile* mf,
+ std::string const& wd)
: cmLocalGenerator(gg, mf)
, WorkingDirectory(wd)
{
@@ -53,10 +54,12 @@ std::string cmLocalCommonGenerator::GetTargetFortranFlags(
}
// Add a module output directory flag if necessary.
- std::string mod_dir = target->GetFortranModuleDirectory();
+ std::string mod_dir =
+ target->GetFortranModuleDirectory(this->WorkingDirectory);
if (!mod_dir.empty()) {
- mod_dir =
- this->Convert(mod_dir, this->WorkingDirectory, cmOutputConverter::SHELL);
+ mod_dir = this->ConvertToOutputFormat(
+ this->ConvertToRelativePath(this->WorkingDirectory, mod_dir),
+ cmOutputConverter::SHELL);
} else {
mod_dir =
this->Makefile->GetSafeDefinition("CMAKE_Fortran_MODDIR_DEFAULT");
diff --git a/Source/cmLocalCommonGenerator.h b/Source/cmLocalCommonGenerator.h
index 9012afd..9454739 100644
--- a/Source/cmLocalCommonGenerator.h
+++ b/Source/cmLocalCommonGenerator.h
@@ -30,21 +30,18 @@ class cmLocalCommonGenerator : public cmLocalGenerator
{
public:
cmLocalCommonGenerator(cmGlobalGenerator* gg, cmMakefile* mf,
- cmOutputConverter::RelativeRoot wd);
+ std::string const& wd);
~cmLocalCommonGenerator() CM_OVERRIDE;
std::string const& GetConfigName() { return this->ConfigName; }
- cmOutputConverter::RelativeRoot GetWorkingDirectory() const
- {
- return this->WorkingDirectory;
- }
+ std::string GetWorkingDirectory() const { return this->WorkingDirectory; }
std::string GetTargetFortranFlags(cmGeneratorTarget const* target,
std::string const& config) CM_OVERRIDE;
protected:
- cmOutputConverter::RelativeRoot WorkingDirectory;
+ std::string WorkingDirectory;
void SetConfigName();
std::string ConfigName;
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 694a9f6..9b12354 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -175,15 +175,15 @@ void cmLocalGenerator::GenerateTestFiles()
(*gi)->Compute(this);
(*gi)->Generate(fout, config, configurationTypes);
}
- size_t i;
- std::vector<cmState::Snapshot> children =
- this->Makefile->GetStateSnapshot().GetChildren();
- for (i = 0; i < children.size(); ++i) {
+ typedef std::vector<cmState::Snapshot> vec_t;
+ vec_t const& children = this->Makefile->GetStateSnapshot().GetChildren();
+ std::string parentBinDir = this->GetCurrentBinaryDirectory();
+ for (vec_t::const_iterator i = children.begin(); i != children.end(); ++i) {
// TODO: Use add_subdirectory instead?
- fout << "subdirs(";
- std::string outP = children[i].GetDirectory().GetCurrentBinary();
- fout << this->ConvertToRelativePath(outP, START_OUTPUT);
- fout << ")" << std::endl;
+ std::string outP = i->GetDirectory().GetCurrentBinary();
+ outP = this->ConvertToRelativePath(parentBinDir, outP);
+ outP = cmOutputConverter::EscapeForCMake(outP);
+ fout << "subdirs(" << outP << ")" << std::endl;
}
}
@@ -1409,7 +1409,9 @@ std::string cmLocalGenerator::ConvertToLinkReference(std::string const& lib,
#endif
// Normal behavior.
- return this->Convert(lib, START_OUTPUT, format);
+ return this->ConvertToOutputFormat(
+ this->ConvertToRelativePath(this->GetCurrentBinaryDirectory(), lib),
+ format);
}
/**
@@ -1531,9 +1533,6 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries,
linkLibs += " ";
}
- // Write the library flags to the build rule.
- fout << linkLibs;
-
// Check what kind of rpath flags to use.
if (cli.GetRuntimeSep().empty()) {
// Each rpath entry gets its own option ("-R a -R b -R c")
@@ -1560,6 +1559,9 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries,
}
}
+ // Write the library flags to the build rule.
+ fout << linkLibs;
+
// Add the linker runtime search path if any.
std::string rpath_link = cli.GetRPathLinkString();
if (!cli.GetRPathLinkFlag().empty() && !rpath_link.empty()) {
@@ -2243,11 +2245,11 @@ std::string cmLocalGenerator::ConstructComment(
std::string comment;
comment = "Generating ";
const char* sep = "";
+ std::string currentBinaryDir = this->GetCurrentBinaryDirectory();
for (std::vector<std::string>::const_iterator o = ccg.GetOutputs().begin();
o != ccg.GetOutputs().end(); ++o) {
comment += sep;
- comment +=
- this->ConvertToRelativePath(*o, cmOutputConverter::START_OUTPUT);
+ comment += this->ConvertToRelativePath(currentBinaryDir, *o);
sep = ", ";
}
return comment;
@@ -2515,14 +2517,15 @@ std::string cmLocalGenerator::GetObjectFileNameWithoutTarget(
const char* fullPath = source.GetFullPath().c_str();
// Try referencing the source relative to the source tree.
- std::string relFromSource = this->ConvertToRelativePath(fullPath, START);
+ std::string relFromSource =
+ this->ConvertToRelativePath(this->GetCurrentSourceDirectory(), fullPath);
assert(!relFromSource.empty());
bool relSource = !cmSystemTools::FileIsFullPath(relFromSource.c_str());
bool subSource = relSource && relFromSource[0] != '.';
// Try referencing the source relative to the binary tree.
std::string relFromBinary =
- this->ConvertToRelativePath(fullPath, START_OUTPUT);
+ this->ConvertToRelativePath(this->GetCurrentBinaryDirectory(), fullPath);
assert(!relFromBinary.empty());
bool relBinary = !cmSystemTools::FileIsFullPath(relFromBinary.c_str());
bool subBinary = relBinary && relFromBinary[0] != '.';
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index 6793f84..82e4d2c 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -34,7 +34,7 @@
cmLocalNinjaGenerator::cmLocalNinjaGenerator(cmGlobalGenerator* gg,
cmMakefile* mf)
- : cmLocalCommonGenerator(gg, mf, cmOutputConverter::HOME_OUTPUT)
+ : cmLocalCommonGenerator(gg, mf, mf->GetState()->GetBinaryDirectory())
, HomeRelativeOutputPath("")
{
this->TargetImplib = "$TARGET_IMPLIB";
@@ -51,7 +51,7 @@ void cmLocalNinjaGenerator::Generate()
// Compute the path to use when referencing the current output
// directory from the top output directory.
this->HomeRelativeOutputPath = this->ConvertToRelativePath(
- this->GetCurrentBinaryDirectory(), cmOutputConverter::HOME_OUTPUT);
+ this->GetBinaryDirectory(), this->GetCurrentBinaryDirectory());
if (this->HomeRelativeOutputPath == ".") {
this->HomeRelativeOutputPath = "";
}
@@ -145,7 +145,8 @@ std::string cmLocalNinjaGenerator::ConvertToIncludeReference(
return this->ConvertToOutputFormat(cmSystemTools::CollapseFullPath(path),
format);
}
- return this->Convert(path, cmOutputConverter::HOME_OUTPUT, format);
+ return this->ConvertToOutputFormat(
+ this->ConvertToRelativePath(this->GetBinaryDirectory(), path), format);
}
// Private methods.
@@ -499,8 +500,10 @@ std::string cmLocalNinjaGenerator::MakeCustomLauncher(
const std::vector<std::string>& outputs = ccg.GetOutputs();
if (!outputs.empty()) {
if (ccg.GetWorkingDirectory().empty()) {
- output = this->Convert(outputs[0], cmOutputConverter::START_OUTPUT,
- cmOutputConverter::SHELL);
+ output = this->ConvertToOutputFormat(
+ this->ConvertToRelativePath(this->GetCurrentBinaryDirectory(),
+ outputs[0]),
+ cmOutputConverter::SHELL);
} else {
output =
this->ConvertToOutputFormat(outputs[0], cmOutputConverter::SHELL);
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 611c502..23d1571 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -94,7 +94,7 @@ static std::string cmSplitExtension(std::string const& in, std::string& base)
cmLocalUnixMakefileGenerator3::cmLocalUnixMakefileGenerator3(
cmGlobalGenerator* gg, cmMakefile* mf)
- : cmLocalCommonGenerator(gg, mf, cmOutputConverter::START_OUTPUT)
+ : cmLocalCommonGenerator(gg, mf, mf->GetCurrentBinaryDirectory())
{
this->MakefileVariableSize = 0;
this->ColorMakefile = false;
@@ -151,7 +151,7 @@ void cmLocalUnixMakefileGenerator3::ComputeHomeRelativeOutputPath()
// Compute the path to use when referencing the current output
// directory from the top output directory.
this->HomeRelativeOutputPath = this->ConvertToRelativePath(
- this->GetCurrentBinaryDirectory(), cmOutputConverter::HOME_OUTPUT);
+ this->GetBinaryDirectory(), this->GetCurrentBinaryDirectory());
if (this->HomeRelativeOutputPath == ".") {
this->HomeRelativeOutputPath = "";
}
@@ -556,8 +556,8 @@ void cmLocalUnixMakefileGenerator3::WriteMakeRule(
}
// Construct the left hand side of the rule.
- std::string tgt = this->Convert(target, cmOutputConverter::HOME_OUTPUT,
- cmOutputConverter::MAKERULE);
+ std::string tgt = cmSystemTools::ConvertToOutputPath(
+ this->ConvertToRelativePath(this->GetBinaryDirectory(), target).c_str());
const char* space = "";
if (tgt.size() == 1) {
@@ -581,11 +581,12 @@ void cmLocalUnixMakefileGenerator3::WriteMakeRule(
} else {
// Split dependencies into multiple rule lines. This allows for
// very long dependency lists even on older make implementations.
+ std::string binDir = this->GetBinaryDirectory();
for (std::vector<std::string>::const_iterator dep = depends.begin();
dep != depends.end(); ++dep) {
replace = *dep;
- replace = this->Convert(replace, cmOutputConverter::HOME_OUTPUT,
- cmOutputConverter::MAKERULE);
+ replace = cmSystemTools::ConvertToOutputPath(
+ this->ConvertToRelativePath(binDir, replace).c_str());
os << cmMakeSafe(tgt) << space << ": " << cmMakeSafe(replace) << "\n";
}
}
@@ -952,6 +953,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand(
// Add each command line to the set of commands.
std::vector<std::string> commands1;
+ std::string currentBinDir = this->GetCurrentBinaryDirectory();
for (unsigned int c = 0; c < ccg.GetNumberOfCommands(); ++c) {
// Build the command line in a single string.
std::string cmd = ccg.GetCommand(c);
@@ -976,8 +978,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand(
// working directory will be the start-output directory.
bool had_slash = cmd.find('/') != cmd.npos;
if (workingDir.empty()) {
- cmd =
- this->ConvertToRelativePath(cmd, cmOutputConverter::START_OUTPUT);
+ cmd = this->ConvertToRelativePath(currentBinDir, cmd);
}
bool has_slash = cmd.find('/') != cmd.npos;
if (had_slash && !has_slash) {
@@ -1001,8 +1002,10 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand(
const std::vector<std::string>& outputs = ccg.GetOutputs();
if (!outputs.empty()) {
if (workingDir.empty()) {
- output = this->Convert(outputs[0], cmOutputConverter::START_OUTPUT,
- cmOutputConverter::SHELL);
+ output = this->ConvertToOutputFormat(
+ this->ConvertToRelativePath(this->GetCurrentBinaryDirectory(),
+ outputs[0]),
+ cmOutputConverter::SHELL);
} else {
output = this->ConvertToOutputFormat(outputs[0],
@@ -1069,7 +1072,8 @@ void cmLocalUnixMakefileGenerator3::AppendCleanCommand(
std::vector<std::string>& commands, const std::vector<std::string>& files,
cmGeneratorTarget* target, const char* filename)
{
- std::string cleanfile = this->GetCurrentBinaryDirectory();
+ std::string currentBinDir = this->GetCurrentBinaryDirectory();
+ std::string cleanfile = currentBinDir;
cleanfile += "/";
cleanfile += this->GetTargetDirectory(target);
cleanfile += "/cmake_clean";
@@ -1087,15 +1091,15 @@ void cmLocalUnixMakefileGenerator3::AppendCleanCommand(
fout << "file(REMOVE_RECURSE\n";
for (std::vector<std::string>::const_iterator f = files.begin();
f != files.end(); ++f) {
- std::string fc =
- this->ConvertToRelativePath(*f, cmOutputConverter::START_OUTPUT);
+ std::string fc = this->ConvertToRelativePath(currentBinDir, *f);
fout << " " << cmOutputConverter::EscapeForCMake(fc) << "\n";
}
fout << ")\n";
}
std::string remove = "$(CMAKE_COMMAND) -P ";
- remove += this->Convert(cleanfile, cmOutputConverter::START_OUTPUT,
- cmOutputConverter::SHELL);
+ remove += this->ConvertToOutputFormat(
+ this->ConvertToRelativePath(this->GetCurrentBinaryDirectory(), cleanfile),
+ cmOutputConverter::SHELL);
commands.push_back(remove);
// For the main clean rule add per-language cleaning.
@@ -1853,9 +1857,9 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo(
const std::string& config =
this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
this->GetIncludeDirectories(includes, target, l->first, config);
+ std::string binaryDir = this->GetState()->GetBinaryDirectory();
if (this->Makefile->IsOn("CMAKE_DEPENDS_IN_PROJECT_ONLY")) {
const char* sourceDir = this->GetState()->GetSourceDirectory();
- const char* binaryDir = this->GetState()->GetBinaryDirectory();
std::vector<std::string>::iterator itr =
std::remove_if(includes.begin(), includes.end(),
::NotInProjectDir(sourceDir, binaryDir));
@@ -1863,9 +1867,7 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo(
}
for (std::vector<std::string>::iterator i = includes.begin();
i != includes.end(); ++i) {
- cmakefileStream << " \""
- << this->ConvertToRelativePath(
- *i, cmOutputConverter::HOME_OUTPUT)
+ cmakefileStream << " \"" << this->ConvertToRelativePath(binaryDir, *i)
<< "\"\n";
}
cmakefileStream << " )\n";
@@ -1930,7 +1932,7 @@ std::string cmLocalUnixMakefileGenerator3::GetRecursiveMakeCall(
if (!tgt.empty()) {
// The make target is always relative to the top of the build tree.
std::string tgt2 =
- this->ConvertToRelativePath(tgt, cmOutputConverter::HOME_OUTPUT);
+ this->ConvertToRelativePath(this->GetBinaryDirectory(), tgt);
// The target may have been written with windows paths.
cmSystemTools::ConvertToOutputSlashes(tgt2);
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 70fe819..f477a0e 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -788,8 +788,8 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
target->GetProperty("Fortran_MODULE_DIRECTORY");
std::string modDir;
if (target_mod_dir) {
- modDir = this->ConvertToRelativePath(target_mod_dir,
- cmOutputConverter::START_OUTPUT);
+ modDir = this->ConvertToRelativePath(this->GetCurrentBinaryDirectory(),
+ target_mod_dir);
} else {
modDir = ".";
}
@@ -1298,10 +1298,11 @@ void cmLocalVisualStudio7GeneratorInternals::OutputLibraries(
std::ostream& fout, ItemVector const& libs)
{
cmLocalVisualStudio7Generator* lg = this->LocalGenerator;
+ std::string currentBinDir = lg->GetCurrentBinaryDirectory();
for (ItemVector::const_iterator l = libs.begin(); l != libs.end(); ++l) {
if (l->IsPath) {
- std::string rel = lg->ConvertToRelativePath(
- l->Value.c_str(), cmOutputConverter::START_OUTPUT);
+ std::string rel =
+ lg->ConvertToRelativePath(currentBinDir, l->Value.c_str());
fout << lg->ConvertToXMLOutputPath(rel.c_str()) << " ";
} else if (!l->Target ||
l->Target->GetType() != cmState::INTERFACE_LIBRARY) {
@@ -1316,13 +1317,13 @@ void cmLocalVisualStudio7GeneratorInternals::OutputObjects(
// VS < 8 does not support per-config source locations so we
// list object library content on the link line instead.
cmLocalVisualStudio7Generator* lg = this->LocalGenerator;
+ std::string currentBinDir = lg->GetCurrentBinaryDirectory();
std::vector<std::string> objs;
gt->UseObjectLibraries(objs, "");
const char* sep = isep ? isep : "";
for (std::vector<std::string>::const_iterator oi = objs.begin();
oi != objs.end(); ++oi) {
- std::string rel =
- lg->ConvertToRelativePath(oi->c_str(), cmOutputConverter::START_OUTPUT);
+ std::string rel = lg->ConvertToRelativePath(currentBinDir, oi->c_str());
fout << sep << lg->ConvertToXMLOutputPath(rel.c_str());
sep = " ";
}
@@ -1332,6 +1333,7 @@ void cmLocalVisualStudio7Generator::OutputLibraryDirectories(
std::ostream& fout, std::vector<std::string> const& dirs)
{
const char* comma = "";
+ std::string currentBinDir = this->GetCurrentBinaryDirectory();
for (std::vector<std::string>::const_iterator d = dirs.begin();
d != dirs.end(); ++d) {
// Remove any trailing slash and skip empty paths.
@@ -1345,8 +1347,8 @@ void cmLocalVisualStudio7Generator::OutputLibraryDirectories(
// Switch to a relative path specification if it is shorter.
if (cmSystemTools::FileIsFullPath(dir.c_str())) {
- std::string rel = this->ConvertToRelativePath(
- dir.c_str(), cmOutputConverter::START_OUTPUT);
+ std::string rel =
+ this->ConvertToRelativePath(currentBinDir, dir.c_str());
if (rel.size() < dir.size()) {
dir = rel;
}
diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx
index d344dc5..77ec6f7 100644
--- a/Source/cmLocalVisualStudioGenerator.cxx
+++ b/Source/cmLocalVisualStudioGenerator.cxx
@@ -205,7 +205,9 @@ std::string cmLocalVisualStudioGenerator::ConstructScript(
}
if (workingDirectory.empty()) {
- script += this->Convert(cmd.c_str(), START_OUTPUT, SHELL);
+ script += this->ConvertToOutputFormat(
+ this->ConvertToRelativePath(this->GetCurrentBinaryDirectory(), cmd),
+ cmOutputConverter::SHELL);
} else {
script += this->ConvertToOutputFormat(cmd.c_str(), SHELL);
}
diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx
index ee9dc8a..033f549 100644
--- a/Source/cmMacroCommand.cxx
+++ b/Source/cmMacroCommand.cxx
@@ -203,10 +203,9 @@ bool cmMacroFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff,
// remove the function blocker now that the macro is defined
mf.RemoveFunctionBlocker(this, lff);
return true;
- } else {
- // decrement for each nested macro that ends
- this->Depth--;
}
+ // decrement for each nested macro that ends
+ this->Depth--;
}
// if it wasn't an endmacro and we are not executing then we must be
@@ -236,7 +235,7 @@ bool cmMacroFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
bool cmMacroCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&)
{
- if (args.size() < 1) {
+ if (args.empty()) {
this->SetError("called with incorrect number of arguments");
return false;
}
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index e5a5e6e..50e7b33 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -979,8 +979,9 @@ void cmMakefile::AddCustomCommandOldStyle(
// then add the source to the target to make sure the rule is
// included.
if (sf && !sf->GetPropertyAsBool("__CMAKE_RULE")) {
- if (this->Targets.find(target) != this->Targets.end()) {
- this->Targets[target].AddSource(sf->GetFullPath());
+ cmTargets::iterator ti = this->Targets.find(target);
+ if (ti != this->Targets.end()) {
+ ti->second.AddSource(sf->GetFullPath());
} else {
cmSystemTools::Error("Attempt to add a custom rule to a target "
"that does not exist yet for target ",
@@ -1924,11 +1925,12 @@ cmTarget* cmMakefile::AddNewTarget(cmState::TargetType type,
const std::string& name)
{
cmTargets::iterator it =
- this->Targets.insert(cmTargets::value_type(name, cmTarget())).first;
- cmTarget& target = it->second;
- target.SetType(type, name);
- target.SetMakefile(this);
+ this->Targets
+ .insert(cmTargets::value_type(
+ name, cmTarget(name, type, cmTarget::VisibilityNormal, this)))
+ .first;
this->GetGlobalGenerator()->IndexTarget(&it->second);
+ this->GetStateSnapshot().GetDirectory().AddNormalTargetName(name);
return &it->second;
}
@@ -3709,10 +3711,10 @@ cmTarget* cmMakefile::AddImportedTarget(const std::string& name,
cmState::TargetType type, bool global)
{
// Create the target.
- CM_AUTO_PTR<cmTarget> target(new cmTarget);
- target->SetType(type, name);
- target->MarkAsImported(global);
- target->SetMakefile(this);
+ CM_AUTO_PTR<cmTarget> target(
+ new cmTarget(name, type, global ? cmTarget::VisibilityImportedGlobally
+ : cmTarget::VisibilityImported,
+ this));
// Add to the set of available imported targets.
this->ImportedTargets[name] = target.get();
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 66e1ca2..82bd1a3 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -138,14 +138,20 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
std::string targetOutPathPDB = this->LocalGenerator->ConvertToOutputFormat(
targetFullPathPDB, cmOutputConverter::SHELL);
// Convert to the output path to use in constructing commands.
- std::string targetOutPath = this->Convert(
- targetFullPath, cmOutputConverter::START_OUTPUT, cmOutputConverter::SHELL);
- std::string targetOutPathReal =
- this->Convert(targetFullPathReal, cmOutputConverter::START_OUTPUT,
- cmOutputConverter::SHELL);
+ std::string targetOutPath = this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPath),
+ cmOutputConverter::SHELL);
+ std::string targetOutPathReal = this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathReal),
+ cmOutputConverter::SHELL);
std::string targetOutPathImport =
- this->Convert(targetFullPathImport, cmOutputConverter::START_OUTPUT,
- cmOutputConverter::SHELL);
+ this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->GetCurrentBinaryDirectory(),
+ targetFullPathImport),
+ cmOutputConverter::SHELL);
// Get the language to use for linking this executable.
std::string linkLanguage =
@@ -219,25 +225,27 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// may need to be cleaned.
std::vector<std::string> exeCleanFiles;
exeCleanFiles.push_back(this->LocalGenerator->ConvertToRelativePath(
- targetFullPath, cmOutputConverter::START_OUTPUT));
+ this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPath));
#ifdef _WIN32
// There may be a manifest file for this target. Add it to the
// clean set just in case.
exeCleanFiles.push_back(this->LocalGenerator->ConvertToRelativePath(
- (targetFullPath + ".manifest").c_str(), cmOutputConverter::START_OUTPUT));
+ this->LocalGenerator->GetCurrentBinaryDirectory(),
+ (targetFullPath + ".manifest").c_str()));
#endif
if (targetNameReal != targetName) {
exeCleanFiles.push_back(this->LocalGenerator->ConvertToRelativePath(
- targetFullPathReal, cmOutputConverter::START_OUTPUT));
+ this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathReal));
}
if (!targetNameImport.empty()) {
exeCleanFiles.push_back(this->LocalGenerator->ConvertToRelativePath(
- targetFullPathImport, cmOutputConverter::START_OUTPUT));
+ this->LocalGenerator->GetCurrentBinaryDirectory(),
+ targetFullPathImport));
std::string implib;
if (this->GeneratorTarget->GetImplibGNUtoMS(targetFullPathImport,
implib)) {
exeCleanFiles.push_back(this->LocalGenerator->ConvertToRelativePath(
- implib, cmOutputConverter::START_OUTPUT));
+ this->LocalGenerator->GetCurrentBinaryDirectory(), implib));
}
}
@@ -245,7 +253,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// cleaned. We do not want to delete the .pdb file just before
// linking the target.
this->CleanFiles.push_back(this->LocalGenerator->ConvertToRelativePath(
- targetFullPathPDB, cmOutputConverter::START_OUTPUT));
+ this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathPDB));
// Add the pre-build and pre-link rules building but not when relinking.
if (!relink) {
@@ -317,14 +325,19 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
vars.Language = linkLanguage.c_str();
vars.Objects = buildObjs.c_str();
std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
- objectDir = this->Convert(objectDir, cmOutputConverter::START_OUTPUT,
- cmOutputConverter::SHELL);
+
+ objectDir = this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->GetCurrentBinaryDirectory(), objectDir),
+ cmOutputConverter::SHELL);
vars.ObjectDir = objectDir.c_str();
cmOutputConverter::OutputFormat output = (useWatcomQuote)
? cmOutputConverter::WATCOMQUOTE
: cmOutputConverter::SHELL;
- std::string target = this->Convert(
- targetFullPathReal, cmOutputConverter::START_OUTPUT, output);
+ std::string target = this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathReal),
+ output);
vars.Target = target.c_str();
vars.TargetPDB = targetOutPathPDB.c_str();
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index c31c469..1d66d52 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -312,17 +312,25 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
// arguments.
std::string targetOutPathPDB = this->LocalGenerator->ConvertToOutputFormat(
targetFullPathPDB, cmOutputConverter::SHELL);
- std::string targetOutPath = this->Convert(
- targetFullPath, cmOutputConverter::START_OUTPUT, cmOutputConverter::SHELL);
- std::string targetOutPathSO =
- this->Convert(targetFullPathSO, cmOutputConverter::START_OUTPUT,
- cmOutputConverter::SHELL);
- std::string targetOutPathReal =
- this->Convert(targetFullPathReal, cmOutputConverter::START_OUTPUT,
- cmOutputConverter::SHELL);
+
+ std::string targetOutPath = this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPath),
+ cmOutputConverter::SHELL);
+ std::string targetOutPathSO = this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathSO),
+ cmOutputConverter::SHELL);
+ std::string targetOutPathReal = this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathReal),
+ cmOutputConverter::SHELL);
std::string targetOutPathImport =
- this->Convert(targetFullPathImport, cmOutputConverter::START_OUTPUT,
- cmOutputConverter::SHELL);
+ this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->GetCurrentBinaryDirectory(),
+ targetFullPathImport),
+ cmOutputConverter::SHELL);
this->NumberOfProgressActions++;
if (!this->NoRuleMessages) {
@@ -368,23 +376,24 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
// Clean files associated with this library.
std::vector<std::string> libCleanFiles;
libCleanFiles.push_back(this->LocalGenerator->ConvertToRelativePath(
- targetFullPath, cmOutputConverter::START_OUTPUT));
+ this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPath));
if (targetNameReal != targetName) {
libCleanFiles.push_back(this->LocalGenerator->ConvertToRelativePath(
- targetFullPathReal, cmOutputConverter::START_OUTPUT));
+ this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathReal));
}
if (targetNameSO != targetName && targetNameSO != targetNameReal) {
libCleanFiles.push_back(this->LocalGenerator->ConvertToRelativePath(
- targetFullPathSO, cmOutputConverter::START_OUTPUT));
+ this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathSO));
}
if (!targetNameImport.empty()) {
libCleanFiles.push_back(this->LocalGenerator->ConvertToRelativePath(
- targetFullPathImport, cmOutputConverter::START_OUTPUT));
+ this->LocalGenerator->GetCurrentBinaryDirectory(),
+ targetFullPathImport));
std::string implib;
if (this->GeneratorTarget->GetImplibGNUtoMS(targetFullPathImport,
implib)) {
libCleanFiles.push_back(this->LocalGenerator->ConvertToRelativePath(
- implib, cmOutputConverter::START_OUTPUT));
+ this->LocalGenerator->GetCurrentBinaryDirectory(), implib));
}
}
@@ -392,15 +401,15 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
// cleaned. We do not want to delete the .pdb file just before
// linking the target.
this->CleanFiles.push_back(this->LocalGenerator->ConvertToRelativePath(
- targetFullPathPDB, cmOutputConverter::START_OUTPUT));
+ this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathPDB));
#ifdef _WIN32
// There may be a manifest file for this target. Add it to the
// clean set just in case.
if (this->GeneratorTarget->GetType() != cmState::STATIC_LIBRARY) {
libCleanFiles.push_back(this->LocalGenerator->ConvertToRelativePath(
- (targetFullPath + ".manifest").c_str(),
- cmOutputConverter::START_OUTPUT));
+ this->LocalGenerator->GetCurrentBinaryDirectory(),
+ (targetFullPath + ".manifest").c_str()));
}
#endif
@@ -535,14 +544,20 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
vars.Language = linkLanguage.c_str();
vars.Objects = buildObjs.c_str();
std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
- objectDir = this->Convert(objectDir, cmOutputConverter::START_OUTPUT,
- cmOutputConverter::SHELL);
+
+ objectDir = this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->GetCurrentBinaryDirectory(), objectDir),
+ cmOutputConverter::SHELL);
+
vars.ObjectDir = objectDir.c_str();
cmOutputConverter::OutputFormat output = (useWatcomQuote)
? cmOutputConverter::WATCOMQUOTE
: cmOutputConverter::SHELL;
- std::string target = this->Convert(
- targetFullPathReal, cmOutputConverter::START_OUTPUT, output);
+ std::string target = this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathReal),
+ output);
vars.Target = target.c_str();
vars.LinkLibraries = linkLibs.c_str();
vars.ObjectsQuoted = buildObjs.c_str();
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 165f96c..e0d9fda 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -162,6 +162,8 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
// files for this target.
std::vector<cmSourceFile const*> customCommands;
this->GeneratorTarget->GetCustomCommands(customCommands, config);
+ std::string currentBinDir =
+ this->LocalGenerator->GetCurrentBinaryDirectory();
for (std::vector<cmSourceFile const*>::const_iterator si =
customCommands.begin();
si != customCommands.end(); ++si) {
@@ -172,8 +174,8 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
const std::vector<std::string>& outputs = ccg.GetOutputs();
for (std::vector<std::string>::const_iterator o = outputs.begin();
o != outputs.end(); ++o) {
- this->CleanFiles.push_back(this->LocalGenerator->ConvertToRelativePath(
- *o, cmOutputConverter::START_OUTPUT));
+ this->CleanFiles.push_back(
+ this->LocalGenerator->ConvertToRelativePath(currentBinDir, *o));
}
}
}
@@ -214,8 +216,11 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
*this->BuildFileStream
<< "# Include any dependencies generated for this target.\n"
<< this->GlobalGenerator->IncludeDirective << " " << root
- << this->Convert(dependFileNameFull, cmOutputConverter::HOME_OUTPUT,
- cmOutputConverter::MAKERULE)
+ << cmSystemTools::ConvertToOutputPath(
+ this->LocalGenerator
+ ->ConvertToRelativePath(this->LocalGenerator->GetBinaryDirectory(),
+ dependFileNameFull)
+ .c_str())
<< "\n\n";
if (!this->NoRuleMessages) {
@@ -223,9 +228,12 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
*this->BuildFileStream
<< "# Include the progress variables for this target.\n"
<< this->GlobalGenerator->IncludeDirective << " " << root
- << this->Convert(this->ProgressFileNameFull,
- cmOutputConverter::HOME_OUTPUT,
- cmOutputConverter::MAKERULE)
+ << cmSystemTools::ConvertToOutputPath(
+ this->LocalGenerator
+ ->ConvertToRelativePath(
+ this->LocalGenerator->GetBinaryDirectory(),
+ this->ProgressFileNameFull)
+ .c_str())
<< "\n\n";
}
@@ -255,8 +263,11 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
*this->BuildFileStream
<< "# Include the compile flags for this target's objects.\n"
<< this->GlobalGenerator->IncludeDirective << " " << root
- << this->Convert(this->FlagFileNameFull, cmOutputConverter::HOME_OUTPUT,
- cmOutputConverter::MAKERULE)
+ << cmSystemTools::ConvertToOutputPath(
+ this->LocalGenerator
+ ->ConvertToRelativePath(this->LocalGenerator->GetBinaryDirectory(),
+ this->FlagFileNameFull)
+ .c_str())
<< "\n\n";
}
@@ -313,9 +324,9 @@ void cmMakefileTargetGenerator::MacOSXContentGeneratorType::operator()(
output += cmSystemTools::GetFilenameName(input);
this->Generator->CleanFiles.push_back(
this->Generator->LocalGenerator->ConvertToRelativePath(
- output, cmOutputConverter::START_OUTPUT));
+ this->Generator->LocalGenerator->GetCurrentBinaryDirectory(), output));
output = this->Generator->LocalGenerator->ConvertToRelativePath(
- output, cmOutputConverter::HOME_OUTPUT);
+ this->Generator->LocalGenerator->GetBinaryDirectory(), output);
// Create a rule to copy the content into the bundle.
std::vector<std::string> depends;
@@ -515,14 +526,17 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
}
}
- targetOutPathReal =
- this->Convert(targetFullPathReal, cmOutputConverter::START_OUTPUT,
- cmOutputConverter::SHELL);
+ targetOutPathReal = this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathReal),
+ cmOutputConverter::SHELL);
targetOutPathPDB = this->LocalGenerator->ConvertToOutputFormat(
targetFullPathPDB, cmOutputConverter::SHELL);
- targetOutPathCompilePDB =
- this->Convert(targetFullPathCompilePDB, cmOutputConverter::START_OUTPUT,
- cmOutputConverter::SHELL);
+ targetOutPathCompilePDB = this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->GetCurrentBinaryDirectory(),
+ targetFullPathCompilePDB),
+ cmOutputConverter::SHELL);
if (this->LocalGenerator->IsMinGWMake() &&
cmHasLiteralSuffix(targetOutPathCompilePDB, "\\")) {
@@ -544,12 +558,16 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
this->LocalGenerator->ConvertToOutputFormat(obj, cmOutputConverter::SHELL);
vars.Object = shellObj.c_str();
std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
- objectDir = this->Convert(objectDir, cmOutputConverter::START_OUTPUT,
- cmOutputConverter::SHELL);
+ objectDir = this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->GetCurrentBinaryDirectory(), objectDir),
+ cmOutputConverter::SHELL);
vars.ObjectDir = objectDir.c_str();
std::string objectFileDir = cmSystemTools::GetFilenamePath(obj);
- objectFileDir = this->Convert(objectFileDir, cmOutputConverter::START_OUTPUT,
- cmOutputConverter::SHELL);
+ objectFileDir = this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->GetCurrentBinaryDirectory(), objectFileDir),
+ cmOutputConverter::SHELL);
vars.ObjectFileDir = objectFileDir.c_str();
vars.Flags = flags.c_str();
@@ -889,12 +907,14 @@ bool cmMakefileTargetGenerator::WriteMakeRule(
// For multiple outputs, make the extra ones depend on the first one.
std::vector<std::string> const output_depends(1, outputs[0]);
+ std::string binDir = this->LocalGenerator->GetBinaryDirectory();
for (std::vector<std::string>::const_iterator o = outputs.begin() + 1;
o != outputs.end(); ++o) {
// Touch the extra output so "make" knows that it was updated,
// but only if the output was acually created.
- std::string const out = this->Convert(*o, cmOutputConverter::HOME_OUTPUT,
- cmOutputConverter::SHELL);
+ std::string const out = this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->ConvertToRelativePath(binDir, *o),
+ cmOutputConverter::SHELL);
std::vector<std::string> output_commands;
bool o_symbolic = false;
@@ -973,12 +993,16 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
*this->InfoFileStream << " )\n";
}
+ std::string const& working_dir =
+ this->LocalGenerator->GetCurrentBinaryDirectory();
+
/* clang-format off */
*this->InfoFileStream
<< "\n"
<< "# Fortran module output directory.\n"
<< "set(CMAKE_Fortran_TARGET_MODULE_DIR \""
- << this->GeneratorTarget->GetFortranModuleDirectory() << "\")\n";
+ << this->GeneratorTarget->GetFortranModuleDirectory(working_dir)
+ << "\")\n";
/* clang-format on */
// and now write the rule to use it
@@ -1180,11 +1204,12 @@ void cmMakefileTargetGenerator::WriteObjectsVariable(
<< this->GeneratorTarget->GetName() << "\n"
<< variableNameExternal << " =";
/* clang-format on */
+ std::string currentBinDir =
+ this->LocalGenerator->GetCurrentBinaryDirectory();
for (std::vector<std::string>::const_iterator i =
this->ExternalObjects.begin();
i != this->ExternalObjects.end(); ++i) {
- object = this->LocalGenerator->ConvertToRelativePath(
- *i, cmOutputConverter::START_OUTPUT);
+ object = this->LocalGenerator->ConvertToRelativePath(currentBinDir, *i);
*this->BuildFileStream << " " << lineContinue << "\n"
<< this->Makefile->GetSafeDefinition(
"CMAKE_OBJECT_NAME");
@@ -1217,8 +1242,10 @@ public:
void Feed(std::string const& obj)
{
// Construct the name of the next object.
- this->NextObject = this->LocalGenerator->Convert(
- obj, cmOutputConverter::START_OUTPUT, cmOutputConverter::RESPONSE);
+ this->NextObject = this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->GetCurrentBinaryDirectory(), obj),
+ cmOutputConverter::RESPONSE);
// Roll over to next string if the limit will be exceeded.
if (this->LengthLimit != std::string::npos &&
@@ -1272,7 +1299,7 @@ void cmMakefileTargetGenerator::WriteTargetDriverRule(
std::string buildTargetRuleName = dir;
buildTargetRuleName += relink ? "/preinstall" : "/build";
buildTargetRuleName = this->LocalGenerator->ConvertToRelativePath(
- buildTargetRuleName, cmOutputConverter::HOME_OUTPUT);
+ this->LocalGenerator->GetBinaryDirectory(), buildTargetRuleName);
// Build the list of target outputs to drive.
std::vector<std::string> depends;
@@ -1460,8 +1487,10 @@ void cmMakefileTargetGenerator::CreateLinkScript(
// Create the makefile command to invoke the link script.
std::string link_command = "$(CMAKE_COMMAND) -E cmake_link_script ";
- link_command += this->Convert(
- linkScriptName, cmOutputConverter::START_OUTPUT, cmOutputConverter::SHELL);
+ link_command += this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->GetCurrentBinaryDirectory(), linkScriptName),
+ cmOutputConverter::SHELL);
link_command += " --verbose=$(VERBOSE)";
makefile_commands.push_back(link_command);
makefile_depends.push_back(linkScriptName);
@@ -1492,9 +1521,9 @@ bool cmMakefileTargetGenerator::CheckUseResponseFileForObjects(
if (size_t const limit = calculateCommandLineLengthLimit()) {
// Compute the total length of our list of object files with room
// for argument separation and quoting. This does not convert paths
- // relative to START_OUTPUT like the final list will be, so the actual
- // list will likely be much shorter than this. However, in the worst
- // case all objects will remain as absolute paths.
+ // relative to CMAKE_CURRENT_BINARY_DIR like the final list will be, so the
+ // actual list will likely be much shorter than this. However, in the
+ // worst case all objects will remain as absolute paths.
size_t length = 0;
for (std::vector<std::string>::const_iterator i = this->Objects.begin();
i != this->Objects.end(); ++i) {
@@ -1695,13 +1724,17 @@ void cmMakefileTargetGenerator::GenDefFile(
cmd = this->LocalGenerator->ConvertToOutputFormat(
cmd, cmOutputConverter::SHELL);
cmd += " -E __create_def ";
- cmd += this->Convert(name_of_def_file, cmOutputConverter::START_OUTPUT,
- cmOutputConverter::SHELL);
+ cmd += this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->GetCurrentBinaryDirectory(), name_of_def_file),
+ cmOutputConverter::SHELL);
cmd += " ";
std::string objlist_file = name_of_def_file;
objlist_file += ".objs";
- cmd += this->Convert(objlist_file, cmOutputConverter::START_OUTPUT,
- cmOutputConverter::SHELL);
+ cmd += this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->GetCurrentBinaryDirectory(), objlist_file),
+ cmOutputConverter::SHELL);
real_link_commands.insert(real_link_commands.begin(), cmd);
// create a list of obj files for the -E __create_def to read
cmGeneratedFileStream fout(objlist_file.c_str());
@@ -1719,9 +1752,10 @@ void cmMakefileTargetGenerator::GenDefFile(
// now add the def file link flag
linkFlags += " ";
linkFlags += this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG");
- linkFlags +=
- this->Convert(name_of_def_file, cmOutputConverter::START_OUTPUT,
- cmOutputConverter::SHELL);
+ linkFlags += this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->GetCurrentBinaryDirectory(), name_of_def_file),
+ cmOutputConverter::SHELL);
linkFlags += " ";
}
}
diff --git a/Source/cmMakefileUtilityTargetGenerator.cxx b/Source/cmMakefileUtilityTargetGenerator.cxx
index b709545..8bf0a23 100644
--- a/Source/cmMakefileUtilityTargetGenerator.cxx
+++ b/Source/cmMakefileUtilityTargetGenerator.cxx
@@ -53,9 +53,12 @@ void cmMakefileUtilityTargetGenerator::WriteRuleFiles()
*this->BuildFileStream
<< "# Include the progress variables for this target.\n"
<< this->GlobalGenerator->IncludeDirective << " " << root
- << this->Convert(this->ProgressFileNameFull,
- cmOutputConverter::HOME_OUTPUT,
- cmOutputConverter::MAKERULE)
+ << cmSystemTools::ConvertToOutputPath(
+ this->LocalGenerator
+ ->ConvertToRelativePath(
+ this->LocalGenerator->GetBinaryDirectory(),
+ this->ProgressFileNameFull)
+ .c_str())
<< "\n\n";
}
diff --git a/Source/cmMarkAsAdvancedCommand.cxx b/Source/cmMarkAsAdvancedCommand.cxx
index 2fb6a75..6c979f6 100644
--- a/Source/cmMarkAsAdvancedCommand.cxx
+++ b/Source/cmMarkAsAdvancedCommand.cxx
@@ -15,7 +15,7 @@
bool cmMarkAsAdvancedCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&)
{
- if (args.size() < 1) {
+ if (args.empty()) {
this->SetError("called with incorrect number of arguments");
return false;
}
diff --git a/Source/cmMathCommand.cxx b/Source/cmMathCommand.cxx
index ca8b926..b812349 100644
--- a/Source/cmMathCommand.cxx
+++ b/Source/cmMathCommand.cxx
@@ -16,7 +16,7 @@
bool cmMathCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&)
{
- if (args.size() < 1) {
+ if (args.empty()) {
this->SetError("must be called with at least one argument.");
return false;
}
diff --git a/Source/cmMessageCommand.cxx b/Source/cmMessageCommand.cxx
index c48910e..e884531 100644
--- a/Source/cmMessageCommand.cxx
+++ b/Source/cmMessageCommand.cxx
@@ -17,7 +17,7 @@
bool cmMessageCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&)
{
- if (args.size() < 1) {
+ if (args.empty()) {
this->SetError("called with incorrect number of arguments");
return false;
}
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 335b552..dbd84cb 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -336,7 +336,7 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd()
std::string targetOutputReal =
this->ConvertToNinjaPath(gt.GetFullPath(cfgName,
/*implib=*/false,
- /*realpath=*/true));
+ /*realname=*/true));
cmakeCommand += targetOutputReal;
cmakeCommand += " || true";
linkCmds.push_back(cmakeCommand);
@@ -414,7 +414,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
std::string targetOutputReal =
ConvertToNinjaPath(gt.GetFullPath(cfgName,
/*implib=*/false,
- /*realpath=*/true));
+ /*realname=*/true));
std::string targetOutputImplib =
ConvertToNinjaPath(gt.GetFullPath(cfgName,
/*implib=*/true));
@@ -642,7 +642,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
}
}
}
- // If we have any PRE_LINK commands, we need to go back to HOME_OUTPUT for
+ // If we have any PRE_LINK commands, we need to go back to CMAKE_BINARY_DIR
+ // for
// the link commands.
if (!preLinkCmdLines.empty()) {
const std::string homeOutDir = localGen.ConvertToOutputFormat(
@@ -690,7 +691,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
// Write the build statement for this target.
bool usedResponseFile = false;
globalGen.WriteBuild(this->GetBuildFileStream(), comment.str(),
- this->LanguageLinkerRule(), outputs, explicitDeps,
+ this->LanguageLinkerRule(), outputs,
+ /*implicitOuts=*/cmNinjaDeps(), explicitDeps,
implicitDeps, orderOnlyDeps, vars, rspfile,
commandLineLengthLimit, &usedResponseFile);
this->WriteLinkRule(usedResponseFile);
@@ -701,7 +703,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
this->GetBuildFileStream(),
"Create executable symlink " + targetOutput,
"CMAKE_SYMLINK_EXECUTABLE", cmNinjaDeps(1, targetOutput),
- cmNinjaDeps(1, targetOutputReal), emptyDeps, emptyDeps, symlinkVars);
+ /*implicitOuts=*/cmNinjaDeps(), cmNinjaDeps(1, targetOutputReal),
+ emptyDeps, emptyDeps, symlinkVars);
} else {
cmNinjaDeps symlinks;
std::string const soName =
@@ -716,7 +719,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
symlinks.push_back(targetOutput);
globalGen.WriteBuild(
this->GetBuildFileStream(), "Create library symlink " + targetOutput,
- "CMAKE_SYMLINK_LIBRARY", symlinks, cmNinjaDeps(1, targetOutputReal),
+ "CMAKE_SYMLINK_LIBRARY", symlinks,
+ /*implicitOuts=*/cmNinjaDeps(), cmNinjaDeps(1, targetOutputReal),
emptyDeps, emptyDeps, symlinkVars);
}
}
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 6ac59d5..fb09bfe 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -607,8 +607,9 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
std::string const rspfile = objectFileName + ".rsp";
this->GetGlobalGenerator()->WriteBuild(
- this->GetBuildFileStream(), comment, rule, outputs, explicitDeps,
- implicitDeps, orderOnlyDeps, vars, rspfile, commandLineLengthLimit);
+ this->GetBuildFileStream(), comment, rule, outputs,
+ /*implicitOuts=*/cmNinjaDeps(), explicitDeps, implicitDeps, orderOnlyDeps,
+ vars, rspfile, commandLineLengthLimit);
if (const char* objectOutputs = source->GetProperty("OBJECT_OUTPUTS")) {
std::vector<std::string> outputList;
diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx
index d44fbb7..7f6edf2 100644
--- a/Source/cmOutputConverter.cxx
+++ b/Source/cmOutputConverter.cxx
@@ -46,51 +46,12 @@ std::string cmOutputConverter::ConvertToOutputForExisting(
return this->ConvertToOutputFormat(remote, format);
}
-std::string cmOutputConverter::ConvertToRelativePath(
- const std::string& source, RelativeRoot relative) const
-{
- std::string result;
-
- switch (relative) {
- case HOME:
- result = this->ConvertToRelativePath(
- this->GetState()->GetSourceDirectoryComponents(), source);
- break;
- case START:
- result = this->ConvertToRelativePath(
- this->StateSnapshot.GetDirectory().GetCurrentSourceComponents(),
- source);
- break;
- case HOME_OUTPUT:
- result = this->ConvertToRelativePath(
- this->GetState()->GetBinaryDirectoryComponents(), source);
- break;
- case START_OUTPUT:
- result = this->ConvertToRelativePath(
- this->StateSnapshot.GetDirectory().GetCurrentBinaryComponents(),
- source);
- break;
- }
- return result;
-}
-
-std::string cmOutputConverter::Convert(const std::string& source,
- RelativeRoot relative,
- OutputFormat output) const
-{
- // Convert the path to a relative path.
- std::string result = this->ConvertToRelativePath(source, relative);
- return this->ConvertToOutputFormat(result, output);
-}
-
std::string cmOutputConverter::ConvertToOutputFormat(const std::string& source,
OutputFormat output) const
{
std::string result = source;
// Convert it to an output path.
- if (output == MAKERULE) {
- result = cmSystemTools::ConvertToOutputPath(result.c_str());
- } else if (output == SHELL || output == WATCOMQUOTE) {
+ if (output == SHELL || output == WATCOMQUOTE) {
result = this->ConvertDirectorySeparatorsForShell(source);
result = this->EscapeForShell(result, true, false, output == WATCOMQUOTE);
} else if (output == RESPONSE) {
@@ -128,41 +89,67 @@ std::string cmOutputConverter::ConvertToRelativePath(
const std::vector<std::string>& local, const std::string& in_remote,
bool force) const
{
- // The path should never be quoted.
- assert(in_remote[0] != '\"');
+ std::string local_path = cmSystemTools::JoinPath(local);
+ return force ? this->ForceToRelativePath(local_path, in_remote)
+ : this->ConvertToRelativePath(local_path, in_remote);
+}
+
+std::string cmOutputConverter::ConvertToRelativePath(
+ std::string const& local_path, std::string const& remote_path) const
+{
+ // The paths should never be quoted.
+ assert(local_path[0] != '\"');
+ assert(remote_path[0] != '\"');
// The local path should never have a trailing slash.
- assert(!local.empty() && !(local[local.size() - 1] == ""));
+ assert(local_path.empty() || local_path[local_path.size() - 1] != '/');
// If the path is already relative then just return the path.
- if (!cmSystemTools::FileIsFullPath(in_remote.c_str())) {
- return in_remote;
- }
-
- if (!force) {
- // Skip conversion if the path and local are not both in the source
- // or both in the binary tree.
- std::string local_path = cmSystemTools::JoinPath(local);
- if (!((cmOutputConverterNotAbove(
- local_path.c_str(),
- this->StateSnapshot.GetDirectory().GetRelativePathTopBinary()) &&
- cmOutputConverterNotAbove(
- in_remote.c_str(),
- this->StateSnapshot.GetDirectory().GetRelativePathTopBinary())) ||
- (cmOutputConverterNotAbove(
- local_path.c_str(),
- this->StateSnapshot.GetDirectory().GetRelativePathTopSource()) &&
- cmOutputConverterNotAbove(in_remote.c_str(),
- this->StateSnapshot.GetDirectory()
- .GetRelativePathTopSource())))) {
- return in_remote;
- }
+ if (!cmSystemTools::FileIsFullPath(remote_path.c_str())) {
+ return remote_path;
+ }
+
+ // Skip conversion if the path and local are not both in the source
+ // or both in the binary tree.
+ if (!((cmOutputConverterNotAbove(
+ local_path.c_str(),
+ this->StateSnapshot.GetDirectory().GetRelativePathTopBinary()) &&
+ cmOutputConverterNotAbove(
+ remote_path.c_str(),
+ this->StateSnapshot.GetDirectory().GetRelativePathTopBinary())) ||
+ (cmOutputConverterNotAbove(
+ local_path.c_str(),
+ this->StateSnapshot.GetDirectory().GetRelativePathTopSource()) &&
+ cmOutputConverterNotAbove(
+ remote_path.c_str(),
+ this->StateSnapshot.GetDirectory().GetRelativePathTopSource())))) {
+ return remote_path;
+ }
+
+ return this->ForceToRelativePath(local_path, remote_path);
+}
+
+std::string cmOutputConverter::ForceToRelativePath(
+ std::string const& local_path, std::string const& remote_path)
+{
+ // The paths should never be quoted.
+ assert(local_path[0] != '\"');
+ assert(remote_path[0] != '\"');
+
+ // The local path should never have a trailing slash.
+ assert(local_path.empty() || local_path[local_path.size() - 1] != '/');
+
+ // If the path is already relative then just return the path.
+ if (!cmSystemTools::FileIsFullPath(remote_path.c_str())) {
+ return remote_path;
}
// Identify the longest shared path component between the remote
// path and the local path.
+ std::vector<std::string> local;
+ cmSystemTools::SplitPath(local_path, local);
std::vector<std::string> remote;
- cmSystemTools::SplitPath(in_remote, remote);
+ cmSystemTools::SplitPath(remote_path, remote);
unsigned int common = 0;
while (common < remote.size() && common < local.size() &&
cmSystemTools::ComparePath(remote[common], local[common])) {
@@ -171,7 +158,7 @@ std::string cmOutputConverter::ConvertToRelativePath(
// If no part of the path is in common then return the full path.
if (common == 0) {
- return in_remote;
+ return remote_path;
}
// If the entire path is in common then just return a ".".
diff --git a/Source/cmOutputConverter.h b/Source/cmOutputConverter.h
index ac58ddc..cc24e53 100644
--- a/Source/cmOutputConverter.h
+++ b/Source/cmOutputConverter.h
@@ -24,40 +24,14 @@ class cmOutputConverter
public:
cmOutputConverter(cmState::Snapshot snapshot);
- /**
- * Convert something to something else. This is a centralized conversion
- * routine used by the generators to handle relative paths and the like.
- * The flags determine what is actually done.
- *
- * relative: treat the argument as a directory and convert it to make it
- * relative or full or unchanged. If relative (HOME, START etc) then that
- * specifies what it should be relative to.
- *
- * output: make the result suitable for output to a...
- *
- * optional: should any relative path operation be controlled by the rel
- * path setting
- */
- enum RelativeRoot
- {
- HOME,
- START,
- HOME_OUTPUT,
- START_OUTPUT
- };
enum OutputFormat
{
- MAKERULE,
SHELL,
WATCOMQUOTE,
RESPONSE
};
std::string ConvertToOutputFormat(const std::string& source,
OutputFormat output) const;
- std::string Convert(const std::string& remote, RelativeRoot local,
- OutputFormat output) const;
- std::string ConvertToRelativePath(const std::string& remote,
- RelativeRoot local) const;
std::string ConvertDirectorySeparatorsForShell(
const std::string& source) const;
@@ -145,6 +119,24 @@ public:
const std::string& in_remote,
bool force = false) const;
+ /**
+ * Convert the given remote path to a relative path with respect to
+ * the given local path. Both paths must use forward slashes and not
+ * already be escaped or quoted.
+ * The conversion is skipped if the paths are not both in the source
+ * or both in the binary tree.
+ */
+ std::string ConvertToRelativePath(std::string const& local_path,
+ std::string const& remote_path) const;
+
+ /**
+ * Convert the given remote path to a relative path with respect to
+ * the given local path. Both paths must use forward slashes and not
+ * already be escaped or quoted.
+ */
+ static std::string ForceToRelativePath(std::string const& local_path,
+ std::string const& remote_path);
+
private:
cmState* GetState() const;
diff --git a/Source/cmOutputRequiredFilesCommand.cxx b/Source/cmOutputRequiredFilesCommand.cxx
index ef636e7..730ce6d 100644
--- a/Source/cmOutputRequiredFilesCommand.cxx
+++ b/Source/cmOutputRequiredFilesCommand.cxx
@@ -307,10 +307,10 @@ protected:
// If dependencies are already done, stop now.
if (info->DependDone) {
return;
- } else {
- // Make sure we don't visit the same file more than once.
- info->DependDone = true;
}
+ // Make sure we don't visit the same file more than once.
+ info->DependDone = true;
+
const char* path = info->FullPath.c_str();
if (!path) {
cmSystemTools::Error(
@@ -405,15 +405,14 @@ protected:
if (result != this->DependInformationMap.end()) {
// Found an instance, return it.
return result->second;
- } else {
- // Didn't find an instance. Create a new one and save it.
- cmDependInformation* info = new cmDependInformation;
- info->FullPath = fullPath;
- info->PathOnly = cmSystemTools::GetFilenamePath(fullPath);
- info->IncludeName = file;
- this->DependInformationMap[fullPath] = info;
- return info;
}
+ // Didn't find an instance. Create a new one and save it.
+ cmDependInformation* info = new cmDependInformation;
+ info->FullPath = fullPath;
+ info->PathOnly = cmSystemTools::GetFilenamePath(fullPath);
+ info->IncludeName = file;
+ this->DependInformationMap[fullPath] = info;
+ return info;
}
/**
diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx
index 139303b..6f98d94 100644
--- a/Source/cmProjectCommand.cxx
+++ b/Source/cmProjectCommand.cxx
@@ -15,7 +15,7 @@
bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&)
{
- if (args.size() < 1) {
+ if (args.empty()) {
this->SetError("PROJECT called with incorrect number of arguments");
return false;
}
diff --git a/Source/cmRemoveCommand.cxx b/Source/cmRemoveCommand.cxx
index 955f712..c695374 100644
--- a/Source/cmRemoveCommand.cxx
+++ b/Source/cmRemoveCommand.cxx
@@ -15,7 +15,7 @@
bool cmRemoveCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&)
{
- if (args.size() < 1) {
+ if (args.empty()) {
return true;
}
diff --git a/Source/cmRemoveDefinitionsCommand.cxx b/Source/cmRemoveDefinitionsCommand.cxx
index 638eda6..77de846 100644
--- a/Source/cmRemoveDefinitionsCommand.cxx
+++ b/Source/cmRemoveDefinitionsCommand.cxx
@@ -16,7 +16,7 @@ bool cmRemoveDefinitionsCommand::InitialPass(
std::vector<std::string> const& args, cmExecutionStatus&)
{
// it is OK to have no arguments
- if (args.size() < 1) {
+ if (args.empty()) {
return true;
}
diff --git a/Source/cmSearchPath.cxx b/Source/cmSearchPath.cxx
index ca3a57f..46498e6 100644
--- a/Source/cmSearchPath.cxx
+++ b/Source/cmSearchPath.cxx
@@ -124,9 +124,8 @@ static std::string cmSearchPathStripBin(std::string const& s)
// If the path is a PREFIX/bin case then add its parent instead.
if ((cmHasLiteralSuffix(s, "/bin")) || (cmHasLiteralSuffix(s, "/sbin"))) {
return cmSystemTools::GetFilenamePath(s);
- } else {
- return s;
}
+ return s;
}
void cmSearchPath::AddEnvPrefixPath(const std::string& variable, bool stripBin)
diff --git a/Source/cmServer.cxx b/Source/cmServer.cxx
new file mode 100644
index 0000000..be001a7
--- /dev/null
+++ b/Source/cmServer.cxx
@@ -0,0 +1,473 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 Stephen Kelly <steveire@gmail.com>
+ Copyright 2016 Tobias Hunger <tobias.hunger@qt.io>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmServer.h"
+
+#include "cmServerProtocol.h"
+#include "cmSystemTools.h"
+#include "cmVersionMacros.h"
+#include "cmake.h"
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+#include "cm_jsoncpp_reader.h"
+#include "cm_jsoncpp_value.h"
+#endif
+
+#include <fstream>
+#include <iostream>
+#include <memory>
+
+static const std::string kTYPE_KEY = "type";
+static const std::string kCOOKIE_KEY = "cookie";
+static const std::string kREPLY_TO_KEY = "inReplyTo";
+static const std::string kERROR_MESSAGE_KEY = "errorMessage";
+
+static const std::string kERROR_TYPE = "error";
+static const std::string kREPLY_TYPE = "reply";
+static const std::string kPROGRESS_TYPE = "progress";
+static const std::string kMESSAGE_TYPE = "message";
+
+static const std::string kSTART_MAGIC = "[== CMake Server ==[";
+static const std::string kEND_MAGIC = "]== CMake Server ==]";
+
+typedef struct
+{
+ uv_write_t req;
+ uv_buf_t buf;
+} write_req_t;
+
+void alloc_buffer(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf)
+{
+ (void)handle;
+ *buf = uv_buf_init(static_cast<char*>(malloc(suggested_size)),
+ static_cast<unsigned int>(suggested_size));
+}
+
+void free_write_req(uv_write_t* req)
+{
+ write_req_t* wr = reinterpret_cast<write_req_t*>(req);
+ free(wr->buf.base);
+ free(wr);
+}
+
+void on_stdout_write(uv_write_t* req, int status)
+{
+ (void)status;
+ auto server = reinterpret_cast<cmServer*>(req->data);
+ free_write_req(req);
+ server->PopOne();
+}
+
+void write_data(uv_stream_t* dest, std::string content, uv_write_cb cb)
+{
+ write_req_t* req = static_cast<write_req_t*>(malloc(sizeof(write_req_t)));
+ req->req.data = dest->data;
+ req->buf = uv_buf_init(static_cast<char*>(malloc(content.size())),
+ static_cast<unsigned int>(content.size()));
+ memcpy(req->buf.base, content.c_str(), content.size());
+ uv_write(reinterpret_cast<uv_write_t*>(req), static_cast<uv_stream_t*>(dest),
+ &req->buf, 1, cb);
+}
+
+void read_stdin(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf)
+{
+ if (nread > 0) {
+ auto server = reinterpret_cast<cmServer*>(stream->data);
+ std::string result = std::string(buf->base, buf->base + nread);
+ server->handleData(result);
+ }
+
+ if (buf->base)
+ free(buf->base);
+}
+
+class cmServer::DebugInfo
+{
+public:
+ DebugInfo()
+ : StartTime(uv_hrtime())
+ {
+ }
+
+ bool PrintStatistics = false;
+
+ std::string OutputFile;
+ uint64_t StartTime;
+};
+
+cmServer::cmServer(bool supportExperimental)
+ : SupportExperimental(supportExperimental)
+{
+ // Register supported protocols:
+ this->RegisterProtocol(new cmServerProtocol1_0);
+}
+
+cmServer::~cmServer()
+{
+ if (!this->Protocol) { // Server was never fully started!
+ return;
+ }
+
+ uv_close(reinterpret_cast<uv_handle_t*>(this->InputStream), NULL);
+ uv_close(reinterpret_cast<uv_handle_t*>(this->OutputStream), NULL);
+ uv_loop_close(this->Loop);
+
+ for (cmServerProtocol* p : this->SupportedProtocols) {
+ delete p;
+ }
+}
+
+void cmServer::PopOne()
+{
+ this->Writing = false;
+ if (this->Queue.empty()) {
+ return;
+ }
+
+ Json::Reader reader;
+ Json::Value value;
+ const std::string input = this->Queue.front();
+ this->Queue.erase(this->Queue.begin());
+
+ if (!reader.parse(input, value)) {
+ this->WriteParseError("Failed to parse JSON input.");
+ return;
+ }
+
+ std::unique_ptr<DebugInfo> debug;
+ Json::Value debugValue = value["debug"];
+ if (!debugValue.isNull()) {
+ debug = std::make_unique<DebugInfo>();
+ debug->OutputFile = debugValue["dumpToFile"].asString();
+ debug->PrintStatistics = debugValue["showStats"].asBool();
+ }
+
+ const cmServerRequest request(this, value[kTYPE_KEY].asString(),
+ value[kCOOKIE_KEY].asString(), value);
+
+ if (request.Type == "") {
+ cmServerResponse response(request);
+ response.SetError("No type given in request.");
+ this->WriteResponse(response, nullptr);
+ return;
+ }
+
+ cmSystemTools::SetMessageCallback(reportMessage,
+ const_cast<cmServerRequest*>(&request));
+ if (this->Protocol) {
+ this->Protocol->CMakeInstance()->SetProgressCallback(
+ reportProgress, const_cast<cmServerRequest*>(&request));
+ this->WriteResponse(this->Protocol->Process(request), debug.get());
+ } else {
+ this->WriteResponse(this->SetProtocolVersion(request), debug.get());
+ }
+}
+
+void cmServer::handleData(const std::string& data)
+{
+ this->DataBuffer += data;
+
+ for (;;) {
+ auto needle = this->DataBuffer.find('\n');
+
+ if (needle == std::string::npos) {
+ return;
+ }
+ std::string line = this->DataBuffer.substr(0, needle);
+ const auto ls = line.size();
+ if (ls > 1 && line.at(ls - 1) == '\r')
+ line.erase(ls - 1, 1);
+ this->DataBuffer.erase(this->DataBuffer.begin(),
+ this->DataBuffer.begin() + needle + 1);
+ if (line == kSTART_MAGIC) {
+ this->JsonData.clear();
+ continue;
+ }
+ if (line == kEND_MAGIC) {
+ this->Queue.push_back(this->JsonData);
+ this->JsonData.clear();
+ if (!this->Writing) {
+ this->PopOne();
+ }
+ } else {
+ this->JsonData += line;
+ this->JsonData += "\n";
+ }
+ }
+}
+
+void cmServer::RegisterProtocol(cmServerProtocol* protocol)
+{
+ if (protocol->IsExperimental() && !this->SupportExperimental) {
+ return;
+ }
+ auto version = protocol->ProtocolVersion();
+ assert(version.first >= 0);
+ assert(version.second >= 0);
+ auto it = std::find_if(this->SupportedProtocols.begin(),
+ this->SupportedProtocols.end(),
+ [version](cmServerProtocol* p) {
+ return p->ProtocolVersion() == version;
+ });
+ if (it == this->SupportedProtocols.end())
+ this->SupportedProtocols.push_back(protocol);
+}
+
+void cmServer::PrintHello() const
+{
+ Json::Value hello = Json::objectValue;
+ hello[kTYPE_KEY] = "hello";
+
+ Json::Value& protocolVersions = hello["supportedProtocolVersions"] =
+ Json::arrayValue;
+
+ for (auto const& proto : this->SupportedProtocols) {
+ auto version = proto->ProtocolVersion();
+ Json::Value tmp = Json::objectValue;
+ tmp["major"] = version.first;
+ tmp["minor"] = version.second;
+ if (proto->IsExperimental()) {
+ tmp["experimental"] = true;
+ }
+ protocolVersions.append(tmp);
+ }
+
+ this->WriteJsonObject(hello, nullptr);
+}
+
+void cmServer::reportProgress(const char* msg, float progress, void* data)
+{
+ const cmServerRequest* request = static_cast<const cmServerRequest*>(data);
+ assert(request);
+ if (progress < 0.0 || progress > 1.0) {
+ request->ReportMessage(msg, "");
+ } else {
+ request->ReportProgress(0, static_cast<int>(progress * 1000), 1000, msg);
+ }
+}
+
+void cmServer::reportMessage(const char* msg, const char* title,
+ bool& /* cancel */, void* data)
+{
+ const cmServerRequest* request = static_cast<const cmServerRequest*>(data);
+ assert(request);
+ assert(msg);
+ std::string titleString;
+ if (title) {
+ titleString = title;
+ }
+ request->ReportMessage(std::string(msg), titleString);
+}
+
+cmServerResponse cmServer::SetProtocolVersion(const cmServerRequest& request)
+{
+ if (request.Type != "handshake")
+ return request.ReportError("Waiting for type \"handshake\".");
+
+ Json::Value requestedProtocolVersion = request.Data["protocolVersion"];
+ if (requestedProtocolVersion.isNull())
+ return request.ReportError(
+ "\"protocolVersion\" is required for \"handshake\".");
+
+ if (!requestedProtocolVersion.isObject())
+ return request.ReportError("\"protocolVersion\" must be a JSON object.");
+
+ Json::Value majorValue = requestedProtocolVersion["major"];
+ if (!majorValue.isInt())
+ return request.ReportError("\"major\" must be set and an integer.");
+
+ Json::Value minorValue = requestedProtocolVersion["minor"];
+ if (!minorValue.isNull() && !minorValue.isInt())
+ return request.ReportError("\"minor\" must be unset or an integer.");
+
+ const int major = majorValue.asInt();
+ const int minor = minorValue.isNull() ? -1 : minorValue.asInt();
+ if (major < 0)
+ return request.ReportError("\"major\" must be >= 0.");
+ if (!minorValue.isNull() && minor < 0)
+ return request.ReportError("\"minor\" must be >= 0 when set.");
+
+ this->Protocol =
+ this->FindMatchingProtocol(this->SupportedProtocols, major, minor);
+ if (!this->Protocol) {
+ return request.ReportError("Protocol version not supported.");
+ }
+
+ std::string errorMessage;
+ if (!this->Protocol->Activate(request, &errorMessage)) {
+ this->Protocol = CM_NULLPTR;
+ return request.ReportError("Failed to activate protocol version: " +
+ errorMessage);
+ }
+ return request.Reply(Json::objectValue);
+}
+
+bool cmServer::Serve()
+{
+ if (this->SupportedProtocols.empty()) {
+ return false;
+ }
+ assert(!this->Protocol);
+
+ this->Loop = uv_default_loop();
+
+ if (uv_guess_handle(1) == UV_TTY) {
+ uv_tty_init(this->Loop, &this->Input.tty, 0, 1);
+ uv_tty_set_mode(&this->Input.tty, UV_TTY_MODE_NORMAL);
+ this->Input.tty.data = this;
+ InputStream = reinterpret_cast<uv_stream_t*>(&this->Input.tty);
+
+ uv_tty_init(this->Loop, &this->Output.tty, 1, 0);
+ uv_tty_set_mode(&this->Output.tty, UV_TTY_MODE_NORMAL);
+ this->Output.tty.data = this;
+ OutputStream = reinterpret_cast<uv_stream_t*>(&this->Output.tty);
+ } else {
+ uv_pipe_init(this->Loop, &this->Input.pipe, 0);
+ uv_pipe_open(&this->Input.pipe, 0);
+ this->Input.pipe.data = this;
+ InputStream = reinterpret_cast<uv_stream_t*>(&this->Input.pipe);
+
+ uv_pipe_init(this->Loop, &this->Output.pipe, 0);
+ uv_pipe_open(&this->Output.pipe, 1);
+ this->Output.pipe.data = this;
+ OutputStream = reinterpret_cast<uv_stream_t*>(&this->Output.pipe);
+ }
+
+ this->PrintHello();
+
+ uv_read_start(this->InputStream, alloc_buffer, read_stdin);
+
+ uv_run(this->Loop, UV_RUN_DEFAULT);
+ return true;
+}
+
+void cmServer::WriteJsonObject(const Json::Value& jsonValue,
+ const DebugInfo* debug) const
+{
+ Json::FastWriter writer;
+
+ auto beforeJson = uv_hrtime();
+ std::string result = writer.write(jsonValue);
+
+ if (debug) {
+ Json::Value copy = jsonValue;
+ if (debug->PrintStatistics) {
+ Json::Value stats = Json::objectValue;
+ auto endTime = uv_hrtime();
+
+ stats["jsonSerialization"] = double(endTime - beforeJson) / 1000000.0;
+ stats["totalTime"] = double(endTime - debug->StartTime) / 1000000.0;
+ stats["size"] = static_cast<int>(result.size());
+ if (!debug->OutputFile.empty()) {
+ stats["dumpFile"] = debug->OutputFile;
+ }
+
+ copy["zzzDebug"] = stats;
+
+ result = writer.write(copy); // Update result to include debug info
+ }
+
+ if (!debug->OutputFile.empty()) {
+ std::ofstream myfile;
+ myfile.open(debug->OutputFile);
+ myfile << result;
+ myfile.close();
+ }
+ }
+
+ this->Writing = true;
+ write_data(this->OutputStream, std::string("\n") + kSTART_MAGIC +
+ std::string("\n") + result + kEND_MAGIC + std::string("\n"),
+ on_stdout_write);
+}
+
+cmServerProtocol* cmServer::FindMatchingProtocol(
+ const std::vector<cmServerProtocol*>& protocols, int major, int minor)
+{
+ cmServerProtocol* bestMatch = nullptr;
+ for (auto protocol : protocols) {
+ auto version = protocol->ProtocolVersion();
+ if (major != version.first)
+ continue;
+ if (minor == version.second)
+ return protocol;
+ if (!bestMatch || bestMatch->ProtocolVersion().second < version.second)
+ bestMatch = protocol;
+ }
+ return minor < 0 ? bestMatch : nullptr;
+}
+
+void cmServer::WriteProgress(const cmServerRequest& request, int min,
+ int current, int max,
+ const std::string& message) const
+{
+ assert(min <= current && current <= max);
+ assert(message.length() != 0);
+
+ Json::Value obj = Json::objectValue;
+ obj[kTYPE_KEY] = kPROGRESS_TYPE;
+ obj[kREPLY_TO_KEY] = request.Type;
+ obj[kCOOKIE_KEY] = request.Cookie;
+ obj["progressMessage"] = message;
+ obj["progressMinimum"] = min;
+ obj["progressMaximum"] = max;
+ obj["progressCurrent"] = current;
+
+ this->WriteJsonObject(obj, nullptr);
+}
+
+void cmServer::WriteMessage(const cmServerRequest& request,
+ const std::string& message,
+ const std::string& title) const
+{
+ if (message.empty())
+ return;
+
+ Json::Value obj = Json::objectValue;
+ obj[kTYPE_KEY] = kMESSAGE_TYPE;
+ obj[kREPLY_TO_KEY] = request.Type;
+ obj[kCOOKIE_KEY] = request.Cookie;
+ obj["message"] = message;
+ if (!title.empty()) {
+ obj["title"] = title;
+ }
+
+ WriteJsonObject(obj, nullptr);
+}
+
+void cmServer::WriteParseError(const std::string& message) const
+{
+ Json::Value obj = Json::objectValue;
+ obj[kTYPE_KEY] = kERROR_TYPE;
+ obj[kERROR_MESSAGE_KEY] = message;
+ obj[kREPLY_TO_KEY] = "";
+ obj[kCOOKIE_KEY] = "";
+
+ this->WriteJsonObject(obj, nullptr);
+}
+
+void cmServer::WriteResponse(const cmServerResponse& response,
+ const DebugInfo* debug) const
+{
+ assert(response.IsComplete());
+
+ Json::Value obj = response.Data();
+ obj[kCOOKIE_KEY] = response.Cookie;
+ obj[kTYPE_KEY] = response.IsError() ? kERROR_TYPE : kREPLY_TYPE;
+ obj[kREPLY_TO_KEY] = response.Type;
+ if (response.IsError()) {
+ obj[kERROR_MESSAGE_KEY] = response.ErrorMessage();
+ }
+
+ this->WriteJsonObject(obj, debug);
+}
diff --git a/Source/cmServer.h b/Source/cmServer.h
new file mode 100644
index 0000000..38a11bb
--- /dev/null
+++ b/Source/cmServer.h
@@ -0,0 +1,97 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 Stephen Kelly <steveire@gmail.com>
+ Copyright 2016 Tobias Hunger <tobias.hunger@qt.io>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#pragma once
+
+#include "cmListFileCache.h"
+#include "cmState.h"
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+#include "cm_jsoncpp_value.h"
+#include "cm_uv.h"
+#endif
+
+#include <string>
+#include <vector>
+
+class cmServerProtocol;
+class cmServerRequest;
+class cmServerResponse;
+
+class cmServer
+{
+public:
+ class DebugInfo;
+
+ cmServer(bool supportExperimental);
+ ~cmServer();
+
+ bool Serve();
+
+ // for callbacks:
+ void PopOne();
+ void handleData(std::string const& data);
+
+private:
+ void RegisterProtocol(cmServerProtocol* protocol);
+
+ static void reportProgress(const char* msg, float progress, void* data);
+ static void reportMessage(const char* msg, const char* title, bool& cancel,
+ void* data);
+
+ // Handle requests:
+ cmServerResponse SetProtocolVersion(const cmServerRequest& request);
+
+ void PrintHello() const;
+
+ // Write responses:
+ void WriteProgress(const cmServerRequest& request, int min, int current,
+ int max, const std::string& message) const;
+ void WriteMessage(const cmServerRequest& request, const std::string& message,
+ const std::string& title) const;
+ void WriteResponse(const cmServerResponse& response,
+ const DebugInfo* debug) const;
+ void WriteParseError(const std::string& message) const;
+
+ void WriteJsonObject(Json::Value const& jsonValue,
+ const DebugInfo* debug) const;
+
+ static cmServerProtocol* FindMatchingProtocol(
+ const std::vector<cmServerProtocol*>& protocols, int major, int minor);
+
+ const bool SupportExperimental;
+
+ cmServerProtocol* Protocol = nullptr;
+ std::vector<cmServerProtocol*> SupportedProtocols;
+ std::vector<std::string> Queue;
+
+ std::string DataBuffer;
+ std::string JsonData;
+
+ uv_loop_t* Loop = nullptr;
+
+ typedef union
+ {
+ uv_tty_t tty;
+ uv_pipe_t pipe;
+ } InOutUnion;
+
+ InOutUnion Input;
+ InOutUnion Output;
+ uv_stream_t* InputStream = nullptr;
+ uv_stream_t* OutputStream = nullptr;
+
+ mutable bool Writing = false;
+
+ friend class cmServerRequest;
+};
diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx
new file mode 100644
index 0000000..26942d3
--- /dev/null
+++ b/Source/cmServerProtocol.cxx
@@ -0,0 +1,272 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2016 Tobias Hunger <tobias.hunger@qt.io>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmServerProtocol.h"
+
+#include "cmExternalMakefileProjectGenerator.h"
+#include "cmServer.h"
+#include "cmSystemTools.h"
+#include "cmake.h"
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+#include "cm_jsoncpp_reader.h"
+#include "cm_jsoncpp_value.h"
+#endif
+
+// Vocabulary:
+
+static const std::string kBUILD_DIRECTORY_KEY = "buildDirectory";
+static const std::string kCOOKIE_KEY = "cookie";
+static const std::string kEXTRA_GENERATOR_KEY = "extraGenerator";
+static const std::string kGENERATOR_KEY = "generator";
+static const std::string kSOURCE_DIRECTORY_KEY = "sourceDirectory";
+static const std::string kTYPE_KEY = "type";
+
+cmServerRequest::cmServerRequest(cmServer* server, const std::string& t,
+ const std::string& c, const Json::Value& d)
+ : Type(t)
+ , Cookie(c)
+ , Data(d)
+ , m_Server(server)
+{
+}
+
+void cmServerRequest::ReportProgress(int min, int current, int max,
+ const std::string& message) const
+{
+ this->m_Server->WriteProgress(*this, min, current, max, message);
+}
+
+void cmServerRequest::ReportMessage(const std::string& message,
+ const std::string& title) const
+{
+ m_Server->WriteMessage(*this, message, title);
+}
+
+cmServerResponse cmServerRequest::Reply(const Json::Value& data) const
+{
+ cmServerResponse response(*this);
+ response.SetData(data);
+ return response;
+}
+
+cmServerResponse cmServerRequest::ReportError(const std::string& message) const
+{
+ cmServerResponse response(*this);
+ response.SetError(message);
+ return response;
+}
+
+cmServerResponse::cmServerResponse(const cmServerRequest& request)
+ : Type(request.Type)
+ , Cookie(request.Cookie)
+{
+}
+
+void cmServerResponse::SetData(const Json::Value& data)
+{
+ assert(this->m_Payload == PAYLOAD_UNKNOWN);
+ if (!data[kCOOKIE_KEY].isNull() || !data[kTYPE_KEY].isNull()) {
+ this->SetError("Response contains cookie or type field.");
+ return;
+ }
+ this->m_Payload = PAYLOAD_DATA;
+ this->m_Data = data;
+}
+
+void cmServerResponse::SetError(const std::string& message)
+{
+ assert(this->m_Payload == PAYLOAD_UNKNOWN);
+ this->m_Payload = PAYLOAD_ERROR;
+ this->m_ErrorMessage = message;
+}
+
+bool cmServerResponse::IsComplete() const
+{
+ return this->m_Payload != PAYLOAD_UNKNOWN;
+}
+
+bool cmServerResponse::IsError() const
+{
+ assert(this->m_Payload != PAYLOAD_UNKNOWN);
+ return this->m_Payload == PAYLOAD_ERROR;
+}
+
+std::string cmServerResponse::ErrorMessage() const
+{
+ if (this->m_Payload == PAYLOAD_ERROR)
+ return this->m_ErrorMessage;
+ else
+ return std::string();
+}
+
+Json::Value cmServerResponse::Data() const
+{
+ assert(this->m_Payload != PAYLOAD_UNKNOWN);
+ return this->m_Data;
+}
+
+bool cmServerProtocol::Activate(const cmServerRequest& request,
+ std::string* errorMessage)
+{
+ this->m_CMakeInstance = std::make_unique<cmake>();
+ const bool result = this->DoActivate(request, errorMessage);
+ if (!result)
+ this->m_CMakeInstance = CM_NULLPTR;
+ return result;
+}
+
+cmake* cmServerProtocol::CMakeInstance() const
+{
+ return this->m_CMakeInstance.get();
+}
+
+bool cmServerProtocol::DoActivate(const cmServerRequest& /*request*/,
+ std::string* /*errorMessage*/)
+{
+ return true;
+}
+
+std::pair<int, int> cmServerProtocol1_0::ProtocolVersion() const
+{
+ return std::make_pair(1, 0);
+}
+
+bool cmServerProtocol1_0::DoActivate(const cmServerRequest& request,
+ std::string* errorMessage)
+{
+ std::string sourceDirectory = request.Data[kSOURCE_DIRECTORY_KEY].asString();
+ const std::string buildDirectory =
+ request.Data[kBUILD_DIRECTORY_KEY].asString();
+ std::string generator = request.Data[kGENERATOR_KEY].asString();
+ std::string extraGenerator = request.Data[kEXTRA_GENERATOR_KEY].asString();
+
+ if (buildDirectory.empty()) {
+ if (errorMessage)
+ *errorMessage =
+ std::string("\"") + kBUILD_DIRECTORY_KEY + "\" is missing.";
+ return false;
+ }
+ cmake* cm = CMakeInstance();
+ if (cmSystemTools::PathExists(buildDirectory)) {
+ if (!cmSystemTools::FileIsDirectory(buildDirectory)) {
+ if (errorMessage)
+ *errorMessage = std::string("\"") + kBUILD_DIRECTORY_KEY +
+ "\" exists but is not a directory.";
+ return false;
+ }
+
+ const std::string cachePath = cm->FindCacheFile(buildDirectory);
+ if (cm->LoadCache(cachePath)) {
+ cmState* state = cm->GetState();
+
+ // Check generator:
+ const std::string cachedGenerator =
+ std::string(state->GetCacheEntryValue("CMAKE_GENERATOR"));
+ if (cachedGenerator.empty() && generator.empty()) {
+ if (errorMessage)
+ *errorMessage =
+ std::string("\"") + kGENERATOR_KEY + "\" is required but unset.";
+ return false;
+ }
+ if (generator.empty()) {
+ generator = cachedGenerator;
+ }
+ if (generator != cachedGenerator) {
+ if (errorMessage)
+ *errorMessage = std::string("\"") + kGENERATOR_KEY +
+ "\" set but incompatible with configured generator.";
+ return false;
+ }
+
+ // check extra generator:
+ const std::string cachedExtraGenerator =
+ std::string(state->GetCacheEntryValue("CMAKE_EXTRA_GENERATOR"));
+ if (!cachedExtraGenerator.empty() && !extraGenerator.empty() &&
+ cachedExtraGenerator != extraGenerator) {
+ if (errorMessage)
+ *errorMessage = std::string("\"") + kEXTRA_GENERATOR_KEY +
+ "\" is set but incompatible with configured extra generator.";
+ return false;
+ }
+ if (extraGenerator.empty()) {
+ extraGenerator = cachedExtraGenerator;
+ }
+
+ // check sourcedir:
+ const std::string cachedSourceDirectory =
+ std::string(state->GetCacheEntryValue("CMAKE_HOME_DIRECTORY"));
+ if (!cachedSourceDirectory.empty() && !sourceDirectory.empty() &&
+ cachedSourceDirectory != sourceDirectory) {
+ if (errorMessage)
+ *errorMessage = std::string("\"") + kSOURCE_DIRECTORY_KEY +
+ "\" is set but incompatible with configured source directory.";
+ return false;
+ }
+ if (sourceDirectory.empty()) {
+ sourceDirectory = cachedSourceDirectory;
+ }
+ }
+ }
+
+ if (sourceDirectory.empty()) {
+ if (errorMessage)
+ *errorMessage = std::string("\"") + kSOURCE_DIRECTORY_KEY +
+ "\" is unset but required.";
+ return false;
+ }
+ if (!cmSystemTools::FileIsDirectory(sourceDirectory)) {
+ if (errorMessage)
+ *errorMessage =
+ std::string("\"") + kSOURCE_DIRECTORY_KEY + "\" is not a directory.";
+ return false;
+ }
+ if (generator.empty()) {
+ if (errorMessage)
+ *errorMessage =
+ std::string("\"") + kGENERATOR_KEY + "\" is unset but required.";
+ return false;
+ }
+
+ const std::string fullGeneratorName =
+ cmExternalMakefileProjectGenerator::CreateFullGeneratorName(
+ generator, extraGenerator);
+
+ cmGlobalGenerator* gg = cm->CreateGlobalGenerator(fullGeneratorName);
+ if (!gg) {
+ if (errorMessage)
+ *errorMessage =
+ std::string("Could not set up the requested combination of \"") +
+ kGENERATOR_KEY + "\" and \"" + kEXTRA_GENERATOR_KEY + "\"";
+ return false;
+ }
+
+ cm->SetGlobalGenerator(gg);
+ cm->SetHomeDirectory(sourceDirectory);
+ cm->SetHomeOutputDirectory(buildDirectory);
+
+ this->m_State = STATE_ACTIVE;
+ return true;
+}
+
+const cmServerResponse cmServerProtocol1_0::Process(
+ const cmServerRequest& request)
+{
+ assert(this->m_State >= STATE_ACTIVE);
+
+ return request.ReportError("Unknown command!");
+}
+
+bool cmServerProtocol1_0::IsExperimental() const
+{
+ return true;
+}
diff --git a/Source/cmServerProtocol.h b/Source/cmServerProtocol.h
new file mode 100644
index 0000000..bab949b
--- /dev/null
+++ b/Source/cmServerProtocol.h
@@ -0,0 +1,121 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2016 Tobias Hunger <tobias.hunger@qt.io>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#pragma once
+
+#include "cmListFileCache.h"
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+#include "cm_jsoncpp_writer.h"
+#endif
+
+#include <memory>
+#include <string>
+
+class cmake;
+class cmServer;
+
+class cmServerRequest;
+
+class cmServerResponse
+{
+public:
+ explicit cmServerResponse(const cmServerRequest& request);
+
+ void SetData(const Json::Value& data);
+ void SetError(const std::string& message);
+
+ bool IsComplete() const;
+ bool IsError() const;
+ std::string ErrorMessage() const;
+ Json::Value Data() const;
+
+ const std::string Type;
+ const std::string Cookie;
+
+private:
+ enum PayLoad
+ {
+ PAYLOAD_UNKNOWN,
+ PAYLOAD_ERROR,
+ PAYLOAD_DATA
+ };
+ PayLoad m_Payload = PAYLOAD_UNKNOWN;
+ std::string m_ErrorMessage;
+ Json::Value m_Data;
+};
+
+class cmServerRequest
+{
+public:
+ cmServerResponse Reply(const Json::Value& data) const;
+ cmServerResponse ReportError(const std::string& message) const;
+
+ const std::string Type;
+ const std::string Cookie;
+ const Json::Value Data;
+
+private:
+ cmServerRequest(cmServer* server, const std::string& t, const std::string& c,
+ const Json::Value& d);
+
+ void ReportProgress(int min, int current, int max,
+ const std::string& message) const;
+ void ReportMessage(const std::string& message,
+ const std::string& title) const;
+
+ cmServer* m_Server;
+
+ friend class cmServer;
+};
+
+class cmServerProtocol
+{
+public:
+ virtual ~cmServerProtocol() {}
+
+ virtual std::pair<int, int> ProtocolVersion() const = 0;
+ virtual bool IsExperimental() const = 0;
+ virtual const cmServerResponse Process(const cmServerRequest& request) = 0;
+
+ bool Activate(const cmServerRequest& request, std::string* errorMessage);
+
+protected:
+ cmake* CMakeInstance() const;
+ // Implement protocol specific activation tasks here. Called from Activate().
+ virtual bool DoActivate(const cmServerRequest& request,
+ std::string* errorMessage);
+
+private:
+ std::unique_ptr<cmake> m_CMakeInstance;
+
+ friend class cmServer;
+};
+
+class cmServerProtocol1_0 : public cmServerProtocol
+{
+public:
+ std::pair<int, int> ProtocolVersion() const override;
+ bool IsExperimental() const override;
+ const cmServerResponse Process(const cmServerRequest& request) override;
+
+private:
+ bool DoActivate(const cmServerRequest& request,
+ std::string* errorMessage) override;
+
+ enum State
+ {
+ STATE_INACTIVE,
+ STATE_ACTIVE
+ };
+ State m_State = STATE_INACTIVE;
+};
diff --git a/Source/cmSetCommand.cxx b/Source/cmSetCommand.cxx
index 8fb6aa0..0660b76 100644
--- a/Source/cmSetCommand.cxx
+++ b/Source/cmSetCommand.cxx
@@ -15,7 +15,7 @@
bool cmSetCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&)
{
- if (args.size() < 1) {
+ if (args.empty()) {
this->SetError("called with incorrect number of arguments");
return false;
}
@@ -59,7 +59,7 @@ bool cmSetCommand::InitialPass(std::vector<std::string> const& args,
}
// SET (VAR PARENT_SCOPE) // Removes the definition of VAR
// in the parent scope.
- else if (args.size() == 2 && args[args.size() - 1] == "PARENT_SCOPE") {
+ if (args.size() == 2 && args[args.size() - 1] == "PARENT_SCOPE") {
this->Makefile->RaiseScope(variable, CM_NULLPTR);
return true;
}
diff --git a/Source/cmSetDirectoryPropertiesCommand.cxx b/Source/cmSetDirectoryPropertiesCommand.cxx
index ca758da..03b195a 100644
--- a/Source/cmSetDirectoryPropertiesCommand.cxx
+++ b/Source/cmSetDirectoryPropertiesCommand.cxx
@@ -17,7 +17,7 @@
bool cmSetDirectoryPropertiesCommand::InitialPass(
std::vector<std::string> const& args, cmExecutionStatus&)
{
- if (args.size() < 1) {
+ if (args.empty()) {
this->SetError("called with incorrect number of arguments");
return false;
}
@@ -45,7 +45,8 @@ bool cmSetDirectoryPropertiesCommand::RunCommand(
if (prop == "VARIABLES") {
errors = "Variables and cache variables should be set using SET command";
return false;
- } else if (prop == "MACROS") {
+ }
+ if (prop == "MACROS") {
errors = "Commands and macros cannot be set using SET_CMAKE_PROPERTIES";
return false;
}
diff --git a/Source/cmSetTestsPropertiesCommand.cxx b/Source/cmSetTestsPropertiesCommand.cxx
index 2fb137f..59d569d 100644
--- a/Source/cmSetTestsPropertiesCommand.cxx
+++ b/Source/cmSetTestsPropertiesCommand.cxx
@@ -18,7 +18,7 @@
bool cmSetTestsPropertiesCommand::InitialPass(
std::vector<std::string> const& args, cmExecutionStatus&)
{
- if (args.size() < 1) {
+ if (args.empty()) {
this->SetError("called with incorrect number of arguments");
return false;
}
diff --git a/Source/cmSourceGroupCommand.cxx b/Source/cmSourceGroupCommand.cxx
index 6db14c0..6f7ef6c 100644
--- a/Source/cmSourceGroupCommand.cxx
+++ b/Source/cmSourceGroupCommand.cxx
@@ -15,7 +15,7 @@
bool cmSourceGroupCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&)
{
- if (args.size() < 1) {
+ if (args.empty()) {
this->SetError("called with incorrect number of arguments");
return false;
}
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index 073c239..6b37b92 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -29,6 +29,11 @@
#include <string.h>
#include <utility>
+static std::string const kBINARY_DIR = "BINARY_DIR";
+static std::string const kBUILDSYSTEM_TARGETS = "BUILDSYSTEM_TARGETS";
+static std::string const kSOURCE_DIR = "SOURCE_DIR";
+static std::string const kSUBDIRECTORIES = "SUBDIRECTORIES";
+
struct cmState::SnapshotDataType
{
cmState::PositionType ScopeParent;
@@ -77,8 +82,6 @@ struct cmState::BuildsystemDirectoryStateType
std::string Location;
std::string OutputLocation;
- std::vector<std::string> CurrentSourceDirectoryComponents;
- std::vector<std::string> CurrentBinaryDirectoryComponents;
// The top-most directories for relative path conversion. Both the
// source and destination location of a relative path conversion
// must be underneath one of these directories (both under source or
@@ -96,6 +99,8 @@ struct cmState::BuildsystemDirectoryStateType
std::vector<std::string> CompileOptions;
std::vector<cmListFileBacktrace> CompileOptionsBacktraces;
+ std::vector<std::string> NormalTargetNames;
+
std::string ProjectName;
cmPropertyMap Properties;
@@ -326,6 +331,7 @@ cmState::Snapshot cmState::Reset()
it->CompileOptions.clear();
it->CompileOptionsBacktraces.clear();
it->DirectoryEnd = pos;
+ it->NormalTargetNames.clear();
it->Properties.clear();
it->Children.clear();
}
@@ -591,10 +597,6 @@ void cmState::SetSourceDirectory(std::string const& sourceDirectory)
{
this->SourceDirectory = sourceDirectory;
cmSystemTools::ConvertToUnixSlashes(this->SourceDirectory);
-
- cmSystemTools::SplitPath(
- cmSystemTools::CollapseFullPath(this->SourceDirectory),
- this->SourceDirectoryComponents);
}
const char* cmState::GetSourceDirectory() const
@@ -602,19 +604,10 @@ const char* cmState::GetSourceDirectory() const
return this->SourceDirectory.c_str();
}
-std::vector<std::string> const& cmState::GetSourceDirectoryComponents() const
-{
- return this->SourceDirectoryComponents;
-}
-
void cmState::SetBinaryDirectory(std::string const& binaryDirectory)
{
this->BinaryDirectory = binaryDirectory;
cmSystemTools::ConvertToUnixSlashes(this->BinaryDirectory);
-
- cmSystemTools::SplitPath(
- cmSystemTools::CollapseFullPath(this->BinaryDirectory),
- this->BinaryDirectoryComponents);
}
void cmState::SetWindowsShell(bool windowsShell)
@@ -692,11 +685,6 @@ const char* cmState::GetBinaryDirectory() const
return this->BinaryDirectory.c_str();
}
-std::vector<std::string> const& cmState::GetBinaryDirectoryComponents() const
-{
- return this->BinaryDirectoryComponents;
-}
-
void cmState::Directory::ComputeRelativePathTopSource()
{
// Relative path conversion inside the source tree is not used to
@@ -978,8 +966,6 @@ void cmState::Directory::SetCurrentSource(std::string const& dir)
cmSystemTools::ConvertToUnixSlashes(loc);
loc = cmSystemTools::CollapseFullPath(loc);
- cmSystemTools::SplitPath(
- loc, this->DirectoryState->CurrentSourceDirectoryComponents);
this->ComputeRelativePathTopSource();
this->Snapshot_.SetDefinition("CMAKE_CURRENT_SOURCE_DIR", loc);
@@ -997,8 +983,6 @@ void cmState::Directory::SetCurrentBinary(std::string const& dir)
cmSystemTools::ConvertToUnixSlashes(loc);
loc = cmSystemTools::CollapseFullPath(loc);
- cmSystemTools::SplitPath(
- loc, this->DirectoryState->CurrentBinaryDirectoryComponents);
this->ComputeRelativePathTopBinary();
this->Snapshot_.SetDefinition("CMAKE_CURRENT_BINARY_DIR", loc);
@@ -1009,18 +993,6 @@ void cmState::Snapshot::SetListFile(const std::string& listfile)
*this->Position->ExecutionListFile = listfile;
}
-std::vector<std::string> const&
-cmState::Directory::GetCurrentSourceComponents() const
-{
- return this->DirectoryState->CurrentSourceDirectoryComponents;
-}
-
-std::vector<std::string> const&
-cmState::Directory::GetCurrentBinaryComponents() const
-{
- return this->DirectoryState->CurrentBinaryDirectoryComponents;
-}
-
const char* cmState::Directory::GetRelativePathTopSource() const
{
return this->DirectoryState->RelativePathTopSource.c_str();
@@ -1703,6 +1675,30 @@ const char* cmState::Directory::GetProperty(const std::string& prop,
}
return "";
}
+ if (prop == kBINARY_DIR) {
+ output = this->GetCurrentBinary();
+ return output.c_str();
+ }
+ if (prop == kSOURCE_DIR) {
+ output = this->GetCurrentSource();
+ return output.c_str();
+ }
+ if (prop == kSUBDIRECTORIES) {
+ std::vector<std::string> child_dirs;
+ std::vector<cmState::Snapshot> const& children =
+ this->DirectoryState->Children;
+ for (std::vector<cmState::Snapshot>::const_iterator ci = children.begin();
+ ci != children.end(); ++ci) {
+ child_dirs.push_back(ci->GetDirectory().GetCurrentSource());
+ }
+ output = cmJoin(child_dirs, ";");
+ return output.c_str();
+ }
+ if (prop == kBUILDSYSTEM_TARGETS) {
+ output = cmJoin(this->DirectoryState->NormalTargetNames, ";");
+ return output.c_str();
+ }
+
if (prop == "LISTFILE_STACK") {
std::vector<std::string> listFiles;
cmState::Snapshot snp = this->Snapshot_;
@@ -1769,6 +1765,11 @@ std::vector<std::string> cmState::Directory::GetPropertyKeys() const
return keys;
}
+void cmState::Directory::AddNormalTargetName(std::string const& name)
+{
+ this->DirectoryState->NormalTargetNames.push_back(name);
+}
+
bool operator==(const cmState::Snapshot& lhs, const cmState::Snapshot& rhs)
{
return lhs.Position == rhs.Position;
diff --git a/Source/cmState.h b/Source/cmState.h
index 9ab4213..1324f5f 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -135,9 +135,6 @@ public:
const char* GetCurrentBinary() const;
void SetCurrentBinary(std::string const& dir);
- std::vector<std::string> const& GetCurrentSourceComponents() const;
- std::vector<std::string> const& GetCurrentBinaryComponents() const;
-
const char* GetRelativePathTopSource() const;
const char* GetRelativePathTopBinary() const;
void SetRelativePathTopSource(const char* dir);
@@ -178,6 +175,8 @@ public:
bool GetPropertyAsBool(const std::string& prop) const;
std::vector<std::string> GetPropertyKeys() const;
+ void AddNormalTargetName(std::string const& name);
+
private:
void ComputeRelativePathTopSource();
void ComputeRelativePathTopBinary();
@@ -312,9 +311,6 @@ public:
const char* GetBinaryDirectory() const;
void SetBinaryDirectory(std::string const& binaryDirectory);
- std::vector<std::string> const& GetSourceDirectoryComponents() const;
- std::vector<std::string> const& GetBinaryDirectoryComponents() const;
-
void SetWindowsShell(bool windowsShell);
bool UseWindowsShell() const;
void SetWindowsVSIDE(bool windowsVSIDE);
@@ -350,8 +346,6 @@ private:
cmLinkedTree<SnapshotDataType> SnapshotData;
cmLinkedTree<cmDefinitions> VarTree;
- std::vector<std::string> SourceDirectoryComponents;
- std::vector<std::string> BinaryDirectoryComponents;
std::string SourceDirectory;
std::string BinaryDirectory;
bool IsInTryCompile;
diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx
index 3c913ee..cfb537f 100644
--- a/Source/cmStringCommand.cxx
+++ b/Source/cmStringCommand.cxx
@@ -26,7 +26,7 @@
bool cmStringCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&)
{
- if (args.size() < 1) {
+ if (args.empty()) {
this->SetError("must be called with at least one argument.");
return false;
}
@@ -34,43 +34,61 @@ bool cmStringCommand::InitialPass(std::vector<std::string> const& args,
const std::string& subCommand = args[0];
if (subCommand == "REGEX") {
return this->HandleRegexCommand(args);
- } else if (subCommand == "REPLACE") {
+ }
+ if (subCommand == "REPLACE") {
return this->HandleReplaceCommand(args);
- } else if (subCommand == "MD5" || subCommand == "SHA1" ||
- subCommand == "SHA224" || subCommand == "SHA256" ||
- subCommand == "SHA384" || subCommand == "SHA512") {
+ }
+ if (subCommand == "MD5" || subCommand == "SHA1" || subCommand == "SHA224" ||
+ subCommand == "SHA256" || subCommand == "SHA384" ||
+ subCommand == "SHA512") {
return this->HandleHashCommand(args);
- } else if (subCommand == "TOLOWER") {
+ }
+ if (subCommand == "TOLOWER") {
return this->HandleToUpperLowerCommand(args, false);
- } else if (subCommand == "TOUPPER") {
+ }
+ if (subCommand == "TOUPPER") {
return this->HandleToUpperLowerCommand(args, true);
- } else if (subCommand == "COMPARE") {
+ }
+ if (subCommand == "COMPARE") {
return this->HandleCompareCommand(args);
- } else if (subCommand == "ASCII") {
+ }
+ if (subCommand == "ASCII") {
return this->HandleAsciiCommand(args);
- } else if (subCommand == "CONFIGURE") {
+ }
+ if (subCommand == "CONFIGURE") {
return this->HandleConfigureCommand(args);
- } else if (subCommand == "LENGTH") {
+ }
+ if (subCommand == "LENGTH") {
return this->HandleLengthCommand(args);
- } else if (subCommand == "APPEND") {
+ }
+ if (subCommand == "APPEND") {
return this->HandleAppendCommand(args);
- } else if (subCommand == "CONCAT") {
+ }
+ if (subCommand == "CONCAT") {
return this->HandleConcatCommand(args);
- } else if (subCommand == "SUBSTRING") {
+ }
+ if (subCommand == "SUBSTRING") {
return this->HandleSubstringCommand(args);
- } else if (subCommand == "STRIP") {
+ }
+ if (subCommand == "STRIP") {
return this->HandleStripCommand(args);
- } else if (subCommand == "RANDOM") {
+ }
+ if (subCommand == "RANDOM") {
return this->HandleRandomCommand(args);
- } else if (subCommand == "FIND") {
+ }
+ if (subCommand == "FIND") {
return this->HandleFindCommand(args);
- } else if (subCommand == "TIMESTAMP") {
+ }
+ if (subCommand == "TIMESTAMP") {
return this->HandleTimestampCommand(args);
- } else if (subCommand == "MAKE_C_IDENTIFIER") {
+ }
+ if (subCommand == "MAKE_C_IDENTIFIER") {
return this->HandleMakeCIdentifierCommand(args);
- } else if (subCommand == "GENEX_STRIP") {
+ }
+ if (subCommand == "GENEX_STRIP") {
return this->HandleGenexStripCommand(args);
- } else if (subCommand == "UUID") {
+ }
+ if (subCommand == "UUID") {
return this->HandleUuidCommand(args);
}
@@ -158,7 +176,8 @@ bool cmStringCommand::HandleConfigureCommand(
if (args.size() < 2) {
this->SetError("No input string specified.");
return false;
- } else if (args.size() < 3) {
+ }
+ if (args.size() < 3) {
this->SetError("No output variable specified.");
return false;
}
@@ -203,14 +222,16 @@ bool cmStringCommand::HandleRegexCommand(std::vector<std::string> const& args)
return false;
}
return this->RegexMatch(args);
- } else if (mode == "MATCHALL") {
+ }
+ if (mode == "MATCHALL") {
if (args.size() < 5) {
this->SetError("sub-command REGEX, mode MATCHALL needs "
"at least 5 arguments total to command.");
return false;
}
return this->RegexMatchAll(args);
- } else if (mode == "REPLACE") {
+ }
+ if (mode == "REPLACE") {
if (args.size() < 6) {
this->SetError("sub-command REGEX, mode REPLACE needs "
"at least 6 arguments total to command.");
@@ -785,7 +806,8 @@ bool cmStringCommand::HandleTimestampCommand(
if (args.size() < 2) {
this->SetError("sub-command TIMESTAMP requires at least one argument.");
return false;
- } else if (args.size() > 4) {
+ }
+ if (args.size() > 4) {
this->SetError("sub-command TIMESTAMP takes at most three arguments.");
return false;
}
diff --git a/Source/cmSubdirCommand.cxx b/Source/cmSubdirCommand.cxx
index 401f588..4893978 100644
--- a/Source/cmSubdirCommand.cxx
+++ b/Source/cmSubdirCommand.cxx
@@ -15,7 +15,7 @@
bool cmSubdirCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&)
{
- if (args.size() < 1) {
+ if (args.empty()) {
this->SetError("called with incorrect number of arguments");
return false;
}
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 7352217..36ed614 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -2416,6 +2416,83 @@ bool cmSystemTools::VersionCompareGreaterEq(std::string const& lhs,
lhs.c_str(), rhs.c_str());
}
+static size_t cm_strverscmp_find_first_difference_or_end(const char* lhs,
+ const char* rhs)
+{
+ size_t i = 0;
+ /* Step forward until we find a difference or both strings end together.
+ The difference may lie on the null-terminator of one string. */
+ while (lhs[i] == rhs[i] && lhs[i] != 0) {
+ ++i;
+ }
+ return i;
+}
+
+static size_t cm_strverscmp_find_digits_begin(const char* s, size_t i)
+{
+ /* Step back until we are not preceded by a digit. */
+ while (i > 0 && isdigit(s[i - 1])) {
+ --i;
+ }
+ return i;
+}
+
+static size_t cm_strverscmp_find_digits_end(const char* s, size_t i)
+{
+ /* Step forward over digits. */
+ while (isdigit(s[i])) {
+ ++i;
+ }
+ return i;
+}
+
+static size_t cm_strverscmp_count_leading_zeros(const char* s, size_t b)
+{
+ size_t i = b;
+ /* Step forward over zeros that are followed by another digit. */
+ while (s[i] == '0' && isdigit(s[i + 1])) {
+ ++i;
+ }
+ return i - b;
+}
+
+static int cm_strverscmp(const char* lhs, const char* rhs)
+{
+ size_t const i = cm_strverscmp_find_first_difference_or_end(lhs, rhs);
+ if (lhs[i] != rhs[i]) {
+ /* The strings differ starting at 'i'. Check for a digit sequence. */
+ size_t const b = cm_strverscmp_find_digits_begin(lhs, i);
+ if (b != i || (isdigit(lhs[i]) && isdigit(rhs[i]))) {
+ /* A digit sequence starts at 'b', preceding or at 'i'. */
+
+ /* Look for leading zeros, implying a leading decimal point. */
+ size_t const lhs_zeros = cm_strverscmp_count_leading_zeros(lhs, b);
+ size_t const rhs_zeros = cm_strverscmp_count_leading_zeros(rhs, b);
+ if (lhs_zeros != rhs_zeros) {
+ /* The side with more leading zeros orders first. */
+ return rhs_zeros > lhs_zeros ? 1 : -1;
+ }
+ if (lhs_zeros == 0) {
+ /* No leading zeros; compare digit sequence lengths. */
+ size_t const lhs_end = cm_strverscmp_find_digits_end(lhs, i);
+ size_t const rhs_end = cm_strverscmp_find_digits_end(rhs, i);
+ if (lhs_end != rhs_end) {
+ /* The side with fewer digits orders first. */
+ return lhs_end > rhs_end ? 1 : -1;
+ }
+ }
+ }
+ }
+
+ /* Ordering was not decided by digit sequence lengths; compare bytes. */
+ return lhs[i] - rhs[i];
+}
+
+int cmSystemTools::strverscmp(std::string const& lhs, std::string const& rhs)
+{
+ return cm_strverscmp(lhs.c_str(), rhs.c_str());
+}
+
bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
bool* removed)
{
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index 3c1a9f4..aecf40e 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -306,6 +306,16 @@ public:
std::string const& rhs);
/**
+ * Compare two ASCII strings using natural versioning order.
+ * Non-numerical characters are compared directly.
+ * Numerical characters are first globbed such that, e.g.
+ * `test000 < test01 < test0 < test1 < test10`.
+ * Return a value less than, equal to, or greater than zero if lhs
+ * precedes, equals, or succeeds rhs in the defined ordering.
+ */
+ static int strverscmp(std::string const& lhs, std::string const& rhs);
+
+ /**
* Determine the file type based on the extension
*/
static FileFormat GetFileFormat(const char* ext);
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index d5274cd..1dad742 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -59,34 +59,28 @@ public:
std::vector<cmListFileBacktrace> LinkImplementationPropertyBacktraces;
};
-cmTarget::cmTarget()
+cmTarget::cmTarget(std::string const& name, cmState::TargetType type,
+ Visibility vis, cmMakefile* mf)
{
- this->Makefile = CM_NULLPTR;
+ assert(mf);
+ this->Name = name;
+ this->TargetTypeValue = type;
+ this->Makefile = mf;
this->HaveInstallRule = false;
this->DLLPlatform = false;
this->IsAndroid = false;
- this->IsImportedTarget = false;
- this->ImportedGloballyVisible = false;
+ this->IsImportedTarget =
+ (vis == VisibilityImported || vis == VisibilityImportedGlobally);
+ this->ImportedGloballyVisible = vis == VisibilityImportedGlobally;
this->BuildInterfaceIncludesAppended = false;
-}
-void cmTarget::SetType(cmState::TargetType type, const std::string& name)
-{
- this->Name = name;
// only add dependency information for library targets
- this->TargetTypeValue = type;
if (this->TargetTypeValue >= cmState::STATIC_LIBRARY &&
this->TargetTypeValue <= cmState::MODULE_LIBRARY) {
this->RecordDependencies = true;
} else {
this->RecordDependencies = false;
}
-}
-
-void cmTarget::SetMakefile(cmMakefile* mf)
-{
- // Set our makefile.
- this->Makefile = mf;
// Check whether this is a DLL platform.
this->DLLPlatform =
@@ -602,8 +596,8 @@ void cmTarget::GetTllSignatureTraces(std::ostream& s, TLLSignature sig) const
it != this->TLLCommands.end(); ++it) {
if (it->first == sig) {
cmListFileContext lfc = it->second;
- lfc.FilePath =
- converter.ConvertToRelativePath(lfc.FilePath, cmOutputConverter::HOME);
+ lfc.FilePath = converter.ConvertToRelativePath(
+ this->Makefile->GetState()->GetSourceDirectory(), lfc.FilePath);
s << " * " << lfc << std::endl;
}
}
@@ -1062,12 +1056,6 @@ void cmTarget::CheckProperty(const std::string& prop,
}
}
-void cmTarget::MarkAsImported(bool global)
-{
- this->IsImportedTarget = true;
- this->ImportedGloballyVisible = global;
-}
-
bool cmTarget::HandleLocationPropertyPolicy(cmMakefile* context) const
{
if (this->IsImported()) {
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index fc30166..4b182bb 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -63,7 +63,16 @@ private:
class cmTarget
{
public:
- cmTarget();
+ enum Visibility
+ {
+ VisibilityNormal,
+ VisibilityImported,
+ VisibilityImportedGlobally
+ };
+
+ cmTarget(std::string const& name, cmState::TargetType type, Visibility vis,
+ cmMakefile* mf);
+
enum CustomCommandType
{
PRE_BUILD,
@@ -76,18 +85,10 @@ public:
*/
cmState::TargetType GetType() const { return this->TargetTypeValue; }
- /**
- * Set the target type
- */
- void SetType(cmState::TargetType f, const std::string& name);
-
- void MarkAsImported(bool global = false);
-
///! Set/Get the name of the target
const std::string& GetName() const { return this->Name; }
- ///! Set the cmMakefile that owns this target
- void SetMakefile(cmMakefile* mf);
+ /** Get the cmMakefile that owns this target. */
cmMakefile* GetMakefile() const { return this->Makefile; }
#define DECLARE_TARGET_POLICY(POLICY) \
diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx
index 1c4a9ce..950db16 100644
--- a/Source/cmTargetLinkLibrariesCommand.cxx
+++ b/Source/cmTargetLinkLibrariesCommand.cxx
@@ -22,7 +22,7 @@ bool cmTargetLinkLibrariesCommand::InitialPass(
std::vector<std::string> const& args, cmExecutionStatus&)
{
// must have one argument
- if (args.size() < 1) {
+ if (args.empty()) {
this->SetError("called with incorrect number of arguments");
return false;
}
@@ -353,10 +353,9 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib,
"INTERFACE_LINK_LIBRARIES",
this->Target->GetDebugGeneratorExpressions(lib, llt).c_str());
return true;
- } else if (this->CurrentProcessingState !=
- ProcessingKeywordPublicInterface &&
- this->CurrentProcessingState !=
- ProcessingPlainPublicInterface) {
+ }
+ if (this->CurrentProcessingState != ProcessingKeywordPublicInterface &&
+ this->CurrentProcessingState != ProcessingPlainPublicInterface) {
if (this->Target->GetType() == cmState::STATIC_LIBRARY) {
std::string configLib =
this->Target->GetDebugGeneratorExpressions(lib, llt);
diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx
index 61b74db..a94212c 100644
--- a/Source/cmTimestamp.cxx
+++ b/Source/cmTimestamp.cxx
@@ -123,6 +123,8 @@ std::string cmTimestamp::AddTimestampComponent(char flag,
formatString += flag;
switch (flag) {
+ case 'a':
+ case 'b':
case 'd':
case 'H':
case 'I':
diff --git a/Source/cmUnsetCommand.cxx b/Source/cmUnsetCommand.cxx
index 05ba65a..874015d 100644
--- a/Source/cmUnsetCommand.cxx
+++ b/Source/cmUnsetCommand.cxx
@@ -15,7 +15,7 @@
bool cmUnsetCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&)
{
- if (args.size() < 1 || args.size() > 2) {
+ if (args.empty() || args.size() > 2) {
this->SetError("called with incorrect number of arguments");
return false;
}
@@ -36,23 +36,21 @@ bool cmUnsetCommand::InitialPass(std::vector<std::string> const& args,
return true;
}
// unset(VAR)
- else if (args.size() == 1) {
+ if (args.size() == 1) {
this->Makefile->RemoveDefinition(variable);
return true;
}
// unset(VAR CACHE)
- else if ((args.size() == 2) && (args[1] == "CACHE")) {
+ if ((args.size() == 2) && (args[1] == "CACHE")) {
this->Makefile->RemoveCacheDefinition(variable);
return true;
}
// unset(VAR PARENT_SCOPE)
- else if ((args.size() == 2) && (args[1] == "PARENT_SCOPE")) {
+ if ((args.size() == 2) && (args[1] == "PARENT_SCOPE")) {
this->Makefile->RaiseScope(variable, CM_NULLPTR);
return true;
}
// ERROR: second argument isn't CACHE or PARENT_SCOPE
- else {
- this->SetError("called with an invalid second argument");
- return false;
- }
+ this->SetError("called with an invalid second argument");
+ return false;
}
diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx
index f30ffe8..cf740db 100644
--- a/Source/cmVariableWatchCommand.cxx
+++ b/Source/cmVariableWatchCommand.cxx
@@ -104,7 +104,7 @@ cmVariableWatchCommand::~cmVariableWatchCommand()
bool cmVariableWatchCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&)
{
- if (args.size() < 1) {
+ if (args.empty()) {
this->SetError("must be called with at least one argument.");
return false;
}
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 8ff7366..85084eb 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -2415,10 +2415,12 @@ void cmVisualStudio10TargetGenerator::AddLibraries(
{
typedef cmComputeLinkInformation::ItemVector ItemVector;
ItemVector libs = cli.GetItems();
+ std::string currentBinDir =
+ this->LocalGenerator->GetCurrentBinaryDirectory();
for (ItemVector::const_iterator l = libs.begin(); l != libs.end(); ++l) {
if (l->IsPath) {
std::string path = this->LocalGenerator->ConvertToRelativePath(
- l->Value.c_str(), cmOutputConverter::START_OUTPUT);
+ currentBinDir, l->Value.c_str());
this->ConvertToWindowsSlash(path);
libVec.push_back(path);
} else if (!l->Target ||
diff --git a/Source/cmWhileCommand.cxx b/Source/cmWhileCommand.cxx
index 93a6271..98bd3ff 100644
--- a/Source/cmWhileCommand.cxx
+++ b/Source/cmWhileCommand.cxx
@@ -104,10 +104,9 @@ bool cmWhileFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff,
messageType);
}
return true;
- } else {
- // decrement for each nested while that ends
- this->Depth--;
}
+ // decrement for each nested while that ends
+ this->Depth--;
}
// record the command
@@ -133,7 +132,7 @@ bool cmWhileFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
bool cmWhileCommand::InvokeInitialPass(
const std::vector<cmListFileArgument>& args, cmExecutionStatus&)
{
- if (args.size() < 1) {
+ if (args.empty()) {
this->SetError("called with incorrect number of arguments");
return false;
}
diff --git a/Source/cm_auto_ptr.hxx b/Source/cm_auto_ptr.hxx
index 2cd35c3..f6c4362 100644
--- a/Source/cm_auto_ptr.hxx
+++ b/Source/cm_auto_ptr.hxx
@@ -12,7 +12,7 @@
#ifndef CM_AUTO_PTR_HXX
#define CM_AUTO_PTR_HXX
-#include <cmsys/Configure.hxx>
+#include <cmConfigure.h>
// FIXME: Use std::auto_ptr on compilers that do not warn about it.
#define CM_AUTO_PTR cm::auto_ptr
@@ -115,7 +115,7 @@ public:
*
* auto_ptr<X> ptr(new X());
*/
- explicit auto_ptr(X* p = 0) throw()
+ explicit auto_ptr(X* p = CM_NULLPTR) throw()
: x_(p)
{
}
@@ -157,7 +157,7 @@ public:
X* release() throw()
{
X* x = this->x_;
- this->x_ = 0;
+ this->x_ = CM_NULLPTR;
return x;
}
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index d6bea3d..0c84283 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -35,7 +35,7 @@
#if defined(CMAKE_BUILD_WITH_CMAKE)
#include "cmGraphVizWriter.h"
#include "cmVariableWatch.h"
-#include <cm_jsoncpp_value.h>
+
#include <cm_jsoncpp_writer.h>
#endif
@@ -233,10 +233,9 @@ cmake::~cmake()
delete this->FileComparison;
}
-std::string cmake::ReportCapabilities() const
-{
- std::string result;
#if defined(CMAKE_BUILD_WITH_CMAKE)
+Json::Value cmake::ReportCapabilitiesJson(bool haveServerMode) const
+{
Json::Value obj = Json::objectValue;
// Version information:
Json::Value version = Json::objectValue;
@@ -281,14 +280,18 @@ std::string cmake::ReportCapabilities() const
generators.append(i->second);
}
obj["generators"] = generators;
+ obj["serverMode"] = haveServerMode;
-#if defined(HAVE_SERVER_MODE) && HAVE_SERVER_MODE
- obj["serverMode"] = true;
-#else
- obj["serverMode"] = false;
+ return obj;
+}
#endif
+
+std::string cmake::ReportCapabilities(bool haveServerMode) const
+{
+ std::string result;
+#if defined(CMAKE_BUILD_WITH_CMAKE)
Json::FastWriter writer;
- result = writer.write(obj);
+ result = writer.write(this->ReportCapabilitiesJson(haveServerMode));
#else
result = "Not supported";
#endif
@@ -588,8 +591,8 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
gg->CreateGenerationObjects();
cmGeneratorTarget* gtgt = gg->FindGeneratorTarget(tgt->GetName());
cmLocalGenerator* lg = gtgt->GetLocalGenerator();
- lg->GetTargetFlags(buildType, linkLibs, frameworkPath, linkPath, flags,
- linkFlags, gtgt, false);
+ lg->GetTargetFlags(buildType, linkLibs, flags, linkFlags, frameworkPath,
+ linkPath, gtgt, false);
linkLibs = frameworkPath + linkPath + linkLibs;
printf("%s\n", linkLibs.c_str());
@@ -1039,6 +1042,28 @@ const char* cmake::GetHomeOutputDirectory() const
return this->State->GetBinaryDirectory();
}
+std::string cmake::FindCacheFile(const std::string& binaryDir)
+{
+ std::string cachePath = binaryDir;
+ cmSystemTools::ConvertToUnixSlashes(cachePath);
+ std::string cacheFile = cachePath;
+ cacheFile += "/CMakeCache.txt";
+ if (!cmSystemTools::FileExists(cacheFile.c_str())) {
+ // search in parent directories for cache
+ std::string cmakeFiles = cachePath;
+ cmakeFiles += "/CMakeFiles";
+ if (cmSystemTools::FileExists(cmakeFiles.c_str())) {
+ std::string cachePathFound =
+ cmSystemTools::FileExistsInParentDirectories("CMakeCache.txt",
+ cachePath.c_str(), "/");
+ if (!cachePathFound.empty()) {
+ cachePath = cmSystemTools::GetFilenamePath(cachePathFound);
+ }
+ }
+ }
+ return cachePath;
+}
+
void cmake::SetGlobalGenerator(cmGlobalGenerator* gg)
{
if (!gg) {
@@ -2337,24 +2362,8 @@ int cmake::Build(const std::string& dir, const std::string& target,
std::cerr << "Error: " << dir << " is not a directory\n";
return 1;
}
- std::string cachePath = dir;
- cmSystemTools::ConvertToUnixSlashes(cachePath);
- std::string cacheFile = cachePath;
- cacheFile += "/CMakeCache.txt";
- if (!cmSystemTools::FileExists(cacheFile.c_str())) {
- // search in parent directories for cache
- std::string cmakeFiles = cachePath;
- cmakeFiles += "/CMakeFiles";
- if (cmSystemTools::FileExists(cmakeFiles.c_str())) {
- std::string cachePathFound =
- cmSystemTools::FileExistsInParentDirectories("CMakeCache.txt",
- cachePath.c_str(), "/");
- if (!cachePathFound.empty()) {
- cachePath = cmSystemTools::GetFilenamePath(cachePathFound);
- }
- }
- }
+ std::string cachePath = FindCacheFile(dir);
if (!this->LoadCache(cachePath)) {
std::cerr << "Error: could not load cache\n";
return 1;
diff --git a/Source/cmake.h b/Source/cmake.h
index 9dc429d..a21c9ca 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -24,6 +24,10 @@
#include <string>
#include <vector>
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+#include "cm_jsoncpp_value.h"
+#endif
+
class cmExternalMakefileProjectGeneratorFactory;
class cmFileTimeComparison;
class cmGlobalGenerator;
@@ -118,7 +122,10 @@ public:
/// Destructor
~cmake();
- std::string ReportCapabilities() const;
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ Json::Value ReportCapabilitiesJson(bool haveServerMode) const;
+#endif
+ std::string ReportCapabilities(bool haveServerMode) const;
static const char* GetCMakeFilesDirectory() { return "/CMakeFiles"; }
static const char* GetCMakeFilesDirectoryPostSlash()
@@ -186,6 +193,9 @@ public:
return this->GlobalGenerator;
}
+ ///! Return the full path to where the CMakeCache.txt file should be.
+ static std::string FindCacheFile(const std::string& binaryDir);
+
///! Return the global generator assigned to this instance of cmake
void SetGlobalGenerator(cmGlobalGenerator*);
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index c2e1d53..38f00e6 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -23,6 +23,10 @@
#include "cm_auto_ptr.hxx"
#include "cmake.h"
+#if defined(HAVE_SERVER_MODE) && HAVE_SERVER_MODE
+#include "cmServer.h"
+#endif
+
#if defined(CMAKE_BUILD_WITH_CMAKE)
#include "cmDependsFortran.h" // For -E cmake_copy_f90_mod callback.
#endif
@@ -91,9 +95,10 @@ void CMakeCommandUsage(const char* program)
<< " remove_directory dir - remove a directory and its contents\n"
<< " rename oldname newname - rename a file or directory "
"(on one volume)\n"
+ << " server - start cmake in server mode\n"
+ << " sleep <number>... - sleep for given number of seconds\n"
<< " tar [cxt][vf][zjJ] file.tar [file/dir1 file/dir2 ...]\n"
<< " - create or extract a tar or zip archive\n"
- << " sleep <number>... - sleep for given number of seconds\n"
<< " time command [args...] - run command and return elapsed time\n"
<< " touch file - touch a file.\n"
<< " touch_nocreate file - touch a file but do not create it.\n"
@@ -527,7 +532,11 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
return 1;
}
cmake cm;
- std::cout << cm.ReportCapabilities();
+#if defined(HAVE_SERVER_MODE) && HAVE_SERVER_MODE
+ std::cout << cm.ReportCapabilities(true);
+#else
+ std::cout << cm.ReportCapabilities(false);
+#endif
return 0;
}
@@ -903,6 +912,36 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
#endif
}
return 0;
+ } else if (args[1] == "server") {
+ if (args.size() > 3) {
+ cmSystemTools::Error("Too many arguments to start server mode");
+ return 1;
+ }
+ bool supportExperimental = false;
+ if (args.size() == 3) {
+ if (args[2] == "--experimental") {
+ supportExperimental = true;
+ } else {
+ cmSystemTools::Error("Unknown argument for server mode");
+ return 1;
+ }
+ }
+#if defined(HAVE_SERVER_MODE) && HAVE_SERVER_MODE
+ cmServer server(supportExperimental);
+ if (server.Serve()) {
+ return 0;
+ } else {
+ cmSystemTools::Error(
+ "CMake server could not find any supported protocol. "
+ "Try with \"--experimental\" to enable "
+ "experimental support.");
+ return 1;
+ }
+#else
+ static_cast<void>(supportExperimental);
+ cmSystemTools::Error("CMake was not built with server mode enabled");
+ return 1;
+#endif
}
#if defined(CMAKE_BUILD_WITH_CMAKE)
diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt
index 87f6048..c4fe5e8 100644
--- a/Source/kwsys/CMakeLists.txt
+++ b/Source/kwsys/CMakeLists.txt
@@ -123,6 +123,7 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
SET(KWSYS_USE_FStream 1)
SET(KWSYS_USE_String 1)
SET(KWSYS_USE_SystemInformation 1)
+ SET(KWSYS_USE_ConsoleBuf 1)
ENDIF()
# Enforce component dependencies.
@@ -154,6 +155,9 @@ ENDIF()
IF(KWSYS_USE_FStream)
SET(KWSYS_USE_Encoding 1)
ENDIF()
+IF(KWSYS_USE_ConsoleBuf)
+ SET(KWSYS_USE_Encoding 1)
+ENDIF()
# Setup the large file support default.
IF(KWSYS_LFS_DISABLE)
@@ -673,7 +677,7 @@ SET(KWSYS_HXX_FILES Configure String
# Add selected C++ classes.
SET(cppclasses
Directory DynamicLoader Encoding Glob RegularExpression SystemTools
- CommandLineArguments IOStream FStream SystemInformation
+ CommandLineArguments IOStream FStream SystemInformation ConsoleBuf
)
FOREACH(cpp ${cppclasses})
IF(KWSYS_USE_${cpp})
@@ -926,6 +930,20 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
testFStream
)
ENDIF()
+ IF(KWSYS_USE_ConsoleBuf)
+ ADD_EXECUTABLE(testConsoleBufChild testConsoleBufChild.cxx)
+ SET_PROPERTY(TARGET testConsoleBufChild PROPERTY LABELS ${KWSYS_LABELS_EXE})
+ TARGET_LINK_LIBRARIES(testConsoleBufChild ${KWSYS_NAMESPACE})
+ SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
+ testConsoleBuf
+ )
+ IF("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC" AND
+ NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "19.0")
+ set_property(SOURCE testConsoleBuf.cxx testConsoleBufChild.cxx PROPERTY COMPILE_FLAGS /utf-8)
+ ENDIF()
+ SET_PROPERTY(SOURCE testConsoleBuf.cxx APPEND PROPERTY COMPILE_DEFINITIONS
+ KWSYS_ENCODING_DEFAULT_CODEPAGE=${KWSYS_ENCODING_DEFAULT_CODEPAGE})
+ ENDIF()
IF(KWSYS_USE_SystemInformation)
SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testSystemInformation)
ENDIF()
diff --git a/Source/kwsys/ConsoleBuf.hxx.in b/Source/kwsys/ConsoleBuf.hxx.in
new file mode 100644
index 0000000..8aeeda1
--- /dev/null
+++ b/Source/kwsys/ConsoleBuf.hxx.in
@@ -0,0 +1,348 @@
+/*============================================================================
+ KWSys - Kitware System Library
+ Copyright 2000-2016 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef @KWSYS_NAMESPACE@_ConsoleBuf_hxx
+#define @KWSYS_NAMESPACE@_ConsoleBuf_hxx
+
+#include <@KWSYS_NAMESPACE@/Configure.hxx>
+#include <@KWSYS_NAMESPACE@/Encoding.hxx>
+#include <string>
+#include <cstring>
+#include <sstream>
+#include <streambuf>
+#include <iostream>
+#include <stdexcept>
+
+#if defined(_WIN32)
+# include <windows.h>
+# if __cplusplus >= 201103L
+# include <system_error>
+# endif
+#endif
+
+namespace @KWSYS_NAMESPACE@
+{
+#if defined(_WIN32)
+
+ template<class CharT, class Traits = std::char_traits<CharT> >
+ class @KWSYS_NAMESPACE@_EXPORT BasicConsoleBuf :
+ public std::basic_streambuf<CharT, Traits> {
+ public:
+ typedef typename Traits::int_type int_type;
+ typedef typename Traits::char_type char_type;
+
+ class Manager {
+ public:
+ Manager(std::basic_ios<CharT, Traits> &ios, const bool err = false)
+ : m_consolebuf(0)
+ {
+ m_ios = &ios;
+ try {
+ m_consolebuf = new BasicConsoleBuf<CharT, Traits>(err);
+ m_streambuf = m_ios->rdbuf(m_consolebuf);
+ } catch (const std::runtime_error& ex) {
+ std::cerr << "Failed to create ConsoleBuf!" << std::endl
+ << ex.what() << std::endl;
+ };
+ }
+
+ ~Manager()
+ {
+ if (m_consolebuf) {
+ delete m_consolebuf;
+ m_ios->rdbuf(m_streambuf);
+ }
+ }
+
+ private:
+ std::basic_ios<CharT, Traits> *m_ios;
+ std::basic_streambuf<CharT, Traits> *m_streambuf;
+ BasicConsoleBuf<CharT, Traits> *m_consolebuf;
+ };
+
+ BasicConsoleBuf(const bool err = false) :
+ flush_on_newline(true),
+ input_pipe_codepage(0),
+ output_pipe_codepage(0),
+ input_file_codepage(CP_UTF8),
+ output_file_codepage(CP_UTF8),
+ m_consolesCodepage(0)
+ {
+ m_hInput = ::GetStdHandle(STD_INPUT_HANDLE);
+ checkHandle(true, "STD_INPUT_HANDLE");
+ if (!setActiveInputCodepage()) {
+ throw std::runtime_error("setActiveInputCodepage failed!");
+ }
+ m_hOutput = err ? ::GetStdHandle(STD_ERROR_HANDLE) :
+ ::GetStdHandle(STD_OUTPUT_HANDLE);
+ checkHandle(false, err ? "STD_ERROR_HANDLE" : "STD_OUTPUT_HANDLE");
+ if (!setActiveOutputCodepage()) {
+ throw std::runtime_error("setActiveOutputCodepage failed!");
+ }
+ _setg();
+ _setp();
+ }
+
+ ~BasicConsoleBuf() throw()
+ {
+ sync();
+ }
+
+ bool activateCodepageChange()
+ {
+ return setActiveInputCodepage() && setActiveOutputCodepage();
+ }
+
+ protected:
+ virtual int sync() {
+ bool success = true;
+ if (m_hInput && m_isConsoleInput &&
+ ::FlushConsoleInputBuffer(m_hInput) == 0) {
+ success = false;
+ }
+ if (m_hOutput && !m_obuffer.empty()) {
+ const std::wstring wbuffer = getBuffer(m_obuffer);
+ if (m_isConsoleOutput) {
+ DWORD charsWritten;
+ success = ::WriteConsoleW(m_hOutput, wbuffer.c_str(),
+ (DWORD)wbuffer.size(), &charsWritten,
+ NULL) == 0 ? false : true;
+ } else {
+ DWORD bytesWritten;
+ std::string buffer;
+ success = encodeOutputBuffer(wbuffer, buffer);
+ if (success) {
+ success = ::WriteFile(m_hOutput, buffer.c_str(),
+ (DWORD)buffer.size(), &bytesWritten,
+ NULL) == 0 ? false : true;
+ }
+ }
+ }
+ m_ibuffer.clear();
+ m_obuffer.clear();
+ _setg();
+ _setp();
+ return success ? 0 : -1;
+ }
+
+ virtual int_type underflow() {
+ if (this->gptr() >= this->egptr()) {
+ if (!m_hInput) {
+ _setg(true);
+ return Traits::eof();
+ }
+ if (m_isConsoleInput) {
+ wchar_t wbuffer[128];
+ DWORD charsRead;
+ if (::ReadConsoleW(m_hInput, wbuffer, (sizeof(wbuffer) / sizeof(wbuffer[0])) - 1,
+ &charsRead, NULL) == 0 || charsRead == 0) {
+ _setg(true);
+ return Traits::eof();
+ }
+ wbuffer[charsRead] = L'\0';
+ setBuffer(wbuffer, m_ibuffer);
+ } else {
+ std::wstring totalBuffer;
+ std::wstring wbuffer;
+ char buffer[128];
+ DWORD bytesRead;
+ while (::ReadFile(m_hInput, buffer, (sizeof(buffer) / sizeof(buffer[0])) - 1,
+ &bytesRead, NULL) == 0) {
+ if (::GetLastError() == ERROR_MORE_DATA) {
+ buffer[bytesRead] = '\0';
+ if (decodeInputBuffer(buffer, wbuffer)) {
+ totalBuffer += wbuffer;
+ continue;
+ }
+ }
+ _setg(true);
+ return Traits::eof();
+ }
+ buffer[bytesRead] = '\0';
+ if (!decodeInputBuffer(buffer, wbuffer)) {
+ _setg(true);
+ return Traits::eof();
+ }
+ totalBuffer += wbuffer;
+ setBuffer(totalBuffer, m_ibuffer);
+ }
+ _setg();
+ }
+ return Traits::to_int_type(*this->gptr());
+ }
+
+ virtual int_type overflow(int_type ch = Traits::eof()) {
+ if (!Traits::eq_int_type(ch, Traits::eof())) {
+ char_type chr = Traits::to_char_type(ch);
+ m_obuffer += chr;
+ if ((flush_on_newline && Traits::eq(chr, '\n')) ||
+ Traits::eq_int_type(ch, 0x00)) {
+ sync();
+ }
+ return ch;
+ }
+ sync();
+ return Traits::eof();
+ }
+
+ public:
+ bool flush_on_newline;
+ UINT input_pipe_codepage;
+ UINT output_pipe_codepage;
+ UINT input_file_codepage;
+ UINT output_file_codepage;
+
+ private:
+ HANDLE m_hInput;
+ HANDLE m_hOutput;
+ std::basic_string<char_type> m_ibuffer;
+ std::basic_string<char_type> m_obuffer;
+ bool m_isConsoleInput;
+ bool m_isConsoleOutput;
+ UINT m_activeInputCodepage;
+ UINT m_activeOutputCodepage;
+ UINT m_consolesCodepage;
+ void checkHandle(bool input, std::string handleName) {
+ if ((input && m_hInput == INVALID_HANDLE_VALUE) ||
+ (!input && m_hOutput == INVALID_HANDLE_VALUE)) {
+ std::string errmsg = "GetStdHandle(" + handleName +
+ ") returned INVALID_HANDLE_VALUE";
+#if __cplusplus >= 201103L
+ throw std::system_error(::GetLastError(),
+ std::system_category(), errmsg);
+#else
+ throw std::runtime_error(errmsg);
+#endif
+ }
+ }
+ UINT getConsolesCodepage() {
+ if (!m_consolesCodepage) {
+ m_consolesCodepage = GetConsoleCP();
+ if (!m_consolesCodepage) {
+ m_consolesCodepage = GetACP();
+ }
+ }
+ return m_consolesCodepage;
+ }
+ bool setActiveInputCodepage() {
+ m_isConsoleInput = false;
+ switch (GetFileType(m_hInput)) {
+ case FILE_TYPE_DISK:
+ m_activeInputCodepage = input_file_codepage;
+ break;
+ case FILE_TYPE_CHAR:
+ m_isConsoleInput = true;
+ break;
+ case FILE_TYPE_PIPE:
+ m_activeInputCodepage = input_pipe_codepage;
+ break;
+ default:
+ return false;
+ }
+ if (!m_isConsoleInput && m_activeInputCodepage == 0) {
+ m_activeInputCodepage = getConsolesCodepage();
+ }
+ return true;
+ }
+ bool setActiveOutputCodepage() {
+ m_isConsoleOutput = false;
+ switch (GetFileType(m_hOutput)) {
+ case FILE_TYPE_DISK:
+ m_activeOutputCodepage = output_file_codepage;
+ break;
+ case FILE_TYPE_CHAR:
+ m_isConsoleOutput = true;
+ break;
+ case FILE_TYPE_PIPE:
+ m_activeOutputCodepage = output_pipe_codepage;
+ break;
+ default:
+ return false;
+ }
+ if (!m_isConsoleOutput && m_activeOutputCodepage == 0) {
+ m_activeOutputCodepage = getConsolesCodepage();
+ }
+ return true;
+ }
+ void _setg(bool empty = false) {
+ if (!empty) {
+ this->setg((char_type *)m_ibuffer.data(),
+ (char_type *)m_ibuffer.data(),
+ (char_type *)m_ibuffer.data() + m_ibuffer.size());
+ } else {
+ this->setg((char_type *)m_ibuffer.data(),
+ (char_type *)m_ibuffer.data() + m_ibuffer.size(),
+ (char_type *)m_ibuffer.data() + m_ibuffer.size());
+ }
+ }
+ void _setp() {
+ this->setp((char_type *)m_obuffer.data(),
+ (char_type *)m_obuffer.data() + m_obuffer.size());
+ }
+ bool encodeOutputBuffer(const std::wstring wbuffer,
+ std::string &buffer) {
+ const int length = WideCharToMultiByte(m_activeOutputCodepage, 0,
+ wbuffer.c_str(),
+ (int)wbuffer.size(), NULL, 0,
+ NULL, NULL);
+ char *buf = new char[length + 1];
+ const bool success = WideCharToMultiByte(m_activeOutputCodepage, 0,
+ wbuffer.c_str(),
+ (int)wbuffer.size(), buf,
+ length, NULL, NULL) > 0
+ ? true : false;
+ buf[length] = '\0';
+ buffer = buf;
+ delete[] buf;
+ return success;
+ }
+ bool decodeInputBuffer(const char *buffer, std::wstring &wbuffer) {
+ int actualCodepage = m_activeInputCodepage;
+ const char BOM_UTF8[] = { char(0xEF), char(0xBB), char(0xBF) };
+ if (std::memcmp(buffer, BOM_UTF8, sizeof(BOM_UTF8)) == 0) {
+ // PowerShell uses UTF-8 with BOM for pipes
+ actualCodepage = CP_UTF8;
+ buffer += sizeof(BOM_UTF8);
+ }
+ const int wlength = MultiByteToWideChar(actualCodepage, 0, buffer,
+ -1, NULL, 0);
+ wchar_t *wbuf = new wchar_t[wlength];
+ const bool success = MultiByteToWideChar(actualCodepage, 0, buffer,
+ -1, wbuf, wlength) > 0
+ ? true : false;
+ wbuffer = wbuf;
+ delete[] wbuf;
+ return success;
+ }
+ std::wstring getBuffer(const std::basic_string<char> buffer) {
+ return Encoding::ToWide(buffer);
+ }
+ std::wstring getBuffer(const std::basic_string<wchar_t> buffer) {
+ return buffer;
+ }
+ void setBuffer(const std::wstring wbuffer,
+ std::basic_string<char> &target) {
+ target = Encoding::ToNarrow(wbuffer);
+ }
+ void setBuffer(const std::wstring wbuffer,
+ std::basic_string<wchar_t> &target) {
+ target = wbuffer;
+ }
+
+ }; // BasicConsoleBuf class
+
+ typedef BasicConsoleBuf<char> ConsoleBuf;
+ typedef BasicConsoleBuf<wchar_t> WConsoleBuf;
+
+#endif
+} // KWSYS_NAMESPACE
+
+#endif
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index 1a73b16..4281c38 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -3982,16 +3982,16 @@ std::string SystemTools::RelativePath(const std::string& local, const std::strin
}
#ifdef _WIN32
-static int GetCasePathName(const std::string & pathIn,
- std::string & casePath)
+static std::string GetCasePathName(std::string const& pathIn)
{
+ std::string casePath;
std::vector<std::string> path_components;
SystemTools::SplitPath(pathIn, path_components);
if(path_components[0].empty()) // First component always exists.
{
// Relative paths cannot be converted.
- casePath = "";
- return 0;
+ casePath = pathIn;
+ return casePath;
}
// Start with root component.
@@ -4015,38 +4015,45 @@ static int GetCasePathName(const std::string & pathIn,
sep = "/";
}
+ // Convert case of all components that exist.
+ bool converting = true;
for(; idx < path_components.size(); idx++)
{
casePath += sep;
sep = "/";
- std::string test_str = casePath;
- test_str += path_components[idx];
-
- // If path component contains wildcards, we skip matching
- // because these filenames are not allowed on windows,
- // and we do not want to match a different file.
- if(path_components[idx].find('*') != std::string::npos ||
- path_components[idx].find('?') != std::string::npos)
- {
- casePath = "";
- return 0;
- }
- WIN32_FIND_DATAW findData;
- HANDLE hFind = ::FindFirstFileW(Encoding::ToWide(test_str).c_str(),
- &findData);
- if (INVALID_HANDLE_VALUE != hFind)
- {
- casePath += Encoding::ToNarrow(findData.cFileName);
- ::FindClose(hFind);
- }
- else
+ if (converting)
{
- casePath = "";
- return 0;
+ // If path component contains wildcards, we skip matching
+ // because these filenames are not allowed on windows,
+ // and we do not want to match a different file.
+ if(path_components[idx].find('*') != std::string::npos ||
+ path_components[idx].find('?') != std::string::npos)
+ {
+ converting = false;
+ }
+ else
+ {
+ std::string test_str = casePath;
+ test_str += path_components[idx];
+ WIN32_FIND_DATAW findData;
+ HANDLE hFind = ::FindFirstFileW(Encoding::ToWide(test_str).c_str(),
+ &findData);
+ if (INVALID_HANDLE_VALUE != hFind)
+ {
+ path_components[idx] = Encoding::ToNarrow(findData.cFileName);
+ ::FindClose(hFind);
+ }
+ else
+ {
+ converting = false;
+ }
+ }
}
+
+ casePath += path_components[idx];
}
- return (int)casePath.size();
+ return casePath;
}
#endif
@@ -4065,11 +4072,10 @@ std::string SystemTools::GetActualCaseForPath(const std::string& p)
{
return i->second;
}
- std::string casePath;
- int len = GetCasePathName(p, casePath);
- if(len == 0 || len > MAX_PATH+1)
+ std::string casePath = GetCasePathName(p);
+ if (casePath.size() > MAX_PATH)
{
- return p;
+ return casePath;
}
(*SystemTools::PathCaseMap)[p] = casePath;
return casePath;
diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in
index 28ff0b3..5849145 100644
--- a/Source/kwsys/SystemTools.hxx.in
+++ b/Source/kwsys/SystemTools.hxx.in
@@ -374,10 +374,11 @@ public:
static const char* GetExecutableExtension();
/**
- * Given a path that exists on a windows machine, return the
- * actuall case of the path as it was created. If the file
- * does not exist path is returned unchanged. This does nothing
- * on unix but return path.
+ * Given a path on a Windows machine, return the actual case of
+ * the path as it exists on disk. Path components that do not
+ * exist on disk are returned unchanged. Relative paths are always
+ * returned unchanged. Drive letters are always made upper case.
+ * This does nothing on non-Windows systems but return the path.
*/
static std::string GetActualCaseForPath(const std::string& path);
diff --git a/Source/kwsys/testConsoleBuf.cxx b/Source/kwsys/testConsoleBuf.cxx
new file mode 100644
index 0000000..3dc3337
--- /dev/null
+++ b/Source/kwsys/testConsoleBuf.cxx
@@ -0,0 +1,714 @@
+/*============================================================================
+ KWSys - Kitware System Library
+ Copyright 2000-2016 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "kwsysPrivate.h"
+
+// Ignore Windows version levels defined by command-line flags. This
+// source needs access to all APIs available on the host in order for
+// the test to run properly. The test binary is not installed anyway.
+#undef _WIN32_WINNT
+#undef NTDDI_VERSION
+
+#include KWSYS_HEADER(Encoding.hxx)
+
+// Work-around CMake dependency scanning limitation. This must
+// duplicate the above list of headers.
+#if 0
+# include "Encoding.hxx.in"
+#endif
+
+#if defined(_WIN32)
+
+#include <windows.h>
+#include <string.h>
+#include <wchar.h>
+#include <iostream>
+#include <iomanip>
+#include <stdexcept>
+#include "testConsoleBuf.hxx"
+
+#if defined(_MSC_VER) && _MSC_VER >= 1800
+# define KWSYS_WINDOWS_DEPRECATED_GetVersion
+#endif
+// يونيكود
+static const WCHAR UnicodeInputTestString[] = L"\u064A\u0648\u0646\u064A\u0643\u0648\u062F!";
+static UINT TestCodepage = KWSYS_ENCODING_DEFAULT_CODEPAGE;
+
+static const DWORD waitTimeout = 10 * 1000;
+static STARTUPINFO startupInfo;
+static PROCESS_INFORMATION processInfo;
+static HANDLE beforeInputEvent;
+static HANDLE afterOutputEvent;
+static std::string encodedInputTestString;
+static std::string encodedTestString;
+
+static void displayError(DWORD errorCode) {
+ std::cerr.setf(std::ios::hex, std::ios::basefield);
+ std::cerr << "Failed with error: 0x" << errorCode << "!" << std::endl;
+ LPWSTR message;
+ if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ errorCode,
+ 0,
+ (LPWSTR)&message, 0,
+ NULL)
+ ) {
+ std::cerr << "Error message: " << kwsys::Encoding::ToNarrow(message) << std::endl;
+ HeapFree(GetProcessHeap(), 0, message);
+ } else {
+ std::cerr << "FormatMessage() failed with error: 0x" << GetLastError() << "!" << std::endl;
+ }
+ std::cerr.unsetf(std::ios::hex);
+}
+
+std::basic_streambuf<char> *errstream(const char *unused) {
+ static_cast<void>(unused);
+ return std::cerr.rdbuf();
+}
+
+std::basic_streambuf<wchar_t> *errstream(const wchar_t *unused) {
+ static_cast<void>(unused);
+ return std::wcerr.rdbuf();
+}
+
+//----------------------------------------------------------------------------
+template<typename T>
+static void dumpBuffers(const T *expected, const T *received, size_t size) {
+ std::basic_ostream<T> err(errstream(expected));
+ err << "Expected output: '" << std::basic_string<T>(expected, size) << "'" << std::endl;
+ if (err.fail()) {
+ err.clear();
+ err << "--- Error while outputting ---" << std::endl;
+ }
+ err << "Received output: '" << std::basic_string<T>(received, size) << "'" << std::endl;
+ if (err.fail()) {
+ err.clear();
+ err << "--- Error while outputting ---" << std::endl;
+ }
+ std::cerr << "Expected output | Received output" << std::endl;
+ for (size_t i = 0; i < size; i++) {
+ std::cerr << std::setbase(16) << std::setfill('0') << " " <<
+ "0x" << std::setw(8) << static_cast<unsigned int>(expected[i]) << " | " <<
+ "0x" << std::setw(8) << static_cast<unsigned int>(received[i]);
+ if (static_cast<unsigned int>(expected[i]) != static_cast<unsigned int>(received[i])) {
+ std::cerr << " MISMATCH!";
+ }
+ std::cerr << std::endl;
+ }
+ std::cerr << std::endl << std::flush;
+}
+
+//----------------------------------------------------------------------------
+static bool createProcess(HANDLE hIn, HANDLE hOut, HANDLE hErr)
+{
+ BOOL bInheritHandles = FALSE;
+ DWORD dwCreationFlags = 0;
+ memset(&processInfo, 0, sizeof(processInfo));
+ memset(&startupInfo, 0, sizeof(startupInfo));
+ startupInfo.cb = sizeof(startupInfo);
+ startupInfo.dwFlags = STARTF_USESHOWWINDOW;
+ startupInfo.wShowWindow = SW_HIDE;
+ if (hIn || hOut || hErr) {
+ startupInfo.dwFlags |= STARTF_USESTDHANDLES;
+ startupInfo.hStdInput = hIn;
+ startupInfo.hStdOutput = hOut;
+ startupInfo.hStdError = hErr;
+ bInheritHandles = TRUE;
+ }
+
+ WCHAR cmd[MAX_PATH];
+ if (GetModuleFileNameW(NULL, cmd, MAX_PATH) == 0) {
+ std::cerr << "GetModuleFileName failed!" << std::endl;
+ return false;
+ }
+ WCHAR *p = cmd + wcslen(cmd);
+ while (p > cmd && *p != L'\\') p--;
+ *(p+1) = 0;
+ wcscat(cmd, cmdConsoleBufChild);
+ wcscat(cmd, L".exe");
+
+ bool success = CreateProcessW(NULL, // No module name (use command line)
+ cmd, // Command line
+ NULL, // Process handle not inheritable
+ NULL, // Thread handle not inheritable
+ bInheritHandles, // Set handle inheritance
+ dwCreationFlags,
+ NULL, // Use parent's environment block
+ NULL, // Use parent's starting directory
+ &startupInfo, // Pointer to STARTUPINFO structure
+ &processInfo) != 0; // Pointer to PROCESS_INFORMATION structure
+ if (!success) {
+ DWORD lastError = GetLastError();
+ std::cerr << "CreateProcess(" << kwsys::Encoding::ToNarrow(cmd) << ")" << std::endl;
+ displayError(lastError);
+ }
+ return success;
+}
+
+//----------------------------------------------------------------------------
+static void finishProcess(bool success)
+{
+ if (success) {
+ success = WaitForSingleObject(processInfo.hProcess, waitTimeout)
+ == WAIT_OBJECT_0;
+ };
+ if (!success) {
+ TerminateProcess(processInfo.hProcess, 1);
+ }
+ CloseHandle(processInfo.hProcess);
+ CloseHandle(processInfo.hThread);
+}
+
+//----------------------------------------------------------------------------
+static bool createPipe(PHANDLE readPipe, PHANDLE writePipe)
+{
+ SECURITY_ATTRIBUTES securityAttributes;
+ securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
+ securityAttributes.bInheritHandle = TRUE;
+ securityAttributes.lpSecurityDescriptor = NULL;
+ return CreatePipe(readPipe, writePipe, &securityAttributes, 0) == 0
+ ? false : true;
+}
+
+//----------------------------------------------------------------------------
+static void finishPipe(HANDLE readPipe, HANDLE writePipe)
+{
+ if (readPipe != INVALID_HANDLE_VALUE) {
+ CloseHandle(readPipe);
+ }
+ if (writePipe != INVALID_HANDLE_VALUE) {
+ CloseHandle(writePipe);
+ }
+}
+
+//----------------------------------------------------------------------------
+static HANDLE createFile(LPCWSTR fileName)
+{
+ SECURITY_ATTRIBUTES securityAttributes;
+ securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
+ securityAttributes.bInheritHandle = TRUE;
+ securityAttributes.lpSecurityDescriptor = NULL;
+
+ HANDLE file = CreateFileW(fileName,
+ GENERIC_READ | GENERIC_WRITE,
+ 0, // do not share
+ &securityAttributes,
+ CREATE_ALWAYS, // overwrite existing
+ FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
+ NULL); // no template
+ if (file == INVALID_HANDLE_VALUE) {
+ DWORD lastError = GetLastError();
+ std::cerr << "CreateFile(" << kwsys::Encoding::ToNarrow(fileName) << ")" << std::endl;
+ displayError(lastError);
+ }
+ return file;
+}
+
+//----------------------------------------------------------------------------
+static void finishFile(HANDLE file)
+{
+ if (file != INVALID_HANDLE_VALUE) {
+ CloseHandle(file);
+ }
+}
+
+//----------------------------------------------------------------------------
+
+#ifndef MAPVK_VK_TO_VSC
+# define MAPVK_VK_TO_VSC (0)
+#endif
+
+static void writeInputKeyEvent(INPUT_RECORD inputBuffer[], WCHAR chr)
+{
+ inputBuffer[0].EventType = KEY_EVENT;
+ inputBuffer[0].Event.KeyEvent.bKeyDown = TRUE;
+ inputBuffer[0].Event.KeyEvent.wRepeatCount = 1;
+ SHORT keyCode = VkKeyScanW(chr);
+ if (keyCode == -1) {
+ // Character can't be entered with current keyboard layout
+ // Just set any, it doesn't really matter
+ keyCode = 'K';
+ }
+ inputBuffer[0].Event.KeyEvent.wVirtualKeyCode = LOBYTE(keyCode);
+ inputBuffer[0].Event.KeyEvent.wVirtualScanCode =
+ MapVirtualKey(inputBuffer[0].Event.KeyEvent.wVirtualKeyCode,
+ MAPVK_VK_TO_VSC);
+ inputBuffer[0].Event.KeyEvent.uChar.UnicodeChar = chr;
+ inputBuffer[0].Event.KeyEvent.dwControlKeyState = 0;
+ if ((HIBYTE(keyCode) & 1) == 1) {
+ inputBuffer[0].Event.KeyEvent.dwControlKeyState |= SHIFT_PRESSED;
+ }
+ if ((HIBYTE(keyCode) & 2) == 2) {
+ inputBuffer[0].Event.KeyEvent.dwControlKeyState |= RIGHT_CTRL_PRESSED;
+ }
+ if ((HIBYTE(keyCode) & 4) == 4) {
+ inputBuffer[0].Event.KeyEvent.dwControlKeyState |= RIGHT_ALT_PRESSED;
+ }
+ inputBuffer[1].EventType = inputBuffer[0].EventType;
+ inputBuffer[1].Event.KeyEvent.bKeyDown = FALSE;
+ inputBuffer[1].Event.KeyEvent.wRepeatCount = 1;
+ inputBuffer[1].Event.KeyEvent.wVirtualKeyCode = inputBuffer[0].Event.
+ KeyEvent.wVirtualKeyCode;
+ inputBuffer[1].Event.KeyEvent.wVirtualScanCode = inputBuffer[0].Event.
+ KeyEvent.wVirtualScanCode;
+ inputBuffer[1].Event.KeyEvent.uChar.UnicodeChar = inputBuffer[0].Event.
+ KeyEvent.uChar.UnicodeChar;
+ inputBuffer[1].Event.KeyEvent.dwControlKeyState = 0;
+}
+
+//----------------------------------------------------------------------------
+static int testPipe()
+{
+ int didFail = 1;
+ HANDLE inPipeRead = INVALID_HANDLE_VALUE;
+ HANDLE inPipeWrite = INVALID_HANDLE_VALUE;
+ HANDLE outPipeRead = INVALID_HANDLE_VALUE;
+ HANDLE outPipeWrite = INVALID_HANDLE_VALUE;
+ HANDLE errPipeRead = INVALID_HANDLE_VALUE;
+ HANDLE errPipeWrite = INVALID_HANDLE_VALUE;
+ UINT currentCodepage = GetConsoleCP();
+ char buffer[200];
+ char buffer2[200];
+ try {
+ if (!createPipe(&inPipeRead, &inPipeWrite) ||
+ !createPipe(&outPipeRead, &outPipeWrite) ||
+ !createPipe(&errPipeRead, &errPipeWrite)) {
+ throw std::runtime_error("createFile failed!");
+ }
+ if (TestCodepage == CP_ACP) {
+ TestCodepage = GetACP();
+ }
+ if (!SetConsoleCP(TestCodepage)) {
+ throw std::runtime_error("SetConsoleCP failed!");
+ }
+
+ DWORD bytesWritten = 0;
+ if (!WriteFile(inPipeWrite, encodedInputTestString.c_str(),
+ (DWORD)encodedInputTestString.size(), &bytesWritten, NULL)
+ || bytesWritten == 0) {
+ throw std::runtime_error("WriteFile failed!");
+ }
+
+ if (createProcess(inPipeRead, outPipeWrite, errPipeWrite)) {
+ try {
+ DWORD status;
+ if ((status = WaitForSingleObject(afterOutputEvent, waitTimeout)) != WAIT_OBJECT_0) {
+ std::cerr.setf(std::ios::hex, std::ios::basefield);
+ std::cerr << "WaitForSingleObject returned unexpected status 0x" << status << std::endl;
+ std::cerr.unsetf(std::ios::hex);
+ throw std::runtime_error("WaitForSingleObject failed!");
+ }
+ DWORD bytesRead = 0;
+ if (!ReadFile(outPipeRead, buffer, sizeof(buffer), &bytesRead, NULL)
+ || bytesRead == 0) {
+ throw std::runtime_error("ReadFile#1 failed!");
+ }
+ if ((bytesRead < encodedTestString.size() + 1 + encodedInputTestString.size()
+ && !ReadFile(outPipeRead, buffer + bytesRead,
+ sizeof(buffer) - bytesRead, &bytesRead, NULL))
+ || bytesRead == 0) {
+ throw std::runtime_error("ReadFile#2 failed!");
+ }
+ if (memcmp(buffer, encodedTestString.c_str(),
+ encodedTestString.size()) == 0 &&
+ memcmp(buffer + encodedTestString.size() + 1,
+ encodedInputTestString.c_str(),
+ encodedInputTestString.size()) == 0) {
+ bytesRead = 0;
+ if (!ReadFile(errPipeRead, buffer2, sizeof(buffer2), &bytesRead, NULL)
+ || bytesRead == 0) {
+ throw std::runtime_error("ReadFile#3 failed!");
+ }
+ buffer2[bytesRead - 1] = 0;
+ didFail = encodedTestString.compare(buffer2) == 0 ? 0 : 1;
+ }
+ if (didFail != 0) {
+ std::cerr << "Pipe's output didn't match expected output!" << std::endl << std::flush;
+ dumpBuffers<char>(encodedTestString.c_str(), buffer, encodedTestString.size());
+ dumpBuffers<char>(encodedInputTestString.c_str(), buffer + encodedTestString.size() + 1, encodedInputTestString.size());
+ dumpBuffers<char>(encodedTestString.c_str(), buffer2, encodedTestString.size());
+ }
+ } catch (const std::runtime_error &ex) {
+ DWORD lastError = GetLastError();
+ std::cerr << "In function " << __FUNCTION__ << ":" << ex.what() << std::endl << std::flush;
+ displayError(lastError);
+ }
+ finishProcess(didFail == 0);
+ }
+ } catch (const std::runtime_error &ex) {
+ DWORD lastError = GetLastError();
+ std::cerr << "In function " << __FUNCTION__ << ":" << ex.what() << std::endl << std::flush;
+ displayError(lastError);
+ }
+ finishPipe(inPipeRead, inPipeWrite);
+ finishPipe(outPipeRead, outPipeWrite);
+ finishPipe(errPipeRead, errPipeWrite);
+ SetConsoleCP(currentCodepage);
+ return didFail;
+}
+
+//----------------------------------------------------------------------------
+static int testFile()
+{
+ int didFail = 1;
+ HANDLE inFile = INVALID_HANDLE_VALUE;
+ HANDLE outFile = INVALID_HANDLE_VALUE;
+ HANDLE errFile = INVALID_HANDLE_VALUE;
+ try {
+ if ((inFile = createFile(L"stdinFile.txt")) == INVALID_HANDLE_VALUE ||
+ (outFile = createFile(L"stdoutFile.txt")) == INVALID_HANDLE_VALUE ||
+ (errFile = createFile(L"stderrFile.txt")) == INVALID_HANDLE_VALUE) {
+ throw std::runtime_error("createFile failed!");
+ }
+ int length = 0;
+ DWORD bytesWritten = 0;
+ char buffer[200];
+ char buffer2[200];
+
+ if ((length = WideCharToMultiByte(TestCodepage, 0, UnicodeInputTestString, -1,
+ buffer, sizeof(buffer),
+ NULL, NULL)) == 0) {
+ throw std::runtime_error("WideCharToMultiByte failed!");
+ }
+ buffer[length - 1] = '\n';
+ if (!WriteFile(inFile, buffer, length, &bytesWritten, NULL)
+ || bytesWritten == 0) {
+ throw std::runtime_error("WriteFile failed!");
+ }
+ if (SetFilePointer(inFile, 0, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
+ throw std::runtime_error("SetFilePointer failed!");
+ }
+
+ if (createProcess(inFile, outFile, errFile)) {
+ DWORD bytesRead = 0;
+ try {
+ DWORD status;
+ if ((status = WaitForSingleObject(afterOutputEvent, waitTimeout)) != WAIT_OBJECT_0) {
+ std::cerr.setf(std::ios::hex, std::ios::basefield);
+ std::cerr << "WaitForSingleObject returned unexpected status 0x" << status << std::endl;
+ std::cerr.unsetf(std::ios::hex);
+ throw std::runtime_error("WaitForSingleObject failed!");
+ }
+ if (SetFilePointer(outFile, 0, 0, FILE_BEGIN)
+ == INVALID_SET_FILE_POINTER) {
+ throw std::runtime_error("SetFilePointer#1 failed!");
+ }
+ if (!ReadFile(outFile, buffer, sizeof(buffer), &bytesRead, NULL)
+ || bytesRead == 0) {
+ throw std::runtime_error("ReadFile#1 failed!");
+ }
+ buffer[bytesRead - 1] = 0;
+ if (memcmp(buffer, encodedTestString.c_str(),
+ encodedTestString.size()) == 0 &&
+ memcmp(buffer + encodedTestString.size() + 1,
+ encodedInputTestString.c_str(),
+ encodedInputTestString.size() - 1) == 0) {
+ bytesRead = 0;
+ if (SetFilePointer(errFile, 0, 0, FILE_BEGIN)
+ == INVALID_SET_FILE_POINTER) {
+ throw std::runtime_error("SetFilePointer#2 failed!");
+ }
+ if (!ReadFile(errFile, buffer2, sizeof(buffer2), &bytesRead, NULL)
+ || bytesRead == 0) {
+ throw std::runtime_error("ReadFile#2 failed!");
+ }
+ buffer2[bytesRead - 1] = 0;
+ didFail = encodedTestString.compare(buffer2) == 0 ? 0 : 1;
+ }
+ if (didFail != 0) {
+ std::cerr << "File's output didn't match expected output!" << std::endl << std::flush;
+ dumpBuffers<char>(encodedTestString.c_str(), buffer, encodedTestString.size());
+ dumpBuffers<char>(encodedInputTestString.c_str(), buffer + encodedTestString.size() + 1, encodedInputTestString.size() - 1);
+ dumpBuffers<char>(encodedTestString.c_str(), buffer2, encodedTestString.size());
+ }
+ } catch (const std::runtime_error &ex) {
+ DWORD lastError = GetLastError();
+ std::cerr << "In function " << __FUNCTION__ << ":" << ex.what() << std::endl << std::flush;
+ displayError(lastError);
+ }
+ finishProcess(didFail == 0);
+ }
+ } catch (const std::runtime_error &ex) {
+ DWORD lastError = GetLastError();
+ std::cerr << "In function " << __FUNCTION__ << ":" << ex.what() << std::endl << std::flush;
+ displayError(lastError);
+ }
+ finishFile(inFile);
+ finishFile(outFile);
+ finishFile(errFile);
+ return didFail;
+}
+
+#ifndef _WIN32_WINNT_VISTA
+# define _WIN32_WINNT_VISTA 0x0600
+#endif
+
+//----------------------------------------------------------------------------
+static int testConsole()
+{
+ int didFail = 1;
+ HANDLE parentIn = GetStdHandle(STD_INPUT_HANDLE);
+ HANDLE parentOut = GetStdHandle(STD_OUTPUT_HANDLE);
+ HANDLE parentErr = GetStdHandle(STD_ERROR_HANDLE);
+ HANDLE hIn = parentIn;
+ HANDLE hOut = parentOut;
+ DWORD consoleMode;
+ bool newConsole = false;
+ bool forceNewConsole = false;
+ bool restoreConsole = false;
+ LPCWSTR TestFaceName = L"Lucida Console";
+ const DWORD TestFontFamily = 0x00000036;
+ const DWORD TestFontSize = 0x000c0000;
+ HKEY hConsoleKey;
+ WCHAR FaceName[200];
+ FaceName[0] = 0;
+ DWORD FaceNameSize = sizeof(FaceName);
+ DWORD FontFamily = TestFontFamily;
+ DWORD FontSize = TestFontSize;
+#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersion
+# pragma warning (push)
+# ifdef __INTEL_COMPILER
+# pragma warning (disable:1478)
+# else
+# pragma warning (disable:4996)
+# endif
+#endif
+ const bool isVistaOrGreater = LOBYTE(LOWORD(GetVersion())) >= HIBYTE(_WIN32_WINNT_VISTA);
+#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersion
+# pragma warning (pop)
+#endif
+ if (!isVistaOrGreater) {
+ if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Console", 0, KEY_READ | KEY_WRITE,
+ &hConsoleKey) == ERROR_SUCCESS) {
+ DWORD dwordSize = sizeof(DWORD);
+ if (RegQueryValueExW(hConsoleKey, L"FontFamily", NULL, NULL,
+ (LPBYTE)&FontFamily, &dwordSize) == ERROR_SUCCESS) {
+ if (FontFamily != TestFontFamily) {
+ RegQueryValueExW(hConsoleKey, L"FaceName", NULL, NULL,
+ (LPBYTE)FaceName, &FaceNameSize);
+ RegQueryValueExW(hConsoleKey, L"FontSize", NULL, NULL,
+ (LPBYTE)&FontSize, &dwordSize);
+
+ RegSetValueExW(hConsoleKey, L"FontFamily", 0, REG_DWORD,
+ (BYTE *)&TestFontFamily, sizeof(TestFontFamily));
+ RegSetValueExW(hConsoleKey, L"FaceName", 0, REG_SZ,
+ (BYTE *)TestFaceName, (DWORD)((wcslen(TestFaceName) + 1) * sizeof(WCHAR)));
+ RegSetValueExW(hConsoleKey, L"FontSize", 0, REG_DWORD,
+ (BYTE *)&TestFontSize, sizeof(TestFontSize));
+
+ restoreConsole = true;
+ forceNewConsole = true;
+ }
+ } else {
+ std::cerr << "RegGetValueW(FontFamily) failed!" << std::endl << std::flush;
+ }
+ RegCloseKey(hConsoleKey);
+ } else {
+ std::cerr << "RegOpenKeyExW(HKEY_CURRENT_USER\\Console) failed!" << std::endl << std::flush;
+ }
+ }
+ if (forceNewConsole || GetConsoleMode(parentOut, &consoleMode) == 0) {
+ // Not a real console, let's create new one.
+ FreeConsole();
+ if (!AllocConsole()) {
+ std::cerr << "AllocConsole failed!" << std::endl << std::flush;
+ return didFail;
+ }
+ SECURITY_ATTRIBUTES securityAttributes;
+ securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
+ securityAttributes.bInheritHandle = TRUE;
+ securityAttributes.lpSecurityDescriptor = NULL;
+ hIn = CreateFileW(L"CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
+ &securityAttributes, OPEN_EXISTING, 0, NULL);
+ if (hIn == INVALID_HANDLE_VALUE) {
+ DWORD lastError = GetLastError();
+ std::cerr << "CreateFile(CONIN$)" << std::endl;
+ displayError(lastError);
+ }
+ hOut = CreateFileW(L"CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
+ &securityAttributes, OPEN_EXISTING, 0, NULL);
+ if (hOut == INVALID_HANDLE_VALUE) {
+ DWORD lastError = GetLastError();
+ std::cerr << "CreateFile(CONOUT$)" << std::endl;
+ displayError(lastError);
+ }
+ SetStdHandle(STD_INPUT_HANDLE, hIn);
+ SetStdHandle(STD_OUTPUT_HANDLE, hOut);
+ SetStdHandle(STD_ERROR_HANDLE, hOut);
+ newConsole = true;
+ }
+
+#if _WIN32_WINNT >= _WIN32_WINNT_VISTA
+ if (isVistaOrGreater) {
+ CONSOLE_FONT_INFOEX consoleFont;
+ memset(&consoleFont, 0, sizeof(consoleFont));
+ consoleFont.cbSize = sizeof(consoleFont);
+ HMODULE kernel32 = LoadLibraryW(L"kernel32.dll");
+ typedef BOOL (WINAPI *GetCurrentConsoleFontExFunc)(HANDLE hConsoleOutput, BOOL bMaximumWindow, PCONSOLE_FONT_INFOEX lpConsoleCurrentFontEx);
+ typedef BOOL (WINAPI *SetCurrentConsoleFontExFunc)(HANDLE hConsoleOutput, BOOL bMaximumWindow, PCONSOLE_FONT_INFOEX lpConsoleCurrentFontEx);
+ GetCurrentConsoleFontExFunc getConsoleFont = (GetCurrentConsoleFontExFunc)GetProcAddress(kernel32, "GetCurrentConsoleFontEx");
+ SetCurrentConsoleFontExFunc setConsoleFont = (SetCurrentConsoleFontExFunc)GetProcAddress(kernel32, "SetCurrentConsoleFontEx");
+ if (getConsoleFont(hOut, FALSE, &consoleFont)) {
+ if (consoleFont.FontFamily != TestFontFamily) {
+ consoleFont.FontFamily = TestFontFamily;
+ wcscpy(consoleFont.FaceName, TestFaceName);
+ if (!setConsoleFont(hOut, FALSE, &consoleFont)) {
+ std::cerr << "SetCurrentConsoleFontEx failed!" << std::endl << std::flush;
+ }
+ }
+ } else {
+ std::cerr << "GetCurrentConsoleFontEx failed!" << std::endl << std::flush;
+ }
+ } else {
+#endif
+ if (restoreConsole && RegOpenKeyExW(HKEY_CURRENT_USER, L"Console", 0,
+ KEY_WRITE, &hConsoleKey) == ERROR_SUCCESS) {
+ RegSetValueExW(hConsoleKey, L"FontFamily", 0, REG_DWORD,
+ (BYTE *)&FontFamily, sizeof(FontFamily));
+ if (FaceName[0] != 0) {
+ RegSetValueExW(hConsoleKey, L"FaceName", 0, REG_SZ,
+ (BYTE *)FaceName, FaceNameSize);
+ } else {
+ RegDeleteValueW(hConsoleKey, L"FaceName");
+ }
+ RegSetValueExW(hConsoleKey, L"FontSize", 0, REG_DWORD,
+ (BYTE *)&FontSize, sizeof(FontSize));
+ RegCloseKey(hConsoleKey);
+ }
+#if _WIN32_WINNT >= _WIN32_WINNT_VISTA
+ }
+#endif
+
+ if (createProcess(NULL, NULL, NULL)) {
+ try {
+ DWORD status;
+ if ((status = WaitForSingleObject(beforeInputEvent, waitTimeout)) != WAIT_OBJECT_0) {
+ std::cerr.setf(std::ios::hex, std::ios::basefield);
+ std::cerr << "WaitForSingleObject returned unexpected status 0x" << status << std::endl;
+ std::cerr.unsetf(std::ios::hex);
+ throw std::runtime_error("WaitForSingleObject#1 failed!");
+ }
+ INPUT_RECORD inputBuffer[(sizeof(UnicodeInputTestString) /
+ sizeof(UnicodeInputTestString[0])) * 2];
+ memset(&inputBuffer, 0, sizeof(inputBuffer));
+ unsigned int i = 0;
+ for (i = 0; i < (sizeof(UnicodeInputTestString) /
+ sizeof(UnicodeInputTestString[0]) - 1); i++) {
+ writeInputKeyEvent(&inputBuffer[i*2], UnicodeInputTestString[i]);
+ }
+ writeInputKeyEvent(&inputBuffer[i*2], VK_RETURN);
+ DWORD eventsWritten = 0;
+ // We need to wait a bit before writing to console so child process have started waiting for input on stdin.
+ Sleep(300);
+ if (!WriteConsoleInputW(hIn, inputBuffer, sizeof(inputBuffer) /
+ sizeof(inputBuffer[0]),
+ &eventsWritten) || eventsWritten == 0) {
+ throw std::runtime_error("WriteConsoleInput failed!");
+ }
+ if ((status = WaitForSingleObject(afterOutputEvent, waitTimeout)) != WAIT_OBJECT_0) {
+ std::cerr.setf(std::ios::hex, std::ios::basefield);
+ std::cerr << "WaitForSingleObject returned unexpected status 0x" << status << std::endl;
+ std::cerr.unsetf(std::ios::hex);
+ throw std::runtime_error("WaitForSingleObject#2 failed!");
+ }
+ CONSOLE_SCREEN_BUFFER_INFO screenBufferInfo;
+ if (!GetConsoleScreenBufferInfo(hOut, &screenBufferInfo)) {
+ throw std::runtime_error("GetConsoleScreenBufferInfo failed!");
+ }
+
+ COORD coord;
+ DWORD charsRead = 0;
+ coord.X = 0;
+ coord.Y = screenBufferInfo.dwCursorPosition.Y - 4;
+ WCHAR *outputBuffer = new WCHAR[screenBufferInfo.dwSize.X * 4];
+ if (!ReadConsoleOutputCharacterW(hOut, outputBuffer,
+ screenBufferInfo.dwSize.X * 4, coord, &charsRead)
+ || charsRead == 0) {
+ delete[] outputBuffer;
+ throw std::runtime_error("ReadConsoleOutputCharacter failed!");
+ }
+ std::wstring wideTestString = kwsys::Encoding::ToWide(encodedTestString);
+ std::wstring wideInputTestString = kwsys::Encoding::ToWide(encodedInputTestString);
+ if (memcmp(outputBuffer, wideTestString.c_str(),
+ wideTestString.size() * sizeof(wchar_t)) == 0 &&
+ memcmp(outputBuffer + screenBufferInfo.dwSize.X * 1,
+ wideTestString.c_str(), wideTestString.size() * sizeof(wchar_t)) == 0 &&
+ memcmp(outputBuffer + screenBufferInfo.dwSize.X * 2,
+ UnicodeInputTestString, sizeof(UnicodeInputTestString) -
+ sizeof(WCHAR)) == 0 &&
+ memcmp(outputBuffer + screenBufferInfo.dwSize.X * 3,
+ wideInputTestString.c_str(),
+ (wideInputTestString.size() - 1) * sizeof(wchar_t)) == 0
+ ) {
+ didFail = 0;
+ } else {
+ std::cerr << "Console's output didn't match expected output!" << std::endl << std::flush;
+ dumpBuffers<wchar_t>(wideTestString.c_str(), outputBuffer, wideTestString.size());
+ dumpBuffers<wchar_t>(wideTestString.c_str(), outputBuffer + screenBufferInfo.dwSize.X * 1, wideTestString.size());
+ dumpBuffers<wchar_t>(UnicodeInputTestString, outputBuffer + screenBufferInfo.dwSize.X * 2, (sizeof(UnicodeInputTestString) - 1) / sizeof(WCHAR));
+ dumpBuffers<wchar_t>(wideInputTestString.c_str(), outputBuffer + screenBufferInfo.dwSize.X * 3, wideInputTestString.size() - 1);
+ }
+ delete[] outputBuffer;
+ } catch (const std::runtime_error &ex) {
+ DWORD lastError = GetLastError();
+ std::cerr << "In function " << __FUNCTION__ << ":" << ex.what() << std::endl << std::flush;
+ displayError(lastError);
+ }
+ finishProcess(didFail == 0);
+ }
+ if (newConsole) {
+ SetStdHandle(STD_INPUT_HANDLE, parentIn);
+ SetStdHandle(STD_OUTPUT_HANDLE, parentOut);
+ SetStdHandle(STD_ERROR_HANDLE, parentErr);
+ CloseHandle(hIn);
+ CloseHandle(hOut);
+ FreeConsole();
+ }
+ return didFail;
+}
+
+#endif
+
+//----------------------------------------------------------------------------
+int testConsoleBuf(int, char*[])
+{
+ int ret = 0;
+
+#if defined(_WIN32)
+ beforeInputEvent = CreateEventW(NULL,
+ FALSE, // auto-reset event
+ FALSE, // initial state is nonsignaled
+ BeforeInputEventName); // object name
+ if (!beforeInputEvent) {
+ std::cerr << "CreateEvent#1 failed " << GetLastError() << std::endl;
+ return 1;
+ }
+
+ afterOutputEvent = CreateEventW(NULL, FALSE, FALSE, AfterOutputEventName);
+ if (!afterOutputEvent) {
+ std::cerr << "CreateEvent#2 failed " << GetLastError() << std::endl;
+ return 1;
+ }
+
+ encodedTestString = kwsys::Encoding::ToNarrow(UnicodeTestString);
+ encodedInputTestString = kwsys::Encoding::ToNarrow(UnicodeInputTestString);
+ encodedInputTestString += "\n";
+
+ ret |= testPipe();
+ ret |= testFile();
+ ret |= testConsole();
+
+ CloseHandle(beforeInputEvent);
+ CloseHandle(afterOutputEvent);
+#endif
+
+ return ret;
+}
diff --git a/Source/kwsys/testConsoleBuf.hxx b/Source/kwsys/testConsoleBuf.hxx
new file mode 100644
index 0000000..7c2f4c6
--- /dev/null
+++ b/Source/kwsys/testConsoleBuf.hxx
@@ -0,0 +1,25 @@
+/*============================================================================
+ KWSys - Kitware System Library
+ Copyright 2000-2016 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef testConsoleBuf_hxx
+#define testConsoleBuf_hxx
+
+static const wchar_t cmdConsoleBufChild[] = L"testConsoleBufChild";
+
+static const wchar_t BeforeInputEventName[] = L"BeforeInputEvent";
+static const wchar_t AfterOutputEventName[] = L"AfterOutputEvent";
+
+// यूनिकोड είναι здорово!
+static const wchar_t UnicodeTestString[] = L"\u092F\u0942\u0928\u093F\u0915\u094B\u0921 "
+ L"\u03B5\u03AF\u03BD\u03B1\u03B9 "
+ L"\u0437\u0434\u043E\u0440\u043E\u0432\u043E!";
+
+#endif
diff --git a/Source/kwsys/testConsoleBufChild.cxx b/Source/kwsys/testConsoleBufChild.cxx
new file mode 100644
index 0000000..2da39f2
--- /dev/null
+++ b/Source/kwsys/testConsoleBufChild.cxx
@@ -0,0 +1,63 @@
+/*============================================================================
+ KWSys - Kitware System Library
+ Copyright 2000-2016 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "kwsysPrivate.h"
+
+#include KWSYS_HEADER(ConsoleBuf.hxx)
+#include KWSYS_HEADER(Encoding.hxx)
+
+// Work-around CMake dependency scanning limitation. This must
+// duplicate the above list of headers.
+#if 0
+# include "ConsoleBuf.hxx.in"
+# include "Encoding.hxx.in"
+#endif
+
+#include <iostream>
+#include "testConsoleBuf.hxx"
+
+//----------------------------------------------------------------------------
+int main(int argc, const char* argv[])
+{
+#if defined(_WIN32)
+ kwsys::ConsoleBuf::Manager out(std::cout);
+ kwsys::ConsoleBuf::Manager err(std::cerr, true);
+ kwsys::ConsoleBuf::Manager in(std::cin);
+
+ if (argc > 1) {
+ std::cout << argv[1] << std::endl;
+ std::cerr << argv[1] << std::endl;
+ } else {
+ std::string str = kwsys::Encoding::ToNarrow(UnicodeTestString);
+ std::cout << str << std::endl;
+ std::cerr << str << std::endl;
+ }
+
+ std::string input;
+ HANDLE event = OpenEventW(EVENT_MODIFY_STATE, FALSE, BeforeInputEventName);
+ if (event) {
+ SetEvent(event);
+ CloseHandle(event);
+ }
+
+ std::cin >> input;
+ std::cout << input << std::endl;
+ event = OpenEventW(EVENT_MODIFY_STATE, FALSE, AfterOutputEventName);
+ if (event) {
+ SetEvent(event);
+ CloseHandle(event);
+ }
+#else
+ static_cast<void>(argc);
+ static_cast<void>(argv);
+#endif
+ return 0;
+}
diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx
index 9252ea6..880b46e 100644
--- a/Source/kwsys/testSystemTools.cxx
+++ b/Source/kwsys/testSystemTools.cxx
@@ -940,7 +940,7 @@ static bool CheckRelativePath(
const std::string& expected)
{
std::string result = kwsys::SystemTools::RelativePath(local, remote);
- if(expected != result)
+ if (!kwsys::SystemTools::ComparePath(expected, result))
{
std::cerr << "RelativePath(" << local << ", " << remote
<< ") yielded " << result << " instead of " << expected << std::endl;
@@ -965,7 +965,7 @@ static bool CheckCollapsePath(
const std::string& expected)
{
std::string result = kwsys::SystemTools::CollapseFullPath(path);
- if(expected != result)
+ if (!kwsys::SystemTools::ComparePath(expected, result))
{
std::cerr << "CollapseFullPath(" << path
<< ") yielded " << result << " instead of " << expected << std::endl;
diff --git a/Tests/CMakeLib/CMakeLists.txt b/Tests/CMakeLib/CMakeLists.txt
index 7ef3c03..405917a 100644
--- a/Tests/CMakeLib/CMakeLists.txt
+++ b/Tests/CMakeLib/CMakeLists.txt
@@ -11,6 +11,7 @@ set(CMakeLib_TESTS
testUTF8
testXMLParser
testXMLSafe
+ testFindPackageCommand
)
set(testRST_ARGS ${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/Tests/CMakeLib/testFindPackageCommand.cxx b/Tests/CMakeLib/testFindPackageCommand.cxx
new file mode 100644
index 0000000..1cddb0e
--- /dev/null
+++ b/Tests/CMakeLib/testFindPackageCommand.cxx
@@ -0,0 +1,76 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2011 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmFindPackageCommand.h"
+
+#include <iostream>
+#include <string>
+
+#define cmPassed(m) std::cout << "Passed: " << (m) << "\n"
+#define cmFailed(m) \
+ std::cout << "FAILED: " << (m) << "\n"; \
+ failed = 1
+
+int testFindPackageCommand(int /*unused*/, char* /*unused*/ [])
+{
+ int failed = 0;
+
+ // ----------------------------------------------------------------------
+ // Test cmFindPackage::Sort
+ std::vector<std::string> testString;
+ testString.push_back("lib-0.0");
+ testString.push_back("lib-1.2");
+ testString.push_back("lib-2.0");
+ testString.push_back("lib-19.0.1");
+ testString.push_back("lib-20.01.1");
+ testString.push_back("lib-20.2.2a");
+
+ cmFindPackageCommand::Sort(testString.begin(), testString.end(),
+ cmFindPackageCommand::Natural,
+ cmFindPackageCommand::Asc);
+ if (!(testString[0] == "lib-0.0" && testString[1] == "lib-1.2" &&
+ testString[2] == "lib-2.0" && testString[3] == "lib-19.0.1" &&
+ testString[4] == "lib-20.01.1" && testString[5] == "lib-20.2.2a")) {
+ cmFailed("cmSystemTools::Sort fail with Natural ASC");
+ }
+
+ cmFindPackageCommand::Sort(testString.begin(), testString.end(),
+ cmFindPackageCommand::Natural,
+ cmFindPackageCommand::Dec);
+ if (!(testString[5] == "lib-0.0" && testString[4] == "lib-1.2" &&
+ testString[3] == "lib-2.0" && testString[2] == "lib-19.0.1" &&
+ testString[1] == "lib-20.01.1" && testString[0] == "lib-20.2.2a")) {
+ cmFailed("cmSystemTools::Sort fail with Natural ASC");
+ }
+
+ cmFindPackageCommand::Sort(testString.begin(), testString.end(),
+ cmFindPackageCommand::Name_order,
+ cmFindPackageCommand::Dec);
+ if (!(testString[5] == "lib-0.0" && testString[4] == "lib-1.2" &&
+ testString[3] == "lib-19.0.1" && testString[2] == "lib-2.0" &&
+ testString[1] == "lib-20.01.1" && testString[0] == "lib-20.2.2a")) {
+ cmFailed("cmSystemTools::Sort fail with Name DEC");
+ }
+
+ cmFindPackageCommand::Sort(testString.begin(), testString.end(),
+ cmFindPackageCommand::Name_order,
+ cmFindPackageCommand::Asc);
+ if (!(testString[0] == "lib-0.0" && testString[1] == "lib-1.2" &&
+ testString[2] == "lib-19.0.1" && testString[3] == "lib-2.0" &&
+ testString[4] == "lib-20.01.1" && testString[5] == "lib-20.2.2a")) {
+ cmFailed("cmSystemTools::Sort fail with Natural ASC");
+ }
+
+ if (!failed) {
+ cmPassed("cmSystemTools::Sort working");
+ }
+ return failed;
+}
diff --git a/Tests/CMakeLib/testSystemTools.cxx b/Tests/CMakeLib/testSystemTools.cxx
index e834b93..5b5c8d2 100644
--- a/Tests/CMakeLib/testSystemTools.cxx
+++ b/Tests/CMakeLib/testSystemTools.cxx
@@ -19,6 +19,13 @@
std::cout << "FAILED: " << (m) << "\n"; \
failed = 1
+#define cmAssert(exp, m) \
+ if ((exp)) { \
+ cmPassed(m); \
+ } else { \
+ cmFailed(m); \
+ }
+
int testSystemTools(int /*unused*/, char* /*unused*/ [])
{
int failed = 0;
@@ -26,10 +33,67 @@ int testSystemTools(int /*unused*/, char* /*unused*/ [])
// Test cmSystemTools::UpperCase
std::string str = "abc";
std::string strupper = "ABC";
- if (cmSystemTools::UpperCase(str) == strupper) {
- cmPassed("cmSystemTools::UpperCase is working");
- } else {
- cmFailed("cmSystemTools::UpperCase is working");
+ cmAssert(cmSystemTools::UpperCase(str) == strupper,
+ "cmSystemTools::UpperCase");
+
+ // ----------------------------------------------------------------------
+ // Test cmSystemTools::strverscmp
+ cmAssert(cmSystemTools::strverscmp("", "") == 0, "strverscmp empty string");
+ cmAssert(cmSystemTools::strverscmp("abc", "") > 0,
+ "strverscmp string vs empty string");
+ cmAssert(cmSystemTools::strverscmp("abc", "abc") == 0,
+ "strverscmp same string");
+ cmAssert(cmSystemTools::strverscmp("abd", "abc") > 0,
+ "strverscmp character string");
+ cmAssert(cmSystemTools::strverscmp("abc", "abd") < 0,
+ "strverscmp symmetric");
+ cmAssert(cmSystemTools::strverscmp("12345", "12344") > 0,
+ "strverscmp natural numbers");
+ cmAssert(cmSystemTools::strverscmp("100", "99") > 0,
+ "strverscmp natural numbers different digits");
+ cmAssert(cmSystemTools::strverscmp("12345", "00345") > 0,
+ "strverscmp natural against decimal (same length)");
+ cmAssert(cmSystemTools::strverscmp("99999999999999", "99999999999991") > 0,
+ "strverscmp natural overflow");
+ cmAssert(cmSystemTools::strverscmp("00000000000009", "00000000000001") > 0,
+ "strverscmp deciaml precision");
+ cmAssert(cmSystemTools::strverscmp("a.b.c.0", "a.b.c.000") > 0,
+ "strverscmp multiple zeros");
+ cmAssert(cmSystemTools::strverscmp("lib_1.2_10", "lib_1.2_2") > 0,
+ "strverscmp last number ");
+ cmAssert(cmSystemTools::strverscmp("12lib", "2lib") > 0,
+ "strverscmp first number ");
+ cmAssert(cmSystemTools::strverscmp("02lib", "002lib") > 0,
+ "strverscmp first number decimal ");
+ cmAssert(cmSystemTools::strverscmp("10", "9a") > 0,
+ "strverscmp letter filler ");
+ cmAssert(cmSystemTools::strverscmp("000", "0001") > 0,
+ "strverscmp zero and leading zeros ");
+
+ // test sorting using standard strvercmp input
+ std::vector<std::string> testString;
+ testString.push_back("000");
+ testString.push_back("00");
+ testString.push_back("01");
+ testString.push_back("010");
+ testString.push_back("09");
+ testString.push_back("0");
+ testString.push_back("1");
+ testString.push_back("9");
+ testString.push_back("10");
+
+ // test global ordering of input strings
+ for (size_t i = 0; i < testString.size() - 1; i++) {
+ for (size_t j = i + 1; j < testString.size(); j++) {
+ if (cmSystemTools::strverscmp(testString[i], testString[j]) >= 0) {
+ cmFailed("cmSystemTools::strverscmp error in comparing strings " +
+ testString[i] + " " + testString[j]);
+ }
+ }
+ }
+
+ if (!failed) {
+ cmPassed("cmSystemTools::strverscmp working");
}
return failed;
}
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 97770ed..8cf1faa 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -2722,6 +2722,15 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
ADD_TEST_MACRO(CMakeCommands.target_compile_definitions target_compile_definitions)
ADD_TEST_MACRO(CMakeCommands.target_compile_options target_compile_options)
+ if(CMake_HAVE_SERVER_MODE)
+ # The cmake server-mode test requires python for a simple client.
+ find_package(PythonInterp QUIET)
+ if(PYTHON_EXECUTABLE)
+ set(Server_BUILD_OPTIONS -DPYTHON_EXECUTABLE:FILEPATH=${PYTHON_EXECUTABLE})
+ ADD_TEST_MACRO(Server Server)
+ endif()
+ endif()
+
configure_file(
"${CMake_SOURCE_DIR}/Tests/CTestTestCrash/test.cmake.in"
"${CMake_BINARY_DIR}/Tests/CTestTestCrash/test.cmake"
diff --git a/Tests/CMakeTests/String-TIMESTAMP-MonthWeekNames.cmake b/Tests/CMakeTests/String-TIMESTAMP-MonthWeekNames.cmake
new file mode 100644
index 0000000..1cd44ff
--- /dev/null
+++ b/Tests/CMakeTests/String-TIMESTAMP-MonthWeekNames.cmake
@@ -0,0 +1,11 @@
+string(TIMESTAMP output "%a;%b")
+message("~${output}~")
+
+list(LENGTH output output_length)
+
+set(expected_output_length 2)
+
+if(NOT output_length EQUAL ${expected_output_length})
+ message(FATAL_ERROR "expected ${expected_output_length} entries in output "
+ "with all specifiers; found ${output_length}")
+endif()
diff --git a/Tests/CMakeTests/StringTest.cmake.in b/Tests/CMakeTests/StringTest.cmake.in
index aba35fe..a45b205 100644
--- a/Tests/CMakeTests/StringTest.cmake.in
+++ b/Tests/CMakeTests/StringTest.cmake.in
@@ -36,6 +36,8 @@ set(TIMESTAMP-IncompleteSpecifier-RESULT 0)
set(TIMESTAMP-IncompleteSpecifier-STDERR "~foobar%~")
set(TIMESTAMP-AllSpecifiers-RESULT 0)
set(TIMESTAMP-AllSpecifiers-STDERR "~[0-9]+(;[0-9]+)*~")
+set(TIMESTAMP-MonthWeekNames-RESULT 0)
+set(TIMESTAMP-MonthWeekNames-STDERR "~[^%]+;[^%]+~")
set(TIMESTAMP-UnixTime-RESULT 0)
set(TIMESTAMP-UnixTime-STDERR "~[1-9][0-9]+~")
@@ -60,6 +62,7 @@ check_cmake_test(String
TIMESTAMP-UnknownSpecifier
TIMESTAMP-IncompleteSpecifier
TIMESTAMP-AllSpecifiers
+ TIMESTAMP-MonthWeekNames
TIMESTAMP-UnixTime
)
diff --git a/Tests/FindPackageTest/CMakeLists.txt b/Tests/FindPackageTest/CMakeLists.txt
index 04bbbc6..1a6f204 100644
--- a/Tests/FindPackageTest/CMakeLists.txt
+++ b/Tests/FindPackageTest/CMakeLists.txt
@@ -633,3 +633,33 @@ endif()
if(PACKAGE_VERSION_UNSUITABLE)
message(SEND_ERROR "PACKAGE_VERSION_UNSUITABLE set, but must not be !")
endif()
+
+
+############################################################################
+##Test FIND_PACKAGE using sorting
+set(CMAKE_PREFIX_PATH ${CMAKE_CURRENT_SOURCE_DIR})
+SET(CMAKE_FIND_PACKAGE_SORT_ORDER NAME)
+SET(CMAKE_FIND_PACKAGE_SORT_DIRECTION ASC)
+
+set(SortLib_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE)
+FIND_PACKAGE(SortLib CONFIG)
+IF (NOT "${SortLib_VERSION}" STREQUAL "3.1.1")
+ message(SEND_ERROR "FIND_PACKAGE_SORT_ORDER Name Asc! ${SortLib_VERSION}")
+endif()
+unset(SortLib_VERSION)
+
+
+set(SortLib_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE)
+SET(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL)
+SET(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC)
+FIND_PACKAGE(SortLib CONFIG)
+IF (NOT "${SortLib_VERSION}" STREQUAL "3.10.1")
+ message(SEND_ERROR "FIND_PACKAGE_SORT_ORDER Natural! Dec ${SortLib_VERSION}")
+endif()
+set(SortLib_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE)
+unset(SortLib_VERSION)
+
+
+unset(CMAKE_FIND_PACKAGE_SORT_ORDER)
+unset(CMAKE_FIND_PACKAGE_SORT_DIRECTION)
+set(CMAKE_PREFIX_PATH )
diff --git a/Tests/FindPackageTest/SortLib-3.1.1/SortLibConfig.cmake b/Tests/FindPackageTest/SortLib-3.1.1/SortLibConfig.cmake
new file mode 100644
index 0000000..c1f2088
--- /dev/null
+++ b/Tests/FindPackageTest/SortLib-3.1.1/SortLibConfig.cmake
@@ -0,0 +1,2 @@
+set(SORT_LIB_VERSION 3.1.1)
+message("SortLib 3.1.1 config reached")
diff --git a/Tests/FindPackageTest/SortLib-3.1.1/SortLibConfigVersion.cmake b/Tests/FindPackageTest/SortLib-3.1.1/SortLibConfigVersion.cmake
new file mode 100644
index 0000000..fa927c7
--- /dev/null
+++ b/Tests/FindPackageTest/SortLib-3.1.1/SortLibConfigVersion.cmake
@@ -0,0 +1,9 @@
+set(PACKAGE_VERSION 3.1.1)
+if(PACKAGE_FIND_VERSION_MAJOR EQUAL 3)
+ if(PACKAGE_FIND_VERSION_MINOR EQUAL 1)
+ set(PACKAGE_VERSION_COMPATIBLE 1)
+ if(PACKAGE_FIND_VERSION_PATCH EQUAL 1)
+ set(PACKAGE_VERSION_EXACT 1)
+ endif()
+ endif()
+endif()
diff --git a/Tests/FindPackageTest/SortLib-3.10.1/SortLibConfig.cmake b/Tests/FindPackageTest/SortLib-3.10.1/SortLibConfig.cmake
new file mode 100644
index 0000000..3f3f659
--- /dev/null
+++ b/Tests/FindPackageTest/SortLib-3.10.1/SortLibConfig.cmake
@@ -0,0 +1,2 @@
+set(SORT_LIB_VERSION 3.10.1)
+message("SortLib 3.10.1 config reached")
diff --git a/Tests/FindPackageTest/SortLib-3.10.1/SortLibConfigVersion.cmake b/Tests/FindPackageTest/SortLib-3.10.1/SortLibConfigVersion.cmake
new file mode 100644
index 0000000..6f44c2d
--- /dev/null
+++ b/Tests/FindPackageTest/SortLib-3.10.1/SortLibConfigVersion.cmake
@@ -0,0 +1,9 @@
+set(PACKAGE_VERSION 3.10.1)
+if(PACKAGE_FIND_VERSION_MAJOR EQUAL 3)
+ if(PACKAGE_FIND_VERSION_MINOR EQUAL 10)
+ set(PACKAGE_VERSION_COMPATIBLE 1)
+ if(PACKAGE_FIND_VERSION_PATCH EQUAL 1)
+ set(PACKAGE_VERSION_EXACT 1)
+ endif()
+ endif()
+endif()
diff --git a/Tests/RunCMake/AndroidMK/AndroidMK-check.cmake b/Tests/RunCMake/AndroidMK/AndroidMK-check.cmake
new file mode 100644
index 0000000..691e326
--- /dev/null
+++ b/Tests/RunCMake/AndroidMK/AndroidMK-check.cmake
@@ -0,0 +1,30 @@
+# This file does a regex file compare on the generated
+# Android.mk files from the AndroidMK test
+
+macro(compare_file_to_expected file expected_file)
+ file(READ "${file}" ANDROID_MK)
+ # clean up new lines
+ string(REGEX REPLACE "\r\n" "\n" ANDROID_MK "${ANDROID_MK}")
+ string(REGEX REPLACE "\n+$" "" ANDROID_MK "${ANDROID_MK}")
+ # read in the expected regex file
+ file(READ "${expected_file}" expected)
+ # clean up new lines
+ string(REGEX REPLACE "\r\n" "\n" expected "${expected}")
+ string(REGEX REPLACE "\n+$" "" expected "${expected}")
+ # compare the file to the expected regex and if there is not a match
+ # put an error message in RunCMake_TEST_FAILED
+ if(NOT "${ANDROID_MK}" MATCHES "${expected}")
+ set(RunCMake_TEST_FAILED
+ "${file} does not match ${expected_file}:
+
+Android.mk contents = [\n${ANDROID_MK}\n]
+Expected = [\n${expected}\n]")
+ endif()
+endmacro()
+
+compare_file_to_expected(
+"${RunCMake_BINARY_DIR}/AndroidMK-build/Android.mk"
+"${RunCMake_TEST_SOURCE_DIR}/expectedBuildAndroidMK.txt")
+compare_file_to_expected(
+"${RunCMake_BINARY_DIR}/AndroidMK-build/CMakeFiles/Export/share/ndk-modules/Android.mk"
+"${RunCMake_TEST_SOURCE_DIR}/expectedInstallAndroidMK.txt")
diff --git a/Tests/RunCMake/AndroidMK/AndroidMK.cmake b/Tests/RunCMake/AndroidMK/AndroidMK.cmake
new file mode 100644
index 0000000..ed21e58
--- /dev/null
+++ b/Tests/RunCMake/AndroidMK/AndroidMK.cmake
@@ -0,0 +1,11 @@
+project(build)
+set(CMAKE_BUILD_TYPE Debug)
+add_library(foo foo.cxx)
+add_library(car foo.cxx)
+add_library(bar foo.cxx)
+add_library(dog foo.cxx)
+target_link_libraries(foo car bar dog debug -lm)
+export(TARGETS bar dog car foo ANDROID_MK
+ ${build_BINARY_DIR}/Android.mk)
+install(TARGETS bar dog car foo DESTINATION lib EXPORT myexp)
+install(EXPORT_ANDROID_MK myexp DESTINATION share/ndk-modules)
diff --git a/Tests/RunCMake/AndroidMK/CMakeLists.txt b/Tests/RunCMake/AndroidMK/CMakeLists.txt
new file mode 100644
index 0000000..576787a
--- /dev/null
+++ b/Tests/RunCMake/AndroidMK/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.5)
+project(${RunCMake_TEST} NONE) # or languages needed
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/AndroidMK/RunCMakeTest.cmake b/Tests/RunCMake/AndroidMK/RunCMakeTest.cmake
new file mode 100644
index 0000000..786d45b
--- /dev/null
+++ b/Tests/RunCMake/AndroidMK/RunCMakeTest.cmake
@@ -0,0 +1,2 @@
+include(RunCMake)
+run_cmake(AndroidMK)
diff --git a/Tests/RunCMake/AndroidMK/expectedBuildAndroidMK.txt b/Tests/RunCMake/AndroidMK/expectedBuildAndroidMK.txt
new file mode 100644
index 0000000..def8fcb
--- /dev/null
+++ b/Tests/RunCMake/AndroidMK/expectedBuildAndroidMK.txt
@@ -0,0 +1,23 @@
+LOCAL_PATH.*call my-dir.*
+include.*CLEAR_VARS.*
+LOCAL_MODULE.*bar
+LOCAL_SRC_FILES.*bar.*
+include.*PREBUILT_STATIC_LIBRARY.*
+.*
+include.*CLEAR_VARS.*
+LOCAL_MODULE.*dog
+LOCAL_SRC_FILES.*.*dog.*
+include.*PREBUILT_STATIC_LIBRARY.*
+.*
+include.*CLEAR_VARS.*
+LOCAL_MODULE.*car
+LOCAL_SRC_FILES.*.*car.*
+include.*PREBUILT_STATIC_LIBRARY.*
+.*
+include.*CLEAR_VARS.*
+LOCAL_MODULE.*foo
+LOCAL_SRC_FILES.*.*foo.*
+LOCAL_CPP_FEATURES.*rtti exceptions
+LOCAL_STATIC_LIBRARIES.*car bar dog
+LOCAL_EXPORT_LDLIBS := -lm
+include.*PREBUILT_STATIC_LIBRARY.*
diff --git a/Tests/RunCMake/AndroidMK/expectedInstallAndroidMK.txt b/Tests/RunCMake/AndroidMK/expectedInstallAndroidMK.txt
new file mode 100644
index 0000000..1bdb308
--- /dev/null
+++ b/Tests/RunCMake/AndroidMK/expectedInstallAndroidMK.txt
@@ -0,0 +1,25 @@
+LOCAL_PATH.*call my-dir.*
+_IMPORT_PREFIX.*LOCAL_PATH./../..
+
+include.*CLEAR_VARS.*
+LOCAL_MODULE.*bar
+LOCAL_SRC_FILES.*_IMPORT_PREFIX./lib.*bar.*
+include.*PREBUILT_STATIC_LIBRARY.*
+
+include.*CLEAR_VARS.
+LOCAL_MODULE.*dog
+LOCAL_SRC_FILES.*_IMPORT_PREFIX./lib.*dog.*
+include.*PREBUILT_STATIC_LIBRARY.*
+
+include.*CLEAR_VARS.*
+LOCAL_MODULE.*car
+LOCAL_SRC_FILES.*_IMPORT_PREFIX./lib.*car.*
+include.*PREBUILT_STATIC_LIBRARY.*
+
+include.*CLEAR_VARS.*
+LOCAL_MODULE.*foo
+LOCAL_SRC_FILES.*_IMPORT_PREFIX\)/lib.*foo.*
+LOCAL_CPP_FEATURES.*rtti exceptions
+LOCAL_STATIC_LIBRARIES.*car bar dog
+LOCAL_EXPORT_LDLIBS := -lm
+include.*PREBUILT_STATIC_LIBRARY.*
diff --git a/Tests/RunCMake/AndroidMK/foo.cxx b/Tests/RunCMake/AndroidMK/foo.cxx
new file mode 100644
index 0000000..3695dc9
--- /dev/null
+++ b/Tests/RunCMake/AndroidMK/foo.cxx
@@ -0,0 +1,3 @@
+void foo()
+{
+}
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index ce475e0..a1f35d7 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -332,6 +332,8 @@ add_RunCMake_test_group(CPack "DEB;RPM;TGZ")
# for MSVC compilers CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS property is used
add_RunCMake_test(AutoExportDll)
+add_RunCMake_test(AndroidMK)
+
if(CMake_TEST_ANDROID_NDK OR CMake_TEST_ANDROID_STANDALONE_TOOLCHAIN)
if(NOT "${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
message(FATAL_ERROR "Android tests supported only by Makefile and Ninja generators")
diff --git a/Tests/RunCMake/CPack/CMakeLists.txt b/Tests/RunCMake/CPack/CMakeLists.txt
index 46f1367..e42e971 100644
--- a/Tests/RunCMake/CPack/CMakeLists.txt
+++ b/Tests/RunCMake/CPack/CMakeLists.txt
@@ -1,11 +1,11 @@
cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
project(${RunCMake_TEST} CXX)
-include(${RunCMake_TEST}.cmake)
+include(${RunCMake_TEST_FILE_PREFIX}.cmake)
# include test generator specifics
-if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${GENERATOR_TYPE}/${RunCMake_TEST}-specifics.cmake")
- include("${GENERATOR_TYPE}/${RunCMake_TEST}-specifics.cmake")
+if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${GENERATOR_TYPE}/${RunCMake_TEST_FILE_PREFIX}-specifics.cmake")
+ include("${GENERATOR_TYPE}/${RunCMake_TEST_FILE_PREFIX}-specifics.cmake")
endif()
set(CPACK_GENERATOR "${GENERATOR_TYPE}")
diff --git a/Tests/RunCMake/CPack/CPackTestHelpers.cmake b/Tests/RunCMake/CPack/CPackTestHelpers.cmake
index 7bf42f9..7e6b4b1 100644
--- a/Tests/RunCMake/CPack/CPackTestHelpers.cmake
+++ b/Tests/RunCMake/CPack/CPackTestHelpers.cmake
@@ -1,9 +1,15 @@
cmake_policy(SET CMP0057 NEW)
-function(run_cpack_test TEST_NAME types build)
+function(run_cpack_test_common_ TEST_NAME types build SUBTEST_SUFFIX source)
if(TEST_TYPE IN_LIST types)
set(RunCMake_TEST_NO_CLEAN TRUE)
set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/${TEST_NAME}-build")
+ set(full_test_name_ "${TEST_NAME}")
+
+ if(SUBTEST_SUFFIX)
+ set(RunCMake_TEST_BINARY_DIR "${RunCMake_TEST_BINARY_DIR}-${SUBTEST_SUFFIX}-subtest")
+ set(full_test_name_ "${full_test_name_}-${SUBTEST_SUFFIX}-subtest")
+ endif()
# TODO this should be executed only once per ctest run (not per generator)
file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
@@ -24,27 +30,48 @@ function(run_cpack_test TEST_NAME types build)
endif()
# execute cmake
- set(RunCMake_TEST_OPTIONS "-DGENERATOR_TYPE=${TEST_TYPE}")
- run_cmake(${TEST_NAME})
+ set(RunCMake_TEST_OPTIONS "-DGENERATOR_TYPE=${TEST_TYPE}"
+ "-DRunCMake_TEST_FILE_PREFIX=${TEST_NAME}"
+ "-DRunCMake_SUBTEST_SUFFIX=${SUBTEST_SUFFIX}")
+ run_cmake(${full_test_name_})
# execute optional build step
if(build)
- run_cmake_command(${TEST_NAME}-Build "${CMAKE_COMMAND}" --build "${RunCMake_TEST_BINARY_DIR}")
+ run_cmake_command(${full_test_name_}-Build "${CMAKE_COMMAND}" --build "${RunCMake_TEST_BINARY_DIR}")
+ endif()
+
+ if(source)
+ set(pack_params_ -G ${TEST_TYPE} --config ./CPackSourceConfig.cmake)
+ FILE(APPEND ${RunCMake_TEST_BINARY_DIR}/CPackSourceConfig.cmake
+ "\nset(CPACK_RPM_SOURCE_PKG_BUILD_PARAMS \"-DRunCMake_TEST:STRING=${full_test_name_}\ -DRunCMake_TEST_FILE_PREFIX:STRING=${TEST_NAME}\")")
+ else()
+ unset(pack_params_)
endif()
# execute cpack
execute_process(
- COMMAND "${CMAKE_CPACK_COMMAND}"
+ COMMAND ${CMAKE_CPACK_COMMAND} ${pack_params_}
WORKING_DIRECTORY "${RunCMake_TEST_BINARY_DIR}"
+ RESULT_VARIABLE "result_"
OUTPUT_FILE "${RunCMake_TEST_BINARY_DIR}/test_output.txt"
ERROR_FILE "${RunCMake_TEST_BINARY_DIR}/test_error.txt"
)
+ foreach(o out err)
+ if(SUBTEST_SUFFIX AND EXISTS ${RunCMake_SOURCE_DIR}/${TEST_TYPE}/${TEST_NAME}-${SUBTEST_SUFFIX}-std${o}.txt)
+ set(RunCMake-std${o}-file "${TEST_TYPE}/${TEST_NAME}-${SUBTEST_SUFFIX}-std${o}.txt")
+ elseif(EXISTS ${RunCMake_SOURCE_DIR}/${TEST_TYPE}/${TEST_NAME}-std${o}.txt)
+ set(RunCMake-std${o}-file "${TEST_TYPE}/${TEST_NAME}-std${o}.txt")
+ endif()
+ endforeach()
+
# verify result
run_cmake_command(
- ${TEST_TYPE}/${TEST_NAME}
+ ${TEST_TYPE}/${full_test_name_}
"${CMAKE_COMMAND}"
- -DRunCMake_TEST=${TEST_NAME}
+ -DRunCMake_TEST=${full_test_name_}
+ -DRunCMake_TEST_FILE_PREFIX=${TEST_NAME}
+ -DRunCMake_SUBTEST_SUFFIX=${SUBTEST_SUFFIX}
-DGENERATOR_TYPE=${TEST_TYPE}
"-Dsrc_dir=${RunCMake_SOURCE_DIR}"
"-Dbin_dir=${RunCMake_TEST_BINARY_DIR}"
@@ -53,3 +80,17 @@ function(run_cpack_test TEST_NAME types build)
)
endif()
endfunction()
+
+function(run_cpack_test TEST_NAME types build)
+ run_cpack_test_common_("${TEST_NAME}" "${types}" "${build}" "" false)
+endfunction()
+
+function(run_cpack_source_test TEST_NAME types build)
+ run_cpack_test_common_("${TEST_NAME}" "${types}" "${build}" "" true)
+endfunction()
+
+function(run_cpack_test_subtests TEST_NAME SUBTEST_SUFFIXES types build)
+ foreach(suffix_ IN LISTS SUBTEST_SUFFIXES)
+ run_cpack_test_common_("${TEST_NAME}" "${types}" "${build}" "${suffix_}" false)
+ endforeach()
+endfunction()
diff --git a/Tests/RunCMake/CPack/PACKAGE_CHECKSUM.cmake b/Tests/RunCMake/CPack/PACKAGE_CHECKSUM.cmake
new file mode 100644
index 0000000..5ca288c
--- /dev/null
+++ b/Tests/RunCMake/CPack/PACKAGE_CHECKSUM.cmake
@@ -0,0 +1,4 @@
+install(FILES CMakeLists.txt DESTINATION foo)
+
+set(CPACK_PACKAGE_NAME "package_checksum")
+set(CPACK_PACKAGE_CHECKSUM ${RunCMake_SUBTEST_SUFFIX})
diff --git a/Tests/RunCMake/CPack/RPM/SOURCE_PACKAGE-ExpectedFiles.cmake b/Tests/RunCMake/CPack/RPM/SOURCE_PACKAGE-ExpectedFiles.cmake
new file mode 100644
index 0000000..d6811eb
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/SOURCE_PACKAGE-ExpectedFiles.cmake
@@ -0,0 +1,5 @@
+set(whitespaces_ "[\t\n\r ]*")
+
+set(EXPECTED_FILES_COUNT "1")
+set(EXPECTED_FILE_1 "source_package*.src.rpm")
+set(EXPECTED_FILE_CONTENT_1 "^source_package-0.1.1.tar.gz${whitespaces_}source_package.spec$")
diff --git a/Tests/RunCMake/CPack/RPM/SOURCE_PACKAGE-VerifyResult.cmake b/Tests/RunCMake/CPack/RPM/SOURCE_PACKAGE-VerifyResult.cmake
new file mode 100644
index 0000000..a84e296
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/SOURCE_PACKAGE-VerifyResult.cmake
@@ -0,0 +1,63 @@
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test_rpm")
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test_rpm/BUILD")
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test_rpm/BUILDROOT")
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test_rpm/RPMS")
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test_rpm/SOURCES")
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test_rpm/SPECS")
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test_rpm/SRPMS")
+
+# make sure that we are using the version of cmake and cpack that we are testing
+get_filename_component(cpack_path_ "${CMAKE_CPACK_COMMAND}" DIRECTORY)
+set(ENV{PATH} "${cpack_path_}:$ENV{PATH}")
+
+execute_process(COMMAND ${RPMBUILD_EXECUTABLE} --define "_topdir ${CMAKE_CURRENT_BINARY_DIR}/test_rpm" --rebuild ${FOUND_FILE_1}
+ RESULT_VARIABLE result_
+ ERROR_VARIABLE error_
+ OUTPUT_QUIET
+ )
+
+set(output_error_message_
+ "\n${RPMBUILD_EXECUTABLE} error: '${error_}';\nresult: '${result_}';\n${output_error_message}")
+
+set(EXPECTED_FILE_CONTENT_ "^/foo${whitespaces_}/foo/test_prog$")
+
+file(GLOB_RECURSE FOUND_FILE_ RELATIVE "${CMAKE_CURRENT_BINARY_DIR}/test_rpm/RPMS" "${CMAKE_CURRENT_BINARY_DIR}/test_rpm/RPMS/*.rpm")
+list(APPEND foundFiles_ "${FOUND_FILE_}")
+list(LENGTH FOUND_FILE_ foundFilesCount_)
+
+if(foundFilesCount_ EQUAL 1)
+ unset(PACKAGE_CONTENT)
+ getPackageContent("${CMAKE_CURRENT_BINARY_DIR}/test_rpm/RPMS/${FOUND_FILE_}" "PACKAGE_CONTENT")
+
+ string(REGEX MATCH "${EXPECTED_FILE_CONTENT_}"
+ expected_content_list "${PACKAGE_CONTENT}")
+
+ if(NOT expected_content_list)
+ message(FATAL_ERROR
+ "Unexpected file content!\n"
+ " Content: '${PACKAGE_CONTENT}'\n\n"
+ " Expected: '${EXPECTED_FILE_CONTENT_}'"
+ "${output_error_message_}")
+ endif()
+else()
+ message(FATAL_ERROR
+ "Found more than one file!"
+ " Found files count '${foundFilesCount_}'."
+ " Files: '${FOUND_FILE_}'"
+ "${output_error_message_}")
+endif()
+
+# check that there were no extra files generated
+foreach(all_files_glob_ IN LISTS ALL_FILES_GLOB)
+ file(GLOB foundAll_ RELATIVE "${CMAKE_CURRENT_BINARY_DIR}/test_rpm/RPMS" "${all_files_glob_}")
+ list(APPEND allFoundFiles_ "${foundAll_}")
+endforeach()
+
+list(LENGTH foundFiles_ foundFilesCount_)
+list(LENGTH allFoundFiles_ allFoundFilesCount_)
+
+if(NOT foundFilesCount_ EQUAL allFoundFilesCount_)
+ message(FATAL_ERROR
+ "Found more files than expected! Found files: '${allFoundFiles_}'"
+ "${output_error_message_}")
+endif()
diff --git a/Tests/RunCMake/CPack/RunCMakeTest.cmake b/Tests/RunCMake/CPack/RunCMakeTest.cmake
index a3029cf..60d42ac 100644
--- a/Tests/RunCMake/CPack/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CPack/RunCMakeTest.cmake
@@ -5,6 +5,7 @@ include("${RunCMake_SOURCE_DIR}/CPackTestHelpers.cmake")
# args: TEST_NAME "GENERATORS" RUN_CMAKE_BUILD_STEP
run_cpack_test(MINIMAL "RPM;DEB;TGZ" false)
+run_cpack_source_test(SOURCE_PACKAGE "RPM" true)
run_cpack_test(PARTIALLY_RELOCATABLE_WARNING "RPM" false)
run_cpack_test(DEB_EXTRA "DEB" false)
run_cpack_test(DEPENDENCIES "RPM;DEB" true)
@@ -18,3 +19,4 @@ run_cpack_test(DEB_GENERATE_SHLIBS "DEB" true)
run_cpack_test(DEB_GENERATE_SHLIBS_LDCONFIG "DEB" true)
run_cpack_test(DEBUGINFO "RPM" true)
run_cpack_test(LONG_FILENAMES "DEB" false)
+run_cpack_test_subtests(PACKAGE_CHECKSUM "invalid;MD5;SHA1;SHA224;SHA256;SHA384;SHA512" "TGZ" false)
diff --git a/Tests/RunCMake/CPack/SOURCE_PACKAGE.cmake b/Tests/RunCMake/CPack/SOURCE_PACKAGE.cmake
new file mode 100644
index 0000000..9958c2a
--- /dev/null
+++ b/Tests/RunCMake/CPack/SOURCE_PACKAGE.cmake
@@ -0,0 +1,9 @@
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/main.cpp"
+ "int main() {return 0;}")
+add_executable(test_prog "${CMAKE_CURRENT_BINARY_DIR}/main.cpp")
+
+install(TARGETS test_prog DESTINATION foo COMPONENT applications)
+
+set(CPACK_RPM_FILE_NAME "RPM-DEFAULT")
+
+set(CPACK_PACKAGE_NAME "source_package")
diff --git a/Tests/RunCMake/CPack/TGZ/PACKAGE_CHECKSUM-ExpectedFiles.cmake b/Tests/RunCMake/CPack/TGZ/PACKAGE_CHECKSUM-ExpectedFiles.cmake
new file mode 100644
index 0000000..205dcd8
--- /dev/null
+++ b/Tests/RunCMake/CPack/TGZ/PACKAGE_CHECKSUM-ExpectedFiles.cmake
@@ -0,0 +1,9 @@
+set(whitespaces_ "[\t\n\r ]*")
+
+set(EXPECTED_FILES_COUNT "0")
+
+if (NOT ${RunCMake_SUBTEST_SUFFIX} MATCHES "invalid")
+ set(EXPECTED_FILES_COUNT "1")
+ set(EXPECTED_FILE_1 "package_checksum*.tar.gz")
+ set(EXPECTED_FILE_CONTENT_1 "^[^\n]*package_checksum*-[^\n]*/foo/\n[^\n]*package_checksum-[^\n]*/foo/CMakeLists.txt$")
+endif()
diff --git a/Tests/RunCMake/CPack/TGZ/PACKAGE_CHECKSUM-VerifyResult.cmake b/Tests/RunCMake/CPack/TGZ/PACKAGE_CHECKSUM-VerifyResult.cmake
new file mode 100644
index 0000000..e9e65d6
--- /dev/null
+++ b/Tests/RunCMake/CPack/TGZ/PACKAGE_CHECKSUM-VerifyResult.cmake
@@ -0,0 +1,14 @@
+if(NOT ${RunCMake_SUBTEST_SUFFIX} MATCHES "invalid")
+ string(TOLOWER ${RunCMake_SUBTEST_SUFFIX} EXTENSION)
+ file(GLOB PACKAGE RELATIVE ${bin_dir} "*.tar.gz")
+ file(GLOB CSUMFILE RELATIVE ${bin_dir} "*.${EXTENSION}")
+ file(STRINGS ${CSUMFILE} CHSUM_VALUE)
+ file(${RunCMake_SUBTEST_SUFFIX} ${PACKAGE} expected_value )
+ set(expected_value "${expected_value} ${PACKAGE}")
+
+ if(NOT expected_value STREQUAL CHSUM_VALUE)
+ message(FATAL_ERROR "Generated checksum is not valid! Expected [${expected_value}] Got [${CHSUM_VALUE}]")
+ endif()
+else()
+ message(${error})
+endif()
diff --git a/Tests/RunCMake/CPack/TGZ/PACKAGE_CHECKSUM-invalid-stderr.txt b/Tests/RunCMake/CPack/TGZ/PACKAGE_CHECKSUM-invalid-stderr.txt
new file mode 100644
index 0000000..abf6d8c
--- /dev/null
+++ b/Tests/RunCMake/CPack/TGZ/PACKAGE_CHECKSUM-invalid-stderr.txt
@@ -0,0 +1,2 @@
+^CPack Error: Cannot recognize algorithm: invalid
+CPack Error: Error when generating package: package_checksum$
diff --git a/Tests/RunCMake/CPack/VerifyResult.cmake b/Tests/RunCMake/CPack/VerifyResult.cmake
index 074890f..8bc2a58 100644
--- a/Tests/RunCMake/CPack/VerifyResult.cmake
+++ b/Tests/RunCMake/CPack/VerifyResult.cmake
@@ -8,10 +8,10 @@ file(READ "${bin_dir}/test_error.txt" error)
file(READ "${config_file}" config_file_content)
set(output_error_message
- "\nCPack output: '${output}'\nCPack error: '${error}';\nconfig file: '${config_file_content}'")
+ "\nCPack output: '${output}'\nCPack error: '${error}';\nCPack result: '${PACKAGING_RESULT}';\nconfig file: '${config_file_content}'")
# check that expected generated files exist and contain expected content
-include("${src_dir}/${GENERATOR_TYPE}/${RunCMake_TEST}-ExpectedFiles.cmake")
+include("${src_dir}/${GENERATOR_TYPE}/${RunCMake_TEST_FILE_PREFIX}-ExpectedFiles.cmake")
if(NOT EXPECTED_FILES_COUNT EQUAL 0)
foreach(file_no_ RANGE 1 ${EXPECTED_FILES_COUNT})
@@ -82,8 +82,8 @@ else()
endif()
# handle additional result verifications
-if(EXISTS "${src_dir}/${GENERATOR_TYPE}/${RunCMake_TEST}-VerifyResult.cmake")
- include("${src_dir}/${GENERATOR_TYPE}/${RunCMake_TEST}-VerifyResult.cmake")
+if(EXISTS "${src_dir}/${GENERATOR_TYPE}/${RunCMake_TEST_FILE_PREFIX}-VerifyResult.cmake")
+ include("${src_dir}/${GENERATOR_TYPE}/${RunCMake_TEST_FILE_PREFIX}-VerifyResult.cmake")
else()
# by default only print out output and error so that they can be compared by
# regex
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-result.txt b/Tests/RunCMake/CommandLine/E_server-arg-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_server-arg-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-stderr.txt b/Tests/RunCMake/CommandLine/E_server-arg-stderr.txt
new file mode 100644
index 0000000..4dcbab9
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_server-arg-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: Unknown argument for server mode$
diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
index 6ae47a8..9f76ad9 100644
--- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -12,6 +12,7 @@ run_cmake_command(E_capabilities ${CMAKE_COMMAND} -E capabilities)
run_cmake_command(E_capabilities-arg ${CMAKE_COMMAND} -E capabilities --extra-arg)
run_cmake_command(E_echo_append ${CMAKE_COMMAND} -E echo_append)
run_cmake_command(E_rename-no-arg ${CMAKE_COMMAND} -E rename)
+run_cmake_command(E_server-arg ${CMAKE_COMMAND} -E server --extra-arg)
run_cmake_command(E_touch_nocreate-no-arg ${CMAKE_COMMAND} -E touch_nocreate)
run_cmake_command(E_time ${CMAKE_COMMAND} -E time ${CMAKE_COMMAND} -E echo "hello world")
diff --git a/Tests/RunCMake/add_custom_command/AppendNotOutput-stderr.txt b/Tests/RunCMake/add_custom_command/AppendNotOutput-stderr.txt
index 96d0972..cd542d8 100644
--- a/Tests/RunCMake/add_custom_command/AppendNotOutput-stderr.txt
+++ b/Tests/RunCMake/add_custom_command/AppendNotOutput-stderr.txt
@@ -1,5 +1,8 @@
CMake Error at AppendNotOutput.cmake:1 \(add_custom_command\):
- add_custom_command given APPEND option with output.*
+ add_custom_command given APPEND option with output
+
+ .*RunCMake/add_custom_command/AppendNotOutput-build/out.*
+
which is not already a custom command output.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set-result.txt b/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set-stderr.txt b/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set-stderr.txt
new file mode 100644
index 0000000..247923b
--- /dev/null
+++ b/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at DOWNLOAD-httpheader-not-set.cmake:[0-9]+ \(file\):
+ file DOWNLOAD missing string for HTTPHEADER.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set.cmake b/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set.cmake
new file mode 100644
index 0000000..6efc958
--- /dev/null
+++ b/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set.cmake
@@ -0,0 +1 @@
+file(DOWNLOAD "" "" HTTPHEADER "Content-Type: application/x-compressed-tar" HTTPHEADER)
diff --git a/Tests/RunCMake/file/DOWNLOAD-pass-not-set-result.txt b/Tests/RunCMake/file/DOWNLOAD-pass-not-set-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/file/DOWNLOAD-pass-not-set-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/DOWNLOAD-pass-not-set-stderr.txt b/Tests/RunCMake/file/DOWNLOAD-pass-not-set-stderr.txt
new file mode 100644
index 0000000..2fa2731
--- /dev/null
+++ b/Tests/RunCMake/file/DOWNLOAD-pass-not-set-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at DOWNLOAD-pass-not-set.cmake:[0-9]+ \(file\):
+ file DOWNLOAD missing string for USERPWD.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/file/DOWNLOAD-pass-not-set.cmake b/Tests/RunCMake/file/DOWNLOAD-pass-not-set.cmake
new file mode 100644
index 0000000..61eff6d
--- /dev/null
+++ b/Tests/RunCMake/file/DOWNLOAD-pass-not-set.cmake
@@ -0,0 +1 @@
+file(DOWNLOAD "" "" USERPWD)
diff --git a/Tests/RunCMake/file/DOWNLOAD-unused-argument-result.txt b/Tests/RunCMake/file/DOWNLOAD-unused-argument-result.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/file/DOWNLOAD-unused-argument-result.txt
diff --git a/Tests/RunCMake/file/DOWNLOAD-unused-argument-stderr.txt b/Tests/RunCMake/file/DOWNLOAD-unused-argument-stderr.txt
new file mode 100644
index 0000000..82a78c9
--- /dev/null
+++ b/Tests/RunCMake/file/DOWNLOAD-unused-argument-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Warning \(dev\) at DOWNLOAD-unused-argument.cmake:[0-9]+ \(file\):
+ Unexpected argument: JUNK
+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/DOWNLOAD-unused-argument.cmake b/Tests/RunCMake/file/DOWNLOAD-unused-argument.cmake
new file mode 100644
index 0000000..2e3fbe1
--- /dev/null
+++ b/Tests/RunCMake/file/DOWNLOAD-unused-argument.cmake
@@ -0,0 +1,5 @@
+file(DOWNLOAD
+ "file://${CMAKE_CURRENT_SOURCE_DIR}/DOWNLOAD-unused-argument.txt"
+ "${CMAKE_CURRENT_BINARY_DIR}/unused-argument.txt"
+ JUNK
+ )
diff --git a/Tests/RunCMake/file/DOWNLOAD-unused-argument.txt b/Tests/RunCMake/file/DOWNLOAD-unused-argument.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/file/DOWNLOAD-unused-argument.txt
diff --git a/Tests/RunCMake/file/LOCK-lowercase.cmake b/Tests/RunCMake/file/LOCK-lowercase.cmake
new file mode 100644
index 0000000..373afda
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-lowercase.cmake
@@ -0,0 +1,11 @@
+set(lock "${CMAKE_CURRENT_BINARY_DIR}/file-to-lock")
+
+if(WIN32)
+ string(TOLOWER ${lock} lock)
+endif()
+
+file(LOCK ${lock} TIMEOUT 0)
+file(LOCK ${lock} RELEASE)
+
+file(LOCK ${lock} TIMEOUT 0)
+file(LOCK ${lock} RELEASE)
diff --git a/Tests/RunCMake/file/RunCMakeTest.cmake b/Tests/RunCMake/file/RunCMakeTest.cmake
index 5f85bba..48fa757 100644
--- a/Tests/RunCMake/file/RunCMakeTest.cmake
+++ b/Tests/RunCMake/file/RunCMakeTest.cmake
@@ -1,6 +1,12 @@
include(RunCMake)
run_cmake(DOWNLOAD-hash-mismatch)
+run_cmake(DOWNLOAD-unused-argument)
+run_cmake(DOWNLOAD-httpheader-not-set)
+run_cmake(DOWNLOAD-pass-not-set)
+run_cmake(UPLOAD-unused-argument)
+run_cmake(UPLOAD-httpheader-not-set)
+run_cmake(UPLOAD-pass-not-set)
run_cmake(INSTALL-DIRECTORY)
run_cmake(INSTALL-MESSAGE-bad)
run_cmake(FileOpenFailRead)
@@ -18,6 +24,7 @@ run_cmake(LOCK-error-no-result-variable)
run_cmake(LOCK-error-no-timeout)
run_cmake(LOCK-error-timeout)
run_cmake(LOCK-error-unknown-option)
+run_cmake(LOCK-lowercase)
run_cmake(GLOB)
run_cmake(GLOB_RECURSE)
# test is valid both for GLOB and GLOB_RECURSE
diff --git a/Tests/RunCMake/file/UPLOAD-httpheader-not-set-result.txt b/Tests/RunCMake/file/UPLOAD-httpheader-not-set-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/file/UPLOAD-httpheader-not-set-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/UPLOAD-httpheader-not-set-stderr.txt b/Tests/RunCMake/file/UPLOAD-httpheader-not-set-stderr.txt
new file mode 100644
index 0000000..341baf5
--- /dev/null
+++ b/Tests/RunCMake/file/UPLOAD-httpheader-not-set-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at UPLOAD-httpheader-not-set.cmake:[0-9]+ \(file\):
+ file UPLOAD missing string for HTTPHEADER.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/file/UPLOAD-httpheader-not-set.cmake b/Tests/RunCMake/file/UPLOAD-httpheader-not-set.cmake
new file mode 100644
index 0000000..18d43cc
--- /dev/null
+++ b/Tests/RunCMake/file/UPLOAD-httpheader-not-set.cmake
@@ -0,0 +1 @@
+file(UPLOAD "" "" HTTPHEADER "Content-Type: application/x-compressed-tar" HTTPHEADER)
diff --git a/Tests/RunCMake/file/UPLOAD-pass-not-set-result.txt b/Tests/RunCMake/file/UPLOAD-pass-not-set-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/file/UPLOAD-pass-not-set-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/UPLOAD-pass-not-set-stderr.txt b/Tests/RunCMake/file/UPLOAD-pass-not-set-stderr.txt
new file mode 100644
index 0000000..089c0ad
--- /dev/null
+++ b/Tests/RunCMake/file/UPLOAD-pass-not-set-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at UPLOAD-pass-not-set.cmake:[0-9]+ \(file\):
+ file UPLOAD missing string for USERPWD.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/file/UPLOAD-pass-not-set.cmake b/Tests/RunCMake/file/UPLOAD-pass-not-set.cmake
new file mode 100644
index 0000000..4f3d86c
--- /dev/null
+++ b/Tests/RunCMake/file/UPLOAD-pass-not-set.cmake
@@ -0,0 +1 @@
+file(UPLOAD "" "" USERPWD)
diff --git a/Tests/RunCMake/file/UPLOAD-unused-argument-result.txt b/Tests/RunCMake/file/UPLOAD-unused-argument-result.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/file/UPLOAD-unused-argument-result.txt
diff --git a/Tests/RunCMake/file/UPLOAD-unused-argument-stderr.txt b/Tests/RunCMake/file/UPLOAD-unused-argument-stderr.txt
new file mode 100644
index 0000000..3c1b744
--- /dev/null
+++ b/Tests/RunCMake/file/UPLOAD-unused-argument-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Warning \(dev\) at UPLOAD-unused-argument.cmake:[0-9]+ \(file\):
+ Unexpected argument: JUNK
+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/UPLOAD-unused-argument.cmake b/Tests/RunCMake/file/UPLOAD-unused-argument.cmake
new file mode 100644
index 0000000..94ac9ac
--- /dev/null
+++ b/Tests/RunCMake/file/UPLOAD-unused-argument.cmake
@@ -0,0 +1,5 @@
+file(UPLOAD
+ "${CMAKE_CURRENT_SOURCE_DIR}/UPLOAD-unused-argument.txt"
+ "file://${CMAKE_CURRENT_BINARY_DIR}/unused-argument.txt"
+ JUNK
+ )
diff --git a/Tests/RunCMake/file/UPLOAD-unused-argument.txt b/Tests/RunCMake/file/UPLOAD-unused-argument.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/file/UPLOAD-unused-argument.txt
diff --git a/Tests/RunCMake/get_filename_component/KnownComponents.cmake b/Tests/RunCMake/get_filename_component/KnownComponents.cmake
index d822258..7dfb55d 100644
--- a/Tests/RunCMake/get_filename_component/KnownComponents.cmake
+++ b/Tests/RunCMake/get_filename_component/KnownComponents.cmake
@@ -19,12 +19,12 @@ foreach(c DIRECTORY NAME EXT NAME_WE PATH)
endforeach()
# Test Windows paths with DIRECTORY component and an absolute Windows path.
-get_filename_component(test_slashes "c:\\path\\to\\filename.ext.in" DIRECTORY)
-check("DIRECTORY from backslashes" "${test_slashes}" "c:/path/to")
+get_filename_component(test_slashes "C:\\path\\to\\filename.ext.in" DIRECTORY)
+check("DIRECTORY from backslashes" "${test_slashes}" "C:/path/to")
list(APPEND non_cache_vars test_slashes)
-get_filename_component(test_winroot "c:\\filename.ext.in" DIRECTORY)
-check("DIRECTORY in windows root" "${test_winroot}" "c:/")
+get_filename_component(test_winroot "C:\\filename.ext.in" DIRECTORY)
+check("DIRECTORY in windows root" "${test_winroot}" "C:/")
list(APPEND non_cache_vars test_winroot)
# Test finding absolute paths.
@@ -33,8 +33,8 @@ check("ABSOLUTE" "${test_absolute}" "/path/to/filename.ext.in")
get_filename_component(test_absolute "/../path/to/filename.ext.in" ABSOLUTE)
check("ABSOLUTE .. in root" "${test_absolute}" "/path/to/filename.ext.in")
-get_filename_component(test_absolute "c:/../path/to/filename.ext.in" ABSOLUTE)
-check("ABSOLUTE .. in windows root" "${test_absolute}" "c:/path/to/filename.ext.in")
+get_filename_component(test_absolute "C:/../path/to/filename.ext.in" ABSOLUTE)
+check("ABSOLUTE .. in windows root" "${test_absolute}" "C:/path/to/filename.ext.in")
list(APPEND non_cache_vars test_absolute)
diff --git a/Tests/RunCMake/get_property/directory_properties-stderr.txt b/Tests/RunCMake/get_property/directory_properties-stderr.txt
index 80c9877..6d5bcdb 100644
--- a/Tests/RunCMake/get_property/directory_properties-stderr.txt
+++ b/Tests/RunCMake/get_property/directory_properties-stderr.txt
@@ -3,4 +3,20 @@ get_property: --><--
get_directory_property: -->value<--
get_property: -->value<--
get_directory_property: --><--
-get_property: --><--$
+get_property: --><--
+get_directory_property: -->[^<;]*Tests/RunCMake/get_property/directory_properties<--
+get_property: -->[^<;]*Tests/RunCMake/get_property/directory_properties<--
+get_directory_property: -->[^<;]*Tests/RunCMake/get_property/directory_properties/sub1;[^<;]*Tests/RunCMake/get_property/directory_properties/sub2<--
+get_property: -->[^<;]*Tests/RunCMake/get_property/directory_properties/sub1;[^<;]*Tests/RunCMake/get_property/directory_properties/sub2<--
+get_directory_property: -->CustomTop;InterfaceTop<--
+get_property: -->CustomTop;InterfaceTop<--
+get_directory_property: -->CustomSub;InterfaceSub<--
+get_property: -->CustomSub;InterfaceSub<--
+get_directory_property: -->[^<;]*/Tests/RunCMake/get_property/directory_properties-build<--
+get_property: -->[^<;]*/Tests/RunCMake/get_property/directory_properties-build<--
+get_directory_property: -->[^<;]*/RunCMake/get_property<--
+get_property: -->[^<;]*/Tests/RunCMake/get_property<--
+get_directory_property: -->[^<;]*/Tests/RunCMake/get_property/directory_properties-build/directory_properties<--
+get_property: -->[^<;]*/Tests/RunCMake/get_property/directory_properties-build/directory_properties<--
+get_directory_property: -->[^<;]*/Tests/RunCMake/get_property/directory_properties<--
+get_property: -->[^<;]*/Tests/RunCMake/get_property/directory_properties<--$
diff --git a/Tests/RunCMake/get_property/directory_properties.cmake b/Tests/RunCMake/get_property/directory_properties.cmake
index b0a9b1b..4e68738 100644
--- a/Tests/RunCMake/get_property/directory_properties.cmake
+++ b/Tests/RunCMake/get_property/directory_properties.cmake
@@ -13,3 +13,18 @@ set_directory_properties(PROPERTIES empty "" custom value)
check_directory_property("${CMAKE_CURRENT_SOURCE_DIR}" empty)
check_directory_property("${CMAKE_CURRENT_SOURCE_DIR}" custom)
check_directory_property("${CMAKE_CURRENT_SOURCE_DIR}" noexist)
+
+add_custom_target(CustomTop)
+add_library(InterfaceTop INTERFACE)
+add_library(my::InterfaceTop ALIAS InterfaceTop)
+
+add_subdirectory(directory_properties)
+check_directory_property("${CMAKE_CURRENT_SOURCE_DIR}" SUBDIRECTORIES)
+check_directory_property("${CMAKE_CURRENT_SOURCE_DIR}/directory_properties" SUBDIRECTORIES)
+check_directory_property("${CMAKE_CURRENT_SOURCE_DIR}" BUILDSYSTEM_TARGETS)
+check_directory_property("${CMAKE_CURRENT_SOURCE_DIR}/directory_properties" BUILDSYSTEM_TARGETS)
+
+check_directory_property("${CMAKE_CURRENT_SOURCE_DIR}" BINARY_DIR)
+check_directory_property("${CMAKE_CURRENT_SOURCE_DIR}" SOURCE_DIR)
+check_directory_property("${CMAKE_CURRENT_SOURCE_DIR}/directory_properties" BINARY_DIR)
+check_directory_property("${CMAKE_CURRENT_SOURCE_DIR}/directory_properties" SOURCE_DIR)
diff --git a/Tests/RunCMake/get_property/directory_properties/CMakeLists.txt b/Tests/RunCMake/get_property/directory_properties/CMakeLists.txt
new file mode 100644
index 0000000..7318b97
--- /dev/null
+++ b/Tests/RunCMake/get_property/directory_properties/CMakeLists.txt
@@ -0,0 +1,6 @@
+add_subdirectory(sub1)
+subdirs(sub2)
+
+add_custom_target(CustomSub)
+add_library(InterfaceSub INTERFACE)
+add_library(my::InterfaceSub ALIAS InterfaceSub)
diff --git a/Tests/RunCMake/get_property/directory_properties/sub1/CMakeLists.txt b/Tests/RunCMake/get_property/directory_properties/sub1/CMakeLists.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/get_property/directory_properties/sub1/CMakeLists.txt
diff --git a/Tests/RunCMake/get_property/directory_properties/sub2/CMakeLists.txt b/Tests/RunCMake/get_property/directory_properties/sub2/CMakeLists.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/get_property/directory_properties/sub2/CMakeLists.txt
diff --git a/Tests/Server/CMakeLists.txt b/Tests/Server/CMakeLists.txt
new file mode 100644
index 0000000..8daf12a
--- /dev/null
+++ b/Tests/Server/CMakeLists.txt
@@ -0,0 +1,23 @@
+cmake_minimum_required(VERSION 3.4)
+project(Server CXX)
+
+find_package(PythonInterp REQUIRED)
+
+macro(do_test bsname file)
+ execute_process(COMMAND ${PYTHON_EXECUTABLE}
+ "${CMAKE_SOURCE_DIR}/server-test.py"
+ "${CMAKE_COMMAND}"
+ "${CMAKE_SOURCE_DIR}/${file}"
+ "${CMAKE_SOURCE_DIR}"
+ "${CMAKE_BINARY_DIR}"
+ RESULT_VARIABLE test_result
+ )
+
+ if (NOT test_result EQUAL 0)
+ message(SEND_ERROR "TEST FAILED")
+ endif()
+endmacro()
+
+do_test("test_handshake" "tc_handshake.json")
+
+add_executable(Server empty.cpp)
diff --git a/Tests/Server/cmakelib.py b/Tests/Server/cmakelib.py
new file mode 100644
index 0000000..e89b1f0
--- /dev/null
+++ b/Tests/Server/cmakelib.py
@@ -0,0 +1,126 @@
+import sys, subprocess, json
+
+termwidth = 150
+
+print_communication = True
+
+def ordered(obj):
+ if isinstance(obj, dict):
+ return sorted((k, ordered(v)) for k, v in obj.items())
+ if isinstance(obj, list):
+ return sorted(ordered(x) for x in obj)
+ else:
+ return obj
+
+def col_print(title, array):
+ print
+ print
+ print(title)
+
+ indentwidth = 4
+ indent = " " * indentwidth
+
+ if not array:
+ print(indent + "<None>")
+ return
+
+ padwidth = 2
+
+ maxitemwidth = len(max(array, key=len))
+
+ numCols = max(1, int((termwidth - indentwidth + padwidth) / (maxitemwidth + padwidth)))
+
+ numRows = len(array) // numCols + 1
+
+ pad = " " * padwidth
+
+ for index in range(numRows):
+ print(indent + pad.join(item.ljust(maxitemwidth) for item in array[index::numRows]))
+
+def waitForRawMessage(cmakeCommand):
+ stdoutdata = ""
+ payload = ""
+ while not cmakeCommand.poll():
+ stdoutdataLine = cmakeCommand.stdout.readline()
+ if stdoutdataLine:
+ stdoutdata += stdoutdataLine.decode('utf-8')
+ else:
+ break
+ begin = stdoutdata.find("[== CMake Server ==[\n")
+ end = stdoutdata.find("]== CMake Server ==]")
+
+ if (begin != -1 and end != -1):
+ begin += len("[== CMake Server ==[\n")
+ payload = stdoutdata[begin:end]
+ if print_communication:
+ print("\nSERVER>", json.loads(payload), "\n")
+ return json.loads(payload)
+
+def writeRawData(cmakeCommand, content):
+ writeRawData.counter += 1
+ payload = """
+[== CMake Server ==[
+%s
+]== CMake Server ==]
+""" % content
+
+ rn = ( writeRawData.counter % 2 ) == 0
+
+ if rn:
+ payload = payload.replace('\n', '\r\n')
+
+ if print_communication:
+ print("\nCLIENT>", content, "(Use \\r\\n:", rn, ")\n")
+ cmakeCommand.stdin.write(payload.encode('utf-8'))
+ cmakeCommand.stdin.flush()
+writeRawData.counter = 0
+
+def writePayload(cmakeCommand, obj):
+ writeRawData(cmakeCommand, json.dumps(obj))
+
+def initProc(cmakeCommand):
+ cmakeCommand = subprocess.Popen([cmakeCommand, "-E", "server", "--experimental"],
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE)
+
+ packet = waitForRawMessage(cmakeCommand)
+ if packet == None:
+ print("Not in server mode")
+ sys.exit(1)
+
+ if packet['type'] != 'hello':
+ print("No hello message")
+ sys.exit(1)
+
+ return cmakeCommand
+
+def waitForMessage(cmakeCommand, expected):
+ data = ordered(expected)
+ packet = ordered(waitForRawMessage(cmakeCommand))
+
+ if packet != data:
+ sys.exit(-1)
+ return packet
+
+def waitForReply(cmakeCommand, originalType, cookie):
+ packet = waitForRawMessage(cmakeCommand)
+ if packet['cookie'] != cookie or packet['type'] != 'reply' or packet['inReplyTo'] != originalType:
+ sys.exit(1)
+
+def waitForError(cmakeCommand, originalType, cookie, message):
+ packet = waitForRawMessage(cmakeCommand)
+ if packet['cookie'] != cookie or packet['type'] != 'error' or packet['inReplyTo'] != originalType or packet['errorMessage'] != message:
+ sys.exit(1)
+
+def waitForProgress(cmakeCommand, originalType, cookie, current, message):
+ packet = waitForRawMessage(cmakeCommand)
+ if packet['cookie'] != cookie or packet['type'] != 'progress' or packet['inReplyTo'] != originalType or packet['progressCurrent'] != current or packet['progressMessage'] != message:
+ sys.exit(1)
+
+def handshake(cmakeCommand, major, minor):
+ version = { 'major': major }
+ if minor >= 0:
+ version['minor'] = minor
+
+ writePayload(cmakeCommand, { 'type': 'handshake', 'protocolVersion': version, 'cookie': 'TEST_HANDSHAKE' })
+ waitForReply(cmakeCommand, 'handshake', 'TEST_HANDSHAKE')
diff --git a/Tests/Server/empty.cpp b/Tests/Server/empty.cpp
new file mode 100644
index 0000000..766b775
--- /dev/null
+++ b/Tests/Server/empty.cpp
@@ -0,0 +1,5 @@
+
+int main()
+{
+ return 0;
+}
diff --git a/Tests/Server/server-test.py b/Tests/Server/server-test.py
new file mode 100644
index 0000000..e0a3b3b
--- /dev/null
+++ b/Tests/Server/server-test.py
@@ -0,0 +1,82 @@
+import sys, cmakelib, json
+
+debug = True
+
+cmakeCommand = sys.argv[1]
+testFile = sys.argv[2]
+sourceDir = sys.argv[3]
+buildDir = sys.argv[4]
+
+print("SourceDir: ", sourceDir, " -- BuildDir: ", buildDir)
+
+proc = cmakelib.initProc(cmakeCommand)
+
+with open(testFile) as f:
+ testText = f.read()
+ testText = testText.replace('%BUILDDIR%', buildDir)
+ testText = testText.replace('%SOURCEDIR%', sourceDir)
+ testData = json.loads(testText)
+
+buildDir = sys.argv[3]
+sourceDir = sys.argv[4]
+
+for obj in testData:
+ if 'sendRaw' in obj:
+ data = obj['sendRaw']
+ if debug: print("Sending raw:", data)
+ cmakelib.writeRawData(proc, data)
+ elif 'send' in obj:
+ data = obj['send']
+ if debug: print("Sending:", json.dumps(data))
+ cmakelib.writePayload(proc, data)
+ elif 'recv' in obj:
+ data = obj['recv']
+ if debug: print("Waiting for:", json.dumps(data))
+ cmakelib.waitForMessage(proc, data)
+ elif 'reply' in obj:
+ data = obj['reply']
+ if debug: print("Waiting for reply:", json.dumps(data))
+ originalType = ""
+ cookie = ""
+ if 'cookie' in data: cookie = data['cookie']
+ if 'type' in data: originalType = data['type']
+ cmakelib.waitForReply(proc, originalType, cookie)
+ elif 'error' in obj:
+ data = obj['error']
+ if debug: print("Waiting for error:", json.dumps(data))
+ originalType = ""
+ cookie = ""
+ message = ""
+ if 'cookie' in data: cookie = data['cookie']
+ if 'type' in data: originalType = data['type']
+ if 'message' in data: message = data['message']
+ cmakelib.waitForError(proc, originalType, cookie, message)
+ elif 'progress' in obj:
+ data = obj['progress']
+ if debug: print("Waiting for progress:", json.dumps(data))
+ originalType = ''
+ cookie = ""
+ current = 0
+ message = ""
+ if 'cookie' in data: cookie = data['cookie']
+ if 'type' in data: originalType = data['type']
+ if 'current' in data: current = data['current']
+ if 'message' in data: message = data['message']
+ cmakelib.waitForProgress(proc, originalType, cookie, current, message)
+ elif 'handshake' in obj:
+ data = obj['handshake']
+ if debug: print("Doing handshake:", json.dumps(data))
+ major = -1
+ minor = -1
+ if 'major' in data: major = data['major']
+ if 'minor' in data: minor = data['minor']
+ cmakelib.handshake(proc, major, minor)
+ elif 'message' in obj:
+ print("MESSAGE:", obj["message"])
+ else:
+ print("Unknown command:", json.dumps(obj))
+ sys.exit(2)
+
+ print("Completed")
+
+sys.exit(0)
diff --git a/Tests/Server/tc_handshake.json b/Tests/Server/tc_handshake.json
new file mode 100644
index 0000000..5261581
--- /dev/null
+++ b/Tests/Server/tc_handshake.json
@@ -0,0 +1,71 @@
+[
+{ "message": "Testing basic message handling:" },
+
+{ "sendRaw": "Sometext"},
+{ "recv": {"cookie":"","errorMessage":"Failed to parse JSON input.","inReplyTo":"","type":"error"} },
+
+{ "message": "Testing invalid json input"},
+{ "send": { "test": "sometext" } },
+{ "recv": {"cookie":"","errorMessage":"No type given in request.","inReplyTo":"","type":"error"} },
+
+{ "send": {"test": "sometext","cookie":"monster"} },
+{ "recv": {"cookie":"monster","errorMessage":"No type given in request.","inReplyTo":"","type":"error"} },
+
+{ "message": "Testing handshake" },
+{ "send": {"type": "sometype","cookie":"monster2"} },
+{ "recv": {"cookie":"monster2","errorMessage":"Waiting for type \"handshake\".","inReplyTo":"sometype","type":"error"} },
+
+{ "send": {"type": "handshake"} },
+{ "recv": {"cookie":"","errorMessage":"\"protocolVersion\" is required for \"handshake\".","inReplyTo":"handshake","type":"error"} },
+
+{ "send": {"type": "handshake","foo":"bar"} },
+{ "recv": {"cookie":"","errorMessage":"\"protocolVersion\" is required for \"handshake\".","inReplyTo":"handshake","type":"error"} },
+
+{ "send": {"type": "handshake","protocolVersion":"bar"} },
+{ "recv": {"cookie":"","errorMessage":"\"protocolVersion\" must be a JSON object.","inReplyTo":"handshake","type":"error"} },
+
+{ "send": {"type": "handshake","protocolVersion":{}} },
+{ "recv": {"cookie":"","errorMessage":"\"major\" must be set and an integer.","inReplyTo":"handshake","type":"error"} },
+
+{ "send": {"type": "handshake","protocolVersion":{"major":"foo"}} },
+{ "recv": {"cookie":"","errorMessage":"\"major\" must be set and an integer.","inReplyTo":"handshake","type":"error"} },
+
+{ "send": {"type": "handshake","protocolVersion":{"major":1, "minor":"foo"}} },
+{ "recv": {"cookie":"","errorMessage":"\"minor\" must be unset or an integer.","inReplyTo":"handshake","type":"error"} },
+
+{ "send": {"type": "handshake","protocolVersion":{"major":-1, "minor":-1}} },
+{ "recv": {"cookie":"","errorMessage":"\"major\" must be >= 0.","inReplyTo":"handshake","type":"error"} },
+
+{ "send": {"type": "handshake","protocolVersion":{"major":10, "minor":-1}} },
+{ "recv": {"cookie":"","errorMessage":"\"minor\" must be >= 0 when set.","inReplyTo":"handshake","type":"error"} },
+
+{ "send": {"type": "handshake","protocolVersion":{"major":10000}} },
+{ "recv": {"cookie":"","errorMessage":"Protocol version not supported.","inReplyTo":"handshake","type":"error"} },
+
+{ "send": {"type": "handshake","protocolVersion":{"major":1, "minor":10000}} },
+{ "recv": {"cookie":"","errorMessage":"Protocol version not supported.","inReplyTo":"handshake","type":"error"} },
+
+{ "send": {"cookie":"zimtstern","type": "handshake","protocolVersion":{"major":1}} },
+{ "recv": {"cookie":"zimtstern","inReplyTo":"handshake","type":"error","errorMessage":"Failed to activate protocol version: \"buildDirectory\" is missing."} },
+
+{ "message": "Testing protocol version specific options (1.0):" },
+{ "send": {"cookie":"zimtstern","type": "handshake","protocolVersion":{"major":1},"sourceDirectory":"/tmp/src"} },
+{ "recv": {"cookie":"zimtstern","inReplyTo":"handshake","type":"error","errorMessage":"Failed to activate protocol version: \"buildDirectory\" is missing."} },
+
+{ "send": {"cookie":"zimtstern","type": "handshake","protocolVersion":{"major":1},"sourceDirectory":"/tmp/src","buildDirectory":"/tmp/build"} },
+{ "recv": {"cookie":"zimtstern","inReplyTo":"handshake","type":"error","errorMessage":"Failed to activate protocol version: \"sourceDirectory\" is not a directory."} },
+
+{ "send": {"cookie":"zimtstern","type": "handshake","protocolVersion":{"major":1},"sourceDirectory":".","buildDirectory":"/tmp/build","extraGenerator":"CodeBlocks"} },
+{ "recv": {"cookie":"zimtstern","inReplyTo":"handshake","type":"error","errorMessage":"Failed to activate protocol version: \"generator\" is unset but required."} },
+
+{ "send": {"cookie":"zimtstern","type": "handshake","protocolVersion":{"major":1},"sourceDirectory":".","buildDirectory":"/tmp/build","generator":"XXXX","extraGenerator":"CodeBlocks"} },
+{ "recv": {"cookie":"zimtstern","inReplyTo":"handshake","type":"error","errorMessage":"Failed to activate protocol version: Could not set up the requested combination of \"generator\" and \"extraGenerator\""} },
+
+{ "send": {"cookie":"zimtstern","type": "handshake","protocolVersion":{"major":1},"sourceDirectory":".","buildDirectory":"/tmp/build","generator":"Ninja","extraGenerator":"XXXX"} },
+{ "recv": {"cookie":"zimtstern","inReplyTo":"handshake","type":"error","errorMessage":"Failed to activate protocol version: Could not set up the requested combination of \"generator\" and \"extraGenerator\""} },
+
+{ "send": {"cookie":"zimtstern","type": "handshake","protocolVersion":{"major":1},"sourceDirectory":".","buildDirectory":"/tmp/build","generator":"Ninja","extraGenerator":"CodeBlocks"} },
+{ "recv": {"cookie":"zimtstern","inReplyTo":"handshake","type":"reply"} },
+
+{ "message": "Everything ok." }
+]
diff --git a/Utilities/Doxygen/CMakeLists.txt b/Utilities/Doxygen/CMakeLists.txt
index 6ebf2b4..add5326 100644
--- a/Utilities/Doxygen/CMakeLists.txt
+++ b/Utilities/Doxygen/CMakeLists.txt
@@ -12,7 +12,7 @@
if(NOT CMake_SOURCE_DIR)
set(CMakeDeveloperReference_STANDALONE 1)
- cmake_minimum_required(VERSION 2.8.4 FATAL_ERROR)
+ cmake_minimum_required(VERSION 2.8.12.2 FATAL_ERROR)
get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH)
get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH)
include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake)
diff --git a/Utilities/Release/linux64_release.cmake b/Utilities/Release/linux64_release.cmake
index 168eb86..e7e154e 100644
--- a/Utilities/Release/linux64_release.cmake
+++ b/Utilities/Release/linux64_release.cmake
@@ -21,7 +21,7 @@ set(qt_xcb_libs
set(INITIAL_CACHE "
CMAKE_BUILD_TYPE:STRING=Release
CMAKE_C_STANDARD:STRING=11
-CMAKE_CXX_STANDARD:STRING=11
+CMAKE_CXX_STANDARD:STRING=14
CMAKE_C_FLAGS:STRING=-D_POSIX_C_SOURCE=199506L -D_POSIX_SOURCE=1 -D_SVID_SOURCE=1 -D_BSD_SOURCE=1
CMAKE_EXE_LINKER_FLAGS:STRING=-static-libstdc++ -static-libgcc
CURSES_LIBRARY:FILEPATH=/home/kitware/ncurses-5.9/lib/libncurses.a
diff --git a/Utilities/Release/osx_release.cmake b/Utilities/Release/osx_release.cmake
index e7e5ba4..12b12d7 100644
--- a/Utilities/Release/osx_release.cmake
+++ b/Utilities/Release/osx_release.cmake
@@ -14,7 +14,7 @@ set(CXXFLAGS "-stdlib=libc++")
set(INITIAL_CACHE "
CMAKE_BUILD_TYPE:STRING=Release
CMAKE_C_STANDARD:STRING=11
-CMAKE_CXX_STANDARD:STRING=11
+CMAKE_CXX_STANDARD:STRING=14
CMAKE_OSX_ARCHITECTURES:STRING=x86_64
CMAKE_OSX_DEPLOYMENT_TARGET:STRING=10.7
CMAKE_SKIP_BOOTSTRAP_TEST:STRING=TRUE
diff --git a/Utilities/Release/win32_release.cmake b/Utilities/Release/win32_release.cmake
index a27efda..f54a4ca 100644
--- a/Utilities/Release/win32_release.cmake
+++ b/Utilities/Release/win32_release.cmake
@@ -27,6 +27,6 @@ get_filename_component(path "${CMAKE_CURRENT_LIST_FILE}" PATH)
set(GIT_EXTRA "git config core.autocrlf true")
if(CMAKE_CREATE_VERSION STREQUAL "nightly")
# Some tests fail spuriously too often.
- set(EXTRA_CTEST_ARGS "-E Qt5Autogen")
+ set(EXTRA_CTEST_ARGS "-E 'Qt5Autogen|ConsoleBuf'")
endif()
include(${path}/release_cmake.cmake)
diff --git a/Utilities/Release/win64_release.cmake b/Utilities/Release/win64_release.cmake
index e39a610..bd2690f 100644
--- a/Utilities/Release/win64_release.cmake
+++ b/Utilities/Release/win64_release.cmake
@@ -28,6 +28,6 @@ get_filename_component(path "${CMAKE_CURRENT_LIST_FILE}" PATH)
set(GIT_EXTRA "git config core.autocrlf true")
if(CMAKE_CREATE_VERSION STREQUAL "nightly")
# Some tests fail spuriously too often.
- set(EXTRA_CTEST_ARGS "-E Qt5Autogen")
+ set(EXTRA_CTEST_ARGS "-E 'Qt5Autogen|ConsoleBuf'")
endif()
include(${path}/release_cmake.cmake)
diff --git a/Utilities/Sphinx/CMakeLists.txt b/Utilities/Sphinx/CMakeLists.txt
index 45f79dd..be4850e 100644
--- a/Utilities/Sphinx/CMakeLists.txt
+++ b/Utilities/Sphinx/CMakeLists.txt
@@ -11,7 +11,7 @@
#=============================================================================
if(NOT CMake_SOURCE_DIR)
set(CMakeHelp_STANDALONE 1)
- cmake_minimum_required(VERSION 2.8.4 FATAL_ERROR)
+ cmake_minimum_required(VERSION 2.8.12.2 FATAL_ERROR)
get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH)
get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH)
include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake)