summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/manual/cmake-developer.7.rst6
-rw-r--r--Help/release/dev/ExternalProject_stash_save_all.rst5
-rw-r--r--Help/release/dev/cpack-deb-fakeroot-removal.rts4
-rw-r--r--Help/release/dev/ms-manifest-files.rst7
-rw-r--r--Modules/CMakeCCompiler.cmake.in1
-rw-r--r--Modules/CMakeCCompilerId.c.in11
-rw-r--r--Modules/CMakeCXXCompiler.cmake.in1
-rw-r--r--Modules/CMakeCXXCompilerId.cpp.in10
-rw-r--r--Modules/CMakeDetermineCompilerId.cmake5
-rw-r--r--Modules/CPackDeb.cmake39
-rw-r--r--Modules/Compiler/AppleClang-C.cmake5
-rw-r--r--Modules/Compiler/AppleClang-CXX.cmake6
-rw-r--r--Modules/Compiler/Clang-C.cmake9
-rw-r--r--Modules/Compiler/Clang-CXX.cmake7
-rw-r--r--Modules/Compiler/GNU-C.cmake10
-rw-r--r--Modules/Compiler/GNU-CXX.cmake5
-rw-r--r--Modules/Compiler/SunPro-CXX.cmake7
-rw-r--r--Modules/ExternalProject.cmake24
-rw-r--r--Modules/FindPythonInterp.cmake2
-rw-r--r--Modules/FindPythonLibs.cmake86
-rw-r--r--Modules/Platform/Windows-MSVC.cmake4
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CPack/cmCPackDebGenerator.cxx299
-rw-r--r--Source/QtDialog/CMakeLists.txt16
-rw-r--r--Source/cmArchiveWrite.cxx39
-rw-r--r--Source/cmArchiveWrite.h95
-rw-r--r--Source/cmCommonTargetGenerator.cxx17
-rw-r--r--Source/cmCommonTargetGenerator.h1
-rw-r--r--Source/cmGeneratedFileStream.h4
-rw-r--r--Source/cmGeneratorTarget.cxx14
-rw-r--r--Source/cmGeneratorTarget.h2
-rw-r--r--Source/cmLocalGenerator.cxx7
-rw-r--r--Source/cmLocalGenerator.h1
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx38
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx4
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx4
-rw-r--r--Source/cmMakefileTargetGenerator.cxx9
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx10
-rw-r--r--Source/cmNinjaTargetGenerator.cxx9
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx29
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h1
-rw-r--r--Source/cmcmd.cxx416
-rw-r--r--Source/cmcmd.h14
-rw-r--r--Tests/CMakeLists.txt1
-rw-r--r--Tests/CPackComponentsDEB/CMakeLists.txt19
-rw-r--r--Tests/MSManifest/CMakeLists.txt5
-rw-r--r--Tests/MSManifest/Subdir/CMakeLists.txt9
-rw-r--r--Tests/MSManifest/Subdir/check.cmake6
-rw-r--r--Tests/MSManifest/Subdir/main.c1
-rw-r--r--Tests/MSManifest/Subdir/test.manifest.in4
-rw-r--r--Tests/RunCMake/BuildDepends/C-Exe-Manifest.cmake19
-rw-r--r--Tests/RunCMake/BuildDepends/C-Exe-Manifest.step1.cmake6
-rw-r--r--Tests/RunCMake/BuildDepends/C-Exe-Manifest.step2.cmake6
-rw-r--r--Tests/RunCMake/BuildDepends/C-Exe.cmake12
-rw-r--r--Tests/RunCMake/BuildDepends/C-Exe.step1.cmake3
-rw-r--r--Tests/RunCMake/BuildDepends/C-Exe.step2.cmake3
-rw-r--r--Tests/RunCMake/BuildDepends/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/BuildDepends/RunCMakeTest.cmake34
-rw-r--r--Tests/RunCMake/BuildDepends/check.cmake37
-rw-r--r--Tests/RunCMake/BuildDepends/main.c1
-rw-r--r--Tests/RunCMake/CMakeLists.txt1
-rw-r--r--Tests/RunCMake/CPack/DEB/DEB_EXTRA-VerifyResult.cmake6
-rw-r--r--Tests/RunCMake/CPack/DEB/Helpers.cmake15
-rw-r--r--Tests/RunCMake/CPack/DEB_EXTRA.cmake28
-rw-r--r--Tests/RunCMake/CPack/README.txt4
-rw-r--r--Tests/RunCMake/CPack/VerifyResult.cmake7
-rw-r--r--Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/RunCMake.cmake8
68 files changed, 1096 insertions, 429 deletions
diff --git a/Help/manual/cmake-developer.7.rst b/Help/manual/cmake-developer.7.rst
index 90a081d..a335384 100644
--- a/Help/manual/cmake-developer.7.rst
+++ b/Help/manual/cmake-developer.7.rst
@@ -52,9 +52,9 @@ When adding the first supported feature to a particular CompilerId, it is
necessary to list support for all features known to cmake (See
:variable:`CMAKE_C_COMPILE_FEATURES` and
:variable:`CMAKE_CXX_COMPILE_FEATURES` as appropriate), where available for
-the compiler. Furthermore, set ``CMAKE_<LANG>_STANDARD_DEFAULT`` to the
-default language standard level the compiler uses, or to the empty string
-if the compiler has no notion of standard levels (such as ``MSVC``).
+the compiler. Ensure that the ``CMAKE_<LANG>_STANDARD_DEFAULT`` is set to
+the computed internal variable ``CMAKE_<LANG>_STANDARD_COMPUTED_DEFAULT``
+for compiler versions which should be supported.
It is sensible to record the features for the most recent version of a
particular CompilerId first, and then work backwards. It is sensible to
diff --git a/Help/release/dev/ExternalProject_stash_save_all.rst b/Help/release/dev/ExternalProject_stash_save_all.rst
new file mode 100644
index 0000000..e00ed44
--- /dev/null
+++ b/Help/release/dev/ExternalProject_stash_save_all.rst
@@ -0,0 +1,5 @@
+ExternalProject_stash_save_all
+------------------------------
+
+* Use "git stash save --all" only if supported. The --all option for git-stash
+ wasn't introduced until git version 1.7.6.
diff --git a/Help/release/dev/cpack-deb-fakeroot-removal.rts b/Help/release/dev/cpack-deb-fakeroot-removal.rts
new file mode 100644
index 0000000..e0b97d1
--- /dev/null
+++ b/Help/release/dev/cpack-deb-fakeroot-removal.rts
@@ -0,0 +1,4 @@
+cpack-deb-fakeroot-removal
+--------------------------
+
+* :module:`CPackDeb` no longer uses fakeroot and system tar program for packaging.
diff --git a/Help/release/dev/ms-manifest-files.rst b/Help/release/dev/ms-manifest-files.rst
new file mode 100644
index 0000000..94fbe83
--- /dev/null
+++ b/Help/release/dev/ms-manifest-files.rst
@@ -0,0 +1,7 @@
+ms-manifest-files
+-----------------
+
+* CMake learned to honor ``*.manifest`` source files with MSVC tools.
+ Manifest files named as sources of ``.exe`` and ``.dll`` targets
+ will be merged with linker-generated manifests and embedded in the
+ binary.
diff --git a/Modules/CMakeCCompiler.cmake.in b/Modules/CMakeCCompiler.cmake.in
index 86cd894..2ad2f34 100644
--- a/Modules/CMakeCCompiler.cmake.in
+++ b/Modules/CMakeCCompiler.cmake.in
@@ -2,6 +2,7 @@ set(CMAKE_C_COMPILER "@CMAKE_C_COMPILER@")
set(CMAKE_C_COMPILER_ARG1 "@CMAKE_C_COMPILER_ARG1@")
set(CMAKE_C_COMPILER_ID "@CMAKE_C_COMPILER_ID@")
set(CMAKE_C_COMPILER_VERSION "@CMAKE_C_COMPILER_VERSION@")
+set(CMAKE_C_STANDARD_COMPUTED_DEFAULT "@CMAKE_C_STANDARD_COMPUTED_DEFAULT@")
set(CMAKE_C_COMPILE_FEATURES "@CMAKE_C_COMPILE_FEATURES@")
set(CMAKE_C90_COMPILE_FEATURES "@CMAKE_C90_COMPILE_FEATURES@")
set(CMAKE_C99_COMPILE_FEATURES "@CMAKE_C99_COMPILE_FEATURES@")
diff --git a/Modules/CMakeCCompilerId.c.in b/Modules/CMakeCCompilerId.c.in
index 09ae509..b224007 100644
--- a/Modules/CMakeCCompilerId.c.in
+++ b/Modules/CMakeCCompilerId.c.in
@@ -24,6 +24,17 @@ char const* qnxnto = "INFO" ":" "qnxnto[]";
@CMAKE_C_COMPILER_ID_PLATFORM_CONTENT@
@CMAKE_C_COMPILER_ID_ERROR_FOR_TEST@
+const char* info_language_dialect_default = "INFO" ":" "dialect_default["
+#if !defined(__STDC_VERSION__)
+ "90"
+#elif __STDC_VERSION__ >= 201000L
+ "11"
+#elif __STDC_VERSION__ >= 199901L
+ "99"
+#else
+#endif
+"]";
+
/*--------------------------------------------------------------------------*/
#ifdef ID_VOID_MAIN
diff --git a/Modules/CMakeCXXCompiler.cmake.in b/Modules/CMakeCXXCompiler.cmake.in
index af79a31..c6582a7 100644
--- a/Modules/CMakeCXXCompiler.cmake.in
+++ b/Modules/CMakeCXXCompiler.cmake.in
@@ -2,6 +2,7 @@ set(CMAKE_CXX_COMPILER "@CMAKE_CXX_COMPILER@")
set(CMAKE_CXX_COMPILER_ARG1 "@CMAKE_CXX_COMPILER_ARG1@")
set(CMAKE_CXX_COMPILER_ID "@CMAKE_CXX_COMPILER_ID@")
set(CMAKE_CXX_COMPILER_VERSION "@CMAKE_CXX_COMPILER_VERSION@")
+set(CMAKE_CXX_STANDARD_COMPUTED_DEFAULT "@CMAKE_CXX_STANDARD_COMPUTED_DEFAULT@")
set(CMAKE_CXX_COMPILE_FEATURES "@CMAKE_CXX_COMPILE_FEATURES@")
set(CMAKE_CXX98_COMPILE_FEATURES "@CMAKE_CXX98_COMPILE_FEATURES@")
set(CMAKE_CXX11_COMPILE_FEATURES "@CMAKE_CXX11_COMPILE_FEATURES@")
diff --git a/Modules/CMakeCXXCompilerId.cpp.in b/Modules/CMakeCXXCompilerId.cpp.in
index cc3ab49..d467507 100644
--- a/Modules/CMakeCXXCompilerId.cpp.in
+++ b/Modules/CMakeCXXCompilerId.cpp.in
@@ -23,6 +23,16 @@ char const* qnxnto = "INFO" ":" "qnxnto[]";
@CMAKE_CXX_COMPILER_ID_PLATFORM_CONTENT@
@CMAKE_CXX_COMPILER_ID_ERROR_FOR_TEST@
+const char* info_language_dialect_default = "INFO" ":" "dialect_default["
+#if __cplusplus >= 201402L
+ "14"
+#elif __cplusplus >= 201103L
+ "11"
+#else
+ "98"
+#endif
+"]";
+
/*--------------------------------------------------------------------------*/
int main(int argc, char* argv[])
diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake
index c699315..81f4ae6 100644
--- a/Modules/CMakeDetermineCompilerId.cmake
+++ b/Modules/CMakeDetermineCompilerId.cmake
@@ -102,6 +102,7 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src)
set(CMAKE_${lang}_COMPILER_VERSION "${CMAKE_${lang}_COMPILER_VERSION}" PARENT_SCOPE)
set(CMAKE_${lang}_SIMULATE_ID "${CMAKE_${lang}_SIMULATE_ID}" PARENT_SCOPE)
set(CMAKE_${lang}_SIMULATE_VERSION "${CMAKE_${lang}_SIMULATE_VERSION}" PARENT_SCOPE)
+ set(CMAKE_${lang}_STANDARD_COMPUTED_DEFAULT "${CMAKE_${lang}_STANDARD_COMPUTED_DEFAULT}" PARENT_SCOPE)
endfunction()
include(CMakeCompilerIdDetection)
@@ -487,6 +488,9 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file)
if("${info}" MATCHES "INFO:qnxnto\\[\\]")
set(COMPILER_QNXNTO 1)
endif()
+ if("${info}" MATCHES "INFO:dialect_default\\[([^]\"]*)\\]")
+ set(CMAKE_${lang}_STANDARD_COMPUTED_DEFAULT "${CMAKE_MATCH_1}")
+ endif()
endforeach()
# Construct compiler version from components if needed.
@@ -590,6 +594,7 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file)
set(CMAKE_${lang}_SIMULATE_VERSION "${CMAKE_${lang}_SIMULATE_VERSION}" PARENT_SCOPE)
set(CMAKE_EXECUTABLE_FORMAT "${CMAKE_EXECUTABLE_FORMAT}" PARENT_SCOPE)
set(COMPILER_QNXNTO "${COMPILER_QNXNTO}" PARENT_SCOPE)
+ set(CMAKE_${lang}_STANDARD_COMPUTED_DEFAULT "${CMAKE_${lang}_STANDARD_COMPUTED_DEFAULT}" PARENT_SCOPE)
endfunction()
#-----------------------------------------------------------------------------
diff --git a/Modules/CPackDeb.cmake b/Modules/CPackDeb.cmake
index 6c94d8e..93d51c3 100644
--- a/Modules/CPackDeb.cmake
+++ b/Modules/CPackDeb.cmake
@@ -326,6 +326,34 @@
#
# set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
# "${CMAKE_CURRENT_SOURCE_DIR/prerm;${CMAKE_CURRENT_SOURCE_DIR}/postrm")
+#
+# .. note::
+#
+# The original permissions of the files will be used in the final
+# package unless the variable
+# :variable:`CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION` is set.
+# In particular, the scripts should have the proper executable
+# flag prior to the generation of the package.
+#
+# .. variable:: CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION
+# CPACK_DEBIAN_<COMPONENT>_PACKAGE_CONTROL_STRICT_PERMISSION
+#
+# This variable indicates if the Debian policy on control files should be
+# strictly followed.
+#
+# * Mandatory : NO
+# * Default : FALSE
+#
+# Usage::
+#
+# set(CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION TRUE)
+#
+# .. note::
+#
+# This overrides the permissions on the original files, following the rules
+# set by Debian policy
+# https://www.debian.org/doc/debian-policy/ch-files.html#s-permissions-owners
+#
#=============================================================================
@@ -362,11 +390,6 @@ function(cpack_deb_prepare_package_vars)
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS OFF)
endif()
- find_program(FAKEROOT_EXECUTABLE fakeroot)
- if(FAKEROOT_EXECUTABLE)
- set(CPACK_DEBIAN_FAKEROOT_EXECUTABLE ${FAKEROOT_EXECUTABLE})
- endif()
-
set(WDIR "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_DEB_PACKAGE_COMPONENT_PART_PATH}")
# per component automatic discover: some of the component might not have
@@ -635,7 +658,7 @@ function(cpack_deb_prepare_package_vars)
# Are we packaging components ?
if(CPACK_DEB_PACKAGE_COMPONENT)
# override values with per component version if set
- foreach(VAR_NAME_ "PACKAGE_CONTROL_EXTRA")
+ foreach(VAR_NAME_ "PACKAGE_CONTROL_EXTRA" "PACKAGE_CONTROL_STRICT_PERMISSION")
if(CPACK_DEBIAN_${_local_component_name}_${VAR_NAME_})
set(CPACK_DEBIAN_${VAR_NAME_} "${CPACK_DEBIAN_${_local_component_name}_${VAR_NAME_}}")
endif()
@@ -657,6 +680,7 @@ function(cpack_deb_prepare_package_vars)
message("CPackDeb:Debug: CPACK_PACKAGE_FILE_NAME = ${CPACK_PACKAGE_FILE_NAME}")
message("CPackDeb:Debug: CPACK_PACKAGE_INSTALL_DIRECTORY = ${CPACK_PACKAGE_INSTALL_DIRECTORY}")
message("CPackDeb:Debug: CPACK_TEMPORARY_PACKAGE_FILE_NAME = ${CPACK_TEMPORARY_PACKAGE_FILE_NAME}")
+ message("CPackDeb:Debug: CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION = ${CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION}")
endif()
# For debian source packages:
@@ -682,7 +706,6 @@ function(cpack_deb_prepare_package_vars)
set(GEN_CPACK_DEBIAN_PACKAGE_MAINTAINER "${CPACK_DEBIAN_PACKAGE_MAINTAINER}" PARENT_SCOPE)
set(GEN_CPACK_DEBIAN_PACKAGE_DESCRIPTION "${CPACK_DEBIAN_PACKAGE_DESCRIPTION}" PARENT_SCOPE)
set(GEN_CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS}" PARENT_SCOPE)
- set(GEN_CPACK_DEBIAN_FAKEROOT_EXECUTABLE "${CPACK_DEBIAN_FAKEROOT_EXECUTABLE}" PARENT_SCOPE)
set(GEN_CPACK_DEBIAN_COMPRESSION_TYPE "${CPACK_DEBIAN_COMPRESSION_TYPE}" PARENT_SCOPE)
set(GEN_CPACK_DEBIAN_PACKAGE_RECOMMENDS "${CPACK_DEBIAN_PACKAGE_RECOMMENDS}" PARENT_SCOPE)
set(GEN_CPACK_DEBIAN_PACKAGE_SUGGESTS "${CPACK_DEBIAN_PACKAGE_SUGGESTS}" PARENT_SCOPE)
@@ -694,6 +717,8 @@ function(cpack_deb_prepare_package_vars)
set(GEN_CPACK_DEBIAN_PACKAGE_PROVIDES "${CPACK_DEBIAN_PACKAGE_PROVIDES}" PARENT_SCOPE)
set(GEN_CPACK_DEBIAN_PACKAGE_REPLACES "${CPACK_DEBIAN_PACKAGE_REPLACES}" PARENT_SCOPE)
set(GEN_CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA}" PARENT_SCOPE)
+ set(GEN_CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION
+ "${CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION}" PARENT_SCOPE)
set(GEN_WDIR "${WDIR}" PARENT_SCOPE)
endfunction()
diff --git a/Modules/Compiler/AppleClang-C.cmake b/Modules/Compiler/AppleClang-C.cmake
index 10454f6..1db7d9e 100644
--- a/Modules/Compiler/AppleClang-C.cmake
+++ b/Modules/Compiler/AppleClang-C.cmake
@@ -13,7 +13,10 @@ if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.0)
endif()
if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.0)
- set(CMAKE_C_STANDARD_DEFAULT 99)
+ if (NOT CMAKE_C_STANDARD_COMPUTED_DEFAULT)
+ message(FATAL_ERROR "CMAKE_C_STANDARD_COMPUTED_DEFAULT should be set for ${CMAKE_C_COMPILER_ID} (${CMAKE_C_COMPILER}) version ${CMAKE_C_COMPILER_VERSION}")
+ endif()
+ set(CMAKE_C_STANDARD_DEFAULT ${CMAKE_C_STANDARD_COMPUTED_DEFAULT})
endif()
macro(cmake_record_c_compile_features)
diff --git a/Modules/Compiler/AppleClang-CXX.cmake b/Modules/Compiler/AppleClang-CXX.cmake
index 1ba8a77..031851a 100644
--- a/Modules/Compiler/AppleClang-CXX.cmake
+++ b/Modules/Compiler/AppleClang-CXX.cmake
@@ -23,9 +23,13 @@ elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.1)
endif()
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.0)
- set(CMAKE_CXX_STANDARD_DEFAULT 98)
+ if (NOT CMAKE_CXX_STANDARD_COMPUTED_DEFAULT)
+ message(FATAL_ERROR "CMAKE_CXX_STANDARD_COMPUTED_DEFAULT should be set for ${CMAKE_CXX_COMPILER_ID} (${CMAKE_CXX_COMPILER}) version ${CMAKE_CXX_COMPILER_VERSION}")
+ endif()
+ set(CMAKE_CXX_STANDARD_DEFAULT ${CMAKE_CXX_STANDARD_COMPUTED_DEFAULT})
endif()
+
macro(cmake_record_cxx_compile_features)
macro(_get_appleclang_features std_version list)
record_compiler_features(CXX "${std_version}" ${list})
diff --git a/Modules/Compiler/Clang-C.cmake b/Modules/Compiler/Clang-C.cmake
index 548d0a5..ef3a46a 100644
--- a/Modules/Compiler/Clang-C.cmake
+++ b/Modules/Compiler/Clang-C.cmake
@@ -17,10 +17,11 @@ if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4)
set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-std=gnu11")
endif()
-if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.6)
- set(CMAKE_C_STANDARD_DEFAULT 11)
-elseif(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4)
- set(CMAKE_C_STANDARD_DEFAULT 99)
+if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4)
+ if (NOT CMAKE_C_STANDARD_COMPUTED_DEFAULT)
+ message(FATAL_ERROR "CMAKE_C_STANDARD_COMPUTED_DEFAULT should be set for ${CMAKE_C_COMPILER_ID} (${CMAKE_C_COMPILER}) version ${CMAKE_C_COMPILER_VERSION}")
+ endif()
+ set(CMAKE_C_STANDARD_DEFAULT ${CMAKE_C_STANDARD_COMPUTED_DEFAULT})
endif()
macro(cmake_record_c_compile_features)
diff --git a/Modules/Compiler/Clang-CXX.cmake b/Modules/Compiler/Clang-CXX.cmake
index 84b2c74..fcc7319 100644
--- a/Modules/Compiler/Clang-CXX.cmake
+++ b/Modules/Compiler/Clang-CXX.cmake
@@ -31,8 +31,11 @@ elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4)
set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=gnu++1y")
endif()
-if(UNIX AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4)
- set(CMAKE_CXX_STANDARD_DEFAULT 98)
+if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4)
+ if (NOT CMAKE_CXX_STANDARD_COMPUTED_DEFAULT)
+ message(FATAL_ERROR "CMAKE_CXX_STANDARD_COMPUTED_DEFAULT should be set for ${CMAKE_CXX_COMPILER_ID} (${CMAKE_CXX_COMPILER}) version ${CMAKE_CXX_COMPILER_VERSION}")
+ endif()
+ set(CMAKE_CXX_STANDARD_DEFAULT ${CMAKE_CXX_STANDARD_COMPUTED_DEFAULT})
endif()
macro(cmake_record_cxx_compile_features)
diff --git a/Modules/Compiler/GNU-C.cmake b/Modules/Compiler/GNU-C.cmake
index 031ab73..5c68b1e 100644
--- a/Modules/Compiler/GNU-C.cmake
+++ b/Modules/Compiler/GNU-C.cmake
@@ -22,12 +22,14 @@ elseif (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.6)
set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-std=gnu1x")
endif()
-if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0)
- set(CMAKE_C_STANDARD_DEFAULT 11)
-elseif(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.4)
- set(CMAKE_C_STANDARD_DEFAULT 90)
+if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.4)
+ if (NOT CMAKE_C_STANDARD_COMPUTED_DEFAULT)
+ message(FATAL_ERROR "CMAKE_C_STANDARD_COMPUTED_DEFAULT should be set for ${CMAKE_C_COMPILER_ID} (${CMAKE_C_COMPILER}) version ${CMAKE_C_COMPILER_VERSION}")
+ endif()
+ set(CMAKE_C_STANDARD_DEFAULT ${CMAKE_C_STANDARD_COMPUTED_DEFAULT})
endif()
+
macro(cmake_record_c_compile_features)
macro(_get_gcc_features std_version list)
record_compiler_features(C "${std_version}" ${list})
diff --git a/Modules/Compiler/GNU-CXX.cmake b/Modules/Compiler/GNU-CXX.cmake
index 2dc02f0..cbb0293 100644
--- a/Modules/Compiler/GNU-CXX.cmake
+++ b/Modules/Compiler/GNU-CXX.cmake
@@ -35,7 +35,10 @@ elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8)
endif()
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4)
- set(CMAKE_CXX_STANDARD_DEFAULT 98)
+ if (NOT CMAKE_CXX_STANDARD_COMPUTED_DEFAULT)
+ message(FATAL_ERROR "CMAKE_CXX_STANDARD_COMPUTED_DEFAULT should be set for ${CMAKE_CXX_COMPILER_ID} (${CMAKE_CXX_COMPILER}) version ${CMAKE_CXX_COMPILER_VERSION}")
+ endif()
+ set(CMAKE_CXX_STANDARD_DEFAULT ${CMAKE_CXX_STANDARD_COMPUTED_DEFAULT})
endif()
macro(cmake_record_cxx_compile_features)
diff --git a/Modules/Compiler/SunPro-CXX.cmake b/Modules/Compiler/SunPro-CXX.cmake
index e0c02d9..ff68ee9 100644
--- a/Modules/Compiler/SunPro-CXX.cmake
+++ b/Modules/Compiler/SunPro-CXX.cmake
@@ -36,8 +36,11 @@ if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.13)
set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=c++11")
endif()
-if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.13)
- set(CMAKE_CXX_STANDARD_DEFAULT 98)
+if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.13)
+ if (NOT CMAKE_CXX_STANDARD_COMPUTED_DEFAULT)
+ message(FATAL_ERROR "CMAKE_CXX_STANDARD_COMPUTED_DEFAULT should be set for ${CMAKE_CXX_COMPILER_ID} (${CMAKE_CXX_COMPILER}) version ${CMAKE_CXX_COMPILER_VERSION}")
+ endif()
+ set(CMAKE_CXX_STANDARD_DEFAULT ${CMAKE_CXX_STANDARD_COMPUTED_DEFAULT})
endif()
macro(cmake_record_cxx_compile_features)
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index 0fbf7c3..90ceedf 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -646,6 +646,11 @@ endfunction()
function(_ep_write_gitupdate_script script_filename git_EXECUTABLE git_tag git_submodules git_repository work_dir)
+ if(NOT GIT_VERSION_STRING VERSION_LESS 1.7.6)
+ set(git_stash_save_options --all --quiet)
+ else()
+ set(git_stash_save_options --quiet)
+ endif()
file(WRITE ${script_filename}
"if(\"${git_tag}\" STREQUAL \"\")
message(FATAL_ERROR \"Tag for git checkout should not be empty.\")
@@ -724,7 +729,7 @@ if(error_code OR is_remote_ref OR NOT (\"\${tag_sha}\" STREQUAL \"\${head_sha}\"
# perform git pull --rebase
if(need_stash)
execute_process(
- COMMAND \"${git_EXECUTABLE}\" stash save --all --quiet
+ COMMAND \"${git_EXECUTABLE}\" stash save ${git_stash_save_options}
WORKING_DIRECTORY \"${work_dir}\"
RESULT_VARIABLE error_code
)
@@ -1631,20 +1636,6 @@ function(_ep_add_mkdir_command name)
endfunction()
-function(_ep_get_git_version git_EXECUTABLE git_version_var)
- if(git_EXECUTABLE)
- execute_process(
- COMMAND "${git_EXECUTABLE}" --version
- OUTPUT_VARIABLE ov
- ERROR_VARIABLE ev
- OUTPUT_STRIP_TRAILING_WHITESPACE
- )
- string(REGEX REPLACE "^git version (.+)$" "\\1" version "${ov}")
- set(${git_version_var} "${version}" PARENT_SCOPE)
- endif()
-endfunction()
-
-
function(_ep_is_dir_empty dir empty_var)
file(GLOB gr "${dir}/*")
if("${gr}" STREQUAL "")
@@ -1747,8 +1738,7 @@ function(_ep_add_download_command name)
# The git submodule update '--recursive' flag requires git >= v1.6.5
#
- _ep_get_git_version("${GIT_EXECUTABLE}" git_version)
- if(git_version VERSION_LESS 1.6.5)
+ if(GIT_VERSION_STRING VERSION_LESS 1.6.5)
message(FATAL_ERROR "error: git version 1.6.5 or later required for 'git submodule update --recursive': git_version='${git_version}'")
endif()
diff --git a/Modules/FindPythonInterp.cmake b/Modules/FindPythonInterp.cmake
index 8784e18..879192e 100644
--- a/Modules/FindPythonInterp.cmake
+++ b/Modules/FindPythonInterp.cmake
@@ -51,7 +51,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.4 3.3 3.2 3.1 3.0)
+set(_PYTHON3_VERSIONS 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 b80d3ce..68e1228 100644
--- a/Modules/FindPythonLibs.cmake
+++ b/Modules/FindPythonLibs.cmake
@@ -49,6 +49,25 @@
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
+# Use the executable's path as a hint
+set(_Python_LIBRARY_PATH_HINT)
+if(PYTHON_EXECUTABLE)
+ if(WIN32)
+ get_filename_component(_Python_PREFIX ${PYTHON_EXECUTABLE} PATH)
+ if(_Python_PREFIX)
+ set(_Python_LIBRARY_PATH_HINT ${_Python_PREFIX}/libs)
+ endif()
+ unset(_Python_PREFIX)
+ else()
+ get_filename_component(_Python_PREFIX ${PYTHON_EXECUTABLE} PATH)
+ get_filename_component(_Python_PREFIX ${_Python_PREFIX} PATH)
+ if(_Python_PREFIX)
+ set(_Python_LIBRARY_PATH_HINT ${_Python_PREFIX}/lib)
+ endif()
+ unset(_Python_PREFIX)
+ endif()
+endif()
+
include(${CMAKE_CURRENT_LIST_DIR}/CMakeFindFrameworks.cmake)
# Search for the python framework on Apple.
CMAKE_FIND_FRAMEWORKS(Python)
@@ -64,7 +83,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.4 3.3 3.2 3.1 3.0)
+set(_PYTHON3_VERSIONS 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)
@@ -112,6 +131,7 @@ foreach(_CURRENT_VERSION ${_Python_VERSIONS})
if(WIN32)
find_library(PYTHON_DEBUG_LIBRARY
NAMES python${_CURRENT_VERSION_NO_DOTS}_d python
+ HINTS ${_Python_LIBRARY_PATH_HINT}
PATHS
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs/Debug
[HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs/Debug
@@ -134,6 +154,8 @@ foreach(_CURRENT_VERSION ${_Python_VERSIONS})
python${_CURRENT_VERSION}m
python${_CURRENT_VERSION}u
python${_CURRENT_VERSION}
+ HINTS
+ ${_Python_LIBRARY_PATH_HINT}
PATHS
${PYTHON_FRAMEWORK_LIBRARIES}
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs
@@ -150,33 +172,42 @@ foreach(_CURRENT_VERSION ${_Python_VERSIONS})
PATH_SUFFIXES python${_CURRENT_VERSION}/config
)
- # For backward compatibility, honour value of PYTHON_INCLUDE_PATH, if
- # PYTHON_INCLUDE_DIR is not set.
- if(DEFINED PYTHON_INCLUDE_PATH AND NOT DEFINED PYTHON_INCLUDE_DIR)
- set(PYTHON_INCLUDE_DIR "${PYTHON_INCLUDE_PATH}" CACHE PATH
- "Path to where Python.h is found" FORCE)
- endif()
+ # Don't search for include dir until library location is known
+ if(PYTHON_LIBRARY)
- set(PYTHON_FRAMEWORK_INCLUDES)
- if(Python_FRAMEWORKS AND NOT PYTHON_INCLUDE_DIR)
- foreach(dir ${Python_FRAMEWORKS})
- list(APPEND PYTHON_FRAMEWORK_INCLUDES
- ${dir}/Versions/${_CURRENT_VERSION}/include/python${_CURRENT_VERSION})
- endforeach()
- endif()
+ # Use the library's install prefix as a hint
+ set(_Python_INCLUDE_PATH_HINT)
+ get_filename_component(_Python_PREFIX ${PYTHON_LIBRARY} PATH)
+ get_filename_component(_Python_PREFIX ${_Python_PREFIX} PATH)
+ if(_Python_PREFIX)
+ set(_Python_INCLUDE_PATH_HINT ${_Python_PREFIX}/include)
+ endif()
+ unset(_Python_PREFIX)
+
+ # Add framework directories to the search paths
+ set(PYTHON_FRAMEWORK_INCLUDES)
+ if(Python_FRAMEWORKS AND NOT PYTHON_INCLUDE_DIR)
+ foreach(dir ${Python_FRAMEWORKS})
+ list(APPEND PYTHON_FRAMEWORK_INCLUDES
+ ${dir}/Versions/${_CURRENT_VERSION}/include)
+ endforeach()
+ endif()
- find_path(PYTHON_INCLUDE_DIR
- NAMES Python.h
- PATHS
- ${PYTHON_FRAMEWORK_INCLUDES}
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/include
- [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/include
- PATH_SUFFIXES
- python${_CURRENT_VERSION}mu
- python${_CURRENT_VERSION}m
- python${_CURRENT_VERSION}u
- python${_CURRENT_VERSION}
- )
+ find_path(PYTHON_INCLUDE_DIR
+ NAMES Python.h
+ HINTS
+ ${_Python_INCLUDE_PATH_HINT}
+ PATHS
+ ${PYTHON_FRAMEWORK_INCLUDES}
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/include
+ [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/include
+ PATH_SUFFIXES
+ python${_CURRENT_VERSION}mu
+ python${_CURRENT_VERSION}m
+ python${_CURRENT_VERSION}u
+ python${_CURRENT_VERSION}
+ )
+ endif()
# For backward compatibility, set PYTHON_INCLUDE_PATH.
set(PYTHON_INCLUDE_PATH "${PYTHON_INCLUDE_DIR}")
@@ -194,6 +225,9 @@ foreach(_CURRENT_VERSION ${_Python_VERSIONS})
endif()
endforeach()
+unset(_Python_INCLUDE_PATH_HINT)
+unset(_Python_LIBRARY_PATH_HINT)
+
mark_as_advanced(
PYTHON_DEBUG_LIBRARY
PYTHON_LIBRARY
diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake
index 94470c3..8594596 100644
--- a/Modules/Platform/Windows-MSVC.cmake
+++ b/Modules/Platform/Windows-MSVC.cmake
@@ -274,8 +274,8 @@ set (CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL_INIT ${CMAKE_EXE_LINKER_FLAGS_MINSIZER
macro(__windows_compiler_msvc lang)
if(NOT MSVC_VERSION LESS 1400)
# for 2005 make sure the manifest is put in the dll with mt
- set(_CMAKE_VS_LINK_DLL "<CMAKE_COMMAND> -E vs_link_dll ")
- set(_CMAKE_VS_LINK_EXE "<CMAKE_COMMAND> -E vs_link_exe ")
+ set(_CMAKE_VS_LINK_DLL "<CMAKE_COMMAND> -E vs_link_dll --intdir=<OBJECT_DIR> --manifests <MANIFESTS> -- ")
+ set(_CMAKE_VS_LINK_EXE "<CMAKE_COMMAND> -E vs_link_exe --intdir=<OBJECT_DIR> --manifests <MANIFESTS> -- ")
endif()
set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
"${_CMAKE_VS_LINK_DLL}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /dll /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <LINK_FLAGS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index a0d0160..17f8db5 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 3)
-set(CMake_VERSION_PATCH 20150917)
+set(CMake_VERSION_PATCH 20150921)
#set(CMake_VERSION_RC 1)
diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx
index 5049a3f..9402689 100644
--- a/Source/CPack/cmCPackDebGenerator.cxx
+++ b/Source/CPack/cmCPackDebGenerator.cxx
@@ -15,6 +15,7 @@
#include "cmMakefile.h"
#include "cmGeneratedFileStream.h"
#include "cmCPackLog.h"
+#include "cmArchiveWrite.h"
#include <cmsys/SystemTools.hxx>
#include <cmsys/Glob.hxx>
@@ -388,9 +389,9 @@ int cmCPackDebGenerator::createDeb()
{
std::string dirName = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
dirName += '/';
- for (std::vector<std::string>::const_iterator fileIt =
- packageFiles.begin();
- fileIt != packageFiles.end(); ++ fileIt )
+ for (std::vector<std::string>::const_iterator fileIt =
+ packageFiles.begin();
+ fileIt != packageFiles.end(); ++ fileIt )
{
totalSize += cmSystemTools::FileLength(*fileIt);
}
@@ -401,8 +402,9 @@ int cmCPackDebGenerator::createDeb()
out << std::endl;
}
- std::string cmd(this->GetOption("GEN_CPACK_DEBIAN_FAKEROOT_EXECUTABLE"));
+ const std::string strGenWDIR(this->GetOption("GEN_WDIR"));
+ cmArchiveWrite::Compress tar_compression_type = cmArchiveWrite::CompressGZip;
const char* debian_compression_type =
this->GetOption("GEN_CPACK_DEBIAN_COMPRESSION_TYPE");
if(!debian_compression_type)
@@ -410,102 +412,127 @@ int cmCPackDebGenerator::createDeb()
debian_compression_type = "gzip";
}
- std::string cmake_tar = " ", compression_modifier = "a", compression_suffix;
+ std::string compression_suffix;
if(!strcmp(debian_compression_type, "lzma")) {
compression_suffix = ".lzma";
+ tar_compression_type = cmArchiveWrite::CompressLZMA;
} else if(!strcmp(debian_compression_type, "xz")) {
compression_suffix = ".xz";
+ tar_compression_type = cmArchiveWrite::CompressXZ;
} else if(!strcmp(debian_compression_type, "bzip2")) {
compression_suffix = ".bz2";
- compression_modifier = "j";
- cmake_tar += "\"" + cmSystemTools::GetCMakeCommand() + "\" -E ";
+ tar_compression_type = cmArchiveWrite::CompressBZip2;
} else if(!strcmp(debian_compression_type, "gzip")) {
compression_suffix = ".gz";
- compression_modifier = "z";
- cmake_tar += "\"" + cmSystemTools::GetCMakeCommand() + "\" -E ";
+ tar_compression_type = cmArchiveWrite::CompressGZip;
} else if(!strcmp(debian_compression_type, "none")) {
compression_suffix = "";
- compression_modifier = "";
- cmake_tar += "\"" + cmSystemTools::GetCMakeCommand() + "\" -E ";
+ tar_compression_type = cmArchiveWrite::CompressNone;
} else {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Error unrecognized compression type: "
<< debian_compression_type << std::endl);
}
- cmd += cmake_tar + "tar c" + compression_modifier + "f data.tar"
- + compression_suffix;
- // now add all directories which have to be compressed
- // collect all top level install dirs for that
- // e.g. /opt/bin/foo, /usr/bin/bar and /usr/bin/baz would give /usr and /opt
- size_t topLevelLength = std::string(this->GetOption("GEN_WDIR")).length();
- cmCPackLogger(cmCPackLog::LOG_DEBUG, "WDIR: \""
- << this->GetOption("GEN_WDIR")
- << "\", length = " << topLevelLength
+ std::string filename_data_tar = strGenWDIR
+ + "/data.tar" + compression_suffix;
+
+ // atomic file generation for data.tar
+ {
+ cmGeneratedFileStream fileStream_data_tar;
+ fileStream_data_tar.Open(filename_data_tar.c_str(), false, true);
+ if(!fileStream_data_tar)
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error opening the file \"" << filename_data_tar << "\" for writing"
<< std::endl);
- std::set<std::string> installDirs;
+ return 0;
+ }
+ cmArchiveWrite data_tar(fileStream_data_tar, tar_compression_type, "paxr");
+
+ // uid/gid should be the one of the root user, and this root user has
+ // always uid/gid equal to 0.
+ data_tar.SetUIDAndGID(0u, 0u);
+ data_tar.SetUNAMEAndGNAME("root", "root");
+
+ // now add all directories which have to be compressed
+ // collect all top level install dirs for that
+ // e.g. /opt/bin/foo, /usr/bin/bar and /usr/bin/baz would
+ // give /usr and /opt
+ size_t topLevelLength = strGenWDIR.length();
+ cmCPackLogger(cmCPackLog::LOG_DEBUG, "WDIR: \""
+ << strGenWDIR
+ << "\", length = " << topLevelLength
+ << std::endl);
+ std::set<std::string> orderedFiles;
+
+ // we have to reconstruct the parent folders as well
+
for (std::vector<std::string>::const_iterator fileIt =
- packageFiles.begin();
- fileIt != packageFiles.end(); ++ fileIt )
- {
- cmCPackLogger(cmCPackLog::LOG_DEBUG, "FILEIT: \"" << *fileIt << "\""
- << std::endl);
- std::string::size_type slashPos = fileIt->find('/', topLevelLength+1);
- std::string relativeDir = fileIt->substr(topLevelLength,
- slashPos - topLevelLength);
- cmCPackLogger(cmCPackLog::LOG_DEBUG, "RELATIVEDIR: \"" << relativeDir
- << "\"" << std::endl);
- if (installDirs.find(relativeDir) == installDirs.end())
+ packageFiles.begin();
+ fileIt != packageFiles.end(); ++ fileIt )
{
- installDirs.insert(relativeDir);
- cmd += " .";
- cmd += relativeDir;
+ std::string currentPath = *fileIt;
+ while(currentPath != strGenWDIR)
+ {
+ // the last one IS strGenWDIR, but we do not want this one:
+ // XXX/application/usr/bin/myprogram with GEN_WDIR=XXX/application
+ // should not add XXX/application
+ orderedFiles.insert(currentPath);
+ currentPath = cmSystemTools::CollapseCombinedPath(currentPath, "..");
+ }
}
- }
- std::string output;
- int retval = -1;
- int res = cmSystemTools::RunSingleCommand(cmd.c_str(), &output, &output,
- &retval, this->GetOption("GEN_WDIR"), this->GeneratorVerbose, 0);
- if ( !res || retval )
- {
- std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- tmpFile += "/Deb.log";
- cmGeneratedFileStream ofs(tmpFile.c_str());
- ofs << "# Run command: " << cmd << std::endl
- << "# Working directory: " << toplevel << std::endl
- << "# Output:" << std::endl
- << output << std::endl;
- cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running tar command: "
- << cmd << std::endl
- << "Please check " << tmpFile << " for errors" << std::endl);
- return 0;
- }
+ for (std::set<std::string>::const_iterator fileIt =
+ orderedFiles.begin();
+ fileIt != orderedFiles.end(); ++ fileIt )
+ {
+ cmCPackLogger(cmCPackLog::LOG_DEBUG, "FILEIT: \"" << *fileIt << "\""
+ << std::endl);
+ std::string::size_type slashPos = fileIt->find('/', topLevelLength+1);
+ std::string relativeDir = fileIt->substr(topLevelLength,
+ slashPos - topLevelLength);
+ cmCPackLogger(cmCPackLog::LOG_DEBUG, "RELATIVEDIR: \"" << relativeDir
+ << "\"" << std::endl);
- std::string md5filename;
- md5filename = this->GetOption("GEN_WDIR");
- md5filename += "/md5sums";
+ // do not recurse because the loop will do it
+ if(!data_tar.Add(*fileIt, topLevelLength, ".", false))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Problem adding file to tar:" << std::endl
+ << "#top level directory: "
+ << strGenWDIR << std::endl
+ << "#file: " << *fileIt << std::endl
+ << "#error:" << data_tar.GetError() << std::endl);
+ return 0;
+ }
+ }
+ } // scope for file generation
- { // the scope is needed for cmGeneratedFileStream
+
+ std::string md5filename = strGenWDIR + "/md5sums";
+ {
+ // the scope is needed for cmGeneratedFileStream
cmGeneratedFileStream out(md5filename.c_str());
- std::vector<std::string>::const_iterator fileIt;
-// std::string topLevelWithTrailingSlash = toplevel;
+
std::string topLevelWithTrailingSlash =
this->GetOption("CPACK_TEMPORARY_DIRECTORY");
topLevelWithTrailingSlash += '/';
- for ( fileIt = packageFiles.begin();
- fileIt != packageFiles.end(); ++ fileIt )
+ for (std::vector<std::string>::const_iterator fileIt =
+ packageFiles.begin();
+ fileIt != packageFiles.end(); ++ fileIt )
{
- cmd = "\"";
+ std::string cmd = "\"";
cmd += cmSystemTools::GetCMakeCommand();
cmd += "\" -E md5sum \"";
cmd += *fileIt;
cmd += "\"";
- //std::string output;
- //int retVal = -1;
- res = cmSystemTools::RunSingleCommand(cmd.c_str(), &output, &output,
+
+ std::string output;
+ int retval = -1;
+ int res = cmSystemTools::RunSingleCommand(cmd.c_str(), &output, &output,
&retval, toplevel.c_str(), this->GeneratorVerbose, 0);
if ( !res || retval )
{
@@ -521,70 +548,116 @@ int cmCPackDebGenerator::createDeb()
}
// each line contains a eol.
// Do not end the md5sum file with yet another (invalid)
- }
+ }
- // set md5sum file permissins to RW-R--R-- so that deb lintian doesn't warn
- // about it
- cmSystemTools::SetPermissions(md5filename.c_str(),
- S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
- cmd = this->GetOption("GEN_CPACK_DEBIAN_FAKEROOT_EXECUTABLE");
- cmd += cmake_tar + "tar czf control.tar.gz ./control ./md5sums";
+
+ std::string filename_control_tar = strGenWDIR + "/control.tar.gz";
+ // atomic file generation for control.tar
+ {
+ cmGeneratedFileStream fileStream_control_tar;
+ fileStream_control_tar.Open(filename_control_tar.c_str(), false, true);
+ if(!fileStream_control_tar)
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error opening the file \"" << filename_control_tar
+ << "\" for writing" << std::endl);
+ return 0;
+ }
+ cmArchiveWrite control_tar(fileStream_control_tar,
+ tar_compression_type,
+ "paxr");
+
+ // sets permissions and uid/gid for the files
+ control_tar.SetUIDAndGID(0u, 0u);
+ control_tar.SetUNAMEAndGNAME("root", "root");
+
+ /* permissions are set according to
+ https://www.debian.org/doc/debian-policy/ch-files.html#s-permissions-owners
+ and
+ https://lintian.debian.org/tags/control-file-has-bad-permissions.html
+ */
+ const mode_t permission644 = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
+ const mode_t permissionExecute = S_IXUSR | S_IXGRP | S_IXOTH;
+ const mode_t permission755 = permission644 | permissionExecute;
+
+ // for md5sum and control (that we have generated here), we use 644
+ // (RW-R--R--)
+ // so that deb lintian doesn't warn about it
+ control_tar.SetPermissions(permission644);
+
+ // adds control and md5sums
+ if( !control_tar.Add(md5filename, strGenWDIR.length(), ".")
+ || !control_tar.Add(strGenWDIR + "/control", strGenWDIR.length(), "."))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error adding file to tar:" << std::endl
+ << "#top level directory: "
+ << strGenWDIR << std::endl
+ << "#file: \"control\" or \"md5sums\"" << std::endl
+ << "#error:" << control_tar.GetError() << std::endl);
+ return 0;
+ }
+
+ // for the other files, we use
+ // -either the original permission on the files
+ // -either a permission strictly defined by the Debian policies
const char* controlExtra =
this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA");
- if( controlExtra )
- {
- std::vector<std::string> controlExtraList;
- cmSystemTools::ExpandListArgument(controlExtra, controlExtraList);
- for(std::vector<std::string>::iterator i =
- controlExtraList.begin(); i != controlExtraList.end(); ++i)
+ if( controlExtra )
{
- std::string filenamename =
- cmsys::SystemTools::GetFilenameName(*i);
- std::string localcopy = this->GetOption("GEN_WDIR");
- localcopy += "/";
- localcopy += filenamename;
- // if we can copy the file, it means it does exist, let's add it:
- if( cmsys::SystemTools::CopyFileIfDifferent(
- *i, localcopy) )
+ // permissions are now controlled by the original file permissions
+
+ const bool permissionStrictPolicy =
+ this->IsSet("GEN_CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION");
+
+ static const char* strictFiles[] = {
+ "config", "postinst", "postrm", "preinst", "prerm"
+ };
+ std::set<std::string> setStrictFiles(
+ strictFiles,
+ strictFiles + sizeof(strictFiles)/sizeof(strictFiles[0]));
+
+ // default
+ control_tar.ClearPermissions();
+
+ std::vector<std::string> controlExtraList;
+ cmSystemTools::ExpandListArgument(controlExtra, controlExtraList);
+ for(std::vector<std::string>::iterator i = controlExtraList.begin();
+ i != controlExtraList.end(); ++i)
{
- // debian is picky and need relative to ./ path in the tar.*
- cmd += " ./";
- cmd += filenamename;
+ std::string filenamename =
+ cmsys::SystemTools::GetFilenameName(*i);
+ std::string localcopy = strGenWDIR + "/" + filenamename;
+
+ if(permissionStrictPolicy)
+ {
+ control_tar.SetPermissions(setStrictFiles.count(filenamename) ?
+ permission755 : permission644);
+ }
+
+ // if we can copy the file, it means it does exist, let's add it:
+ if( cmsys::SystemTools::CopyFileIfDifferent(*i, localcopy) )
+ {
+ control_tar.Add(localcopy, strGenWDIR.length(), ".");
+ }
}
}
- }
- res = cmSystemTools::RunSingleCommand(cmd.c_str(), &output, &output,
- &retval, this->GetOption("GEN_WDIR"), this->GeneratorVerbose, 0);
+ }
- if ( !res || retval )
- {
- std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- tmpFile += "/Deb.log";
- cmGeneratedFileStream ofs(tmpFile.c_str());
- ofs << "# Run command: " << cmd << std::endl
- << "# Working directory: " << toplevel << std::endl
- << "# Output:" << std::endl
- << output << std::endl;
- cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running tar command: "
- << cmd << std::endl
- << "Please check " << tmpFile << " for errors" << std::endl);
- return 0;
- }
// ar -r your-package-name.deb debian-binary control.tar.* data.tar.*
// since debian packages require BSD ar (most Linux distros and even
// FreeBSD and NetBSD ship GNU ar) we use a copy of OpenBSD ar here.
std::vector<std::string> arFiles;
- std::string topLevelString = this->GetOption("GEN_WDIR");
- topLevelString += "/";
+ std::string topLevelString = strGenWDIR + "/";
arFiles.push_back(topLevelString + "debian-binary");
arFiles.push_back(topLevelString + "control.tar.gz");
arFiles.push_back(topLevelString + "data.tar" + compression_suffix);
- std::string outputFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- outputFileName += "/";
- outputFileName += this->GetOption("CPACK_OUTPUT_FILE_NAME");
- res = ar_append(outputFileName.c_str(), arFiles);
+ std::string outputFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
+ outputFileName += "/";
+ outputFileName += this->GetOption("CPACK_OUTPUT_FILE_NAME");
+ int res = ar_append(outputFileName.c_str(), arFiles);
if ( res!=0 )
{
std::string tmpFile = this->GetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME");
diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt
index ad6a7fb..570b537 100644
--- a/Source/QtDialog/CMakeLists.txt
+++ b/Source/QtDialog/CMakeLists.txt
@@ -78,9 +78,12 @@ if (Qt5Widgets_FOUND)
endif()
endif()
- if(WIN32 AND TARGET Qt5::Core)
+ if(TARGET Qt5::Core)
get_property(_Qt5_Core_LOCATION TARGET Qt5::Core PROPERTY LOCATION)
get_filename_component(Qt_BIN_DIR "${_Qt5_Core_LOCATION}" PATH)
+ if(APPLE)
+ get_filename_component(Qt_BIN_DIR "${Qt_BIN_DIR}" PATH)
+ endif()
endif()
else()
set(QT_MIN_VERSION "4.4.0")
@@ -94,12 +97,6 @@ else()
set(CMake_QT_LIBRARIES ${QT_LIBRARIES})
- if(WIN32 AND EXISTS "${QT_QMAKE_EXECUTABLE}")
- get_filename_component(_Qt_BIN_DIR "${QT_QMAKE_EXECUTABLE}" PATH)
- if(EXISTS "${_Qt_BIN_DIR}/QtCore4.dll")
- set(Qt_BIN_DIR ${_Qt_BIN_DIR})
- endif()
- endif()
endif()
set(SRCS
@@ -157,9 +154,6 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_executable(cmake-gui WIN32 MACOSX_BUNDLE ${SRCS})
target_link_libraries(cmake-gui CMakeLib ${QT_QTMAIN_LIBRARY} ${CMake_QT_LIBRARIES})
-if(Qt_BIN_DIR)
- set_property(TARGET cmake-gui PROPERTY Qt_BIN_DIR ${Qt_BIN_DIR})
-endif()
if(APPLE)
file(STRINGS "${CMake_SOURCE_DIR}/Copyright.txt" copyright_line
@@ -223,7 +217,7 @@ if(CMake_INSTALL_DEPENDENCIES AND (APPLE OR WIN32))
install(CODE "
include(\"${CMake_SOURCE_DIR}/Modules/BundleUtilities.cmake\")
set(BU_CHMOD_BUNDLE_ITEMS ON)
- fixup_bundle(\"${fixup_exe}\" \"${QT_PLUGINS}\" \"${QT_LIBRARY_DIR};${QT_BINARY_DIR}\")
+ fixup_bundle(\"${fixup_exe}\" \"${QT_PLUGINS}\" \"${Qt_BIN_DIR};${QT_LIBRARY_DIR};${QT_BINARY_DIR}\")
" ${COMPONENT})
endif()
diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx
index 9f56324..7946950 100644
--- a/Source/cmArchiveWrite.cxx
+++ b/Source/cmArchiveWrite.cxx
@@ -181,7 +181,10 @@ cmArchiveWrite::~cmArchiveWrite()
}
//----------------------------------------------------------------------------
-bool cmArchiveWrite::Add(std::string path, size_t skip, const char* prefix)
+bool cmArchiveWrite::Add(std::string path,
+ size_t skip,
+ const char* prefix,
+ bool recursive)
{
if(this->Okay())
{
@@ -189,20 +192,21 @@ bool cmArchiveWrite::Add(std::string path, size_t skip, const char* prefix)
{
path.erase(path.size()-1);
}
- this->AddPath(path.c_str(), skip, prefix);
+ this->AddPath(path.c_str(), skip, prefix, recursive);
}
return this->Okay();
}
//----------------------------------------------------------------------------
bool cmArchiveWrite::AddPath(const char* path,
- size_t skip, const char* prefix)
+ size_t skip, const char* prefix,
+ bool recursive)
{
if(!this->AddFile(path, skip, prefix))
{
return false;
}
- if(!cmSystemTools::FileIsDirectory(path) ||
+ if((!cmSystemTools::FileIsDirectory(path) || !recursive) ||
cmSystemTools::FileIsSymlink(path))
{
return true;
@@ -278,6 +282,33 @@ bool cmArchiveWrite::AddFile(const char* file,
}
archive_entry_set_mtime(e, t, 0);
}
+
+ // manages the uid/guid of the entry (if any)
+ if (this->Uid.IsSet() && this->Gid.IsSet())
+ {
+ archive_entry_set_uid(e, this->Uid.Get());
+ archive_entry_set_gid(e, this->Gid.Get());
+ }
+
+ if (this->Uname.size() && this->Gname.size())
+ {
+ archive_entry_set_uname(e, this->Uname.c_str());
+ archive_entry_set_gname(e, this->Gname.c_str());
+ }
+
+
+ // manages the permissions
+ if (this->Permissions.IsSet())
+ {
+ archive_entry_set_perm(e, this->Permissions.Get());
+ }
+
+ if (this->PermissionsMask.IsSet())
+ {
+ mode_t perm = archive_entry_perm(e);
+ archive_entry_set_perm(e, perm & this->PermissionsMask.Get());
+ }
+
// Clear acl and xattr fields not useful for distribution.
archive_entry_acl_clear(e);
archive_entry_xattr_clear(e);
diff --git a/Source/cmArchiveWrite.h b/Source/cmArchiveWrite.h
index e6f515d..8dbbb83 100644
--- a/Source/cmArchiveWrite.h
+++ b/Source/cmArchiveWrite.h
@@ -18,6 +18,22 @@
# error "cmArchiveWrite not allowed during bootstrap build!"
#endif
+template<typename T>
+class cmArchiveWriteOptional
+{
+public:
+ cmArchiveWriteOptional() {this->Clear();}
+ explicit cmArchiveWriteOptional(T val) {this->Set(val);}
+
+ void Set(T val) {this->IsValueSet = true; this->Value=val;}
+ void Clear() {this->IsValueSet = false;}
+ bool IsSet() const {return this->IsValueSet;}
+ T Get() const {return Value;}
+private:
+ T Value;
+ bool IsValueSet;
+};
+
/** \class cmArchiveWrite
* \brief Wrapper around libarchive for writing.
*
@@ -52,7 +68,10 @@ public:
* skip. The remaining part of the input path is appended to the
* "prefix" value to construct the final name in the archive.
*/
- bool Add(std::string path, size_t skip = 0, const char* prefix = 0);
+ bool Add(std::string path,
+ size_t skip = 0,
+ const char* prefix = 0,
+ bool recursive = true);
/** Returns true if there has been no error. */
operator safe_bool() const
@@ -69,9 +88,65 @@ public:
void SetVerbose(bool v) { this->Verbose = v; }
void SetMTime(std::string const& t) { this->MTime = t; }
+
+ //! Sets the permissions of the added files/folders
+ void SetPermissions(mode_t permissions_)
+ {
+ this->Permissions.Set(permissions_);
+ }
+
+ //! Clears permissions - default is used instead
+ void ClearPermissions() { this->Permissions.Clear(); }
+
+ //! Sets the permissions mask of files/folders
+ //!
+ //! The permissions will be copied from the existing file
+ //! or folder. The mask will then be applied to unset
+ //! some of them
+ void SetPermissionsMask(mode_t permissionsMask_)
+ {
+ this->PermissionsMask.Set(permissionsMask_);
+ }
+
+ //! Clears permissions mask - default is used instead
+ void ClearPermissionsMask()
+ {
+ this->PermissionsMask.Clear();
+ }
+
+ //! Sets UID and GID to be used in the tar file
+ void SetUIDAndGID(int uid_, int gid_)
+ {
+ this->Uid.Set(uid_);
+ this->Gid.Set(gid_);
+ }
+
+ //! Clears UID and GID to be used in the tar file - default is used instead
+ void ClearUIDAndGID()
+ {
+ this->Uid.Clear();
+ this->Gid.Clear();
+ }
+
+ //! Sets UNAME and GNAME to be used in the tar file
+ void SetUNAMEAndGNAME(const std::string& uname_, const std::string& gname_)
+ {
+ this->Uname = uname_;
+ this->Gname = gname_;
+ }
+
+ //! Clears UNAME and GNAME to be used in the tar file
+ //! default is used instead
+ void ClearUNAMEAndGNAME()
+ {
+ this->Uname = "";
+ this->Gname = "";
+ }
+
private:
bool Okay() const { return this->Error.empty(); }
- bool AddPath(const char* path, size_t skip, const char* prefix);
+ bool AddPath(const char* path, size_t skip, const char* prefix,
+ bool recursive = true);
bool AddFile(const char* file, size_t skip, const char* prefix);
bool AddData(const char* file, size_t size);
@@ -87,6 +162,22 @@ private:
std::string Format;
std::string Error;
std::string MTime;
+
+ //! UID of the user in the tar file
+ cmArchiveWriteOptional<int> Uid;
+
+ //! GUID of the user in the tar file
+ cmArchiveWriteOptional<int> Gid;
+
+ //! UNAME/GNAME of the user (does not override UID/GID)
+ //!@{
+ std::string Uname;
+ std::string Gname;
+ //!@}
+
+ //! Permissions on files/folders
+ cmArchiveWriteOptional<mode_t> Permissions;
+ cmArchiveWriteOptional<mode_t> PermissionsMask;
};
#endif
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
index 4840e89..252e231 100644
--- a/Source/cmCommonTargetGenerator.cxx
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -412,3 +412,20 @@ cmCommonTargetGenerator::GetLinkedTargetDirectories() const
}
return dirs;
}
+
+std::string cmCommonTargetGenerator::GetManifests()
+{
+ std::vector<cmSourceFile const*> manifest_srcs;
+ this->GeneratorTarget->GetManifests(manifest_srcs, this->ConfigName);
+
+ 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->WorkingDirectory,
+ cmOutputConverter::SHELL));
+ }
+
+ return cmJoin(manifests, " ");
+}
diff --git a/Source/cmCommonTargetGenerator.h b/Source/cmCommonTargetGenerator.h
index 0a49e12..a4b2c10 100644
--- a/Source/cmCommonTargetGenerator.h
+++ b/Source/cmCommonTargetGenerator.h
@@ -88,6 +88,7 @@ protected:
ByLanguageMap DefinesByLanguage;
std::string GetIncludes(std::string const& l);
ByLanguageMap IncludesByLanguage;
+ std::string GetManifests();
std::vector<std::string> GetLinkedTargetDirectories() const;
};
diff --git a/Source/cmGeneratedFileStream.h b/Source/cmGeneratedFileStream.h
index 2aa6beb..8df3e1a 100644
--- a/Source/cmGeneratedFileStream.h
+++ b/Source/cmGeneratedFileStream.h
@@ -56,10 +56,10 @@ protected:
// Whether the real file stream was valid when it was closed.
bool Okay;
- // Whether the destionation file is compressed
+ // Whether the destination file is compressed
bool Compress;
- // Whether the destionation file is compressed
+ // Whether the destination file is compressed
bool CompressExtraExtension;
};
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 09387b7..fb5805b 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -75,6 +75,7 @@ struct IDLSourcesTag {};
struct ResxTag {};
struct ModuleDefinitionFileTag {};
struct AppManifestTag{};
+struct ManifestsTag{};
struct CertificatesTag{};
struct XamlTag{};
@@ -216,6 +217,10 @@ struct TagVisitor
{
DoAccept<IsSameTag<Tag, AppManifestTag>::Result>::Do(this->Data, sf);
}
+ else if (ext == "manifest")
+ {
+ DoAccept<IsSameTag<Tag, ManifestsTag>::Result>::Do(this->Data, sf);
+ }
else if (ext == "pfx")
{
DoAccept<IsSameTag<Tag, CertificatesTag>::Result>::Do(this->Data, sf);
@@ -626,6 +631,15 @@ cmGeneratorTarget
//----------------------------------------------------------------------------
void
cmGeneratorTarget
+::GetManifests(std::vector<cmSourceFile const*>& data,
+ const std::string& config) const
+{
+ IMPLEMENT_VISIT(Manifests);
+}
+
+//----------------------------------------------------------------------------
+void
+cmGeneratorTarget
::GetCertificates(std::vector<cmSourceFile const*>& data,
const std::string& config) const
{
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 06d9a1f..916f281 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -71,6 +71,8 @@ public:
const std::string& config) const;
void GetAppManifest(std::vector<cmSourceFile const*>&,
const std::string& config) const;
+ void GetManifests(std::vector<cmSourceFile const*>&,
+ const std::string& config) const;
void GetCertificates(std::vector<cmSourceFile const*>&,
const std::string& config) const;
void GetXamlSources(std::vector<cmSourceFile const*>&,
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 46d5cd8..97a9f1e 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -525,6 +525,13 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
return replaceValues.LinkFlags;
}
}
+ if(replaceValues.Manifests)
+ {
+ if(variable == "MANIFESTS")
+ {
+ return replaceValues.Manifests;
+ }
+ }
if(replaceValues.Flags)
{
if(variable == "FLAGS")
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index b051e5d..771131f 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -219,6 +219,7 @@ public:
const char* TargetSOName;
const char* TargetInstallNameDir;
const char* LinkFlags;
+ const char* Manifests;
const char* LanguageCompileFlags;
const char* Defines;
const char* Includes;
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index cf67251..a4bce8a 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -972,25 +972,43 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
fout << "\t\t\t\tProxyFileName=\"$(InputName)_p.c\"/>\n";
// end of <Tool Name=VCMIDLTool
- // Check if we need the FAT32 workaround.
+ // Add manifest tool settings.
if(targetBuilds && this->GetVersion() >= cmGlobalVisualStudioGenerator::VS8)
{
+ const char* manifestTool = "VCManifestTool";
+ if (this->FortranProject)
+ {
+ manifestTool = "VFManifestTool";
+ }
+ fout <<
+ "\t\t\t<Tool\n"
+ "\t\t\t\tName=\"" << manifestTool << "\"";
+
+ std::vector<cmSourceFile const*> manifest_srcs;
+ gt->GetManifests(manifest_srcs, configName);
+ if (!manifest_srcs.empty())
+ {
+ fout << "\n\t\t\t\tAdditionalManifestFiles=\"";
+ for (std::vector<cmSourceFile const*>::const_iterator
+ mi = manifest_srcs.begin(); mi != manifest_srcs.end(); ++mi)
+ {
+ std::string m = (*mi)->GetFullPath();
+ fout << this->ConvertToXMLOutputPath(m.c_str()) << ";";
+ }
+ fout << "\"";
+ }
+
+ // Check if we need the FAT32 workaround.
// Check the filesystem type where the target will be written.
- if(cmLVS6G_IsFAT(target.GetDirectory(configName).c_str()))
+ if (cmLVS6G_IsFAT(target.GetDirectory(configName).c_str()))
{
// Add a flag telling the manifest tool to use a workaround
// for FAT32 file systems, which can cause an empty manifest
// to be embedded into the resulting executable. See CMake
// bug #2617.
- const char* manifestTool = "VCManifestTool";
- if(this->FortranProject)
- {
- manifestTool = "VFManifestTool";
- }
- fout << "\t\t\t<Tool\n\t\t\t\tName=\"" << manifestTool << "\"\n"
- << "\t\t\t\tUseFAT32Workaround=\"true\"\n"
- << "\t\t\t/>\n";
+ fout << "\n\t\t\t\tUseFAT32Workaround=\"true\"";
}
+ fout << "/>\n";
}
this->OutputTargetRules(fout, configName, target, libName);
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index ccb0974..90f679e 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -353,6 +353,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
useResponseFileForObjects, buildObjs, depends,
useWatcomQuote);
+ std::string manifests = this->GetManifests();
+
cmLocalGenerator::RuleVariables vars;
vars.RuleLauncher = "RULE_LAUNCH_LINK";
vars.CMTarget = this->Target;
@@ -391,6 +393,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
vars.LinkLibraries = linkLibs.c_str();
vars.Flags = flags.c_str();
vars.LinkFlags = linkFlags.c_str();
+ vars.Manifests = manifests.c_str();
+
// Expand placeholders in the commands.
this->LocalGenerator->TargetImplib = targetOutPathImport;
for(std::vector<std::string>::iterator i = real_link_commands.begin();
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index 2f995e8..cd387a0 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -616,6 +616,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
}
}
+ std::string manifests = this->GetManifests();
+
cmLocalGenerator::RuleVariables vars;
vars.TargetPDB = targetOutPathPDB.c_str();
@@ -660,6 +662,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
}
vars.LinkFlags = linkFlags.c_str();
+ vars.Manifests = manifests.c_str();
+
// Compute the directory portion of the install_name setting.
std::string install_name_dir;
if(this->Target->GetType() == cmTarget::SHARED_LIBRARY)
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index cf88a74..b278087 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -1493,6 +1493,15 @@ void cmMakefileTargetGenerator
depends.push_back(this->ModuleDefinitionFile);
}
+ // Add a dependency on user-specified manifest files, if any.
+ std::vector<cmSourceFile const*> manifest_srcs;
+ this->GeneratorTarget->GetManifests(manifest_srcs, this->ConfigName);
+ for (std::vector<cmSourceFile const*>::iterator mi = manifest_srcs.begin();
+ mi != manifest_srcs.end(); ++mi)
+ {
+ depends.push_back((*mi)->GetFullPath());
+ }
+
// Add user-specified dependencies.
if(const char* linkDepends =
this->Target->GetProperty("LINK_DEPENDS"))
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index b855bea..7e7e600 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -237,6 +237,7 @@ cmNinjaNormalTargetGenerator
vars.Flags = "$FLAGS";
vars.LinkFlags = "$LINK_FLAGS";
+ vars.Manifests = "$MANIFESTS";
std::string langFlags;
if (targetType != cmTarget::EXECUTABLE)
@@ -509,6 +510,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
vars["LINK_FLAGS"] = cmGlobalNinjaGenerator
::EncodeLiteral(vars["LINK_FLAGS"]);
+ vars["MANIFESTS"] = this->GetManifests();
+
vars["LINK_PATH"] = frameworkPath + linkPath;
// Compute architecture specific link flags. Yes, these go into a different
@@ -579,11 +582,12 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
vars["TARGET_PDB"] = base + suffix + dbg_suffix;
}
+ const std::string objPath = GetTarget()->GetSupportDirectory();
+ vars["OBJECT_DIR"] = ConvertToNinjaPath(objPath);
+ EnsureDirectoryExists(objPath);
+
if (this->GetGlobalGenerator()->IsGCCOnWindows())
{
- const std::string objPath = GetTarget()->GetSupportDirectory();
- vars["OBJECT_DIR"] = ConvertToNinjaPath(objPath);
- EnsureDirectoryExists(objPath);
// ar.exe can't handle backslashes in rsp files (implicitly used by gcc)
std::string& linkLibraries = vars["LINK_LIBRARIES"];
std::replace(linkLibraries.begin(), linkLibraries.end(), '\\', '/');
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 81fdde2..752c8a7 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -209,6 +209,15 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps() const
result.push_back(this->ConvertToNinjaPath(this->ModuleDefinitionFile));
}
+ // Add a dependency on user-specified manifest files, if any.
+ std::vector<cmSourceFile const*> manifest_srcs;
+ this->GeneratorTarget->GetManifests(manifest_srcs, this->ConfigName);
+ for (std::vector<cmSourceFile const*>::iterator mi = manifest_srcs.begin();
+ mi != manifest_srcs.end(); ++mi)
+ {
+ result.push_back(this->ConvertToNinjaPath((*mi)->GetFullPath()));
+ }
+
// Add user-specified dependencies.
if (const char* linkDepends = this->Target->GetProperty("LINK_DEPENDS"))
{
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 4c380f7..cb5048d 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -2203,6 +2203,33 @@ cmVisualStudio10TargetGenerator::WriteLibOptions(std::string const& config)
}
}
+void cmVisualStudio10TargetGenerator::WriteManifestOptions(
+ std::string const& config)
+{
+ if (this->Target->GetType() != cmTarget::EXECUTABLE &&
+ this->Target->GetType() != cmTarget::SHARED_LIBRARY &&
+ this->Target->GetType() != cmTarget::MODULE_LIBRARY)
+ {
+ return;
+ }
+
+ std::vector<cmSourceFile const*> manifest_srcs;
+ this->GeneratorTarget->GetManifests(manifest_srcs, config);
+ if (!manifest_srcs.empty())
+ {
+ this->WriteString("<Manifest>\n", 2);
+ this->WriteString("<AdditionalManifestFiles>", 3);
+ for (std::vector<cmSourceFile const*>::const_iterator
+ mi = manifest_srcs.begin(); mi != manifest_srcs.end(); ++mi)
+ {
+ std::string m = this->ConvertPath((*mi)->GetFullPath(), false);
+ this->ConvertToWindowsSlash(m);
+ (*this->BuildFileStream) << m << ";";
+ }
+ (*this->BuildFileStream) << "</AdditionalManifestFiles>\n";
+ this->WriteString("</Manifest>\n", 2);
+ }
+}
//----------------------------------------------------------------------------
void cmVisualStudio10TargetGenerator::WriteAntBuildOptions(
@@ -2740,6 +2767,8 @@ void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups()
this->WriteLinkOptions(*i);
// output lib flags <Lib></Lib>
this->WriteLibOptions(*i);
+ // output manifest flags <Manifest></Manifest>
+ this->WriteManifestOptions(*i);
if(this->NsightTegra &&
this->Target->GetType() == cmTarget::EXECUTABLE &&
this->Target->GetPropertyAsBool("ANDROID_GUI"))
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index 451f8b2..5fadb60 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -111,6 +111,7 @@ private:
void AddLibraries(cmComputeLinkInformation& cli,
std::vector<std::string>& libVec);
void WriteLibOptions(std::string const& config);
+ void WriteManifestOptions(std::string const& config);
void WriteEvents(std::string const& configName);
void WriteEvent(const char* name,
std::vector<cmCustomCommand> const& commands,
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index aa70aa0..f44c77d 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -1355,6 +1355,35 @@ int cmcmd::WindowsCEEnvironment(const char* version, const std::string& name)
return -1;
}
+class cmVSLink
+{
+ int Type;
+ bool Verbose;
+ bool Incremental;
+ bool LinkGeneratesManifest;
+ std::vector<std::string> LinkCommand;
+ std::vector<std::string> UserManifests;
+ std::string LinkerManifestFile;
+ std::string ManifestFile;
+ std::string ManifestFileRC;
+ std::string ManifestFileRes;
+ std::string TargetFile;
+public:
+ cmVSLink(int type, bool verbose)
+ : Type(type)
+ , Verbose(verbose)
+ , Incremental(false)
+ , LinkGeneratesManifest(true)
+ {}
+ bool Parse(std::vector<std::string>::const_iterator argBeg,
+ std::vector<std::string>::const_iterator argEnd);
+ int Link();
+private:
+ int LinkIncremental();
+ int LinkNonIncremental();
+ int RunMT(std::string const& out, bool notify);
+};
+
// For visual studio 2005 and newer manifest files need to be embedded into
// exe and dll's. This code does that in such a way that incremental linking
// still works.
@@ -1364,11 +1393,7 @@ int cmcmd::VisualStudioLink(std::vector<std::string>& args, int type)
{
return -1;
}
- bool verbose = false;
- if(cmSystemTools::GetEnv("VERBOSE"))
- {
- verbose = true;
- }
+ bool verbose = cmSystemTools::GetEnv("VERBOSE")? true:false;
std::vector<std::string> expandedArgs;
for(std::vector<std::string>::iterator i = args.begin();
i != args.end(); ++i)
@@ -1389,79 +1414,19 @@ int cmcmd::VisualStudioLink(std::vector<std::string>& args, int type)
expandedArgs.push_back(*i);
}
}
- bool hasIncremental = false;
- bool hasManifest = true;
- for(std::vector<std::string>::iterator i = expandedArgs.begin();
- i != expandedArgs.end(); ++i)
- {
- if(cmSystemTools::Strucmp(i->c_str(), "/INCREMENTAL:YES") == 0)
- {
- hasIncremental = true;
- }
- if(cmSystemTools::Strucmp(i->c_str(), "/INCREMENTAL") == 0)
- {
- hasIncremental = true;
- }
- if(cmSystemTools::Strucmp(i->c_str(), "/MANIFEST:NO") == 0)
- {
- hasManifest = false;
- }
- }
- if(hasIncremental && hasManifest)
- {
- if(verbose)
- {
- std::cout << "Visual Studio Incremental Link with embedded manifests\n";
- }
- return cmcmd::VisualStudioLinkIncremental(expandedArgs, type, verbose);
- }
- if(verbose)
- {
- if(!hasIncremental)
- {
- std::cout << "Visual Studio Non-Incremental Link\n";
- }
- else
- {
- std::cout << "Visual Studio Incremental Link without manifests\n";
- }
- }
- return cmcmd::VisualStudioLinkNonIncremental(expandedArgs,
- type, hasManifest, verbose);
-}
-int cmcmd::ParseVisualStudioLinkCommand(std::vector<std::string>& args,
- std::vector<std::string>& command,
- std::string& targetName)
-{
- std::vector<std::string>::iterator i = args.begin();
- i++; // skip -E
- i++; // skip vs_link_dll or vs_link_exe
- command.push_back(*i);
- i++; // move past link command
- for(; i != args.end(); ++i)
- {
- command.push_back(*i);
- if(i->find("/Fe") == 0)
- {
- targetName = i->substr(3);
- }
- if(i->find("/out:") == 0)
- {
- targetName = i->substr(5);
- }
- }
- if(targetName.empty() || command.empty())
+ cmVSLink vsLink(type, verbose);
+ if (!vsLink.Parse(expandedArgs.begin()+2, expandedArgs.end()))
{
return -1;
}
- return 0;
+ return vsLink.Link();
}
-bool cmcmd::RunCommand(const char* comment,
+static bool RunCommand(const char* comment,
std::vector<std::string>& command,
bool verbose,
- int* retCodeOut)
+ int* retCodeOut = 0)
{
if(verbose)
{
@@ -1503,8 +1468,134 @@ bool cmcmd::RunCommand(const char* comment,
return retCode == 0;
}
-int cmcmd::VisualStudioLinkIncremental(std::vector<std::string>& args,
- int type, bool verbose)
+bool cmVSLink::Parse(std::vector<std::string>::const_iterator argBeg,
+ std::vector<std::string>::const_iterator argEnd)
+{
+ // Parse our own arguments.
+ std::string intDir;
+ std::vector<std::string>::const_iterator arg = argBeg;
+ while (arg != argEnd && cmHasLiteralPrefix(*arg, "-"))
+ {
+ if (*arg == "--")
+ {
+ ++arg;
+ break;
+ }
+ else if (*arg == "--manifests")
+ {
+ for (++arg; arg != argEnd && !cmHasLiteralPrefix(*arg, "-"); ++arg)
+ {
+ this->UserManifests.push_back(*arg);
+ }
+ }
+ else if (cmHasLiteralPrefix(*arg, "--intdir="))
+ {
+ intDir = arg->substr(9);
+ ++arg;
+ }
+ else
+ {
+ std::cerr << "unknown argument '" << *arg << "'\n";
+ return false;
+ }
+ }
+ if (intDir.empty())
+ {
+ return false;
+ }
+
+ // The rest of the arguments form the link command.
+ if (arg == argEnd)
+ {
+ return false;
+ }
+ this->LinkCommand.insert(this->LinkCommand.begin(), arg, argEnd);
+
+ // Parse the link command to extract information we need.
+ for (; arg != argEnd; ++arg)
+ {
+ if (cmSystemTools::Strucmp(arg->c_str(), "/INCREMENTAL:YES") == 0)
+ {
+ this->Incremental = true;
+ }
+ else if (cmSystemTools::Strucmp(arg->c_str(), "/INCREMENTAL") == 0)
+ {
+ this->Incremental = true;
+ }
+ else if (cmSystemTools::Strucmp(arg->c_str(), "/MANIFEST:NO") == 0)
+ {
+ this->LinkGeneratesManifest = false;
+ }
+ else if (cmHasLiteralPrefix(*arg, "/Fe"))
+ {
+ this->TargetFile = arg->substr(3);
+ }
+ else if (cmHasLiteralPrefix(*arg, "/out:"))
+ {
+ this->TargetFile = arg->substr(5);
+ }
+ }
+
+ if (this->TargetFile.empty())
+ {
+ return false;
+ }
+
+ this->ManifestFile = intDir + "/embed.manifest";
+ this->LinkerManifestFile = intDir + "/intermediate.manifest";
+
+ if (this->Incremental)
+ {
+ // We will compile a resource containing the manifest and
+ // pass it to the link command.
+ this->ManifestFileRC = intDir + "/manifest.rc";
+ this->ManifestFileRes = intDir + "/manifest.res";
+ this->LinkCommand.push_back(this->ManifestFileRes);
+ }
+ else if (this->UserManifests.empty())
+ {
+ // Prior to support for user-specified manifests CMake placed the
+ // linker-generated manifest next to the binary (as if it were not to be
+ // embedded) when not linking incrementally. Preserve this behavior.
+ this->ManifestFile = this->TargetFile + ".manifest";
+ this->LinkerManifestFile = this->ManifestFile;
+ }
+
+ if (this->LinkGeneratesManifest)
+ {
+ this->LinkCommand.push_back("/MANIFEST");
+ this->LinkCommand.push_back("/MANIFESTFILE:" + this->LinkerManifestFile);
+ }
+
+ return true;
+}
+
+int cmVSLink::Link()
+{
+ if (this->Incremental &&
+ (this->LinkGeneratesManifest || !this->UserManifests.empty()))
+ {
+ if (this->Verbose)
+ {
+ std::cout << "Visual Studio Incremental Link with embedded manifests\n";
+ }
+ return LinkIncremental();
+ }
+ if (this->Verbose)
+ {
+ if (!this->Incremental)
+ {
+ std::cout << "Visual Studio Non-Incremental Link\n";
+ }
+ else
+ {
+ std::cout << "Visual Studio Incremental Link without manifests\n";
+ }
+ }
+ return LinkNonIncremental();
+}
+
+int cmVSLink::LinkIncremental()
{
// This follows the steps listed here:
// http://blogs.msdn.com/zakramer/archive/2006/05/22/603558.aspx
@@ -1528,161 +1619,118 @@ int cmcmd::VisualStudioLinkIncremental(std::vector<std::string>& args,
// 7. Finally, the Linker does another incremental link, but since the
// only thing that has changed is the *.res file that contains the
// manifest it is a short link.
- std::vector<std::string> linkCommand;
- std::string targetName;
- if(cmcmd::ParseVisualStudioLinkCommand(args, linkCommand, targetName) == -1)
- {
- return -1;
- }
- std::string manifestArg = "/MANIFESTFILE:";
- std::vector<std::string> rcCommand;
- rcCommand.push_back(cmSystemTools::FindProgram("rc.exe"));
- std::vector<std::string> mtCommand;
- mtCommand.push_back(cmSystemTools::FindProgram("mt.exe"));
- std::string tempManifest;
- tempManifest = targetName;
- tempManifest += ".intermediate.manifest";
- std::string resourceInputFile = targetName;
- resourceInputFile += ".resource.txt";
- if(verbose)
+
+ // Create a resource file referencing the manifest.
+ std::string absManifestFile =
+ cmSystemTools::CollapseFullPath(this->ManifestFile);
+ if (this->Verbose)
{
- std::cout << "Create " << resourceInputFile << "\n";
+ std::cout << "Create " << this->ManifestFileRC << "\n";
}
- // Create input file for rc command
- cmsys::ofstream fout(resourceInputFile.c_str());
- if(!fout)
+ {
+ cmsys::ofstream fout(this->ManifestFileRC.c_str());
+ if (!fout)
{
return -1;
}
- std::string manifestFile = targetName;
- manifestFile += ".embed.manifest";
- std::string fullPath= cmSystemTools::CollapseFullPath(manifestFile);
- fout << type << " /* CREATEPROCESS_MANIFEST_RESOURCE_ID "
- "*/ 24 /* RT_MANIFEST */ " << "\"" << fullPath << "\"";
- fout.close();
- manifestArg += tempManifest;
- // add the manifest arg to the linkCommand
- linkCommand.push_back("/MANIFEST");
- linkCommand.push_back(manifestArg);
- // if manifestFile is not yet created, create an
- // empty one
- if(!cmSystemTools::FileExists(manifestFile.c_str()))
+ fout << this->Type << " /* CREATEPROCESS_MANIFEST_RESOURCE_ID */ "
+ "24 /* RT_MANIFEST */ \"" << absManifestFile << "\"";
+ }
+
+ // If we have not previously generated a manifest file,
+ // generate an empty one so the resource compiler succeeds.
+ if (!cmSystemTools::FileExists(this->ManifestFile))
{
- if(verbose)
+ if (this->Verbose)
{
- std::cout << "Create empty: " << manifestFile << "\n";
+ std::cout << "Create empty: " << this->ManifestFile << "\n";
}
- cmsys::ofstream foutTmp(manifestFile.c_str());
+ cmsys::ofstream foutTmp(this->ManifestFile.c_str());
}
- std::string resourceFile = manifestFile;
- resourceFile += ".res";
- // add the resource file to the end of the link command
- linkCommand.push_back(resourceFile);
- std::string outputOpt = "/fo";
- outputOpt += resourceFile;
- rcCommand.push_back(outputOpt);
- rcCommand.push_back(resourceInputFile);
- // Run rc command to create resource
- if(!cmcmd::RunCommand("RC Pass 1", rcCommand, verbose))
- {
- return -1;
- }
- // Now run the link command to link and create manifest
- if(!cmcmd::RunCommand("LINK Pass 1", linkCommand, verbose))
+
+ // Compile the resource file.
+ std::vector<std::string> rcCommand;
+ rcCommand.push_back(cmSystemTools::FindProgram("rc.exe"));
+ rcCommand.push_back("/fo" + this->ManifestFileRes);
+ rcCommand.push_back(this->ManifestFileRC);
+ if (!RunCommand("RC Pass 1", rcCommand, this->Verbose))
{
return -1;
}
- // create mt command
- std::string outArg("/out:");
- outArg+= manifestFile;
- mtCommand.push_back("/nologo");
- mtCommand.push_back(outArg);
- mtCommand.push_back("/notify_update");
- mtCommand.push_back("/manifest");
- mtCommand.push_back(tempManifest);
- // now run mt.exe to create the final manifest file
- int mtRet =0;
- if(!cmcmd::RunCommand("MT", mtCommand, verbose, &mtRet))
+
+ // Run the link command (possibly generates intermediate manifest).
+ if (!RunCommand("LINK Pass 1", this->LinkCommand, this->Verbose))
{
return -1;
}
- // if mt returns 0, then the manifest was not changed and
- // we do not need to do another link step
- if(mtRet == 0)
- {
- return 0;
- }
- // check for magic mt return value if mt returns the magic number
- // 1090650113 then it means that it updated the manifest file and we need
- // to do the final link. If mt has any value other than 0 or 1090650113
- // then there was some problem with the command itself and there was an
- // error so return the error code back out of cmake so make can report it.
- // (when hosted on a posix system the value is 187)
- if(mtRet != 1090650113 && mtRet != 187)
+
+ // Run the manifest tool to create the final manifest.
+ int mtRet = this->RunMT("/out:" + this->ManifestFile, true);
+
+ // If mt returns 1090650113 (or 187 on a posix host) then it updated the
+ // manifest file so we need to embed it again. Otherwise we are done.
+ if (mtRet != 1090650113 && mtRet != 187)
{
return mtRet;
}
- // update the resource file with the new manifest from the mt command.
- if(!cmcmd::RunCommand("RC Pass 2", rcCommand, verbose))
+
+ // Compile the resource file again.
+ if (!RunCommand("RC Pass 2", rcCommand, this->Verbose))
{
return -1;
}
- // Run the final incremental link that will put the new manifest resource
- // into the file incrementally.
- if(!cmcmd::RunCommand("FINAL LINK", linkCommand, verbose))
+
+ // Link incrementally again to use the updated resource.
+ if (!RunCommand("FINAL LINK", this->LinkCommand, this->Verbose))
{
return -1;
}
return 0;
}
-int cmcmd::VisualStudioLinkNonIncremental(std::vector<std::string>& args,
- int type,
- bool hasManifest,
- bool verbose)
+int cmVSLink::LinkNonIncremental()
{
- std::vector<std::string> linkCommand;
- std::string targetName;
- if(cmcmd::ParseVisualStudioLinkCommand(args, linkCommand, targetName) == -1)
- {
- return -1;
- }
- // Run the link command as given
- if (hasManifest)
- {
- linkCommand.push_back("/MANIFEST");
- }
- if(!cmcmd::RunCommand("LINK", linkCommand, verbose))
+ // Run the link command (possibly generates intermediate manifest).
+ if (!RunCommand("LINK", this->LinkCommand, this->Verbose))
{
return -1;
}
- if(!hasManifest)
+
+ // If we have no manifest files we are done.
+ if (!this->LinkGeneratesManifest && this->UserManifests.empty())
{
return 0;
}
+
+ // Run the manifest tool to embed the final manifest in the binary.
+ std::string mtOut =
+ "/outputresource:" + this->TargetFile + (this->Type == 1? ";#1" : ";#2");
+ return this->RunMT(mtOut, false);
+}
+
+int cmVSLink::RunMT(std::string const& out, bool notify)
+{
std::vector<std::string> mtCommand;
mtCommand.push_back(cmSystemTools::FindProgram("mt.exe"));
mtCommand.push_back("/nologo");
mtCommand.push_back("/manifest");
- std::string manifestFile = targetName;
- manifestFile += ".manifest";
- mtCommand.push_back(manifestFile);
- std::string outresource = "/outputresource:";
- outresource += targetName;
- outresource += ";#";
- if(type == 1)
+ if (this->LinkGeneratesManifest)
{
- outresource += "1";
+ mtCommand.push_back(this->LinkerManifestFile);
}
- else if(type == 2)
+ mtCommand.insert(mtCommand.end(),
+ this->UserManifests.begin(), this->UserManifests.end());
+ mtCommand.push_back(out);
+ if (notify)
{
- outresource += "2";
+ // Add an undocumented option that enables a special return
+ // code to notify us when the manifest is modified.
+ mtCommand.push_back("/notify_update");
}
- mtCommand.push_back(outresource);
- // Now use the mt tool to embed the manifest into the exe or dll
- if(!cmcmd::RunCommand("MT", mtCommand, verbose))
+ int mtRet = 0;
+ if (!RunCommand("MT", mtCommand, this->Verbose, &mtRet))
{
return -1;
}
- return 0;
+ return mtRet;
}
diff --git a/Source/cmcmd.h b/Source/cmcmd.h
index 2bfbae7..64b2406 100644
--- a/Source/cmcmd.h
+++ b/Source/cmcmd.h
@@ -35,20 +35,6 @@ protected:
static int WindowsCEEnvironment(const char* version,
const std::string& name);
static int VisualStudioLink(std::vector<std::string>& args, int type);
- static int VisualStudioLinkIncremental(std::vector<std::string>& args,
- int type,
- bool verbose);
- static int VisualStudioLinkNonIncremental(std::vector<std::string>& args,
- int type,
- bool hasManifest,
- bool verbose);
- static int ParseVisualStudioLinkCommand(std::vector<std::string>& args,
- std::vector<std::string>& command,
- std::string& targetName);
- static bool RunCommand(const char* comment,
- std::vector<std::string>& command,
- bool verbose,
- int* retCodeOut = 0);
};
#endif
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 2c6a42c..fff04ce 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -276,6 +276,7 @@ if(BUILD_TESTING)
if(TEST_RESOURCES)
ADD_TEST_MACRO(VSResource VSResource)
endif()
+ ADD_TEST_MACRO(MSManifest MSManifest)
ADD_TEST_MACRO(Simple Simple)
ADD_TEST_MACRO(PreOrder PreOrder)
ADD_TEST_MACRO(MissingSourceFile MissingSourceFile)
diff --git a/Tests/CPackComponentsDEB/CMakeLists.txt b/Tests/CPackComponentsDEB/CMakeLists.txt
index 5c4eeab..5a5d626 100644
--- a/Tests/CPackComponentsDEB/CMakeLists.txt
+++ b/Tests/CPackComponentsDEB/CMakeLists.txt
@@ -80,6 +80,25 @@ set(CPACK_COMPONENT_HEADERS_DESCRIPTION
# depend on the libraries component.
set(CPACK_COMPONENT_HEADERS_DEPENDS libraries)
+# creates preinst/prerm scripts with specific permissions. Those permissions
+# (especially executable) should be in the final archive
+find_program(CHMOD_PROG chmod)
+if(CHMOD_PROG)
+ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/preinst "echo default_preinst")
+ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/prerm "echo default_prerm")
+
+ # Those should have 755 permission normally. We mess it up to see if
+ # CPACK_DEBIAN_APPLICATIONS_PACKAGE_CONTROL_STRICT_PERMISSION is able to fix
+ # it.
+ execute_process(COMMAND ${CHMOD_PROG} 640 ${CMAKE_CURRENT_BINARY_DIR}/preinst)
+ execute_process(COMMAND ${CHMOD_PROG} 640 ${CMAKE_CURRENT_BINARY_DIR}/prerm)
+
+ set(CPACK_DEBIAN_APPLICATIONS_PACKAGE_CONTROL_EXTRA
+ "${CMAKE_CURRENT_BINARY_DIR}/preinst;${CMAKE_CURRENT_BINARY_DIR}/prerm")
+
+ set(CPACK_DEBIAN_APPLICATIONS_PACKAGE_CONTROL_STRICT_PERMISSION TRUE)
+endif()
+
# We may use the CPack specific config file in order
# to tailor CPack behavior on a CPack generator specific way
# (Behavior would be different for RPM or TGZ or DEB ...)
diff --git a/Tests/MSManifest/CMakeLists.txt b/Tests/MSManifest/CMakeLists.txt
new file mode 100644
index 0000000..300cfa6
--- /dev/null
+++ b/Tests/MSManifest/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.3)
+project(MSManifest C)
+
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
+add_subdirectory(Subdir)
diff --git a/Tests/MSManifest/Subdir/CMakeLists.txt b/Tests/MSManifest/Subdir/CMakeLists.txt
new file mode 100644
index 0000000..a47cf00
--- /dev/null
+++ b/Tests/MSManifest/Subdir/CMakeLists.txt
@@ -0,0 +1,9 @@
+configure_file(test.manifest.in test.manifest)
+add_executable(MSManifest main.c ${CMAKE_CURRENT_BINARY_DIR}/test.manifest)
+
+if(MSVC AND NOT MSVC_VERSION LESS 1400)
+ add_custom_command(TARGET MSManifest POST_BUILD VERBATIM
+ COMMAND ${CMAKE_COMMAND} -Dexe=$<TARGET_FILE:MSManifest>
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/check.cmake
+ )
+endif()
diff --git a/Tests/MSManifest/Subdir/check.cmake b/Tests/MSManifest/Subdir/check.cmake
new file mode 100644
index 0000000..b7b6841
--- /dev/null
+++ b/Tests/MSManifest/Subdir/check.cmake
@@ -0,0 +1,6 @@
+file(STRINGS "${exe}" content REGEX "name=\"Kitware.CMake.MSManifestTest\"")
+if(content)
+ message(STATUS "Expected manifest content found:\n ${content}")
+else()
+ message(FATAL_ERROR "Expected manifest content not found in\n ${exe}")
+endif()
diff --git a/Tests/MSManifest/Subdir/main.c b/Tests/MSManifest/Subdir/main.c
new file mode 100644
index 0000000..78f2de1
--- /dev/null
+++ b/Tests/MSManifest/Subdir/main.c
@@ -0,0 +1 @@
+int main(void) { return 0; }
diff --git a/Tests/MSManifest/Subdir/test.manifest.in b/Tests/MSManifest/Subdir/test.manifest.in
new file mode 100644
index 0000000..540961a
--- /dev/null
+++ b/Tests/MSManifest/Subdir/test.manifest.in
@@ -0,0 +1,4 @@
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <assemblyIdentity type="win32" version="1.0.0.0"
+ name="Kitware.CMake.MSManifestTest"/>
+</assembly>
diff --git a/Tests/RunCMake/BuildDepends/C-Exe-Manifest.cmake b/Tests/RunCMake/BuildDepends/C-Exe-Manifest.cmake
new file mode 100644
index 0000000..ef33012
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/C-Exe-Manifest.cmake
@@ -0,0 +1,19 @@
+enable_language(C)
+
+add_executable(main main.c ${CMAKE_CURRENT_BINARY_DIR}/test.manifest)
+
+if(MSVC AND NOT MSVC_VERSION LESS 1400)
+ set(EXTRA_CHECK [[
+file(STRINGS "$<TARGET_FILE:main>" content REGEX "name=\"Kitware.CMake.C-Exe-Manifest-step[0-9]\"")
+if(NOT "${content}" MATCHES "name=\"Kitware.CMake.C-Exe-Manifest-step${check_step}\"")
+ set(RunCMake_TEST_FAILED "Binary has no manifest with name=\"Kitware.CMake.C-Exe-Manifest-step${check_step}\":\n ${content}")
+endif()
+]])
+endif()
+
+file(GENERATE OUTPUT check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT "
+set(check_pairs
+ \"$<TARGET_FILE:main>|${CMAKE_CURRENT_BINARY_DIR}/test.manifest\"
+ )
+${EXTRA_CHECK}
+")
diff --git a/Tests/RunCMake/BuildDepends/C-Exe-Manifest.step1.cmake b/Tests/RunCMake/BuildDepends/C-Exe-Manifest.step1.cmake
new file mode 100644
index 0000000..c0b939d
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/C-Exe-Manifest.step1.cmake
@@ -0,0 +1,6 @@
+file(WRITE "${RunCMake_TEST_BINARY_DIR}/test.manifest" [[
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <assemblyIdentity type="win32" version="1.0.0.0"
+ name="Kitware.CMake.C-Exe-Manifest-step1"/>
+</assembly>
+]])
diff --git a/Tests/RunCMake/BuildDepends/C-Exe-Manifest.step2.cmake b/Tests/RunCMake/BuildDepends/C-Exe-Manifest.step2.cmake
new file mode 100644
index 0000000..a75bf21
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/C-Exe-Manifest.step2.cmake
@@ -0,0 +1,6 @@
+file(WRITE "${RunCMake_TEST_BINARY_DIR}/test.manifest" [[
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <assemblyIdentity type="win32" version="1.0.0.0"
+ name="Kitware.CMake.C-Exe-Manifest-step2"/>
+</assembly>
+]])
diff --git a/Tests/RunCMake/BuildDepends/C-Exe.cmake b/Tests/RunCMake/BuildDepends/C-Exe.cmake
new file mode 100644
index 0000000..5057ca9
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/C-Exe.cmake
@@ -0,0 +1,12 @@
+enable_language(C)
+
+add_executable(main ${CMAKE_CURRENT_BINARY_DIR}/main.c)
+
+file(GENERATE OUTPUT check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT "
+set(check_pairs
+ \"$<TARGET_FILE:main>|${CMAKE_CURRENT_BINARY_DIR}/main.c\"
+ )
+set(check_exes
+ \"$<TARGET_FILE:main>\"
+ )
+")
diff --git a/Tests/RunCMake/BuildDepends/C-Exe.step1.cmake b/Tests/RunCMake/BuildDepends/C-Exe.step1.cmake
new file mode 100644
index 0000000..08e2949
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/C-Exe.step1.cmake
@@ -0,0 +1,3 @@
+file(WRITE "${RunCMake_TEST_BINARY_DIR}/main.c" [[
+int main(void) { return 1; }
+]])
diff --git a/Tests/RunCMake/BuildDepends/C-Exe.step2.cmake b/Tests/RunCMake/BuildDepends/C-Exe.step2.cmake
new file mode 100644
index 0000000..ee4530c
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/C-Exe.step2.cmake
@@ -0,0 +1,3 @@
+file(WRITE "${RunCMake_TEST_BINARY_DIR}/main.c" [[
+int main(void) { return 2; }
+]])
diff --git a/Tests/RunCMake/BuildDepends/CMakeLists.txt b/Tests/RunCMake/BuildDepends/CMakeLists.txt
new file mode 100644
index 0000000..74b3ff8
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.3)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
new file mode 100644
index 0000000..8782ba9
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
@@ -0,0 +1,34 @@
+include(RunCMake)
+
+function(run_BuildDepends CASE)
+ # Use a single build tree for a few tests without cleaning.
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${CASE}-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ if(RunCMake_GENERATOR MATCHES "Make|Ninja")
+ set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
+ endif()
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ include(${RunCMake_SOURCE_DIR}/${CASE}.step1.cmake OPTIONAL)
+ run_cmake(${CASE})
+ set(RunCMake-check-file check.cmake)
+ set(check_step 1)
+ run_cmake_command(${CASE}-build1 ${CMAKE_COMMAND} --build . --config Debug)
+ if(run_BuildDepends_skip_step_2)
+ return()
+ endif()
+ execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 1.125) # handle 1s resolution
+ include(${RunCMake_SOURCE_DIR}/${CASE}.step2.cmake OPTIONAL)
+ set(check_step 2)
+ run_cmake_command(${CASE}-build2 ${CMAKE_COMMAND} --build . --config Debug)
+endfunction()
+
+run_BuildDepends(C-Exe)
+if(NOT RunCMake_GENERATOR MATCHES "Visual Studio [67]|Xcode")
+ if(RunCMake_GENERATOR MATCHES "Visual Studio 10")
+ # VS 10 forgets to re-link when a manifest changes
+ set(run_BuildDepends_skip_step_2 1)
+ endif()
+ run_BuildDepends(C-Exe-Manifest)
+ unset(run_BuildDepends_skip_step_2)
+endif()
diff --git a/Tests/RunCMake/BuildDepends/check.cmake b/Tests/RunCMake/BuildDepends/check.cmake
new file mode 100644
index 0000000..26a9eb6
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/check.cmake
@@ -0,0 +1,37 @@
+if(EXISTS ${RunCMake_TEST_BINARY_DIR}/check-debug.cmake)
+ include(${RunCMake_TEST_BINARY_DIR}/check-debug.cmake)
+ if(RunCMake_TEST_FAILED)
+ return()
+ endif()
+ foreach(exe IN LISTS check_exes)
+ execute_process(COMMAND ${exe} RESULT_VARIABLE res)
+ if(NOT res EQUAL ${check_step})
+ set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}
+ '${exe}' returned '${res}' but expected '${check_step}'
+")
+ endif()
+ endforeach()
+ foreach(p IN LISTS check_pairs)
+ if("${p}" MATCHES "^(.*)\\|(.*)$")
+ set(lhs "${CMAKE_MATCH_1}")
+ set(rhs "${CMAKE_MATCH_2}")
+ if(NOT EXISTS "${lhs}")
+ set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}
+ '${lhs}' missing
+")
+ elseif(NOT EXISTS "${rhs}")
+ set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}
+ '${rhs}' missing
+")
+ elseif(NOT "${lhs}" IS_NEWER_THAN "${rhs}")
+ set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}
+ '${lhs}' is not newer than '${rhs}'
+")
+ endif()
+ endif()
+ endforeach()
+else()
+ set(RunCMake_TEST_FAILED "
+ '${RunCMake_TEST_BINARY_DIR}/check-debug.cmake' missing
+")
+endif()
diff --git a/Tests/RunCMake/BuildDepends/main.c b/Tests/RunCMake/BuildDepends/main.c
new file mode 100644
index 0000000..78f2de1
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/main.c
@@ -0,0 +1 @@
+int main(void) { return 0; }
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 241cf90..a8f9386 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -124,6 +124,7 @@ if(NOT CMake_TEST_EXTERNAL_CMAKE)
)
endif()
+add_RunCMake_test(BuildDepends)
if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Unix Makefiles|Ninja")
add_RunCMake_test(CompilerChange)
endif()
diff --git a/Tests/RunCMake/CPack/DEB/DEB_EXTRA-VerifyResult.cmake b/Tests/RunCMake/CPack/DEB/DEB_EXTRA-VerifyResult.cmake
index 78b6114..5f929ff 100644
--- a/Tests/RunCMake/CPack/DEB/DEB_EXTRA-VerifyResult.cmake
+++ b/Tests/RunCMake/CPack/DEB/DEB_EXTRA-VerifyResult.cmake
@@ -1,11 +1,17 @@
set(foo_preinst "^echo default_preinst$")
+set(foo_preinst_permissions_regex "-rwxr-xr-x .*")
set(foo_prerm "^echo default_prerm$")
+set(foo_prerm_permissions_regex "-rwxr-xr-x .*")
verifyDebControl("${FOUND_FILE_1}" "foo" "preinst;prerm")
set(bar_preinst "^echo bar_preinst$")
+set(bar_prerm_permissions_regex "-rwx------ .*")
set(bar_prerm "^echo bar_prerm$")
+set(bar_prerm_permissions_regex "-rwx------ .*")
verifyDebControl("${FOUND_FILE_2}" "bar" "preinst;prerm")
set(bas_preinst "^echo default_preinst$")
+set(bas_prerm_permissions_regex "-rwxr-xr-x .*")
set(bas_prerm "^echo default_prerm$")
+set(bas_prerm_permissions_regex "-rwxr-xr-x .*")
verifyDebControl("${FOUND_FILE_3}" "bas" "preinst;prerm")
diff --git a/Tests/RunCMake/CPack/DEB/Helpers.cmake b/Tests/RunCMake/CPack/DEB/Helpers.cmake
index a204a3c..f490130 100644
--- a/Tests/RunCMake/CPack/DEB/Helpers.cmake
+++ b/Tests/RunCMake/CPack/DEB/Helpers.cmake
@@ -14,7 +14,7 @@ function(verifyDebControl FILE PREFIX VERIFY_FILES)
ERROR_VARIABLE err_)
if(err_)
- message(FATAL_ERROR "Debian controll verification failed for file: "
+ message(FATAL_ERROR "Debian control verification failed for file: "
"'${FILE}'; error output: '${err_}'")
endif()
@@ -24,6 +24,19 @@ function(verifyDebControl FILE PREFIX VERIFY_FILES)
message(FATAL_ERROR "Unexpected content in for '${PREFIX}_${FILE_}'!"
" Content: '${content_}'")
endif()
+
+ execute_process(COMMAND ls -l "${CMAKE_CURRENT_BINARY_DIR}/control_${PREFIX}/${FILE_}"
+ OUTPUT_VARIABLE package_permissions_
+ ERROR_VARIABLE package_permissions_error_
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ if(NOT package_permissions_error_)
+ if(NOT package_permissions_ MATCHES "${${PREFIX}_${FILE_}_permissions_regex}")
+ message(FATAL_ERROR "Unexpected file permissions for ${PREFIX}_${FILE_}: '${package_permissions_}'!")
+ endif()
+ else()
+ message(FATAL_ERROR "Listing file permissions failed (${package_permissions_error_})!")
+ endif()
endforeach()
endfunction()
diff --git a/Tests/RunCMake/CPack/DEB_EXTRA.cmake b/Tests/RunCMake/CPack/DEB_EXTRA.cmake
index 46d848d..3c291d5 100644
--- a/Tests/RunCMake/CPack/DEB_EXTRA.cmake
+++ b/Tests/RunCMake/CPack/DEB_EXTRA.cmake
@@ -2,14 +2,32 @@ install(FILES CMakeLists.txt DESTINATION foo COMPONENT foo)
install(FILES CMakeLists.txt DESTINATION bar COMPONENT bar)
install(FILES CMakeLists.txt DESTINATION bas COMPONENT bas)
-file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/preinst "echo default_preinst")
-file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/prerm "echo default_prerm")
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/tmp/preinst "echo default_preinst")
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/tmp/prerm "echo default_prerm")
+
+foreach(file_ preinst prerm)
+ file(COPY ${CMAKE_CURRENT_BINARY_DIR}/tmp/${file_}
+ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
+ FILE_PERMISSIONS
+ OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_READ GROUP_EXECUTE
+ WORLD_READ WORLD_EXECUTE)
+endforeach()
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
- "${CMAKE_CURRENT_BINARY_DIR}/preinst;${CMAKE_CURRENT_BINARY_DIR}/prerm")
+ "${CMAKE_CURRENT_BINARY_DIR}/preinst;${CMAKE_CURRENT_BINARY_DIR}/prerm;${CMAKE_CURRENT_BINARY_DIR}/conffiles")
+
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/bar_tmp/preinst "echo bar_preinst")
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/bar_tmp/prerm "echo bar_prerm")
-file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/bar/preinst "echo bar_preinst")
-file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/bar/prerm "echo bar_prerm")
+foreach(file_ preinst prerm)
+ # not acceptable permissions for lintian but we need to check that
+ # permissions are preserved
+ file(COPY ${CMAKE_CURRENT_BINARY_DIR}/bar_tmp/${file_}
+ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/bar
+ FILE_PERMISSIONS
+ OWNER_READ OWNER_WRITE OWNER_EXECUTE)
+endforeach()
set(CPACK_DEBIAN_BAR_PACKAGE_CONTROL_EXTRA
"${CMAKE_CURRENT_BINARY_DIR}/bar/preinst;${CMAKE_CURRENT_BINARY_DIR}/bar/prerm")
diff --git a/Tests/RunCMake/CPack/README.txt b/Tests/RunCMake/CPack/README.txt
index 365c737..ea68304 100644
--- a/Tests/RunCMake/CPack/README.txt
+++ b/Tests/RunCMake/CPack/README.txt
@@ -32,14 +32,14 @@ different types of packages. This script is placed into CPack test root
directory even if it will be used for only one of the generators.
If test will be used for multiple generators but some of them require some
-generator speciffic commands then those commands should be added to a separate
+generator specific commands then those commands should be added to a separate
file that should be located in '<generator_name>/<test_name>-specifics.cmake'
in CPack test root directory.
CPack execution phase:
----------------------
-Only exececutes CPack for content that was generated during CMake execution
+Only executes CPack for content that was generated during CMake execution
phase.
Verification of generated files:
diff --git a/Tests/RunCMake/CPack/VerifyResult.cmake b/Tests/RunCMake/CPack/VerifyResult.cmake
index 96efa9e..6eab531 100644
--- a/Tests/RunCMake/CPack/VerifyResult.cmake
+++ b/Tests/RunCMake/CPack/VerifyResult.cmake
@@ -28,8 +28,9 @@ if(NOT EXPECTED_FILES_COUNT EQUAL 0)
if(NOT expected_content_list)
message(FATAL_ERROR
- "Unexpected file content for file No. '${file_no_}'!"
- " Content: '${PACKAGE_CONTENT}'"
+ "Unexpected file content for file No. '${file_no_}'!\n"
+ " Content: '${PACKAGE_CONTENT}'\n\n"
+ " Expected: '${EXPECTED_FILE_CONTENT_${file_no_}}'"
"${output_error_message}")
endif()
else()
@@ -56,7 +57,7 @@ if(NOT EXPECTED_FILES_COUNT EQUAL 0)
"${output_error_message}")
endif()
- # sanity check that we didn't accidentaly list wrong files with our regular
+ # sanity check that we didn't accidentally list wrong files with our regular
# expressions
foreach(expected_ IN LISTS allFoundFiles_)
list(FIND foundFiles_ "${expected_}" found_)
diff --git a/Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake b/Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake
index c1b2227..8dc627d 100644
--- a/Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CompileFeatures/RunCMakeTest.cmake
@@ -29,7 +29,7 @@ if (NOT CXX_FEATURES)
run_cmake(NoSupportedCxxFeatures)
run_cmake(NoSupportedCxxFeaturesGenex)
else()
- if(CXX_STANDARD_DEFAULT)
+ if(CXX_STANDARD_DEFAULT EQUAL 98)
run_cmake(LinkImplementationFeatureCycle)
endif()
run_cmake(LinkImplementationFeatureCycleSolved)
diff --git a/Tests/RunCMake/RunCMake.cmake b/Tests/RunCMake/RunCMake.cmake
index 46bc494..db9911d 100644
--- a/Tests/RunCMake/RunCMake.cmake
+++ b/Tests/RunCMake/RunCMake.cmake
@@ -102,7 +102,7 @@ function(run_cmake test)
endif()
foreach(o out err)
string(REGEX REPLACE "\r\n" "\n" actual_std${o} "${actual_std${o}}")
- string(REGEX REPLACE "(^|\n)((==[0-9]+==|BullseyeCoverage|[a-z]+\\([0-9]+\\) malloc:|Error kstat returned)[^\n]*\n)+" "\\1" actual_std${o} "${actual_std${o}}")
+ string(REGEX REPLACE "(^|\n)((==[0-9]+==|BullseyeCoverage|[a-z]+\\([0-9]+\\) malloc:|Error kstat returned|[^\n]*from Time Machine by path|[^\n]*Bullseye Testing Technology)[^\n]*\n)+" "\\1" actual_std${o} "${actual_std${o}}")
string(REGEX REPLACE "\n+$" "" actual_std${o} "${actual_std${o}}")
set(expect_${o} "")
if(DEFINED expect_std${o})
@@ -115,7 +115,11 @@ function(run_cmake test)
endif()
endforeach()
unset(RunCMake_TEST_FAILED)
- include(${top_src}/${test}-check.cmake OPTIONAL)
+ if(RunCMake-check-file AND EXISTS ${top_src}/${RunCMake-check-file})
+ include(${top_src}/${RunCMake-check-file})
+ else()
+ include(${top_src}/${test}-check.cmake OPTIONAL)
+ endif()
if(RunCMake_TEST_FAILED)
set(msg "${RunCMake_TEST_FAILED}\n${msg}")
endif()