summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeCPack.cmake345
-rw-r--r--CMakeLists.txt83
-rw-r--r--Help/manual/cmake-properties.7.rst1
-rw-r--r--Help/manual/cmake-variables.7.rst1
-rw-r--r--Help/prop_tgt/BUILD_RPATH.rst10
-rw-r--r--Help/release/3.7.rst2
-rw-r--r--Help/release/dev/0-sample-topic.rst7
-rw-r--r--Help/release/dev/add-BUILD_RPATH.rst6
-rw-r--r--Help/release/dev/cpack-rpm-single-debuginfo.rst11
-rw-r--r--Help/release/index.rst2
-rw-r--r--Help/variable/CMAKE_BUILD_RPATH.rst10
-rw-r--r--Modules/CPackRPM.cmake322
-rw-r--r--Modules/FindIce.cmake1
-rw-r--r--Modules/FindProtobuf.cmake2
-rw-r--r--Modules/FindSDL.cmake7
-rw-r--r--Modules/Platform/Darwin.cmake2
-rw-r--r--Source/CMakeLists.txt8
-rw-r--r--Source/CMakeVersion.cmake4
-rw-r--r--Source/CPack/cmCPackGenerator.h10
-rw-r--r--Source/CPack/cmCPackLog.cxx2
-rw-r--r--Source/CPack/cmCPackLog.h10
-rw-r--r--Source/CPack/cmCPackRPMGenerator.cxx245
-rw-r--r--Source/CPack/cpack.cxx2
-rw-r--r--Source/CTest/cmCTestMemCheckHandler.cxx4
-rw-r--r--Source/cmCPluginAPI.cxx44
-rw-r--r--Source/cmCTest.cxx7
-rw-r--r--Source/cmCommonTargetGenerator.cxx10
-rw-r--r--Source/cmCommonTargetGenerator.h4
-rw-r--r--Source/cmComputeLinkInformation.cxx6
-rw-r--r--Source/cmConvertMSBuildXMLToJSON.py453
-rw-r--r--Source/cmDependsFortran.cxx45
-rw-r--r--Source/cmDependsFortran.h3
-rw-r--r--Source/cmELF.cxx224
-rw-r--r--Source/cmELF.h23
-rw-r--r--Source/cmGeneratedFileStream.cxx19
-rw-r--r--Source/cmGeneratedFileStream.h7
-rw-r--r--Source/cmGeneratorTarget.cxx3
-rw-r--r--Source/cmGhsMultiTargetGenerator.cxx13
-rw-r--r--Source/cmGlobalGenerator.cxx14
-rw-r--r--Source/cmGlobalGenerator.h15
-rw-r--r--Source/cmGlobalNMakeMakefileGenerator.h6
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx15
-rw-r--r--Source/cmGlobalNinjaGenerator.h8
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx9
-rw-r--r--Source/cmGlobalVisualStudio15Generator.cxx2
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx6
-rw-r--r--Source/cmLinkLibrariesCommand.cxx7
-rw-r--r--Source/cmLinkLineComputer.cxx179
-rw-r--r--Source/cmLinkLineComputer.h50
-rw-r--r--Source/cmLocalGenerator.cxx210
-rw-r--r--Source/cmLocalGenerator.h22
-rw-r--r--Source/cmLocalNinjaGenerator.cxx16
-rw-r--r--Source/cmLocalNinjaGenerator.h4
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx53
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.h3
-rw-r--r--Source/cmMSVC60LinkLineComputer.cxx36
-rw-r--r--Source/cmMSVC60LinkLineComputer.h19
-rw-r--r--Source/cmMakefile.cxx153
-rw-r--r--Source/cmMakefile.h18
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx49
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx73
-rw-r--r--Source/cmMakefileTargetGenerator.cxx165
-rw-r--r--Source/cmMakefileTargetGenerator.h13
-rw-r--r--Source/cmMakefileUtilityTargetGenerator.cxx2
-rw-r--r--Source/cmNinjaLinkLineComputer.cxx19
-rw-r--r--Source/cmNinjaLinkLineComputer.h26
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx15
-rw-r--r--Source/cmOutputConverter.cxx100
-rw-r--r--Source/cmOutputConverter.h36
-rw-r--r--Source/cmServerProtocol.cxx7
-rw-r--r--Source/cmSystemTools.cxx72
-rw-r--r--Source/cmTarget.cxx25
-rw-r--r--Source/cmTarget.h8
-rw-r--r--Source/cmTargetLinkLibrariesCommand.cxx30
-rw-r--r--Source/cm_codecvt.cxx215
-rw-r--r--Source/cm_codecvt.hxx57
-rw-r--r--Source/cmake.cxx115
-rw-r--r--Source/cmake.h2
-rw-r--r--Source/ctest.cxx4
-rw-r--r--Tests/FindPackageModeMakefileTest/CMakeLists.txt13
-rw-r--r--Tests/MacRuntimePath/A/CMakeLists.txt15
-rw-r--r--Tests/RunCMake/CPack/MAIN_COMPONENT.cmake14
-rw-r--r--Tests/RunCMake/CPack/RPM/MAIN_COMPONENT-ExpectedFiles.cmake13
-rw-r--r--Tests/RunCMake/CPack/RPM/MAIN_COMPONENT-found-stderr.txt3
-rw-r--r--Tests/RunCMake/CPack/RPM/MAIN_COMPONENT-invalid-stderr.txt1
-rw-r--r--Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-ExpectedFiles.cmake30
-rw-r--r--Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-no_components-stderr.txt1
-rw-r--r--Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-no_debuginfo-stderr.txt3
-rw-r--r--Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-no_main_component-stderr.txt1
-rw-r--r--Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-one_component-stderr.txt1
-rw-r--r--Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-one_component_main-stderr.txt1
-rw-r--r--Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-one_component_no_debuginfo-stderr.txt1
-rw-r--r--Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-valid-stderr.txt3
-rw-r--r--Tests/RunCMake/CPack/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/CPack/SINGLE_DEBUGINFO.cmake56
-rw-r--r--Tests/RunCMake/CPack/VerifyResult.cmake6
-rw-r--r--Utilities/GitSetup/config2
-rw-r--r--Utilities/Release/README2
-rw-r--r--Utilities/Release/linux64_release.cmake1
-rw-r--r--Utilities/Release/osx_release.cmake2
-rwxr-xr-xbootstrap2
101 files changed, 2780 insertions, 1229 deletions
diff --git a/CMakeCPack.cmake b/CMakeCPack.cmake
index 1889be2..fc042bc 100644
--- a/CMakeCPack.cmake
+++ b/CMakeCPack.cmake
@@ -1,205 +1,200 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
-# If the cmake version includes cpack, use it
-if(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
- if(EXISTS "${CMAKE_ROOT}/Modules/InstallRequiredSystemLibraries.cmake")
- option(CMAKE_INSTALL_DEBUG_LIBRARIES
- "Install Microsoft runtime debug libraries with CMake." FALSE)
- mark_as_advanced(CMAKE_INSTALL_DEBUG_LIBRARIES)
-
- # By default, do not warn when built on machines using only VS Express:
- if(NOT DEFINED CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS)
- set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS ON)
- endif()
+option(CMAKE_INSTALL_DEBUG_LIBRARIES
+ "Install Microsoft runtime debug libraries with CMake." FALSE)
+mark_as_advanced(CMAKE_INSTALL_DEBUG_LIBRARIES)
- if(CMake_INSTALL_DEPENDENCIES)
- include(${CMake_SOURCE_DIR}/Modules/InstallRequiredSystemLibraries.cmake)
- endif()
- endif()
+# By default, do not warn when built on machines using only VS Express:
+if(NOT DEFINED CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS)
+ set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS ON)
+endif()
- set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "CMake is a build tool")
- set(CPACK_PACKAGE_VENDOR "Kitware")
- set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/Copyright.txt")
- set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/Copyright.txt")
- set(CPACK_PACKAGE_NAME "${CMAKE_PROJECT_NAME}")
- set(CPACK_PACKAGE_VERSION "${CMake_VERSION}")
- set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}")
- set(CPACK_SOURCE_PACKAGE_FILE_NAME "cmake-${CMake_VERSION}")
+if(CMake_INSTALL_DEPENDENCIES)
+ include(${CMake_SOURCE_DIR}/Modules/InstallRequiredSystemLibraries.cmake)
+endif()
- # Installers for 32- vs. 64-bit CMake:
- # - Root install directory (displayed to end user at installer-run time)
- # - "NSIS package/display name" (text used in the installer GUI)
- # - Registry key used to store info about the installation
- if(CMAKE_CL_64)
- set(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES64")
- set(CPACK_NSIS_PACKAGE_NAME "${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_VERSION} (Win64)")
+set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "CMake is a build tool")
+set(CPACK_PACKAGE_VENDOR "Kitware")
+set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/Copyright.txt")
+set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/Copyright.txt")
+set(CPACK_PACKAGE_NAME "${CMAKE_PROJECT_NAME}")
+set(CPACK_PACKAGE_VERSION "${CMake_VERSION}")
+set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}")
+set(CPACK_SOURCE_PACKAGE_FILE_NAME "cmake-${CMake_VERSION}")
+
+# Installers for 32- vs. 64-bit CMake:
+# - Root install directory (displayed to end user at installer-run time)
+# - "NSIS package/display name" (text used in the installer GUI)
+# - Registry key used to store info about the installation
+if(CMAKE_CL_64)
+ set(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES64")
+ set(CPACK_NSIS_PACKAGE_NAME "${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_VERSION} (Win64)")
+else()
+ set(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES")
+ set(CPACK_NSIS_PACKAGE_NAME "${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_VERSION}")
+endif()
+set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "${CPACK_NSIS_PACKAGE_NAME}")
+
+if(NOT DEFINED CPACK_SYSTEM_NAME)
+ # make sure package is not Cygwin-unknown, for Cygwin just
+ # cygwin is good for the system name
+ if("x${CMAKE_SYSTEM_NAME}" STREQUAL "xCYGWIN")
+ set(CPACK_SYSTEM_NAME Cygwin)
else()
- set(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES")
- set(CPACK_NSIS_PACKAGE_NAME "${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_VERSION}")
- endif()
- set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "${CPACK_NSIS_PACKAGE_NAME}")
-
- if(NOT DEFINED CPACK_SYSTEM_NAME)
- # make sure package is not Cygwin-unknown, for Cygwin just
- # cygwin is good for the system name
- if("x${CMAKE_SYSTEM_NAME}" STREQUAL "xCYGWIN")
- set(CPACK_SYSTEM_NAME Cygwin)
- else()
- set(CPACK_SYSTEM_NAME ${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR})
- endif()
+ set(CPACK_SYSTEM_NAME ${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR})
endif()
- if(${CPACK_SYSTEM_NAME} MATCHES Windows)
- if(CMAKE_CL_64)
- set(CPACK_SYSTEM_NAME win64-x64)
- set(CPACK_IFW_TARGET_DIRECTORY "@RootDir@/Program Files/${CMAKE_PROJECT_NAME}")
- else()
- set(CPACK_SYSTEM_NAME win32-x86)
- endif()
+endif()
+if(${CPACK_SYSTEM_NAME} MATCHES Windows)
+ if(CMAKE_CL_64)
+ set(CPACK_SYSTEM_NAME win64-x64)
+ set(CPACK_IFW_TARGET_DIRECTORY "@RootDir@/Program Files/${CMAKE_PROJECT_NAME}")
+ else()
+ set(CPACK_SYSTEM_NAME win32-x86)
endif()
+endif()
- # Components
- if(CMake_INSTALL_COMPONENTS)
- set(_CPACK_IFW_COMPONENTS_ALL cmake ctest cpack)
- if(WIN32 AND NOT CYGWIN)
- list(APPEND _CPACK_IFW_COMPONENTS_ALL cmcldeps)
- endif()
- if(APPLE)
- list(APPEND _CPACK_IFW_COMPONENTS_ALL cmakexbuild)
- endif()
- if(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME)
- set(_CPACK_IFW_COMPONENT_UNSPECIFIED_NAME
- ${CMAKE_INSTALL_DEFAULT_COMPONENT_NAME})
- else()
- set(_CPACK_IFW_COMPONENT_UNSPECIFIED_NAME Unspecified)
- endif()
- list(APPEND _CPACK_IFW_COMPONENTS_ALL ${_CPACK_IFW_COMPONENT_UNSPECIFIED_NAME})
- string(TOUPPER "${_CPACK_IFW_COMPONENT_UNSPECIFIED_NAME}"
- _CPACK_IFW_COMPONENT_UNSPECIFIED_UNAME)
- if(BUILD_CursesDialog)
- list(APPEND _CPACK_IFW_COMPONENTS_ALL ccmake)
- endif()
- if(BUILD_QtDialog)
- list(APPEND _CPACK_IFW_COMPONENTS_ALL cmake-gui)
- if(USE_LGPL)
- set(_CPACK_IFW_COMPONENT_CMAKE-GUI_LICENSES "set(CPACK_IFW_COMPONENT_CMAKE-GUI_LICENSES
- \"LGPLv${USE_LGPL}\" \"${CMake_SOURCE_DIR}/Licenses/LGPLv${USE_LGPL}.txt\")")
- endif()
- endif()
- if(SPHINX_MAN)
- list(APPEND _CPACK_IFW_COMPONENTS_ALL sphinx-man)
- endif()
- if(SPHINX_HTML)
- list(APPEND _CPACK_IFW_COMPONENTS_ALL sphinx-html)
- endif()
- if(SPHINX_SINGLEHTML)
- list(APPEND _CPACK_IFW_COMPONENTS_ALL sphinx-singlehtml)
+# Components
+if(CMake_INSTALL_COMPONENTS)
+ set(_CPACK_IFW_COMPONENTS_ALL cmake ctest cpack)
+ if(WIN32 AND NOT CYGWIN)
+ list(APPEND _CPACK_IFW_COMPONENTS_ALL cmcldeps)
+ endif()
+ if(APPLE)
+ list(APPEND _CPACK_IFW_COMPONENTS_ALL cmakexbuild)
+ endif()
+ if(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME)
+ set(_CPACK_IFW_COMPONENT_UNSPECIFIED_NAME
+ ${CMAKE_INSTALL_DEFAULT_COMPONENT_NAME})
+ else()
+ set(_CPACK_IFW_COMPONENT_UNSPECIFIED_NAME Unspecified)
+ endif()
+ list(APPEND _CPACK_IFW_COMPONENTS_ALL ${_CPACK_IFW_COMPONENT_UNSPECIFIED_NAME})
+ string(TOUPPER "${_CPACK_IFW_COMPONENT_UNSPECIFIED_NAME}"
+ _CPACK_IFW_COMPONENT_UNSPECIFIED_UNAME)
+ if(BUILD_CursesDialog)
+ list(APPEND _CPACK_IFW_COMPONENTS_ALL ccmake)
+ endif()
+ if(BUILD_QtDialog)
+ list(APPEND _CPACK_IFW_COMPONENTS_ALL cmake-gui)
+ if(USE_LGPL)
+ set(_CPACK_IFW_COMPONENT_CMAKE-GUI_LICENSES "set(CPACK_IFW_COMPONENT_CMAKE-GUI_LICENSES
+ \"LGPLv${USE_LGPL}\" \"${CMake_SOURCE_DIR}/Licenses/LGPLv${USE_LGPL}.txt\")")
endif()
- if(SPHINX_QTHELP)
- list(APPEND _CPACK_IFW_COMPONENTS_ALL sphinx-qthelp)
+ endif()
+ if(SPHINX_MAN)
+ list(APPEND _CPACK_IFW_COMPONENTS_ALL sphinx-man)
+ endif()
+ if(SPHINX_HTML)
+ list(APPEND _CPACK_IFW_COMPONENTS_ALL sphinx-html)
+ endif()
+ if(SPHINX_SINGLEHTML)
+ list(APPEND _CPACK_IFW_COMPONENTS_ALL sphinx-singlehtml)
+ endif()
+ if(SPHINX_QTHELP)
+ list(APPEND _CPACK_IFW_COMPONENTS_ALL sphinx-qthelp)
+ endif()
+ if(CMake_BUILD_DEVELOPER_REFERENCE)
+ if(CMake_BUILD_DEVELOPER_REFERENCE_HTML)
+ list(APPEND _CPACK_IFW_COMPONENTS_ALL cmake-developer-reference-html)
endif()
- if(CMake_BUILD_DEVELOPER_REFERENCE)
- if(CMake_BUILD_DEVELOPER_REFERENCE_HTML)
- list(APPEND _CPACK_IFW_COMPONENTS_ALL cmake-developer-reference-html)
- endif()
- if(CMake_BUILD_DEVELOPER_REFERENCE_QTHELP)
- list(APPEND _CPACK_IFW_COMPONENTS_ALL cmake-developer-reference-qthelp)
- endif()
+ if(CMake_BUILD_DEVELOPER_REFERENCE_QTHELP)
+ list(APPEND _CPACK_IFW_COMPONENTS_ALL cmake-developer-reference-qthelp)
endif()
- set(_CPACK_IFW_COMPONENTS_CONFIGURATION "
- # Components
- set(CPACK_COMPONENTS_ALL \"${_CPACK_IFW_COMPONENTS_ALL}\")
- set(CPACK_COMPONENTS_GROUPING IGNORE)
+ endif()
+ set(_CPACK_IFW_COMPONENTS_CONFIGURATION "
+# Components
+set(CPACK_COMPONENTS_ALL \"${_CPACK_IFW_COMPONENTS_ALL}\")
+set(CPACK_COMPONENTS_GROUPING IGNORE)
")
- else()
- if(BUILD_QtDialog AND USE_LGPL)
- set(_CPACK_IFW_ADDITIONAL_LICENSES
- "\"LGPLv${USE_LGPL}\" \"${CMake_SOURCE_DIR}/Licenses/LGPLv${USE_LGPL}.txt\"")
- endif()
+else()
+ if(BUILD_QtDialog AND USE_LGPL)
+ set(_CPACK_IFW_ADDITIONAL_LICENSES
+ "\"LGPLv${USE_LGPL}\" \"${CMake_SOURCE_DIR}/Licenses/LGPLv${USE_LGPL}.txt\"")
endif()
+endif()
- # Components scripts configuration
- foreach(_script
- CMake
- CMake.Documentation.SphinxHTML
- CMake.DeveloperReference.HTML)
- configure_file("${CMake_SOURCE_DIR}/Source/QtIFW/${_script}.qs.in"
- "${CMake_BINARY_DIR}/${_script}.qs" @ONLY)
- endforeach()
-
- if(${CMAKE_SYSTEM_NAME} MATCHES Windows)
- set(_CPACK_IFW_PACKAGE_ICON
- "set(CPACK_IFW_PACKAGE_ICON \"${CMake_SOURCE_DIR}/Source/QtDialog/CMakeSetup.ico\")")
- if(BUILD_QtDialog)
- set(_CPACK_IFW_SHORTCUT_OPTIONAL "${_CPACK_IFW_SHORTCUT_OPTIONAL}component.addOperation(\"CreateShortcut\", \"@TargetDir@/bin/cmake-gui.exe\", \"@StartMenuDir@/CMake (cmake-gui).lnk\");\n")
- endif()
- if(SPHINX_HTML)
- set(_CPACK_IFW_SHORTCUT_OPTIONAL "${_CPACK_IFW_SHORTCUT_OPTIONAL}component.addOperation(\"CreateShortcut\", \"@TargetDir@/doc/cmake-${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}/html/index.html\", \"@StartMenuDir@/CMake Documentation.lnk\");\n")
- endif()
- if(CMake_BUILD_DEVELOPER_REFERENCE)
- if(CMake_BUILD_DEVELOPER_REFERENCE_HTML)
- set(_CPACK_IFW_SHORTCUT_OPTIONAL "${_CPACK_IFW_SHORTCUT_OPTIONAL}component.addOperation(\"CreateShortcut\", \"@TargetDir@/doc/cmake-${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}/developer-reference/html/index.html\", \"@StartMenuDir@/CMake Developer Reference.lnk\");\n")
- endif()
- endif()
- configure_file("${CMake_SOURCE_DIR}/Source/QtIFW/installscript.qs.in"
- "${CMake_BINARY_DIR}/installscript.qs" @ONLY
- )
- install(FILES "${CMake_SOURCE_DIR}/Source/QtIFW/cmake.org.html"
- DESTINATION "${CMAKE_DOC_DIR}"
- )
- if(CMake_INSTALL_COMPONENTS)
- set(_CPACK_IFW_PACKAGE_SCRIPT "${CMake_BINARY_DIR}/CMake.qs")
- else()
- set(_CPACK_IFW_PACKAGE_SCRIPT "${CMake_BINARY_DIR}/installscript.qs")
+# Components scripts configuration
+foreach(_script
+ CMake
+ CMake.Documentation.SphinxHTML
+ CMake.DeveloperReference.HTML)
+ configure_file("${CMake_SOURCE_DIR}/Source/QtIFW/${_script}.qs.in"
+ "${CMake_BINARY_DIR}/${_script}.qs" @ONLY)
+endforeach()
+
+if(${CMAKE_SYSTEM_NAME} MATCHES Windows)
+ set(_CPACK_IFW_PACKAGE_ICON
+ "set(CPACK_IFW_PACKAGE_ICON \"${CMake_SOURCE_DIR}/Source/QtDialog/CMakeSetup.ico\")")
+ if(BUILD_QtDialog)
+ set(_CPACK_IFW_SHORTCUT_OPTIONAL "${_CPACK_IFW_SHORTCUT_OPTIONAL}component.addOperation(\"CreateShortcut\", \"@TargetDir@/bin/cmake-gui.exe\", \"@StartMenuDir@/CMake (cmake-gui).lnk\");\n")
+ endif()
+ if(SPHINX_HTML)
+ set(_CPACK_IFW_SHORTCUT_OPTIONAL "${_CPACK_IFW_SHORTCUT_OPTIONAL}component.addOperation(\"CreateShortcut\", \"@TargetDir@/doc/cmake-${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}/html/index.html\", \"@StartMenuDir@/CMake Documentation.lnk\");\n")
+ endif()
+ if(CMake_BUILD_DEVELOPER_REFERENCE)
+ if(CMake_BUILD_DEVELOPER_REFERENCE_HTML)
+ set(_CPACK_IFW_SHORTCUT_OPTIONAL "${_CPACK_IFW_SHORTCUT_OPTIONAL}component.addOperation(\"CreateShortcut\", \"@TargetDir@/doc/cmake-${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}/developer-reference/html/index.html\", \"@StartMenuDir@/CMake Developer Reference.lnk\");\n")
endif()
endif()
-
- if(${CMAKE_SYSTEM_NAME} MATCHES Linux)
- set(CPACK_IFW_TARGET_DIRECTORY "@HomeDir@/${CMAKE_PROJECT_NAME}")
- set(CPACK_IFW_ADMIN_TARGET_DIRECTORY "@ApplicationsDir@/${CMAKE_PROJECT_NAME}")
+ configure_file("${CMake_SOURCE_DIR}/Source/QtIFW/installscript.qs.in"
+ "${CMake_BINARY_DIR}/installscript.qs" @ONLY
+ )
+ install(FILES "${CMake_SOURCE_DIR}/Source/QtIFW/cmake.org.html"
+ DESTINATION "${CMAKE_DOC_DIR}"
+ )
+ if(CMake_INSTALL_COMPONENTS)
+ set(_CPACK_IFW_PACKAGE_SCRIPT "${CMake_BINARY_DIR}/CMake.qs")
+ else()
+ set(_CPACK_IFW_PACKAGE_SCRIPT "${CMake_BINARY_DIR}/installscript.qs")
endif()
+endif()
- set(_CPACK_IFW_PACKAGE_VERSION ${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}.${CMake_VERSION_PATCH})
+if(${CMAKE_SYSTEM_NAME} MATCHES Linux)
+ set(CPACK_IFW_TARGET_DIRECTORY "@HomeDir@/${CMAKE_PROJECT_NAME}")
+ set(CPACK_IFW_ADMIN_TARGET_DIRECTORY "@ApplicationsDir@/${CMAKE_PROJECT_NAME}")
+endif()
- if(NOT DEFINED CPACK_PACKAGE_FILE_NAME)
- # if the CPACK_PACKAGE_FILE_NAME is not defined by the cache
- # default to source package - system, on cygwin system is not
- # needed
- if(CYGWIN)
- set(CPACK_PACKAGE_FILE_NAME "${CPACK_SOURCE_PACKAGE_FILE_NAME}")
- else()
- set(CPACK_PACKAGE_FILE_NAME
- "${CPACK_SOURCE_PACKAGE_FILE_NAME}-${CPACK_SYSTEM_NAME}")
- endif()
+set(_CPACK_IFW_PACKAGE_VERSION ${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}.${CMake_VERSION_PATCH})
+
+if(NOT DEFINED CPACK_PACKAGE_FILE_NAME)
+ # if the CPACK_PACKAGE_FILE_NAME is not defined by the cache
+ # default to source package - system, on cygwin system is not
+ # needed
+ if(CYGWIN)
+ set(CPACK_PACKAGE_FILE_NAME "${CPACK_SOURCE_PACKAGE_FILE_NAME}")
+ else()
+ set(CPACK_PACKAGE_FILE_NAME
+ "${CPACK_SOURCE_PACKAGE_FILE_NAME}-${CPACK_SYSTEM_NAME}")
endif()
+endif()
- set(CPACK_PACKAGE_CONTACT "cmake@cmake.org")
+set(CPACK_PACKAGE_CONTACT "cmake@cmake.org")
- if(UNIX)
- set(CPACK_STRIP_FILES "${CMAKE_BIN_DIR}/ccmake;${CMAKE_BIN_DIR}/cmake;${CMAKE_BIN_DIR}/cpack;${CMAKE_BIN_DIR}/ctest")
- set(CPACK_SOURCE_STRIP_FILES "")
- set(CPACK_PACKAGE_EXECUTABLES "ccmake" "CMake")
- endif()
+if(UNIX)
+ set(CPACK_STRIP_FILES "${CMAKE_BIN_DIR}/ccmake;${CMAKE_BIN_DIR}/cmake;${CMAKE_BIN_DIR}/cpack;${CMAKE_BIN_DIR}/ctest")
+ set(CPACK_SOURCE_STRIP_FILES "")
+ set(CPACK_PACKAGE_EXECUTABLES "ccmake" "CMake")
+endif()
- set(CPACK_WIX_UPGRADE_GUID "8ffd1d72-b7f1-11e2-8ee5-00238bca4991")
+set(CPACK_WIX_UPGRADE_GUID "8ffd1d72-b7f1-11e2-8ee5-00238bca4991")
- if(MSVC AND NOT "$ENV{WIX}" STREQUAL "")
- set(WIX_CUSTOM_ACTION_ENABLED TRUE)
- if(CMAKE_CONFIGURATION_TYPES)
- set(WIX_CUSTOM_ACTION_MULTI_CONFIG TRUE)
- else()
- set(WIX_CUSTOM_ACTION_MULTI_CONFIG FALSE)
- endif()
+if(MSVC AND NOT "$ENV{WIX}" STREQUAL "")
+ set(WIX_CUSTOM_ACTION_ENABLED TRUE)
+ if(CMAKE_CONFIGURATION_TYPES)
+ set(WIX_CUSTOM_ACTION_MULTI_CONFIG TRUE)
else()
- set(WIX_CUSTOM_ACTION_ENABLED FALSE)
+ set(WIX_CUSTOM_ACTION_MULTI_CONFIG FALSE)
endif()
+else()
+ set(WIX_CUSTOM_ACTION_ENABLED FALSE)
+endif()
- # Set the options file that needs to be included inside CMakeCPackOptions.cmake
- set(QT_DIALOG_CPACK_OPTIONS_FILE ${CMake_BINARY_DIR}/Source/QtDialog/QtDialogCPack.cmake)
- configure_file("${CMake_SOURCE_DIR}/CMakeCPackOptions.cmake.in"
- "${CMake_BINARY_DIR}/CMakeCPackOptions.cmake" @ONLY)
- set(CPACK_PROJECT_CONFIG_FILE "${CMake_BINARY_DIR}/CMakeCPackOptions.cmake")
+# Set the options file that needs to be included inside CMakeCPackOptions.cmake
+set(QT_DIALOG_CPACK_OPTIONS_FILE ${CMake_BINARY_DIR}/Source/QtDialog/QtDialogCPack.cmake)
+configure_file("${CMake_SOURCE_DIR}/CMakeCPackOptions.cmake.in"
+ "${CMake_BINARY_DIR}/CMakeCPackOptions.cmake" @ONLY)
+set(CPACK_PROJECT_CONFIG_FILE "${CMake_BINARY_DIR}/CMakeCPackOptions.cmake")
- # include CPack model once all variables are set
- include(CPack)
-endif()
+# include CPack model once all variables are set
+include(CPack)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b4a577c..b8a635f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -366,31 +366,55 @@ macro (CMAKE_BUILD_UTILITIES)
set(CMAKE_COMPRESS_LIBRARIES "cmcompress")
add_subdirectory(Utilities/cmcompress)
CMAKE_SET_TARGET_FOLDER(cmcompress "Utilities/3rdParty")
- if(CMAKE_USE_SYSTEM_BZIP2)
- find_package(BZip2)
+
+ #---------------------------------------------------------------------
+ # Build expat library for CMake, CTest, and libarchive.
+ if(CMAKE_USE_SYSTEM_EXPAT)
+ find_package(EXPAT)
+ if(NOT EXPAT_FOUND)
+ message(FATAL_ERROR
+ "CMAKE_USE_SYSTEM_EXPAT is ON but a expat is not found!")
+ endif()
+ set(CMAKE_EXPAT_INCLUDES ${EXPAT_INCLUDE_DIRS})
+ set(CMAKE_EXPAT_LIBRARIES ${EXPAT_LIBRARIES})
else()
- set(BZIP2_INCLUDE_DIR
- "${CMAKE_CURRENT_SOURCE_DIR}/Utilities/cmbzip2")
- set(BZIP2_LIBRARIES cmbzip2)
- add_subdirectory(Utilities/cmbzip2)
- CMAKE_SET_TARGET_FOLDER(cmbzip2 "Utilities/3rdParty")
+ set(CMAKE_EXPAT_INCLUDES)
+ set(CMAKE_EXPAT_LIBRARIES cmexpat)
+ add_subdirectory(Utilities/cmexpat)
+ CMAKE_SET_TARGET_FOLDER(cmexpat "Utilities/3rdParty")
+ endif()
+
+ #---------------------------------------------------------------------
+ # Build or use system libbz2 for libarchive.
+ if(NOT CMAKE_USE_SYSTEM_LIBARCHIVE)
+ if(CMAKE_USE_SYSTEM_BZIP2)
+ find_package(BZip2)
+ else()
+ set(BZIP2_INCLUDE_DIR
+ "${CMAKE_CURRENT_SOURCE_DIR}/Utilities/cmbzip2")
+ set(BZIP2_LIBRARIES cmbzip2)
+ add_subdirectory(Utilities/cmbzip2)
+ CMAKE_SET_TARGET_FOLDER(cmbzip2 "Utilities/3rdParty")
+ endif()
endif()
#---------------------------------------------------------------------
# Build or use system liblzma for libarchive.
- if(CMAKE_USE_SYSTEM_LIBLZMA)
- find_package(LibLZMA)
- if(NOT LIBLZMA_FOUND)
- message(FATAL_ERROR "CMAKE_USE_SYSTEM_LIBLZMA is ON but LibLZMA is not found!")
+ if(NOT CMAKE_USE_SYSTEM_LIBARCHIVE)
+ if(CMAKE_USE_SYSTEM_LIBLZMA)
+ find_package(LibLZMA)
+ if(NOT LIBLZMA_FOUND)
+ message(FATAL_ERROR "CMAKE_USE_SYSTEM_LIBLZMA is ON but LibLZMA is not found!")
+ endif()
+ set(LZMA_INCLUDE_DIR ${LIBLZMA_INCLUDE_DIRS})
+ set(LZMA_LIBRARY ${LIBLZMA_LIBRARIES})
+ else()
+ add_subdirectory(Utilities/cmliblzma)
+ CMAKE_SET_TARGET_FOLDER(cmliblzma "Utilities/3rdParty")
+ set(LZMA_INCLUDE_DIR
+ "${CMAKE_CURRENT_SOURCE_DIR}/Utilities/cmliblzma/liblzma/api")
+ set(LZMA_LIBRARY cmliblzma)
endif()
- set(LZMA_INCLUDE_DIR ${LIBLZMA_INCLUDE_DIRS})
- set(LZMA_LIBRARY ${LIBLZMA_LIBRARIES})
- else()
- add_subdirectory(Utilities/cmliblzma)
- CMAKE_SET_TARGET_FOLDER(cmliblzma "Utilities/3rdParty")
- set(LZMA_INCLUDE_DIR
- "${CMAKE_CURRENT_SOURCE_DIR}/Utilities/cmliblzma/liblzma/api")
- set(LZMA_LIBRARY cmliblzma)
endif()
#---------------------------------------------------------------------
@@ -403,6 +427,8 @@ macro (CMAKE_BUILD_UTILITIES)
set(CMAKE_TAR_INCLUDES ${LibArchive_INCLUDE_DIRS})
set(CMAKE_TAR_LIBRARIES ${LibArchive_LIBRARIES})
else()
+ set(EXPAT_INCLUDE_DIR ${CMAKE_EXPAT_INCLUDES})
+ set(EXPAT_LIBRARY ${CMAKE_EXPAT_LIBRARIES})
set(ZLIB_INCLUDE_DIR ${CMAKE_ZLIB_INCLUDES})
set(ZLIB_LIBRARY ${CMAKE_ZLIB_LIBRARIES})
add_definitions(-DLIBARCHIVE_STATIC)
@@ -412,7 +438,7 @@ macro (CMAKE_BUILD_UTILITIES)
set(ENABLE_ZLIB ON CACHE INTERNAL "Enable the use of the system found ZLIB library if found")
set(ENABLE_BZip2 ON CACHE INTERNAL "Enable the use of the system found BZip2 library if found")
set(ENABLE_LIBXML2 OFF CACHE INTERNAL "Enable the use of the system found libxml2 library if found")
- set(ENABLE_EXPAT OFF CACHE INTERNAL "Enable the use of the system found EXPAT library if found")
+ set(ENABLE_EXPAT ON CACHE INTERNAL "Enable the use of the system found EXPAT library if found")
set(ENABLE_PCREPOSIX OFF CACHE INTERNAL "Enable the use of the system found PCREPOSIX library if found")
set(ENABLE_LibGCC OFF CACHE INTERNAL "Enable the use of the system found LibGCC library if found")
set(ENABLE_XATTR OFF CACHE INTERNAL "Enable extended attribute support")
@@ -425,23 +451,6 @@ macro (CMAKE_BUILD_UTILITIES)
endif()
#---------------------------------------------------------------------
- # Build expat library for CMake and CTest.
- if(CMAKE_USE_SYSTEM_EXPAT)
- find_package(EXPAT)
- if(NOT EXPAT_FOUND)
- message(FATAL_ERROR
- "CMAKE_USE_SYSTEM_EXPAT is ON but a expat is not found!")
- endif()
- set(CMAKE_EXPAT_INCLUDES ${EXPAT_INCLUDE_DIRS})
- set(CMAKE_EXPAT_LIBRARIES ${EXPAT_LIBRARIES})
- else()
- set(CMAKE_EXPAT_INCLUDES)
- set(CMAKE_EXPAT_LIBRARIES cmexpat)
- add_subdirectory(Utilities/cmexpat)
- CMAKE_SET_TARGET_FOLDER(cmexpat "Utilities/3rdParty")
- endif()
-
- #---------------------------------------------------------------------
# Build jsoncpp library.
if(CMAKE_USE_SYSTEM_JSONCPP)
if(NOT CMAKE_VERSION VERSION_LESS 3.0)
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 271f497..fa21a1f 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -121,6 +121,7 @@ Properties on Targets
/prop_tgt/AUTORCC
/prop_tgt/AUTORCC_OPTIONS
/prop_tgt/BINARY_DIR
+ /prop_tgt/BUILD_RPATH
/prop_tgt/BUILD_WITH_INSTALL_RPATH
/prop_tgt/BUNDLE_EXTENSION
/prop_tgt/BUNDLE
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index b74f867..f76c467 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -257,6 +257,7 @@ Variables that Control the Build
/variable/CMAKE_AUTORCC_OPTIONS
/variable/CMAKE_AUTOUIC
/variable/CMAKE_AUTOUIC_OPTIONS
+ /variable/CMAKE_BUILD_RPATH
/variable/CMAKE_BUILD_WITH_INSTALL_RPATH
/variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY
/variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG
diff --git a/Help/prop_tgt/BUILD_RPATH.rst b/Help/prop_tgt/BUILD_RPATH.rst
new file mode 100644
index 0000000..27393f5
--- /dev/null
+++ b/Help/prop_tgt/BUILD_RPATH.rst
@@ -0,0 +1,10 @@
+BUILD_RPATH
+-----------
+
+A :ref:`;-list <CMake Language Lists>` specifying runtime path (``RPATH``)
+entries to add to binaries linked in the build tree (for platforms that
+support it). The entries will *not* be used for binaries in the install
+tree. See also the :prop_tgt:`INSTALL_RPATH` target property.
+
+This property is initialized by the value of the variable
+:variable:`CMAKE_BUILD_RPATH` if it is set when a target is created.
diff --git a/Help/release/3.7.rst b/Help/release/3.7.rst
index 9794267..3b8ade6 100644
--- a/Help/release/3.7.rst
+++ b/Help/release/3.7.rst
@@ -32,7 +32,7 @@ Generators
with :ref:`Makefile Generators`.
* The :generator:`Visual Studio 15` generator was added. This is
- experimental and based on Preview 4 because this version of VS
+ experimental and based on Preview 5 because this version of VS
has not been released.
* :ref:`Visual Studio Generators` for VS 2010 and above learned to
diff --git a/Help/release/dev/0-sample-topic.rst b/Help/release/dev/0-sample-topic.rst
new file mode 100644
index 0000000..e4cc01e
--- /dev/null
+++ b/Help/release/dev/0-sample-topic.rst
@@ -0,0 +1,7 @@
+0-sample-topic
+--------------
+
+* This is a sample release note for the change in a topic.
+ Developers should add similar notes for each topic branch
+ making a noteworthy change. Each document should be named
+ and titled to match the topic name to avoid merge conflicts.
diff --git a/Help/release/dev/add-BUILD_RPATH.rst b/Help/release/dev/add-BUILD_RPATH.rst
new file mode 100644
index 0000000..0d69e45
--- /dev/null
+++ b/Help/release/dev/add-BUILD_RPATH.rst
@@ -0,0 +1,6 @@
+add-BUILD_RPATH
+---------------
+
+* A :variable:`CMAKE_BUILD_RPATH` variable and corresponding
+ :prop_tgt:`BUILD_RPATH` target property were added to support custom
+ ``RPATH`` locations to be added to binaries in the build tree.
diff --git a/Help/release/dev/cpack-rpm-single-debuginfo.rst b/Help/release/dev/cpack-rpm-single-debuginfo.rst
new file mode 100644
index 0000000..34a710d
--- /dev/null
+++ b/Help/release/dev/cpack-rpm-single-debuginfo.rst
@@ -0,0 +1,11 @@
+cpack-rpm-single-debuginfo
+--------------------------
+
+* The :module:`CPackRPM` module learned to generate main component package
+ which forces generation of a rpm for defined component without component
+ suffix in filename and package name.
+ See :variable:`CPACK_RPM_MAIN_COMPONENT` variable.
+
+* The :module:`CPackRPM` module learned to generate a single debuginfo package
+ on demand even if components packagin is used.
+ See :variable:`CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE` variable.
diff --git a/Help/release/index.rst b/Help/release/index.rst
index 25c6c3e..30decd5 100644
--- a/Help/release/index.rst
+++ b/Help/release/index.rst
@@ -5,6 +5,8 @@ CMake Release Notes
This file should include the adjacent "dev.txt" file
in development versions but not in release versions.
+.. include:: dev.txt
+
Releases
========
diff --git a/Help/variable/CMAKE_BUILD_RPATH.rst b/Help/variable/CMAKE_BUILD_RPATH.rst
new file mode 100644
index 0000000..f20eb41
--- /dev/null
+++ b/Help/variable/CMAKE_BUILD_RPATH.rst
@@ -0,0 +1,10 @@
+CMAKE_BUILD_RPATH
+-----------------
+
+A :ref:`;-list <CMake Language Lists>` specifying runtime path (``RPATH``)
+entries to add to binaries linked in the build tree (for platforms that
+support it). The entries will *not* be used for binaries in the install
+tree. See also the :variable:`CMAKE_INSTALL_RPATH` variable.
+
+This is used to initialize the :prop_tgt:`BUILD_RPATH` target property
+for all targets.
diff --git a/Modules/CPackRPM.cmake b/Modules/CPackRPM.cmake
index 15b62c7..6017ce3 100644
--- a/Modules/CPackRPM.cmake
+++ b/Modules/CPackRPM.cmake
@@ -95,6 +95,17 @@
# and it is up to the packager to set the variables in a manner that will
# prevent such errors.
#
+# .. variable:: CPACK_RPM_MAIN_COMPONENT
+#
+# Main component that is packaged without component suffix.
+#
+# * Mandatory : NO
+# * Default : -
+#
+# This variable can be set to any component or group name so that component or
+# group rpm package is generated without component suffix in filename and
+# package name.
+#
# .. variable:: CPACK_RPM_PACKAGE_VERSION
#
# The RPM package version.
@@ -792,6 +803,26 @@
# * Mandatory : NO
# * Default : -
#
+# .. variable:: CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE
+#
+# Create a single debuginfo package even if components packaging is set.
+#
+# * Mandatory : NO
+# * Default : OFF
+#
+# When this variable is enabled it produces a single debuginfo package even if
+# component packaging is enabled.
+#
+# When using this feature in combination with components packaging and there is
+# more than one component this variable requires :variable:`CPACK_RPM_MAIN_COMPONENT`
+# to be set.
+#
+# .. note::
+#
+# If none of the :variable:`CPACK_RPM_<component>_DEBUGINFO_PACKAGE` variables
+# is set then :variable:`CPACK_RPM_DEBUGINFO_PACKAGE` is automatically set to
+# ``ON`` when :variable:`CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE` is set.
+#
# Packaging of sources (SRPM)
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^
#
@@ -1649,10 +1680,16 @@ function(cpack_rpm_generate_package)
endif()
if(CPACK_RPM_PACKAGE_COMPONENT)
- string(APPEND CPACK_RPM_PACKAGE_NAME "-${CPACK_RPM_PACKAGE_COMPONENT}")
- cpack_rpm_variable_fallback("CPACK_RPM_PACKAGE_NAME"
- "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_NAME"
- "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_PACKAGE_NAME")
+ string(TOUPPER "${CPACK_RPM_MAIN_COMPONENT}"
+ CPACK_RPM_MAIN_COMPONENT_UPPER)
+
+ if(NOT CPACK_RPM_MAIN_COMPONENT_UPPER STREQUAL CPACK_RPM_PACKAGE_COMPONENT_UPPER)
+ string(APPEND CPACK_RPM_PACKAGE_NAME "-${CPACK_RPM_PACKAGE_COMPONENT}")
+
+ cpack_rpm_variable_fallback("CPACK_RPM_PACKAGE_NAME"
+ "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_NAME"
+ "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_PACKAGE_NAME")
+ endif()
endif()
# CPACK_RPM_PACKAGE_VERSION (mandatory)
@@ -2059,7 +2096,7 @@ function(cpack_rpm_generate_package)
"CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_DEBUGINFO_PACKAGE"
"CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_DEBUGINFO_PACKAGE"
"CPACK_RPM_DEBUGINFO_PACKAGE")
- if(CPACK_RPM_DEBUGINFO_PACKAGE)
+ if(CPACK_RPM_DEBUGINFO_PACKAGE OR (CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE AND NOT GENERATE_SPEC_PARTS))
cpack_rpm_variable_fallback("CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX"
"CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_BUILD_SOURCE_DIRS_PREFIX"
"CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_BUILD_SOURCE_DIRS_PREFIX"
@@ -2067,9 +2104,81 @@ function(cpack_rpm_generate_package)
if(NOT CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX)
set(CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX "/usr/src/debug/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}")
endif()
- cpack_rpm_debugsymbol_check("${CPACK_RPM_INSTALL_FILES}" "${WDIR}")
- set(TMP_RPM_DEBUGINFO "
+ if(CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE AND GENERATE_SPEC_PARTS)
+ file(WRITE "${CPACK_RPM_ROOTDIR}/SPECS/${CPACK_RPM_PACKAGE_COMPONENT}.files"
+ "${CPACK_RPM_INSTALL_FILES}")
+ else()
+ if(CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE AND CPACK_RPM_PACKAGE_COMPONENT)
+ # this part is only required by components packaging - with monolithic
+ # packages we can be certain that there are no other components present
+ # so CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE is a noop
+ if(CPACK_RPM_DEBUGINFO_PACKAGE)
+ # only add current package files to debuginfo list if debuginfo
+ # generation is enabled for current package
+ set(install_files_ "${CPACK_RPM_INSTALL_FILES}")
+ else()
+ unset(install_files_)
+ endif()
+
+ file(GLOB files_ "${CPACK_RPM_DIRECTORY}/SPECS/*.files")
+
+ foreach(f_ IN LISTS files_)
+ file(READ "${f_}" tmp_)
+ string(APPEND install_files_ ";${tmp_}")
+ endforeach()
+
+ # if there were other components/groups so we need to move files from them
+ # to current component otherwise those files won't be found
+ file(GLOB components_ LIST_DIRECTORIES true RELATIVE
+ "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}"
+ "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}/*")
+ foreach(component_ IN LISTS components_)
+ string(TOUPPER "${component_}" component_dir_upper_)
+ if(component_dir_upper_ STREQUAL CPACK_RPM_PACKAGE_COMPONENT_UPPER)
+ # skip current component
+ continue()
+ endif()
+
+ cmake_policy(PUSH)
+ cmake_policy(SET CMP0009 NEW)
+ file(GLOB_RECURSE files_for_move_ LIST_DIRECTORIES false RELATIVE
+ "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}/${component_}"
+ "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}/${component_}/*")
+ cmake_policy(POP)
+
+ foreach(f_ IN LISTS files_for_move_)
+ get_filename_component(dir_path_ "${f_}" DIRECTORY)
+ set(src_file_
+ "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}/${component_}/${f_}")
+
+ # check that we are not overriding an existing file that doesn't
+ # match the file that we want to copy
+ if(EXISTS "${src_file_}" AND EXISTS "${WDIR}/${f_}")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E compare_files "${src_file_}" "${WDIR}/${f_}"
+ RESULT_VARIABLE res_
+ )
+ if(res_)
+ message(FATAL_ERROR "CPackRPM:Error: File on path '${WDIR}/${f_}'"
+ " already exists but is a different than the one in component"
+ " '${component_}'! Packages will not be generated.")
+ endif()
+ endif()
+
+ file(MAKE_DIRECTORY "${WDIR}/${dir_path_}")
+ file(RENAME "${src_file_}"
+ "${WDIR}/${f_}")
+ endforeach()
+ endforeach()
+
+ cpack_rpm_debugsymbol_check("${install_files_}" "${WDIR}")
+ else()
+ cpack_rpm_debugsymbol_check("${CPACK_RPM_INSTALL_FILES}" "${WDIR}")
+ endif()
+
+ if(TMP_DEBUGINFO_ADDITIONAL_SOURCES)
+ set(TMP_RPM_DEBUGINFO "
# Modified version of %%debug_package macro
# defined in /usr/lib/rpm/macros as that one
# can't handle injection of extra source files.
@@ -2088,6 +2197,15 @@ package or when debugging this package.
${TMP_DEBUGINFO_ADDITIONAL_SOURCES}
%endif
")
+ elseif(CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE)
+ message(AUTHOR_WARNING "CPackRPM:Warning: debuginfo package was requested"
+ " but will not be generated as no source files were found!")
+ else()
+ message(AUTHOR_WARNING "CPackRPM:Warning: debuginfo package was requested"
+ " but will not be generated as no source files were found! Component: '"
+ "${CPACK_RPM_PACKAGE_COMPONENT}'.")
+ endif()
+ endif()
endif()
# Prepare install files
@@ -2164,12 +2282,25 @@ ${TMP_DEBUGINFO_ADDITIONAL_SOURCES}
cmake_policy(POP)
else()
# old file name format for back compatibility
- set(CPACK_RPM_FILE_NAME "${CPACK_OUTPUT_FILE_NAME}")
+ string(TOUPPER "${CPACK_RPM_MAIN_COMPONENT}"
+ CPACK_RPM_MAIN_COMPONENT_UPPER)
+
+ if(CPACK_RPM_MAIN_COMPONENT_UPPER STREQUAL CPACK_RPM_PACKAGE_COMPONENT_UPPER)
+ # this is the main component so ignore the component filename part
+ set(CPACK_RPM_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}.rpm")
+ else()
+ set(CPACK_RPM_FILE_NAME "${CPACK_OUTPUT_FILE_NAME}")
+ endif()
endif()
# else example:
#set(CPACK_RPM_FILE_NAME "${CPACK_RPM_PACKAGE_NAME}-${CPACK_RPM_PACKAGE_VERSION}-${CPACK_RPM_PACKAGE_RELEASE}-${CPACK_RPM_PACKAGE_ARCHITECTURE}.rpm")
- if(NOT CPACK_RPM_DEBUGINFO_PACKAGE)
+ if(CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE AND GENERATE_SPEC_PARTS)
+ string(TOLOWER "${CPACK_RPM_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}.*\\.rpm" expected_filename_)
+
+ file(WRITE "${CPACK_RPM_ROOTDIR}/SPECS/${CPACK_RPM_PACKAGE_COMPONENT}.rpm_name"
+ "${expected_filename_};${CPACK_RPM_FILE_NAME}")
+ elseif(NOT CPACK_RPM_DEBUGINFO_PACKAGE)
set(FILE_NAME_DEFINE "%define _rpmfilename ${CPACK_RPM_FILE_NAME}")
endif()
endif()
@@ -2264,7 +2395,54 @@ Vendor: \@CPACK_RPM_PACKAGE_VENDOR\@
\@CPACK_RPM_SPEC_CHANGELOG\@
"
)
+
+ elseif(GENERATE_SPEC_PARTS) # binary rpm with single debuginfo package
+ file(WRITE ${CPACK_RPM_BINARY_SPECFILE}.in
+ "# -*- rpm-spec -*-
+%package -n \@CPACK_RPM_PACKAGE_NAME\@
+Summary: \@CPACK_RPM_PACKAGE_SUMMARY\@
+Version: \@CPACK_RPM_PACKAGE_VERSION\@
+Release: \@CPACK_RPM_PACKAGE_RELEASE\@
+License: \@CPACK_RPM_PACKAGE_LICENSE\@
+Group: \@CPACK_RPM_PACKAGE_GROUP\@
+Vendor: \@CPACK_RPM_PACKAGE_VENDOR\@
+
+\@TMP_RPM_URL\@
+\@TMP_RPM_REQUIRES\@
+\@TMP_RPM_REQUIRES_PRE\@
+\@TMP_RPM_REQUIRES_POST\@
+\@TMP_RPM_REQUIRES_PREUN\@
+\@TMP_RPM_REQUIRES_POSTUN\@
+\@TMP_RPM_PROVIDES\@
+\@TMP_RPM_OBSOLETES\@
+\@TMP_RPM_CONFLICTS\@
+\@TMP_RPM_AUTOPROV\@
+\@TMP_RPM_AUTOREQ\@
+\@TMP_RPM_AUTOREQPROV\@
+\@TMP_RPM_BUILDARCH\@
+\@TMP_RPM_PREFIXES\@
+
+%description -n \@CPACK_RPM_PACKAGE_NAME\@
+\@CPACK_RPM_PACKAGE_DESCRIPTION\@
+
+%files -n \@CPACK_RPM_PACKAGE_NAME\@
+%defattr(\@TMP_DEFAULT_FILE_PERMISSIONS\@,\@TMP_DEFAULT_USER\@,\@TMP_DEFAULT_GROUP\@,\@TMP_DEFAULT_DIR_PERMISSIONS\@)
+\@CPACK_RPM_INSTALL_FILES\@
+\@CPACK_RPM_ABSOLUTE_INSTALL_FILES\@
+\@CPACK_RPM_USER_INSTALL_FILES\@
+"
+ )
+
else() # binary rpm
+ if(CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE)
+ # find generated spec file and take its name
+ file(GLOB spec_files_ "${CPACK_RPM_DIRECTORY}/SPECS/*.spec")
+
+ foreach(f_ IN LISTS spec_files_)
+ file(READ "${f_}" tmp_)
+ string(APPEND TMP_OTHER_COMPONENTS "\n${tmp_}\n")
+ endforeach()
+ endif()
# We should generate a USER spec file template:
# - either because the user asked for it : CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE
@@ -2350,6 +2528,8 @@ mv %_topdir/tmpBBroot $RPM_BUILD_ROOT
%changelog
\@CPACK_RPM_SPEC_CHANGELOG\@
+
+\@TMP_OTHER_COMPONENTS\@
"
)
endif()
@@ -2376,60 +2556,90 @@ mv %_topdir/tmpBBroot $RPM_BUILD_ROOT
configure_file(${CPACK_RPM_BINARY_SPECFILE}.in ${CPACK_RPM_BINARY_SPECFILE} @ONLY)
endif()
- if(RPMBUILD_EXECUTABLE)
- # Now call rpmbuild using the SPECFILE
- execute_process(
- COMMAND "${RPMBUILD_EXECUTABLE}" ${RPMBUILD_FLAGS}
- --define "_topdir ${CPACK_RPM_DIRECTORY}"
- --buildroot "%_topdir/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}"
- --target "${CPACK_RPM_PACKAGE_ARCHITECTURE}"
- "${CPACK_RPM_BINARY_SPECFILE}"
- WORKING_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}"
- RESULT_VARIABLE CPACK_RPMBUILD_EXEC_RESULT
- ERROR_FILE "${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.err"
- OUTPUT_FILE "${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.out")
- if(CPACK_RPM_PACKAGE_DEBUG OR CPACK_RPMBUILD_EXEC_RESULT)
- file(READ ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.err RPMBUILDERR)
- file(READ ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.out RPMBUILDOUT)
- message("CPackRPM:Debug: You may consult rpmbuild logs in: ")
- message("CPackRPM:Debug: - ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.err")
- message("CPackRPM:Debug: *** ${RPMBUILDERR} ***")
- message("CPackRPM:Debug: - ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.out")
- message("CPackRPM:Debug: *** ${RPMBUILDOUT} ***")
+ if(NOT GENERATE_SPEC_PARTS) # generate package
+ if(RPMBUILD_EXECUTABLE)
+ # Now call rpmbuild using the SPECFILE
+ execute_process(
+ COMMAND "${RPMBUILD_EXECUTABLE}" ${RPMBUILD_FLAGS}
+ --define "_topdir ${CPACK_RPM_DIRECTORY}"
+ --buildroot "%_topdir/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}"
+ --target "${CPACK_RPM_PACKAGE_ARCHITECTURE}"
+ "${CPACK_RPM_BINARY_SPECFILE}"
+ WORKING_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}"
+ RESULT_VARIABLE CPACK_RPMBUILD_EXEC_RESULT
+ ERROR_FILE "${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.err"
+ OUTPUT_FILE "${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.out")
+ if(CPACK_RPM_PACKAGE_DEBUG OR CPACK_RPMBUILD_EXEC_RESULT)
+ file(READ ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.err RPMBUILDERR)
+ file(READ ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.out RPMBUILDOUT)
+ message("CPackRPM:Debug: You may consult rpmbuild logs in: ")
+ message("CPackRPM:Debug: - ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.err")
+ message("CPackRPM:Debug: *** ${RPMBUILDERR} ***")
+ message("CPackRPM:Debug: - ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.out")
+ message("CPackRPM:Debug: *** ${RPMBUILDOUT} ***")
+ endif()
+ else()
+ if(ALIEN_EXECUTABLE)
+ message(FATAL_ERROR "RPM packaging through alien not done (yet)")
+ endif()
endif()
- else()
- if(ALIEN_EXECUTABLE)
- message(FATAL_ERROR "RPM packaging through alien not done (yet)")
+
+ # find generated rpm files and take their names
+ cmake_policy(PUSH)
+ # Tell file(GLOB_RECURSE) not to follow directory symlinks
+ # even if the project does not set this policy to NEW.
+ cmake_policy(SET CMP0009 NEW)
+ file(GLOB_RECURSE GENERATED_FILES "${CPACK_RPM_DIRECTORY}/RPMS/*.rpm"
+ "${CPACK_RPM_DIRECTORY}/SRPMS/*.rpm")
+ cmake_policy(POP)
+
+ if(NOT GENERATED_FILES)
+ message(FATAL_ERROR "RPM package was not generated! ${CPACK_RPM_DIRECTORY}")
endif()
- endif()
- # find generated rpm files and take their names
- cmake_policy(PUSH)
- # Tell file(GLOB_RECURSE) not to follow directory symlinks
- # even if the project does not set this policy to NEW.
- cmake_policy(SET CMP0009 NEW)
- file(GLOB_RECURSE GENERATED_FILES "${CPACK_RPM_DIRECTORY}/RPMS/*.rpm"
- "${CPACK_RPM_DIRECTORY}/SRPMS/*.rpm")
- cmake_policy(POP)
+ unset(expected_filenames_)
+ unset(filenames_)
+ if(CPACK_RPM_DEBUGINFO_PACKAGE AND NOT CPACK_RPM_FILE_NAME STREQUAL "RPM-DEFAULT")
+ string(TOLOWER "${CPACK_RPM_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}.*\\.rpm" efn_)
+ list(APPEND expected_filenames_ "${efn_}")
+ list(APPEND filenames_ "${CPACK_RPM_FILE_NAME}")
+ endif()
- if(NOT GENERATED_FILES)
- message(FATAL_ERROR "RPM package was not generated! ${CPACK_RPM_DIRECTORY}")
- endif()
+ # check if other files have to be renamed
+ file(GLOB rename_files_ "${CPACK_RPM_DIRECTORY}/SPECS/*.rpm_name")
+ if(rename_files_)
+ foreach(f_ IN LISTS rename_files_)
+ file(READ "${f_}" tmp_)
+ list(GET tmp_ 0 efn_)
+ list(APPEND expected_filenames_ "${efn_}")
+ list(GET tmp_ 1 fn_)
+ list(APPEND filenames_ "${fn_}")
+ endforeach()
+ endif()
- if(CPACK_RPM_DEBUGINFO_PACKAGE AND NOT CPACK_RPM_FILE_NAME STREQUAL "RPM-DEFAULT")
- string(TOLOWER "${CPACK_RPM_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}.*\\.rpm" EXPECTED_FILENAME)
+ if(expected_filenames_)
+ foreach(F IN LISTS GENERATED_FILES)
+ unset(matched_)
+ foreach(expected_ IN LISTS expected_filenames_)
+ if(F MATCHES ".*/${expected_}")
+ list(FIND expected_filenames_ "${expected_}" idx_)
+ list(GET filenames_ ${idx_} filename_)
+ get_filename_component(FILE_PATH "${F}" DIRECTORY)
+ file(RENAME "${F}" "${FILE_PATH}/${filename_}")
+ list(APPEND new_files_list_ "${FILE_PATH}/${filename_}")
+ set(matched_ "YES")
+
+ break()
+ endif()
+ endforeach()
- foreach(F IN LISTS GENERATED_FILES)
- if(F MATCHES ".*/${EXPECTED_FILENAME}")
- get_filename_component(FILE_PATH "${F}" DIRECTORY)
- file(RENAME "${F}" "${FILE_PATH}/${CPACK_RPM_FILE_NAME}")
- list(APPEND new_files_list_ "${FILE_PATH}/${CPACK_RPM_FILE_NAME}")
- else()
- list(APPEND new_files_list_ "${F}")
- endif()
- endforeach()
+ if(NOT matched_)
+ list(APPEND new_files_list_ "${F}")
+ endif()
+ endforeach()
- set(GENERATED_FILES "${new_files_list_}")
+ set(GENERATED_FILES "${new_files_list_}")
+ endif()
endif()
set(GEN_CPACK_OUTPUT_FILES "${GENERATED_FILES}" PARENT_SCOPE)
diff --git a/Modules/FindIce.cmake b/Modules/FindIce.cmake
index 39dc171..a61d4a8 100644
--- a/Modules/FindIce.cmake
+++ b/Modules/FindIce.cmake
@@ -131,6 +131,7 @@ function(_Ice_FIND)
set(ice_versions
3
3.6
+ 3.6.3
3.6.2
3.6.1
3.6.0
diff --git a/Modules/FindProtobuf.cmake b/Modules/FindProtobuf.cmake
index 14e392a..3ffd5a7 100644
--- a/Modules/FindProtobuf.cmake
+++ b/Modules/FindProtobuf.cmake
@@ -264,7 +264,7 @@ function(_protobuf_find_libraries name filename)
mark_as_advanced(${name}_LIBRARY_RELEASE)
find_library(${name}_LIBRARY_DEBUG
- NAMES ${filename}
+ NAMES ${filename}d ${filename}
PATHS ${Protobuf_SRC_ROOT_FOLDER}/vsprojects/${_PROTOBUF_ARCH_DIR}Debug)
mark_as_advanced(${name}_LIBRARY_DEBUG)
diff --git a/Modules/FindSDL.cmake b/Modules/FindSDL.cmake
index c0cdd98..4e4411f 100644
--- a/Modules/FindSDL.cmake
+++ b/Modules/FindSDL.cmake
@@ -122,11 +122,10 @@ if(NOT APPLE)
find_package(Threads)
endif()
-# MinGW needs an additional library, mwindows
-# It's total link flags should look like -lmingw32 -lSDLmain -lSDL -lmwindows
-# (Actually on second look, I think it only needs one of the m* libraries.)
+# MinGW needs an additional link flag, -mwindows
+# It's total link flags should look like -lmingw32 -lSDLmain -lSDL -mwindows
if(MINGW)
- set(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW")
+ set(MINGW32_LIBRARY mingw32 "-mwindows" CACHE STRING "link flags for MinGW")
endif()
if(SDL_LIBRARY_TEMP)
diff --git a/Modules/Platform/Darwin.cmake b/Modules/Platform/Darwin.cmake
index bb085ac..c09bac4 100644
--- a/Modules/Platform/Darwin.cmake
+++ b/Modules/Platform/Darwin.cmake
@@ -105,8 +105,6 @@ if("${_CURRENT_OSX_VERSION}" VERSION_LESS "10.5")
set(CMAKE_LINK_DEPENDENT_LIBRARY_FILES 1)
endif()
-set(CMAKE_C_CREATE_SHARED_LIBRARY_FORBIDDEN_FLAGS -w)
-set(CMAKE_CXX_CREATE_SHARED_LIBRARY_FORBIDDEN_FLAGS -w)
set(CMAKE_C_CREATE_SHARED_LIBRARY
"<CMAKE_C_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS> <LINK_FLAGS> -o <TARGET> <SONAME_FLAG> <TARGET_INSTALLNAME_DIR><TARGET_SONAME> <OBJECTS> <LINK_LIBRARIES>")
set(CMAKE_CXX_CREATE_SHARED_LIBRARY
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index ec49481..048667a 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -300,6 +300,8 @@ set(SRCS
cmInstallDirectoryGenerator.cxx
cmLinkedTree.h
cmLinkItem.h
+ cmLinkLineComputer.cxx
+ cmLinkLineComputer.h
cmListFileCache.cxx
cmListFileCache.h
cmListFileLexer.c
@@ -318,6 +320,8 @@ set(SRCS
cmMakefileUtilityTargetGenerator.cxx
cmMessenger.cxx
cmMessenger.h
+ cmMSVC60LinkLineComputer.cxx
+ cmMSVC60LinkLineComputer.h
cmOSXBundleGenerator.cxx
cmOSXBundleGenerator.h
cmOutputConverter.cxx
@@ -384,6 +388,8 @@ set(SRCS
cm_sha2.c
cm_utf8.h
cm_utf8.c
+ cm_codecvt.hxx
+ cm_codecvt.cxx
)
set(COMMAND_INCLUDES "#include \"cmTargetPropCommandBase.cxx\"\n")
@@ -543,6 +549,8 @@ set(SRCS ${SRCS}
cmNinjaNormalTargetGenerator.h
cmNinjaUtilityTargetGenerator.cxx
cmNinjaUtilityTargetGenerator.h
+ cmNinjaLinkLineComputer.cxx
+ cmNinjaLinkLineComputer.h
)
# Temporary variable for tools targets
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 6cb0fea..0013346 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 7)
-set(CMake_VERSION_PATCH 0)
-set(CMake_VERSION_RC 1)
+set(CMake_VERSION_PATCH 20161013)
+#set(CMake_VERSION_RC 1)
diff --git a/Source/CPack/cmCPackGenerator.h b/Source/CPack/cmCPackGenerator.h
index 9232ffc..db20998 100644
--- a/Source/CPack/cmCPackGenerator.h
+++ b/Source/CPack/cmCPackGenerator.h
@@ -32,16 +32,6 @@ class cmMakefile;
cmCPackLog_msg.str().c_str()); \
} while (0)
-#ifdef cerr
-#undef cerr
-#endif
-#define cerr no_cerr_use_cmCPack_Log
-
-#ifdef cout
-#undef cout
-#endif
-#define cout no_cout_use_cmCPack_Log
-
/** \class cmCPackGenerator
* \brief A superclass of all CPack Generators
*
diff --git a/Source/CPack/cmCPackLog.cxx b/Source/CPack/cmCPackLog.cxx
index be429fe..317f613 100644
--- a/Source/CPack/cmCPackLog.cxx
+++ b/Source/CPack/cmCPackLog.cxx
@@ -15,8 +15,6 @@ cmCPackLog::cmCPackLog()
this->NewLine = true;
this->LastTag = cmCPackLog::NOTAG;
-#undef cerr
-#undef cout
this->DefaultOutput = &std::cout;
this->DefaultError = &std::cerr;
diff --git a/Source/CPack/cmCPackLog.h b/Source/CPack/cmCPackLog.h
index 0831843..370879d 100644
--- a/Source/CPack/cmCPackLog.h
+++ b/Source/CPack/cmCPackLog.h
@@ -19,16 +19,6 @@
(ctSelf)->Log(logType, __FILE__, __LINE__, cmCPackLog_msg.str().c_str()); \
} while (0)
-#ifdef cerr
-#undef cerr
-#endif
-#define cerr no_cerr_use_cmCPack_Log
-
-#ifdef cout
-#undef cout
-#endif
-#define cout no_cout_use_cmCPack_Log
-
/** \class cmCPackLog
* \brief A container for CPack generators
*
diff --git a/Source/CPack/cmCPackRPMGenerator.cxx b/Source/CPack/cmCPackRPMGenerator.cxx
index bd55206..9817327 100644
--- a/Source/CPack/cmCPackRPMGenerator.cxx
+++ b/Source/CPack/cmCPackRPMGenerator.cxx
@@ -105,39 +105,224 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup)
packageFileNames.clear();
std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
- // The default behavior is to have one package by component group
- // unless CPACK_COMPONENTS_IGNORE_GROUP is specified.
- if (!ignoreGroup) {
- std::map<std::string, cmCPackComponentGroup>::iterator compGIt;
- for (compGIt = this->ComponentGroups.begin();
- compGIt != this->ComponentGroups.end(); ++compGIt) {
- cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging component group: "
- << compGIt->first << std::endl);
- retval &= PackageOnePack(initialTopLevel, compGIt->first);
+ const char* mainComponent = this->GetOption("CPACK_RPM_MAIN_COMPONENT");
+
+ if (this->IsOn("CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE") &&
+ !this->IsOn("CPACK_RPM_DEBUGINFO_PACKAGE")) {
+ // check if we need to set CPACK_RPM_DEBUGINFO_PACKAGE because non of
+ // the components is setting per component debuginfo package variable
+ bool shouldSet = true;
+
+ if (ignoreGroup) {
+ std::map<std::string, cmCPackComponent>::iterator compIt;
+ for (compIt = this->Components.begin(); compIt != this->Components.end();
+ ++compIt) {
+ std::string component(compIt->first);
+ std::transform(component.begin(), component.end(), component.begin(),
+ ::toupper);
+
+ if (this->IsOn("CPACK_RPM_" + compIt->first + "_DEBUGINFO_PACKAGE") ||
+ this->IsOn("CPACK_RPM_" + component + "_DEBUGINFO_PACKAGE")) {
+ shouldSet = false;
+ break;
+ }
+ }
+ } else {
+ std::map<std::string, cmCPackComponentGroup>::iterator compGIt;
+ for (compGIt = this->ComponentGroups.begin();
+ compGIt != this->ComponentGroups.end(); ++compGIt) {
+ std::string component(compGIt->first);
+ std::transform(component.begin(), component.end(), component.begin(),
+ ::toupper);
+
+ if (this->IsOn("CPACK_RPM_" + compGIt->first + "_DEBUGINFO_PACKAGE") ||
+ this->IsOn("CPACK_RPM_" + component + "_DEBUGINFO_PACKAGE")) {
+ shouldSet = false;
+ break;
+ }
+ }
+
+ if (shouldSet) {
+ std::map<std::string, cmCPackComponent>::iterator compIt;
+ for (compIt = this->Components.begin();
+ compIt != this->Components.end(); ++compIt) {
+ // Does the component belong to a group?
+ if (compIt->second.Group == CM_NULLPTR) {
+ std::string component(compIt->first);
+ std::transform(component.begin(), component.end(),
+ component.begin(), ::toupper);
+
+ if (this->IsOn("CPACK_RPM_" + compIt->first +
+ "_DEBUGINFO_PACKAGE") ||
+ this->IsOn("CPACK_RPM_" + component + "_DEBUGINFO_PACKAGE")) {
+ shouldSet = false;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (shouldSet) {
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Setting "
+ << "CPACK_RPM_DEBUGINFO_PACKAGE because "
+ << "CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE is set but "
+ << " none of the "
+ << "CPACK_RPM_<component>_DEBUGINFO_PACKAGE variables "
+ << "are set." << std::endl);
+ this->SetOption("CPACK_RPM_DEBUGINFO_PACKAGE", "ON");
}
- // Handle Orphan components (components not belonging to any groups)
- std::map<std::string, cmCPackComponent>::iterator compIt;
- for (compIt = this->Components.begin(); compIt != this->Components.end();
- ++compIt) {
- // Does the component belong to a group?
- if (compIt->second.Group == CM_NULLPTR) {
- cmCPackLogger(
- cmCPackLog::LOG_VERBOSE, "Component <"
- << compIt->second.Name
- << "> does not belong to any group, package it separately."
- << std::endl);
+ }
+
+ if (mainComponent) {
+ if (this->IsOn("CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE")) {
+ this->SetOption("GENERATE_SPEC_PARTS", "ON");
+ }
+
+ std::string mainComponentUpper(mainComponent);
+ std::transform(mainComponentUpper.begin(), mainComponentUpper.end(),
+ mainComponentUpper.begin(), ::toupper);
+
+ // The default behavior is to have one package by component group
+ // unless CPACK_COMPONENTS_IGNORE_GROUP is specified.
+ if (!ignoreGroup) {
+ std::map<std::string, cmCPackComponentGroup>::iterator mainCompGIt =
+ this->ComponentGroups.end();
+
+ std::map<std::string, cmCPackComponentGroup>::iterator compGIt;
+ for (compGIt = this->ComponentGroups.begin();
+ compGIt != this->ComponentGroups.end(); ++compGIt) {
+ std::string component(compGIt->first);
+ std::transform(component.begin(), component.end(), component.begin(),
+ ::toupper);
+
+ if (mainComponentUpper == component) {
+ // main component will be handled last
+ mainCompGIt = compGIt;
+ continue;
+ }
+
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging component group: "
+ << compGIt->first << std::endl);
+ retval &= PackageOnePack(initialTopLevel, compGIt->first);
+ }
+ // Handle Orphan components (components not belonging to any groups)
+ std::map<std::string, cmCPackComponent>::iterator mainCompIt =
+ this->Components.end();
+ std::map<std::string, cmCPackComponent>::iterator compIt;
+ for (compIt = this->Components.begin(); compIt != this->Components.end();
+ ++compIt) {
+ // Does the component belong to a group?
+ if (compIt->second.Group == CM_NULLPTR) {
+ std::string component(compIt->first);
+ std::transform(component.begin(), component.end(), component.begin(),
+ ::toupper);
+
+ if (mainComponentUpper == component) {
+ // main component will be handled last
+ mainCompIt = compIt;
+ continue;
+ }
+
+ cmCPackLogger(
+ cmCPackLog::LOG_VERBOSE, "Component <"
+ << compIt->second.Name
+ << "> does not belong to any group, package it separately."
+ << std::endl);
+ retval &= PackageOnePack(initialTopLevel, compIt->first);
+ }
+ }
+
+ if (retval) {
+ this->SetOption("GENERATE_SPEC_PARTS", "OFF");
+
+ if (mainCompGIt != this->ComponentGroups.end()) {
+ retval &= PackageOnePack(initialTopLevel, mainCompGIt->first);
+ } else if (mainCompIt != this->Components.end()) {
+ retval &= PackageOnePack(initialTopLevel, mainCompIt->first);
+ } else {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "CPACK_RPM_MAIN_COMPONENT set"
+ << " to non existing component.\n");
+ retval = 0;
+ }
+ }
+ }
+ // CPACK_COMPONENTS_IGNORE_GROUPS is set
+ // We build 1 package per component
+ else {
+ std::map<std::string, cmCPackComponent>::iterator mainCompIt =
+ this->Components.end();
+
+ std::map<std::string, cmCPackComponent>::iterator compIt;
+ for (compIt = this->Components.begin(); compIt != this->Components.end();
+ ++compIt) {
+ std::string component(compIt->first);
+ std::transform(component.begin(), component.end(), component.begin(),
+ ::toupper);
+
+ if (mainComponentUpper == component) {
+ // main component will be handled last
+ mainCompIt = compIt;
+ continue;
+ }
+
retval &= PackageOnePack(initialTopLevel, compIt->first);
}
+
+ if (retval) {
+ this->SetOption("GENERATE_SPEC_PARTS", "OFF");
+
+ if (mainCompIt != this->Components.end()) {
+ retval &= PackageOnePack(initialTopLevel, mainCompIt->first);
+ } else {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "CPACK_RPM_MAIN_COMPONENT set"
+ << " to non existing component.\n");
+ retval = 0;
+ }
+ }
}
- }
- // CPACK_COMPONENTS_IGNORE_GROUPS is set
- // We build 1 package per component
- else {
- std::map<std::string, cmCPackComponent>::iterator compIt;
- for (compIt = this->Components.begin(); compIt != this->Components.end();
- ++compIt) {
- retval &= PackageOnePack(initialTopLevel, compIt->first);
+ } else if (!this->IsOn("CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE") ||
+ this->Components.size() == 1) {
+ // The default behavior is to have one package by component group
+ // unless CPACK_COMPONENTS_IGNORE_GROUP is specified.
+ if (!ignoreGroup) {
+ std::map<std::string, cmCPackComponentGroup>::iterator compGIt;
+ for (compGIt = this->ComponentGroups.begin();
+ compGIt != this->ComponentGroups.end(); ++compGIt) {
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging component group: "
+ << compGIt->first << std::endl);
+ retval &= PackageOnePack(initialTopLevel, compGIt->first);
+ }
+ // Handle Orphan components (components not belonging to any groups)
+ std::map<std::string, cmCPackComponent>::iterator compIt;
+ for (compIt = this->Components.begin(); compIt != this->Components.end();
+ ++compIt) {
+ // Does the component belong to a group?
+ if (compIt->second.Group == CM_NULLPTR) {
+ cmCPackLogger(
+ cmCPackLog::LOG_VERBOSE, "Component <"
+ << compIt->second.Name
+ << "> does not belong to any group, package it separately."
+ << std::endl);
+ retval &= PackageOnePack(initialTopLevel, compIt->first);
+ }
+ }
+ }
+ // CPACK_COMPONENTS_IGNORE_GROUPS is set
+ // We build 1 package per component
+ else {
+ std::map<std::string, cmCPackComponent>::iterator compIt;
+ for (compIt = this->Components.begin(); compIt != this->Components.end();
+ ++compIt) {
+ retval &= PackageOnePack(initialTopLevel, compIt->first);
+ }
}
+ } else {
+ cmCPackLogger(
+ cmCPackLog::LOG_ERROR, "CPACK_RPM_MAIN_COMPONENT not set but"
+ << " it is mandatory with CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE"
+ << " being set.\n");
+ retval = 0;
}
if (retval) {
@@ -156,6 +341,10 @@ int cmCPackRPMGenerator::PackageComponentsAllInOne(
packageFileNames.clear();
std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
+ if (this->IsOn("CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE")) {
+ this->SetOption("CPACK_RPM_DEBUGINFO_PACKAGE", "ON");
+ }
+
cmCPackLogger(cmCPackLog::LOG_VERBOSE,
"Packaging all groups in one package..."
"(CPACK_COMPONENTS_ALL_[GROUPS_]IN_ONE_PACKAGE is set)"
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index 5c45b14..a3281ab 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -415,9 +415,7 @@ int main(int argc, char const* const* argv)
}
doc.SetSection("Generators", v);
-#undef cout
return doc.PrintRequestedDocumentation(std::cout) ? 0 : 1;
-#define cout no_cout_use_cmCPack_Log
}
if (cmSystemTools::GetErrorOccuredFlag()) {
diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx
index b37db30..0052a16 100644
--- a/Source/CTest/cmCTestMemCheckHandler.cxx
+++ b/Source/CTest/cmCTestMemCheckHandler.cxx
@@ -375,11 +375,7 @@ void cmCTestMemCheckHandler::GenerateDartOutput(cmXMLWriter& xml)
xml.StartElement("DefectList");
for (cc = 0; cc < this->GlobalResults.size(); cc++) {
if (this->GlobalResults[cc]) {
-#ifdef cerr
-#undef cerr
-#endif
std::cerr.width(35);
-#define cerr no_cerr
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
this->ResultStringsLong[cc]
<< " - " << this->GlobalResults[cc] << std::endl,
diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx
index 3a08aea..56a469d 100644
--- a/Source/cmCPluginAPI.cxx
+++ b/Source/cmCPluginAPI.cxx
@@ -162,7 +162,14 @@ void CCONV cmAddLinkDirectoryForTarget(void* arg, const char* tgt,
const char* d)
{
cmMakefile* mf = static_cast<cmMakefile*>(arg);
- mf->AddLinkDirectoryForTarget(tgt, d);
+ cmTarget* t = mf->FindLocalNonAliasTarget(tgt);
+ if (!t) {
+ cmSystemTools::Error(
+ "Attempt to add link directories to non-existent target: ", tgt,
+ " for directory ", d);
+ return;
+ }
+ t->AddLinkDirectory(d);
}
void CCONV cmAddExecutable(void* arg, const char* exename, int numSrcs,
@@ -330,6 +337,35 @@ void CCONV cmAddCustomCommandToTarget(void* arg, const char* target,
cctype, no_comment, no_working_dir);
}
+static void addLinkLibrary(cmMakefile* mf, std::string const& target,
+ std::string const& lib, cmTargetLinkLibraryType llt)
+{
+ cmTarget* t = mf->FindLocalNonAliasTarget(target);
+ if (!t) {
+ std::ostringstream e;
+ e << "Attempt to add link library \"" << lib << "\" to target \"" << target
+ << "\" which is not built in this directory.";
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return;
+ }
+
+ cmTarget* tgt = mf->GetGlobalGenerator()->FindTarget(lib);
+ if (tgt && (tgt->GetType() != cmState::STATIC_LIBRARY) &&
+ (tgt->GetType() != cmState::SHARED_LIBRARY) &&
+ (tgt->GetType() != cmState::INTERFACE_LIBRARY) &&
+ !tgt->IsExecutableWithExports()) {
+ std::ostringstream e;
+ e << "Target \"" << lib << "\" of type "
+ << cmState::GetTargetTypeName(tgt->GetType())
+ << " may not be linked into another target. "
+ << "One may link only to STATIC or SHARED libraries, or "
+ << "to executables with the ENABLE_EXPORTS property set.";
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ }
+
+ t->AddLinkLibrary(*mf, lib, llt);
+}
+
void CCONV cmAddLinkLibraryForTarget(void* arg, const char* tgt,
const char* value, int libtype)
{
@@ -337,13 +373,13 @@ void CCONV cmAddLinkLibraryForTarget(void* arg, const char* tgt,
switch (libtype) {
case CM_LIBRARY_GENERAL:
- mf->AddLinkLibraryForTarget(tgt, value, GENERAL_LibraryType);
+ addLinkLibrary(mf, tgt, value, GENERAL_LibraryType);
break;
case CM_LIBRARY_DEBUG:
- mf->AddLinkLibraryForTarget(tgt, value, DEBUG_LibraryType);
+ addLinkLibrary(mf, tgt, value, DEBUG_LibraryType);
break;
case CM_LIBRARY_OPTIMIZED:
- mf->AddLinkLibraryForTarget(tgt, value, OPTIMIZED_LibraryType);
+ addLinkLibrary(mf, tgt, value, OPTIMIZED_LibraryType);
break;
}
}
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 1824d94..7dc9e33 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -2651,13 +2651,6 @@ static const char* cmCTestStringLogType[] = { "DEBUG",
"ERROR_MESSAGE",
CM_NULLPTR };
-#ifdef cerr
-#undef cerr
-#endif
-#ifdef cout
-#undef cout
-#endif
-
#define cmCTestLogOutputFileLine(stream) \
if (this->ShowLineNumbers) { \
(stream) << std::endl << file << ":" << line << " "; \
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
index 6887a31..b995fa1 100644
--- a/Source/cmCommonTargetGenerator.cxx
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -12,6 +12,7 @@
#include "cmComputeLinkInformation.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalCommonGenerator.h"
+#include "cmLinkLineComputer.h"
#include "cmLocalCommonGenerator.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
@@ -59,7 +60,8 @@ void cmCommonTargetGenerator::AddFeatureFlags(std::string& flags,
}
}
-void cmCommonTargetGenerator::AddModuleDefinitionFlag(std::string& flags)
+void cmCommonTargetGenerator::AddModuleDefinitionFlag(
+ cmLinkLineComputer* linkLineComputer, std::string& flags)
{
if (!this->ModuleDefinitionFile) {
return;
@@ -75,8 +77,10 @@ void cmCommonTargetGenerator::AddModuleDefinitionFlag(std::string& flags)
// Append the flag and value. Use ConvertToLinkReference to help
// vs6's "cl -link" pass it to the linker.
std::string flag = defFileFlag;
- flag += (this->LocalGenerator->ConvertToLinkReference(
- this->ModuleDefinitionFile->GetFullPath()));
+ flag += this->LocalGenerator->ConvertToOutputFormat(
+ linkLineComputer->ConvertToLinkReference(
+ this->ModuleDefinitionFile->GetFullPath()),
+ cmOutputConverter::SHELL);
this->LocalGenerator->AppendFlags(flags, flag);
}
diff --git a/Source/cmCommonTargetGenerator.h b/Source/cmCommonTargetGenerator.h
index 707b81e..fe27038 100644
--- a/Source/cmCommonTargetGenerator.h
+++ b/Source/cmCommonTargetGenerator.h
@@ -16,6 +16,7 @@ class cmGlobalCommonGenerator;
class cmLocalCommonGenerator;
class cmMakefile;
class cmSourceFile;
+class cmLinkLineComputer;
/** \class cmCommonTargetGenerator
* \brief Common infrastructure for Makefile and Ninja per-target generators
@@ -37,7 +38,8 @@ protected:
bool GetFeatureAsBool(const std::string& feature);
// Helper to add flag for windows .def file.
- void AddModuleDefinitionFlag(std::string& flags);
+ void AddModuleDefinitionFlag(cmLinkLineComputer* linkLineComputer,
+ std::string& flags);
cmGeneratorTarget* GeneratorTarget;
cmMakefile* Makefile;
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index dc8236d..0807ef8 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -1710,6 +1710,12 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
const char* install_rpath = this->Target->GetProperty("INSTALL_RPATH");
cmCLI_ExpandListUnique(install_rpath, runtimeDirs, emitted);
}
+ if (use_build_rpath) {
+ // Add directories explicitly specified by user
+ if (const char* build_rpath = this->Target->GetProperty("BUILD_RPATH")) {
+ cmCLI_ExpandListUnique(build_rpath, runtimeDirs, emitted);
+ }
+ }
if (use_build_rpath || use_link_rpath) {
std::string rootPath = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT");
const char* stagePath =
diff --git a/Source/cmConvertMSBuildXMLToJSON.py b/Source/cmConvertMSBuildXMLToJSON.py
new file mode 100644
index 0000000..93ab8a8
--- /dev/null
+++ b/Source/cmConvertMSBuildXMLToJSON.py
@@ -0,0 +1,453 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+import argparse
+import codecs
+import copy
+import logging
+import json
+import os
+
+from collections import OrderedDict
+from xml.dom.minidom import parse, parseString, Element
+
+
+class VSFlags:
+ """Flags corresponding to cmIDEFlagTable."""
+ UserValue = "UserValue" # (1 << 0)
+ UserIgnored = "UserIgnored" # (1 << 1)
+ UserRequired = "UserRequired" # (1 << 2)
+ Continue = "Continue" #(1 << 3)
+ SemicolonAppendable = "SemicolonAppendable" # (1 << 4)
+ UserFollowing = "UserFollowing" # (1 << 5)
+ CaseInsensitive = "CaseInsensitive" # (1 << 6)
+ UserValueIgnored = [UserValue, UserIgnored]
+ UserValueRequired = [UserValue, UserRequired]
+
+
+def vsflags(*args):
+ """Combines the flags."""
+ values = []
+
+ for arg in args:
+ __append_list(values, arg)
+
+ return values
+
+
+def read_msbuild_xml(path, values={}):
+ """Reads the MS Build XML file at the path and returns its contents.
+
+ Keyword arguments:
+ values -- The map to append the contents to (default {})
+ """
+
+ # Attempt to read the file contents
+ try:
+ document = parse(path)
+ except Exception as e:
+ logging.exception('Could not read MS Build XML file at %s', path)
+ return values
+
+ # Convert the XML to JSON format
+ logging.info('Processing MS Build XML file at %s', path)
+
+ # Get the rule node
+ rule = document.getElementsByTagName('Rule')[0]
+
+ rule_name = rule.attributes['Name'].value
+
+ logging.info('Found rules for %s', rule_name)
+
+ # Proprocess Argument values
+ __preprocess_arguments(rule)
+
+ # Get all the values
+ converted_values = []
+ __convert(rule, 'EnumProperty', converted_values, __convert_enum)
+ __convert(rule, 'BoolProperty', converted_values, __convert_bool)
+ __convert(rule, 'StringListProperty', converted_values,
+ __convert_string_list)
+ __convert(rule, 'StringProperty', converted_values, __convert_string)
+ __convert(rule, 'IntProperty', converted_values, __convert_string)
+
+ values[rule_name] = converted_values
+
+ return values
+
+
+def read_msbuild_json(path, values=[]):
+ """Reads the MS Build JSON file at the path and returns its contents.
+
+ Keyword arguments:
+ values -- The list to append the contents to (default [])
+ """
+ if not os.path.exists(path):
+ logging.info('Could not find MS Build JSON file at %s', path)
+ return values
+
+ try:
+ values.extend(__read_json_file(path))
+ except Exception as e:
+ logging.exception('Could not read MS Build JSON file at %s', path)
+ return values
+
+ logging.info('Processing MS Build JSON file at %s', path)
+
+ return values
+
+
+def main():
+ """Script entrypoint."""
+ # Parse the arguments
+ parser = argparse.ArgumentParser(
+ description='Convert MSBuild XML to JSON format')
+
+ parser.add_argument(
+ '-t', '--toolchain', help='The name of the toolchain', required=True)
+ parser.add_argument(
+ '-o', '--output', help='The output directory', default='')
+ parser.add_argument(
+ '-r',
+ '--overwrite',
+ help='Whether previously output should be overwritten',
+ dest='overwrite',
+ action='store_true')
+ parser.set_defaults(overwrite=False)
+ parser.add_argument(
+ '-d',
+ '--debug',
+ help="Debug tool output",
+ action="store_const",
+ dest="loglevel",
+ const=logging.DEBUG,
+ default=logging.WARNING)
+ parser.add_argument(
+ '-v',
+ '--verbose',
+ help="Verbose output",
+ action="store_const",
+ dest="loglevel",
+ const=logging.INFO)
+ parser.add_argument('input', help='The input files', nargs='+')
+
+ args = parser.parse_args()
+
+ toolchain = args.toolchain
+
+ logging.basicConfig(level=args.loglevel)
+ logging.info('Creating %s toolchain files', toolchain)
+
+ values = {}
+
+ # Iterate through the inputs
+ for input in args.input:
+ input = __get_path(input)
+
+ read_msbuild_xml(input, values)
+
+ # Determine if the output directory needs to be created
+ output_dir = __get_path(args.output)
+
+ if not os.path.exists(output_dir):
+ os.mkdir(output_dir)
+ logging.info('Created output directory %s', output_dir)
+
+ for key, value in values.items():
+ output_path = __output_path(toolchain, key, output_dir)
+
+ if os.path.exists(output_path) and not args.overwrite:
+ logging.info('Comparing previous output to current')
+
+ __merge_json_values(value, read_msbuild_json(output_path))
+ else:
+ logging.info('Original output will be overwritten')
+
+ logging.info('Writing MS Build JSON file at %s', output_path)
+
+ __write_json_file(output_path, value)
+
+
+###########################################################################################
+# private joining functions
+def __merge_json_values(current, previous):
+ """Merges the values between the current and previous run of the script."""
+ for value in current:
+ name = value['name']
+
+ # Find the previous value
+ previous_value = __find_and_remove_value(previous, value)
+
+ if previous_value is not None:
+ flags = value['flags']
+ previous_flags = previous_value['flags']
+
+ if flags != previous_flags:
+ logging.warning(
+ 'Flags for %s are different. Using previous value.', name)
+
+ value['flags'] = previous_flags
+ else:
+ logging.warning('Value %s is a new value', name)
+
+ for value in previous:
+ name = value['name']
+ logging.warning(
+ 'Value %s not present in current run. Appending value.', name)
+
+ current.append(value)
+
+
+def __find_and_remove_value(list, compare):
+ """Finds the value in the list that corresponds with the value of compare."""
+ # next throws if there are no matches
+ try:
+ found = next(value for value in list
+ if value['name'] == compare['name'] and value['switch'] ==
+ compare['switch'])
+ except:
+ return None
+
+ list.remove(found)
+
+ return found
+
+
+###########################################################################################
+# private xml functions
+def __convert(root, tag, values, func):
+ """Converts the tag type found in the root and converts them using the func
+ and appends them to the values.
+ """
+ elements = root.getElementsByTagName(tag)
+
+ for element in elements:
+ converted = func(element)
+
+ # Append to the list
+ __append_list(values, converted)
+
+
+def __convert_enum(node):
+ """Converts an EnumProperty node to JSON format."""
+ name = __get_attribute(node, 'Name')
+ logging.debug('Found EnumProperty named %s', name)
+
+ converted_values = []
+
+ for value in node.getElementsByTagName('EnumValue'):
+ converted = __convert_node(value)
+
+ converted['value'] = converted['name']
+ converted['name'] = name
+
+ # Modify flags when there is an argument child
+ __with_argument(value, converted)
+
+ converted_values.append(converted)
+
+ return converted_values
+
+
+def __convert_bool(node):
+ """Converts an BoolProperty node to JSON format."""
+ converted = __convert_node(node, default_value='true')
+
+ # Check for a switch for reversing the value
+ reverse_switch = __get_attribute(node, 'ReverseSwitch')
+
+ if reverse_switch:
+ converted_reverse = copy.deepcopy(converted)
+
+ converted_reverse['switch'] = reverse_switch
+ converted_reverse['value'] = 'false'
+
+ return [converted_reverse, converted]
+
+ # Modify flags when there is an argument child
+ __with_argument(node, converted)
+
+ return __check_for_flag(converted)
+
+
+def __convert_string_list(node):
+ """Converts a StringListProperty node to JSON format."""
+ converted = __convert_node(node)
+
+ # Determine flags for the string list
+ flags = vsflags(VSFlags.UserValue)
+
+ # Check for a separator to determine if it is semicolon appendable
+ # If not present assume the value should be ;
+ separator = __get_attribute(node, 'Separator', default_value=';')
+
+ if separator == ';':
+ flags = vsflags(flags, VSFlags.SemicolonAppendable)
+
+ converted['flags'] = flags
+
+ return __check_for_flag(converted)
+
+
+def __convert_string(node):
+ """Converts a StringProperty node to JSON format."""
+ converted = __convert_node(node, default_flags=vsflags(VSFlags.UserValue))
+
+ return __check_for_flag(converted)
+
+
+def __convert_node(node, default_value='', default_flags=vsflags()):
+ """Converts a XML node to a JSON equivalent."""
+ name = __get_attribute(node, 'Name')
+ logging.debug('Found %s named %s', node.tagName, name)
+
+ converted = {}
+ converted['name'] = name
+ converted['switch'] = __get_attribute(node, 'Switch')
+ converted['comment'] = __get_attribute(node, 'DisplayName')
+ converted['value'] = default_value
+
+ # Check for the Flags attribute in case it was created during preprocessing
+ flags = __get_attribute(node, 'Flags')
+
+ if flags:
+ flags = flags.split(',')
+ else:
+ flags = default_flags
+
+ converted['flags'] = flags
+
+ return converted
+
+
+def __check_for_flag(value):
+ """Checks whether the value has a switch value.
+
+ If not then returns None as it should not be added.
+ """
+ if value['switch']:
+ return value
+ else:
+ logging.warning('Skipping %s which has no command line switch',
+ value['name'])
+ return None
+
+
+def __with_argument(node, value):
+ """Modifies the flags in value if the node contains an Argument."""
+ arguments = node.getElementsByTagName('Argument')
+
+ if arguments:
+ logging.debug('Found argument within %s', value['name'])
+ value['flags'] = vsflags(VSFlags.UserValueIgnored, VSFlags.Continue)
+
+
+def __preprocess_arguments(root):
+ """Preprocesses occurrances of Argument within the root.
+
+ Argument XML values reference other values within the document by name. The
+ referenced value does not contain a switch. This function will add the
+ switch associated with the argument.
+ """
+ # Set the flags to require a value
+ flags = ','.join(vsflags(VSFlags.UserValueRequired))
+
+ # Search through the arguments
+ arguments = root.getElementsByTagName('Argument')
+
+ for argument in arguments:
+ reference = __get_attribute(argument, 'Property')
+ found = None
+
+ # Look for the argument within the root's children
+ for child in root.childNodes:
+ # Ignore Text nodes
+ if isinstance(child, Element):
+ name = __get_attribute(child, 'Name')
+
+ if name == reference:
+ found = child
+ break
+
+ if found is not None:
+ logging.info('Found property named %s', reference)
+ # Get the associated switch
+ switch = __get_attribute(argument.parentNode, 'Switch')
+
+ # See if there is already a switch associated with the element.
+ if __get_attribute(found, 'Switch'):
+ logging.debug('Copying node %s', reference)
+ clone = found.cloneNode(True)
+ root.insertBefore(clone, found)
+ found = clone
+
+ found.setAttribute('Switch', switch)
+ found.setAttribute('Flags', flags)
+ else:
+ logging.warning('Could not find property named %s', reference)
+
+
+def __get_attribute(node, name, default_value=''):
+ """Retrieves the attribute of the given name from the node.
+
+ If not present then the default_value is used.
+ """
+ if node.hasAttribute(name):
+ return node.attributes[name].value.strip()
+ else:
+ return default_value
+
+
+###########################################################################################
+# private path functions
+def __get_path(path):
+ """Gets the path to the file."""
+ if not os.path.isabs(path):
+ path = os.path.join(os.getcwd(), path)
+
+ return os.path.normpath(path)
+
+
+def __output_path(toolchain, rule, output_dir):
+ """Gets the output path for a file given the toolchain, rule and output_dir"""
+ filename = '%s_%s.json' % (toolchain, rule)
+ return os.path.join(output_dir, filename)
+
+
+###########################################################################################
+# private JSON file functions
+def __read_json_file(path):
+ """Reads a JSON file at the path."""
+ with open(path, 'r') as f:
+ return json.load(f)
+
+
+def __write_json_file(path, values):
+ """Writes a JSON file at the path with the values provided."""
+ # Sort the keys to ensure ordering
+ sort_order = ['name', 'switch', 'comment', 'value', 'flags']
+ sorted_values = [
+ OrderedDict(
+ sorted(
+ value.items(), key=lambda value: sort_order.index(value[0])))
+ for value in values
+ ]
+
+ with open(path, 'w') as f:
+ json.dump(sorted_values, f, indent=2, separators=(',', ': '))
+
+
+###########################################################################################
+# private list helpers
+def __append_list(append_to, value):
+ """Appends the value to the list."""
+ if value is not None:
+ if isinstance(value, list):
+ append_to.extend(value)
+ else:
+ append_to.append(value)
+
+###########################################################################################
+# main entry point
+if __name__ == "__main__":
+ main()
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx
index c1c8880..aaa9d3a 100644
--- a/Source/cmDependsFortran.cxx
+++ b/Source/cmDependsFortran.cxx
@@ -198,16 +198,13 @@ bool cmDependsFortran::Finalize(std::ostream& makeDepends,
stamp += ".mod.stamp";
fcStream << "\n";
fcStream << " \""
- << this->LocalGenerator->ConvertToRelativePath(currentBinDir,
- mod_lower)
+ << this->MaybeConvertToRelativePath(currentBinDir, mod_lower)
<< "\"\n";
fcStream << " \""
- << this->LocalGenerator->ConvertToRelativePath(currentBinDir,
- mod_upper)
+ << this->MaybeConvertToRelativePath(currentBinDir, mod_upper)
<< "\"\n";
fcStream << " \""
- << this->LocalGenerator->ConvertToRelativePath(currentBinDir,
- stamp)
+ << this->MaybeConvertToRelativePath(currentBinDir, stamp)
<< "\"\n";
}
fcStream << " )\n";
@@ -323,17 +320,16 @@ bool cmDependsFortran::WriteDependenciesReal(const char* obj,
// Write the include dependencies to the output stream.
std::string binDir = this->LocalGenerator->GetBinaryDirectory();
- std::string obj_i = this->LocalGenerator->ConvertToRelativePath(binDir, obj);
+ std::string obj_i = this->MaybeConvertToRelativePath(binDir, obj);
std::string obj_m = cmSystemTools::ConvertToOutputPath(obj_i.c_str());
internalDepends << obj_i << std::endl;
internalDepends << " " << src << std::endl;
for (std::set<std::string>::const_iterator i = info.Includes.begin();
i != info.Includes.end(); ++i) {
- makeDepends
- << obj_m << ": "
- << cmSystemTools::ConvertToOutputPath(
- this->LocalGenerator->ConvertToRelativePath(binDir, *i).c_str())
- << std::endl;
+ makeDepends << obj_m << ": "
+ << cmSystemTools::ConvertToOutputPath(
+ this->MaybeConvertToRelativePath(binDir, *i).c_str())
+ << std::endl;
internalDepends << " " << *i << std::endl;
}
makeDepends << std::endl;
@@ -359,7 +355,7 @@ bool cmDependsFortran::WriteDependenciesReal(const char* obj,
proxy += *i;
proxy += ".mod.proxy";
proxy = cmSystemTools::ConvertToOutputPath(
- this->LocalGenerator->ConvertToRelativePath(binDir, proxy).c_str());
+ this->MaybeConvertToRelativePath(binDir, proxy).c_str());
// since we require some things add them to our list of requirements
makeDepends << obj_m << ".requires: " << proxy << std::endl;
@@ -375,8 +371,7 @@ bool cmDependsFortran::WriteDependenciesReal(const char* obj,
if (!required->second.empty()) {
// This module is known. Depend on its timestamp file.
std::string stampFile = cmSystemTools::ConvertToOutputPath(
- this->LocalGenerator->ConvertToRelativePath(binDir, required->second)
- .c_str());
+ this->MaybeConvertToRelativePath(binDir, required->second).c_str());
makeDepends << obj_m << ": " << stampFile << "\n";
} else {
// This module is not known to CMake. Try to locate it where
@@ -384,7 +379,7 @@ bool cmDependsFortran::WriteDependenciesReal(const char* obj,
std::string module;
if (this->FindModule(*i, module)) {
module = cmSystemTools::ConvertToOutputPath(
- this->LocalGenerator->ConvertToRelativePath(binDir, module).c_str());
+ this->MaybeConvertToRelativePath(binDir, module).c_str());
makeDepends << obj_m << ": " << module << "\n";
}
}
@@ -398,7 +393,7 @@ bool cmDependsFortran::WriteDependenciesReal(const char* obj,
proxy += *i;
proxy += ".mod.proxy";
proxy = cmSystemTools::ConvertToOutputPath(
- this->LocalGenerator->ConvertToRelativePath(binDir, proxy).c_str());
+ this->MaybeConvertToRelativePath(binDir, proxy).c_str());
makeDepends << proxy << ": " << obj_m << ".provides" << std::endl;
}
@@ -420,14 +415,14 @@ bool cmDependsFortran::WriteDependenciesReal(const char* obj,
modFile += "/";
modFile += *i;
modFile = this->LocalGenerator->ConvertToOutputFormat(
- this->LocalGenerator->ConvertToRelativePath(binDir, modFile),
+ this->MaybeConvertToRelativePath(binDir, modFile),
cmOutputConverter::SHELL);
std::string stampFile = stamp_dir;
stampFile += "/";
stampFile += m;
stampFile += ".mod.stamp";
stampFile = this->LocalGenerator->ConvertToOutputFormat(
- this->LocalGenerator->ConvertToRelativePath(binDir, stampFile),
+ this->MaybeConvertToRelativePath(binDir, stampFile),
cmOutputConverter::SHELL);
makeDepends << "\t$(CMAKE_COMMAND) -E cmake_copy_f90_mod " << modFile
<< " " << stampFile;
@@ -448,7 +443,7 @@ bool cmDependsFortran::WriteDependenciesReal(const char* obj,
std::string driver = this->TargetDirectory;
driver += "/build";
driver = cmSystemTools::ConvertToOutputPath(
- this->LocalGenerator->ConvertToRelativePath(binDir, driver).c_str());
+ this->MaybeConvertToRelativePath(binDir, driver).c_str());
makeDepends << driver << ": " << obj_m << ".provides.build\n";
}
@@ -708,3 +703,13 @@ bool cmDependsFortran::ModulesDiffer(const char* modFile,
// content.
return cmFortranStreamsDiffer(finModFile, finStampFile);
}
+
+std::string cmDependsFortran::MaybeConvertToRelativePath(
+ std::string const& base, std::string const& path)
+{
+ if (!cmOutputConverter::ContainedInDirectory(
+ base, path, this->LocalGenerator->GetStateSnapshot().GetDirectory())) {
+ return path;
+ }
+ return cmOutputConverter::ForceToRelativePath(base, path);
+}
diff --git a/Source/cmDependsFortran.h b/Source/cmDependsFortran.h
index 8d347f4..90b82d4 100644
--- a/Source/cmDependsFortran.h
+++ b/Source/cmDependsFortran.h
@@ -78,6 +78,9 @@ protected:
private:
cmDependsFortran(cmDependsFortran const&); // Purposely not implemented.
void operator=(cmDependsFortran const&); // Purposely not implemented.
+
+ std::string MaybeConvertToRelativePath(std::string const& base,
+ std::string const& path);
};
#endif
diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx
index 2d86674..0655da9 100644
--- a/Source/cmELF.cxx
+++ b/Source/cmELF.cxx
@@ -132,18 +132,13 @@ public:
// Forward to the per-class implementation.
virtual unsigned int GetNumberOfSections() const = 0;
- virtual unsigned int GetDynamicEntryCount() = 0;
virtual unsigned long GetDynamicEntryPosition(int j) = 0;
+ virtual cmELF::DynamicEntryList GetDynamicEntries() = 0;
+ virtual std::vector<char> EncodeDynamicEntries(
+ const cmELF::DynamicEntryList&) = 0;
virtual StringEntry const* GetDynamicSectionString(unsigned int tag) = 0;
virtual void PrintInfo(std::ostream& os) const = 0;
- bool ReadBytes(unsigned long pos, unsigned long size, char* buf)
- {
- this->Stream.seekg(pos);
- this->Stream.read(buf, size);
- return !this->Stream.fail();
- }
-
// Lookup the SONAME in the DYNAMIC section.
StringEntry const* GetSOName()
{
@@ -246,10 +241,13 @@ public:
return static_cast<unsigned int>(this->ELFHeader.e_shnum);
}
- // Get the file position and size of a dynamic section entry.
- unsigned int GetDynamicEntryCount() CM_OVERRIDE;
+ // Get the file position of a dynamic section entry.
unsigned long GetDynamicEntryPosition(int j) CM_OVERRIDE;
+ cmELF::DynamicEntryList GetDynamicEntries() CM_OVERRIDE;
+ std::vector<char> EncodeDynamicEntries(const cmELF::DynamicEntryList&)
+ CM_OVERRIDE;
+
// Lookup a string from the dynamic section with the given tag.
StringEntry const* GetDynamicSectionString(unsigned int tag) CM_OVERRIDE;
@@ -289,6 +287,10 @@ public:
}
private:
+ // ByteSwap(ELF_Dyn) assumes d_val and d_ptr are the same size
+ typedef char dyn_size_assert
+ [sizeof(ELF_Dyn().d_un.d_val) == sizeof(ELF_Dyn().d_un.d_ptr) ? 1 : -1];
+
void ByteSwap(ELF_Ehdr& elf_header)
{
cmELFByteSwap(elf_header.e_type);
@@ -323,121 +325,7 @@ private:
void ByteSwap(ELF_Dyn& dyn)
{
cmELFByteSwap(dyn.d_tag);
- switch (dyn.d_tag) {
- case DT_NULL: /* dyn.d_un ignored */
- break;
- case DT_NEEDED:
- cmELFByteSwap(dyn.d_un.d_val);
- break;
- case DT_PLTRELSZ:
- cmELFByteSwap(dyn.d_un.d_val);
- break;
- case DT_PLTGOT:
- cmELFByteSwap(dyn.d_un.d_ptr);
- break;
- case DT_HASH:
- cmELFByteSwap(dyn.d_un.d_ptr);
- break;
- case DT_STRTAB:
- cmELFByteSwap(dyn.d_un.d_ptr);
- break;
- case DT_SYMTAB:
- cmELFByteSwap(dyn.d_un.d_ptr);
- break;
- case DT_RELA:
- cmELFByteSwap(dyn.d_un.d_ptr);
- break;
- case DT_RELASZ:
- cmELFByteSwap(dyn.d_un.d_val);
- break;
- case DT_RELAENT:
- cmELFByteSwap(dyn.d_un.d_val);
- break;
- case DT_STRSZ:
- cmELFByteSwap(dyn.d_un.d_val);
- break;
- case DT_SYMENT:
- cmELFByteSwap(dyn.d_un.d_val);
- break;
- case DT_INIT:
- cmELFByteSwap(dyn.d_un.d_ptr);
- break;
- case DT_FINI:
- cmELFByteSwap(dyn.d_un.d_ptr);
- break;
- case DT_SONAME:
- cmELFByteSwap(dyn.d_un.d_val);
- break;
- case DT_RPATH:
- cmELFByteSwap(dyn.d_un.d_val);
- break;
- case DT_SYMBOLIC: /* dyn.d_un ignored */
- break;
- case DT_REL:
- cmELFByteSwap(dyn.d_un.d_ptr);
- break;
- case DT_RELSZ:
- cmELFByteSwap(dyn.d_un.d_val);
- break;
- case DT_RELENT:
- cmELFByteSwap(dyn.d_un.d_val);
- break;
- case DT_PLTREL:
- cmELFByteSwap(dyn.d_un.d_val);
- break;
- case DT_DEBUG:
- cmELFByteSwap(dyn.d_un.d_ptr);
- break;
- case DT_TEXTREL: /* dyn.d_un ignored */
- break;
- case DT_JMPREL:
- cmELFByteSwap(dyn.d_un.d_ptr);
- break;
-#ifdef T_BIND_NOW
- case T_BIND_NOW: /* dyn.d_un ignored */
- break;
-#endif
-#ifdef DT_INIT_ARRAY
- case DT_INIT_ARRAY:
- cmELFByteSwap(dyn.d_un.d_ptr);
- break;
-#endif
-#ifdef DT_FINI_ARRAY
- case DT_FINI_ARRAY:
- cmELFByteSwap(dyn.d_un.d_ptr);
- break;
-#endif
-#ifdef DT_INIT_ARRAYSZ
- case DT_INIT_ARRAYSZ:
- cmELFByteSwap(dyn.d_un.d_val);
- break;
-#endif
-#ifdef DT_FINI_ARRAYSZ
- case DT_FINI_ARRAYSZ:
- cmELFByteSwap(dyn.d_un.d_val);
- break;
-#endif
-#ifdef DT_RUNPATH
- case DT_RUNPATH:
- cmELFByteSwap(dyn.d_un.d_val);
- break;
-#endif
-#ifdef DT_FLAGS
- case DT_FLAGS:
- cmELFByteSwap(dyn.d_un.d_val);
- break;
-#endif
-#ifdef DT_PREINIT_ARRAY
- case DT_PREINIT_ARRAY:
- cmELFByteSwap(dyn.d_un.d_ptr);
- break;
-#endif
-#ifdef DT_PREINIT_ARRAYSZ
- case DT_PREINIT_ARRAYSZ:
- cmELFByteSwap(dyn.d_un.d_val);
- break;
-#endif
- }
+ cmELFByteSwap(dyn.d_un.d_val);
}
bool FileTypeValid(ELF_Half et)
@@ -636,30 +524,64 @@ bool cmELFInternalImpl<Types>::LoadDynamicSection()
}
template <class Types>
-unsigned int cmELFInternalImpl<Types>::GetDynamicEntryCount()
+unsigned long cmELFInternalImpl<Types>::GetDynamicEntryPosition(int j)
{
if (!this->LoadDynamicSection()) {
return 0;
}
- for (unsigned int i = 0; i < this->DynamicSectionEntries.size(); ++i) {
- if (this->DynamicSectionEntries[i].d_tag == DT_NULL) {
- return i;
- }
+ if (j < 0 || j >= static_cast<int>(this->DynamicSectionEntries.size())) {
+ return 0;
}
- return static_cast<unsigned int>(this->DynamicSectionEntries.size());
+ ELF_Shdr const& sec = this->SectionHeaders[this->DynamicSectionIndex];
+ return static_cast<unsigned long>(sec.sh_offset + sec.sh_entsize * j);
}
template <class Types>
-unsigned long cmELFInternalImpl<Types>::GetDynamicEntryPosition(int j)
+cmELF::DynamicEntryList cmELFInternalImpl<Types>::GetDynamicEntries()
{
+ cmELF::DynamicEntryList result;
+
+ // Ensure entries have been read from file
if (!this->LoadDynamicSection()) {
- return 0;
+ return result;
}
- if (j < 0 || j >= static_cast<int>(this->DynamicSectionEntries.size())) {
- return 0;
+
+ // Copy into public array
+ result.reserve(this->DynamicSectionEntries.size());
+ for (typename std::vector<ELF_Dyn>::iterator di =
+ this->DynamicSectionEntries.begin();
+ di != this->DynamicSectionEntries.end(); ++di) {
+ ELF_Dyn& dyn = *di;
+ result.push_back(
+ std::pair<unsigned long, unsigned long>(dyn.d_tag, dyn.d_un.d_val));
}
- ELF_Shdr const& sec = this->SectionHeaders[this->DynamicSectionIndex];
- return static_cast<unsigned long>(sec.sh_offset + sec.sh_entsize * j);
+
+ return result;
+}
+
+template <class Types>
+std::vector<char> cmELFInternalImpl<Types>::EncodeDynamicEntries(
+ const cmELF::DynamicEntryList& entries)
+{
+ std::vector<char> result;
+ result.reserve(sizeof(ELF_Dyn) * entries.size());
+
+ for (cmELF::DynamicEntryList::const_iterator it = entries.begin();
+ it != entries.end(); it++) {
+ // Store the entry in an ELF_Dyn, byteswap it, then serialize to chars
+ ELF_Dyn dyn;
+ dyn.d_tag = static_cast<tagtype>(it->first);
+ dyn.d_un.d_val = static_cast<tagtype>(it->second);
+
+ if (this->NeedSwap) {
+ ByteSwap(dyn);
+ }
+
+ char* pdyn = reinterpret_cast<char*>(&dyn);
+ result.insert(result.end(), pdyn, pdyn + sizeof(ELF_Dyn));
+ }
+
+ return result;
}
template <class Types>
@@ -752,6 +674,15 @@ cmELF::StringEntry const* cmELFInternalImpl<Types>::GetDynamicSectionString(
//============================================================================
// External class implementation.
+const long cmELF::TagRPath = DT_RPATH;
+const long cmELF::TagRunPath = DT_RUNPATH;
+
+#ifdef DT_MIPS_RLD_MAP_REL
+const long cmELF::TagMipsRldMapRel = DT_MIPS_RLD_MAP_REL;
+#else
+const long cmELF::TagMipsRldMapRel = 0;
+#endif
+
cmELF::cmELF(const char* fname)
: Internal(CM_NULLPTR)
{
@@ -839,28 +770,31 @@ unsigned int cmELF::GetNumberOfSections() const
return 0;
}
-unsigned int cmELF::GetDynamicEntryCount() const
+unsigned long cmELF::GetDynamicEntryPosition(int index) const
{
if (this->Valid()) {
- return this->Internal->GetDynamicEntryCount();
+ return this->Internal->GetDynamicEntryPosition(index);
}
return 0;
}
-unsigned long cmELF::GetDynamicEntryPosition(int index) const
+cmELF::DynamicEntryList cmELF::GetDynamicEntries() const
{
if (this->Valid()) {
- return this->Internal->GetDynamicEntryPosition(index);
+ return this->Internal->GetDynamicEntries();
}
- return 0;
+
+ return cmELF::DynamicEntryList();
}
-bool cmELF::ReadBytes(unsigned long pos, unsigned long size, char* buf) const
+std::vector<char> cmELF::EncodeDynamicEntries(
+ const cmELF::DynamicEntryList& dentries) const
{
if (this->Valid()) {
- return this->Internal->ReadBytes(pos, size, buf);
+ return this->Internal->EncodeDynamicEntries(dentries);
}
- return false;
+
+ return std::vector<char>();
}
bool cmELF::GetSOName(std::string& soname)
diff --git a/Source/cmELF.h b/Source/cmELF.h
index 7e7c1d6..763a240 100644
--- a/Source/cmELF.h
+++ b/Source/cmELF.h
@@ -7,6 +7,8 @@
#include <iosfwd>
#include <string>
+#include <utility>
+#include <vector>
#if !defined(CMAKE_USE_ELF_PARSER)
#error "This file may be included only if CMAKE_USE_ELF_PARSER is enabled."
@@ -61,22 +63,27 @@ public:
int IndexInSection;
};
+ /** Represent entire dynamic section header */
+ typedef std::vector<std::pair<long, unsigned long> > DynamicEntryList;
+
/** Get the type of the file opened. */
FileType GetFileType() const;
/** Get the number of ELF sections present. */
unsigned int GetNumberOfSections() const;
- /** Get the number of DYNAMIC section entries before the first
- DT_NULL. Returns zero on error. */
- unsigned int GetDynamicEntryCount() const;
-
/** Get the position of a DYNAMIC section header entry. Returns
zero on error. */
unsigned long GetDynamicEntryPosition(int index) const;
- /** Read bytes from the file. */
- bool ReadBytes(unsigned long pos, unsigned long size, char* buf) const;
+ /** Get a copy of all the DYNAMIC section header entries.
+ Returns an empty vector on error */
+ DynamicEntryList GetDynamicEntries() const;
+
+ /** Encodes a DYNAMIC section header entry list into a char vector according
+ to the type of ELF file this is */
+ std::vector<char> EncodeDynamicEntries(
+ const DynamicEntryList& entries) const;
/** Get the SONAME field if any. */
bool GetSOName(std::string& soname);
@@ -91,6 +98,10 @@ public:
/** Print human-readable information about the ELF file. */
void PrintInfo(std::ostream& os) const;
+ /** Interesting dynamic tags.
+ If the tag is 0, it does not exist in the host ELF implementation */
+ static const long TagRPath, TagRunPath, TagMipsRldMapRel;
+
private:
friend class cmELFInternal;
bool Valid() const;
diff --git a/Source/cmGeneratedFileStream.cxx b/Source/cmGeneratedFileStream.cxx
index 02717a4..6cdb7f5 100644
--- a/Source/cmGeneratedFileStream.cxx
+++ b/Source/cmGeneratedFileStream.cxx
@@ -10,13 +10,21 @@
#include <cm_zlib.h>
#endif
-cmGeneratedFileStream::cmGeneratedFileStream()
+cmGeneratedFileStream::cmGeneratedFileStream(Encoding encoding)
: cmGeneratedFileStreamBase()
, Stream()
{
+#ifdef CMAKE_BUILD_WITH_CMAKE
+ if (encoding != codecvt::None) {
+ imbue(std::locale(getloc(), new codecvt(encoding)));
+ }
+#else
+ static_cast<void>(encoding);
+#endif
}
-cmGeneratedFileStream::cmGeneratedFileStream(const char* name, bool quiet)
+cmGeneratedFileStream::cmGeneratedFileStream(const char* name, bool quiet,
+ Encoding encoding)
: cmGeneratedFileStreamBase(name)
, Stream(TempName.c_str())
{
@@ -26,6 +34,13 @@ cmGeneratedFileStream::cmGeneratedFileStream(const char* name, bool quiet)
this->TempName.c_str());
cmSystemTools::ReportLastSystemError("");
}
+#ifdef CMAKE_BUILD_WITH_CMAKE
+ if (encoding != codecvt::None) {
+ imbue(std::locale(getloc(), new codecvt(encoding)));
+ }
+#else
+ static_cast<void>(encoding);
+#endif
}
cmGeneratedFileStream::~cmGeneratedFileStream()
diff --git a/Source/cmGeneratedFileStream.h b/Source/cmGeneratedFileStream.h
index 515954c..a027b01 100644
--- a/Source/cmGeneratedFileStream.h
+++ b/Source/cmGeneratedFileStream.h
@@ -5,6 +5,7 @@
#include <cmConfigure.h>
+#include <cm_codecvt.hxx>
#include <cmsys/FStream.hxx>
#include <string>
@@ -71,12 +72,13 @@ class cmGeneratedFileStream : private cmGeneratedFileStreamBase,
{
public:
typedef cmsys::ofstream Stream;
+ typedef codecvt::Encoding Encoding;
/**
* This constructor prepares a default stream. The open method must
* be used before writing to the stream.
*/
- cmGeneratedFileStream();
+ cmGeneratedFileStream(Encoding encoding = codecvt::None);
/**
* This constructor takes the name of the file to be generated. It
@@ -84,7 +86,8 @@ public:
* file cannot be opened an error message is produced unless the
* second argument is set to true.
*/
- cmGeneratedFileStream(const char* name, bool quiet = false);
+ cmGeneratedFileStream(const char* name, bool quiet = false,
+ Encoding encoding = codecvt::None);
/**
* The destructor checks the stream status to be sure the temporary
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index e8d66a2..7eb0ebf 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -4965,6 +4965,9 @@ bool cmGeneratorTarget::HaveBuildTreeRPATH(const std::string& config) const
if (this->GetPropertyAsBool("SKIP_BUILD_RPATH")) {
return false;
}
+ if (this->GetProperty("BUILD_RPATH")) {
+ return true;
+ }
if (cmLinkImplementationLibraries const* impl =
this->GetLinkImplementationLibraries(config)) {
return !impl->Libraries.empty();
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
index 959dfdb..5fbaea4 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -5,6 +5,7 @@
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGhsMultiGenerator.h"
+#include "cmLinkLineComputer.h"
#include "cmLocalGhsMultiGenerator.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
@@ -244,7 +245,7 @@ void cmGhsMultiTargetGenerator::SetCompilerFlags(std::string const& config,
flags, this->GeneratorTarget, lang);
// Append old-style preprocessor definition flags.
- if (std::string(" ") != std::string(this->Makefile->GetDefineFlags())) {
+ if (this->Makefile->GetDefineFlags() != " ") {
this->LocalGenerator->AppendFlags(flags,
this->Makefile->GetDefineFlags());
}
@@ -362,9 +363,15 @@ void cmGhsMultiTargetGenerator::WriteTargetLinkLibraries(
this->GeneratorTarget->GetCreateRuleVariable(language, config);
bool useWatcomQuote =
this->Makefile->IsOn(createRule + "_USE_WATCOM_QUOTE");
+ CM_AUTO_PTR<cmLinkLineComputer> linkLineComputer(
+ this->GetGlobalGenerator()->CreateLinkLineComputer(
+ this->LocalGenerator,
+ this->LocalGenerator->GetStateSnapshot().GetDirectory()));
+ linkLineComputer->SetUseWatcomQuote(useWatcomQuote);
+
this->LocalGenerator->GetTargetFlags(
- config, linkLibraries, flags, linkFlags, frameworkPath, linkPath,
- this->GeneratorTarget, useWatcomQuote);
+ linkLineComputer.get(), config, linkLibraries, flags, linkFlags,
+ frameworkPath, linkPath, this->GeneratorTarget);
linkFlags = cmSystemTools::TrimWhitespace(linkFlags);
if (!linkPath.empty()) {
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 7132ade..1aa6af1 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -20,7 +20,9 @@
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmInstallGenerator.h"
+#include "cmLinkLineComputer.h"
#include "cmLocalGenerator.h"
+#include "cmMSVC60LinkLineComputer.h"
#include "cmMakefile.h"
#include "cmOutputConverter.h"
#include "cmPolicies.h"
@@ -1412,6 +1414,18 @@ cmGlobalGenerator::CreateQtAutoGeneratorsTargets()
return autogenTargets;
}
+cmLinkLineComputer* cmGlobalGenerator::CreateLinkLineComputer(
+ cmOutputConverter* outputConverter, cmState::Directory stateDir) const
+{
+ return new cmLinkLineComputer(outputConverter, stateDir);
+}
+
+cmLinkLineComputer* cmGlobalGenerator::CreateMSVC60LinkLineComputer(
+ cmOutputConverter* outputConverter, cmState::Directory stateDir) const
+{
+ return new cmMSVC60LinkLineComputer(outputConverter, stateDir);
+}
+
void cmGlobalGenerator::FinalizeTargetCompileInfo()
{
std::vector<std::string> const langs =
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index add2b92..38eaa76 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -10,6 +10,7 @@
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetDepend.h"
+#include "cm_codecvt.hxx"
#include <iosfwd>
#include <map>
@@ -33,7 +34,9 @@ class cmExportBuildFileGenerator;
class cmExternalMakefileProjectGenerator;
class cmGeneratorTarget;
class cmLocalGenerator;
+class cmLinkLineComputer;
class cmMakefile;
+class cmOutputConverter;
class cmake;
/** \class cmGlobalGenerator
@@ -60,6 +63,12 @@ public:
return this->GetName() == name;
}
+ /** Get encoding used by generator for makefile files */
+ virtual codecvt::Encoding GetMakefileEncoding() const
+ {
+ return codecvt::None;
+ }
+
/** Tell the generator about the target system. */
virtual bool SetSystemName(std::string const&, cmMakefile*) { return true; }
@@ -98,6 +107,12 @@ public:
*/
virtual void Generate();
+ virtual cmLinkLineComputer* CreateLinkLineComputer(
+ cmOutputConverter* outputConverter, cmState::Directory stateDir) const;
+
+ cmLinkLineComputer* CreateMSVC60LinkLineComputer(
+ cmOutputConverter* outputConverter, cmState::Directory stateDir) const;
+
/**
* Set/Get and Clear the enabled languages.
*/
diff --git a/Source/cmGlobalNMakeMakefileGenerator.h b/Source/cmGlobalNMakeMakefileGenerator.h
index f169e76..6eb2124 100644
--- a/Source/cmGlobalNMakeMakefileGenerator.h
+++ b/Source/cmGlobalNMakeMakefileGenerator.h
@@ -26,6 +26,12 @@ public:
}
static std::string GetActualName() { return "NMake Makefiles"; }
+ /** Get encoding used by generator for makefile files */
+ codecvt::Encoding GetMakefileEncoding() const CM_OVERRIDE
+ {
+ return codecvt::ANSI;
+ }
+
/** Get the documentation entry for this generator. */
static void GetDocumentation(cmDocumentationEntry& entry);
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index f5a0e68..67df038 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -11,6 +11,7 @@
#include "cmLocalGenerator.h"
#include "cmLocalNinjaGenerator.h"
#include "cmMakefile.h"
+#include "cmNinjaLinkLineComputer.h"
#include "cmOutputConverter.h"
#include "cmState.h"
#include "cmSystemTools.h"
@@ -64,6 +65,14 @@ void cmGlobalNinjaGenerator::WriteComment(std::ostream& os,
os << "# " << comment.substr(lpos) << "\n\n";
}
+cmLinkLineComputer* cmGlobalNinjaGenerator::CreateLinkLineComputer(
+ cmOutputConverter* outputConverter, cmState::Directory /* stateDir */) const
+{
+ return new cmNinjaLinkLineComputer(
+ outputConverter,
+ this->LocalGenerators[0]->GetStateSnapshot().GetDirectory(), this);
+}
+
std::string cmGlobalNinjaGenerator::EncodeRuleName(std::string const& name)
{
// Ninja rule names must match "[a-zA-Z0-9_.-]+". Use ".xx" to encode
@@ -830,7 +839,8 @@ static void EnsureTrailingSlash(std::string& path)
#endif
}
-std::string cmGlobalNinjaGenerator::ConvertToNinjaPath(const std::string& path)
+std::string cmGlobalNinjaGenerator::ConvertToNinjaPath(
+ const std::string& path) const
{
cmLocalNinjaGenerator* ng =
static_cast<cmLocalNinjaGenerator*>(this->LocalGenerators[0]);
@@ -1421,7 +1431,8 @@ void cmGlobalNinjaGenerator::InitOutputPathPrefix()
EnsureTrailingSlash(this->OutputPathPrefix);
}
-std::string cmGlobalNinjaGenerator::NinjaOutputPath(std::string const& path)
+std::string cmGlobalNinjaGenerator::NinjaOutputPath(
+ std::string const& path) const
{
if (!this->HasOutputPathPrefix() || cmSystemTools::FileIsFullPath(path)) {
return path;
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index dcf7406..6b77a2b 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -70,6 +70,10 @@ public:
std::string EncodePath(const std::string& path);
static std::string EncodeDepfileSpace(const std::string& path);
+ cmLinkLineComputer* CreateLinkLineComputer(
+ cmOutputConverter* outputConverter,
+ cmState::Directory stateDir) const CM_OVERRIDE;
+
/**
* Write the given @a comment to the output stream @a os. It
* handles new line character properly.
@@ -233,7 +237,7 @@ public:
return this->RulesFileStream;
}
- std::string ConvertToNinjaPath(const std::string& path);
+ std::string ConvertToNinjaPath(const std::string& path) const;
std::string ConvertToNinjaFolderRule(const std::string& path);
struct MapToNinjaPathImpl
@@ -333,7 +337,7 @@ public:
bool SupportsConsolePool() const;
bool SupportsImplicitOuts() const;
- std::string NinjaOutputPath(std::string const& path);
+ std::string NinjaOutputPath(std::string const& path) const;
bool HasOutputPathPrefix() const { return !this->OutputPathPrefix.empty(); }
void StripNinjaOutputPathPrefixAsSuffix(std::string& path);
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index 4a5cc77..daacef0 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -201,7 +201,8 @@ void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
this->GetCMakeInstance()->GetHomeOutputDirectory();
makefileName += cmake::GetCMakeFilesDirectory();
makefileName += "/Makefile2";
- cmGeneratedFileStream makefileStream(makefileName.c_str());
+ cmGeneratedFileStream makefileStream(makefileName.c_str(), false,
+ this->GetMakefileEncoding());
if (!makefileStream) {
return;
}
@@ -306,16 +307,12 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
// reset lg to the first makefile
lg = static_cast<cmLocalUnixMakefileGenerator3*>(this->LocalGenerators[0]);
- // Build the path to the cache file.
- std::string cache = this->GetCMakeInstance()->GetHomeOutputDirectory();
- cache += "/CMakeCache.txt";
-
std::string currentBinDir = lg->GetCurrentBinaryDirectory();
// Save the list to the cmake file.
cmakefileStream
<< "# The top level Makefile was generated from the following files:\n"
<< "set(CMAKE_MAKEFILE_DEPENDS\n"
- << " \"" << lg->ConvertToRelativePath(currentBinDir, cache) << "\"\n";
+ << " \"CMakeCache.txt\"\n";
for (std::vector<std::string>::const_iterator i = lfiles.begin();
i != lfiles.end(); ++i) {
cmakefileStream << " \"" << lg->ConvertToRelativePath(currentBinDir, *i)
diff --git a/Source/cmGlobalVisualStudio15Generator.cxx b/Source/cmGlobalVisualStudio15Generator.cxx
index 4d62f2b..a833a5f 100644
--- a/Source/cmGlobalVisualStudio15Generator.cxx
+++ b/Source/cmGlobalVisualStudio15Generator.cxx
@@ -79,7 +79,7 @@ cmGlobalVisualStudio15Generator::cmGlobalVisualStudio15Generator(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\15.0\\Setup\\VC;"
"ProductDir",
vc15Express, cmSystemTools::KeyWOW64_32);
- this->DefaultPlatformToolset = "v140";
+ this->DefaultPlatformToolset = "v141";
this->Version = VS15;
}
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 4ff612d..75fc2e4 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -3325,14 +3325,14 @@ std::string cmGlobalXCodeGenerator::RelativeToSource(const char* p)
{
// We force conversion because Xcode breakpoints do not work unless
// they are in a file named relative to the source tree.
- return this->CurrentLocalGenerator->ConvertToRelativePath(
- this->ProjectSourceDirectoryComponents, p, true);
+ return cmOutputConverter::ForceToRelativePath(
+ cmSystemTools::JoinPath(this->ProjectSourceDirectoryComponents), p);
}
std::string cmGlobalXCodeGenerator::RelativeToBinary(const char* p)
{
return this->CurrentLocalGenerator->ConvertToRelativePath(
- this->ProjectOutputDirectoryComponents, p);
+ cmSystemTools::JoinPath(this->ProjectOutputDirectoryComponents), p);
}
std::string cmGlobalXCodeGenerator::XCodeEscapePath(const std::string& p)
diff --git a/Source/cmLinkLibrariesCommand.cxx b/Source/cmLinkLibrariesCommand.cxx
index bb0e27b..4202cf5 100644
--- a/Source/cmLinkLibrariesCommand.cxx
+++ b/Source/cmLinkLibrariesCommand.cxx
@@ -20,7 +20,7 @@ bool cmLinkLibrariesCommand::InitialPass(std::vector<std::string> const& args,
"a library");
return false;
}
- this->Makefile->AddLinkLibrary(*i, DEBUG_LibraryType);
+ this->Makefile->AppendProperty("LINK_LIBRARIES", "debug");
} else if (*i == "optimized") {
++i;
if (i == args.end()) {
@@ -28,10 +28,9 @@ bool cmLinkLibrariesCommand::InitialPass(std::vector<std::string> const& args,
"a library");
return false;
}
- this->Makefile->AddLinkLibrary(*i, OPTIMIZED_LibraryType);
- } else {
- this->Makefile->AddLinkLibrary(*i);
+ this->Makefile->AppendProperty("LINK_LIBRARIES", "optimized");
}
+ this->Makefile->AppendProperty("LINK_LIBRARIES", i->c_str());
}
return true;
diff --git a/Source/cmLinkLineComputer.cxx b/Source/cmLinkLineComputer.cxx
new file mode 100644
index 0000000..24f3578
--- /dev/null
+++ b/Source/cmLinkLineComputer.cxx
@@ -0,0 +1,179 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmLinkLineComputer.h"
+#include "cmComputeLinkInformation.h"
+#include "cmGeneratorTarget.h"
+#include "cmOutputConverter.h"
+
+cmLinkLineComputer::cmLinkLineComputer(cmOutputConverter* outputConverter,
+ cmState::Directory stateDir)
+ : StateDir(stateDir)
+ , OutputConverter(outputConverter)
+ , ForResponse(false)
+ , UseWatcomQuote(false)
+ , Relink(false)
+{
+}
+
+cmLinkLineComputer::~cmLinkLineComputer()
+{
+}
+
+void cmLinkLineComputer::SetUseWatcomQuote(bool useWatcomQuote)
+{
+ this->UseWatcomQuote = useWatcomQuote;
+}
+
+void cmLinkLineComputer::SetForResponse(bool forResponse)
+{
+ this->ForResponse = forResponse;
+}
+
+void cmLinkLineComputer::SetRelink(bool relink)
+{
+ this->Relink = relink;
+}
+
+std::string cmLinkLineComputer::ConvertToLinkReference(
+ std::string const& lib) const
+{
+ std::string relLib = lib;
+
+ if (cmOutputConverter::ContainedInDirectory(
+ this->StateDir.GetCurrentBinary(), lib, this->StateDir)) {
+ relLib = cmOutputConverter::ForceToRelativePath(
+ this->StateDir.GetCurrentBinary(), lib);
+ }
+ return relLib;
+}
+
+std::string cmLinkLineComputer::ComputeLinkLibs(cmComputeLinkInformation& cli)
+{
+ std::string linkLibs;
+ typedef cmComputeLinkInformation::ItemVector ItemVector;
+ ItemVector const& items = cli.GetItems();
+ for (ItemVector::const_iterator li = items.begin(); li != items.end();
+ ++li) {
+ if (li->Target && li->Target->GetType() == cmState::INTERFACE_LIBRARY) {
+ continue;
+ }
+ if (li->IsPath) {
+ linkLibs +=
+ this->ConvertToOutputFormat(this->ConvertToLinkReference(li->Value));
+ } else {
+ linkLibs += li->Value;
+ }
+ linkLibs += " ";
+ }
+ return linkLibs;
+}
+
+std::string cmLinkLineComputer::ConvertToOutputFormat(std::string const& input)
+{
+ cmOutputConverter::OutputFormat shellFormat = (this->ForResponse)
+ ? cmOutputConverter::RESPONSE
+ : ((this->UseWatcomQuote) ? cmOutputConverter::WATCOMQUOTE
+ : cmOutputConverter::SHELL);
+
+ return this->OutputConverter->ConvertToOutputFormat(input, shellFormat);
+}
+
+std::string cmLinkLineComputer::ConvertToOutputForExisting(
+ std::string const& input)
+{
+ cmOutputConverter::OutputFormat shellFormat = (this->ForResponse)
+ ? cmOutputConverter::RESPONSE
+ : ((this->UseWatcomQuote) ? cmOutputConverter::WATCOMQUOTE
+ : cmOutputConverter::SHELL);
+
+ return this->OutputConverter->ConvertToOutputForExisting(input, shellFormat);
+}
+
+std::string cmLinkLineComputer::ComputeLinkPath(
+ cmComputeLinkInformation& cli, std::string const& libPathFlag,
+ std::string const& libPathTerminator)
+{
+ std::string linkPath;
+ std::vector<std::string> const& libDirs = cli.GetDirectories();
+ for (std::vector<std::string>::const_iterator libDir = libDirs.begin();
+ libDir != libDirs.end(); ++libDir) {
+ std::string libpath = this->ConvertToOutputForExisting(*libDir);
+ linkPath += " " + libPathFlag;
+ linkPath += libpath;
+ linkPath += libPathTerminator;
+ linkPath += " ";
+ }
+ return linkPath;
+}
+
+std::string cmLinkLineComputer::ComputeRPath(cmComputeLinkInformation& cli)
+{
+ std::string rpath;
+ // Check what kind of rpath flags to use.
+ if (cli.GetRuntimeSep().empty()) {
+ // Each rpath entry gets its own option ("-R a -R b -R c")
+ std::vector<std::string> runtimeDirs;
+ cli.GetRPath(runtimeDirs, this->Relink);
+
+ for (std::vector<std::string>::iterator ri = runtimeDirs.begin();
+ ri != runtimeDirs.end(); ++ri) {
+ rpath += cli.GetRuntimeFlag();
+ rpath += this->ConvertToOutputFormat(*ri);
+ rpath += " ";
+ }
+ } else {
+ // All rpath entries are combined ("-Wl,-rpath,a:b:c").
+ std::string rpathString = cli.GetRPathString(this->Relink);
+
+ // Store the rpath option in the stream.
+ if (!rpathString.empty()) {
+ rpath += cli.GetRuntimeFlag();
+ rpath +=
+ this->OutputConverter->EscapeForShell(rpathString, !this->ForResponse);
+ rpath += " ";
+ }
+ }
+ return rpath;
+}
+
+std::string cmLinkLineComputer::ComputeFrameworkPath(
+ cmComputeLinkInformation& cli, std::string const& fwSearchFlag)
+{
+ std::string frameworkPath;
+ if (!fwSearchFlag.empty()) {
+ std::vector<std::string> const& fwDirs = cli.GetFrameworkPaths();
+ for (std::vector<std::string>::const_iterator fdi = fwDirs.begin();
+ fdi != fwDirs.end(); ++fdi) {
+ frameworkPath += fwSearchFlag;
+ frameworkPath += this->ConvertToOutputFormat(*fdi);
+ frameworkPath += " ";
+ }
+ }
+ return frameworkPath;
+}
+
+std::string cmLinkLineComputer::ComputeLinkLibraries(
+ cmComputeLinkInformation& cli, std::string const& stdLibString)
+{
+ std::ostringstream fout;
+ fout << this->ComputeRPath(cli);
+
+ // Write the library flags to the build rule.
+ fout << this->ComputeLinkLibs(cli);
+
+ // Add the linker runtime search path if any.
+ std::string rpath_link = cli.GetRPathLinkString();
+ if (!cli.GetRPathLinkFlag().empty() && !rpath_link.empty()) {
+ fout << cli.GetRPathLinkFlag();
+ fout << this->OutputConverter->EscapeForShell(rpath_link,
+ !this->ForResponse);
+ fout << " ";
+ }
+
+ if (!stdLibString.empty()) {
+ fout << stdLibString << " ";
+ }
+
+ return fout.str();
+}
diff --git a/Source/cmLinkLineComputer.h b/Source/cmLinkLineComputer.h
new file mode 100644
index 0000000..1fb9b24
--- /dev/null
+++ b/Source/cmLinkLineComputer.h
@@ -0,0 +1,50 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#ifndef cmLinkLineComputer_h
+#define cmLinkLineComputer_h
+
+#include "cmState.h"
+
+class cmComputeLinkInformation;
+class cmOutputConverter;
+
+class cmLinkLineComputer
+{
+public:
+ cmLinkLineComputer(cmOutputConverter* outputConverter,
+ cmState::Directory stateDir);
+ virtual ~cmLinkLineComputer();
+
+ void SetUseWatcomQuote(bool useWatcomQuote);
+ void SetForResponse(bool forResponse);
+ void SetRelink(bool relink);
+
+ virtual std::string ConvertToLinkReference(std::string const& input) const;
+
+ std::string ComputeLinkPath(cmComputeLinkInformation& cli,
+ std::string const& libPathFlag,
+ std::string const& libPathTerminator);
+
+ std::string ComputeFrameworkPath(cmComputeLinkInformation& cli,
+ std::string const& fwSearchFlag);
+
+ std::string ComputeLinkLibraries(cmComputeLinkInformation& cli,
+ std::string const& stdLibString);
+
+private:
+ std::string ComputeLinkLibs(cmComputeLinkInformation& cli);
+ std::string ComputeRPath(cmComputeLinkInformation& cli);
+
+ std::string ConvertToOutputFormat(std::string const& input);
+ std::string ConvertToOutputForExisting(std::string const& input);
+
+ cmState::Directory StateDir;
+ cmOutputConverter* OutputConverter;
+
+ bool ForResponse;
+ bool UseWatcomQuote;
+ bool Relink;
+};
+
+#endif
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index f24b717..3b19694 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -12,6 +12,7 @@
#include "cmInstallGenerator.h"
#include "cmInstallScriptGenerator.h"
#include "cmInstallTargetGenerator.h"
+#include "cmLinkLineComputer.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
#include "cmSystemTools.h"
@@ -1148,11 +1149,12 @@ void cmLocalGenerator::GetStaticLibraryFlags(std::string& flags,
}
void cmLocalGenerator::GetTargetFlags(
- const std::string& config, std::string& linkLibs, std::string& flags,
- std::string& linkFlags, std::string& frameworkPath, std::string& linkPath,
- cmGeneratorTarget* target, bool useWatcomQuote)
+ cmLinkLineComputer* linkLineComputer, const std::string& config,
+ std::string& linkLibs, std::string& flags, std::string& linkFlags,
+ std::string& frameworkPath, std::string& linkPath, cmGeneratorTarget* target)
{
const std::string buildType = cmSystemTools::UpperCase(config);
+ cmComputeLinkInformation* pcli = target->GetLinkInformation(config);
const char* libraryLinkVariable =
"CMAKE_SHARED_LINKER_FLAGS"; // default to shared library
@@ -1176,12 +1178,13 @@ void cmLocalGenerator::GetTargetFlags(
!(this->Makefile->IsOn("CYGWIN") || this->Makefile->IsOn("MINGW"))) {
std::vector<cmSourceFile*> sources;
target->GetSourceFiles(sources, buildType);
+ std::string defFlag =
+ this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG");
for (std::vector<cmSourceFile*>::const_iterator i = sources.begin();
i != sources.end(); ++i) {
cmSourceFile* sf = *i;
if (sf->GetExtension() == "def") {
- linkFlags +=
- this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG");
+ linkFlags += defFlag;
linkFlags += this->ConvertToOutputFormat(
cmSystemTools::CollapseFullPath(sf->GetFullPath()), SHELL);
linkFlags += " ";
@@ -1202,8 +1205,10 @@ void cmLocalGenerator::GetTargetFlags(
linkFlags += " ";
}
}
- this->OutputLinkLibraries(linkLibs, frameworkPath, linkPath, *target,
- false, false, useWatcomQuote);
+ if (pcli) {
+ this->OutputLinkLibraries(pcli, linkLineComputer, linkLibs,
+ frameworkPath, linkPath);
+ }
} break;
case cmState::EXECUTABLE: {
linkFlags += this->Makefile->GetSafeDefinition("CMAKE_EXE_LINKER_FLAGS");
@@ -1222,8 +1227,10 @@ void cmLocalGenerator::GetTargetFlags(
return;
}
this->AddLanguageFlags(flags, linkLanguage, buildType);
- this->OutputLinkLibraries(linkLibs, frameworkPath, linkPath, *target,
- false, false, useWatcomQuote);
+ if (pcli) {
+ this->OutputLinkLibraries(pcli, linkLineComputer, linkLibs,
+ frameworkPath, linkPath);
+ }
if (cmSystemTools::IsOn(
this->Makefile->GetDefinition("BUILD_SHARED_LIBS"))) {
std::string sFlagVar = std::string("CMAKE_SHARED_BUILD_") +
@@ -1248,6 +1255,14 @@ void cmLocalGenerator::GetTargetFlags(
linkFlags += this->Makefile->GetSafeDefinition(exportFlagVar);
linkFlags += " ";
}
+
+ std::string cmp0065Flags =
+ this->GetLinkLibsCMP0065(linkLanguage, *target);
+ if (!cmp0065Flags.empty()) {
+ linkFlags += cmp0065Flags;
+ linkFlags += " ";
+ }
+
const char* targetLinkFlags = target->GetProperty("LINK_FLAGS");
if (targetLinkFlags) {
linkFlags += targetLinkFlags;
@@ -1374,63 +1389,18 @@ std::string cmLocalGenerator::GetTargetFortranFlags(
return std::string();
}
-std::string cmLocalGenerator::ConvertToLinkReference(std::string const& lib,
- OutputFormat format)
-{
-#if defined(_WIN32) && !defined(__CYGWIN__)
- // Work-ardound command line parsing limitations in MSVC 6.0
- if (this->Makefile->IsOn("MSVC60")) {
- // Search for the last space.
- std::string::size_type pos = lib.rfind(' ');
- if (pos != lib.npos) {
- // Find the slash after the last space, if any.
- pos = lib.find('/', pos);
-
- // Convert the portion of the path with a space to a short path.
- std::string sp;
- if (cmSystemTools::GetShortPath(lib.substr(0, pos).c_str(), sp)) {
- // Append the rest of the path with no space.
- sp += lib.substr(pos);
-
- // Convert to an output path.
- return this->ConvertToOutputFormat(sp.c_str(), format);
- }
- }
- }
-#endif
-
- // Normal behavior.
- return this->ConvertToOutputFormat(
- this->ConvertToRelativePath(this->GetCurrentBinaryDirectory(), lib),
- format);
-}
-
/**
* Output the linking rules on a command line. For executables,
* targetLibrary should be a NULL pointer. For libraries, it should point
* to the name of the library. This will not link a library against itself.
*/
-void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries,
- std::string& frameworkPath,
- std::string& linkPath,
- cmGeneratorTarget& tgt, bool relink,
- bool forResponseFile,
- bool useWatcomQuote)
-{
- OutputFormat shellFormat =
- (forResponseFile) ? RESPONSE : ((useWatcomQuote) ? WATCOMQUOTE : SHELL);
- bool escapeAllowMakeVars = !forResponseFile;
- std::ostringstream fout;
- std::string config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
- cmComputeLinkInformation* pcli = tgt.GetLinkInformation(config);
- if (!pcli) {
- return;
- }
+void cmLocalGenerator::OutputLinkLibraries(
+ cmComputeLinkInformation* pcli, cmLinkLineComputer* linkLineComputer,
+ std::string& linkLibraries, std::string& frameworkPath,
+ std::string& linkPath)
+{
cmComputeLinkInformation& cli = *pcli;
- // Collect library linking flags command line options.
- std::string linkLibs;
-
std::string linkLanguage = cli.GetLinkLanguage();
std::string libPathFlag =
@@ -1438,6 +1408,34 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries,
std::string libPathTerminator =
this->Makefile->GetSafeDefinition("CMAKE_LIBRARY_PATH_TERMINATOR");
+ // Add standard libraries for this language.
+ std::string standardLibsVar = "CMAKE_";
+ standardLibsVar += cli.GetLinkLanguage();
+ standardLibsVar += "_STANDARD_LIBRARIES";
+ std::string stdLibString;
+ if (const char* stdLibs = this->Makefile->GetDefinition(standardLibsVar)) {
+ stdLibString = stdLibs;
+ }
+
+ // Append the framework search path flags.
+ std::string fwSearchFlagVar = "CMAKE_";
+ fwSearchFlagVar += linkLanguage;
+ fwSearchFlagVar += "_FRAMEWORK_SEARCH_FLAG";
+ std::string fwSearchFlag =
+ this->Makefile->GetSafeDefinition(fwSearchFlagVar);
+
+ frameworkPath = linkLineComputer->ComputeFrameworkPath(cli, fwSearchFlag);
+ linkPath =
+ linkLineComputer->ComputeLinkPath(cli, libPathFlag, libPathTerminator);
+
+ linkLibraries = linkLineComputer->ComputeLinkLibraries(cli, stdLibString);
+}
+
+std::string cmLocalGenerator::GetLinkLibsCMP0065(
+ std::string const& linkLanguage, cmGeneratorTarget& tgt) const
+{
+ std::string linkFlags;
+
// Flags to link an executable to shared libraries.
if (tgt.GetType() == cmState::EXECUTABLE &&
this->StateSnapshot.GetState()->GetGlobalPropertyAsBool(
@@ -1476,100 +1474,10 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries,
std::string linkFlagsVar = "CMAKE_SHARED_LIBRARY_LINK_";
linkFlagsVar += linkLanguage;
linkFlagsVar += "_FLAGS";
- linkLibs = this->Makefile->GetSafeDefinition(linkFlagsVar);
- linkLibs += " ";
- }
- }
-
- // Append the framework search path flags.
- std::string fwSearchFlagVar = "CMAKE_";
- fwSearchFlagVar += linkLanguage;
- fwSearchFlagVar += "_FRAMEWORK_SEARCH_FLAG";
- const char* fwSearchFlag = this->Makefile->GetDefinition(fwSearchFlagVar);
- if (fwSearchFlag && *fwSearchFlag) {
- std::vector<std::string> const& fwDirs = cli.GetFrameworkPaths();
- for (std::vector<std::string>::const_iterator fdi = fwDirs.begin();
- fdi != fwDirs.end(); ++fdi) {
- frameworkPath += fwSearchFlag;
- frameworkPath += this->ConvertToOutputFormat(*fdi, shellFormat);
- frameworkPath += " ";
- }
- }
-
- // Append the library search path flags.
- std::vector<std::string> const& libDirs = cli.GetDirectories();
- for (std::vector<std::string>::const_iterator libDir = libDirs.begin();
- libDir != libDirs.end(); ++libDir) {
- std::string libpath =
- this->ConvertToOutputForExisting(*libDir, shellFormat);
- linkPath += " " + libPathFlag;
- linkPath += libpath;
- linkPath += libPathTerminator;
- linkPath += " ";
- }
-
- // Append the link items.
- typedef cmComputeLinkInformation::ItemVector ItemVector;
- ItemVector const& items = cli.GetItems();
- for (ItemVector::const_iterator li = items.begin(); li != items.end();
- ++li) {
- if (li->Target && li->Target->GetType() == cmState::INTERFACE_LIBRARY) {
- continue;
- }
- if (li->IsPath) {
- linkLibs += this->ConvertToLinkReference(li->Value, shellFormat);
- } else {
- linkLibs += li->Value;
- }
- linkLibs += " ";
- }
-
- // Check what kind of rpath flags to use.
- if (cli.GetRuntimeSep().empty()) {
- // Each rpath entry gets its own option ("-R a -R b -R c")
- std::vector<std::string> runtimeDirs;
- cli.GetRPath(runtimeDirs, relink);
-
- std::string rpath;
- for (std::vector<std::string>::iterator ri = runtimeDirs.begin();
- ri != runtimeDirs.end(); ++ri) {
- rpath += cli.GetRuntimeFlag();
- rpath += this->ConvertToOutputFormat(*ri, shellFormat);
- rpath += " ";
- }
- fout << rpath;
- } else {
- // All rpath entries are combined ("-Wl,-rpath,a:b:c").
- std::string rpath = cli.GetRPathString(relink);
-
- // Store the rpath option in the stream.
- if (!rpath.empty()) {
- fout << cli.GetRuntimeFlag();
- fout << this->EscapeForShell(rpath, escapeAllowMakeVars);
- fout << " ";
+ linkFlags = this->Makefile->GetSafeDefinition(linkFlagsVar);
}
}
-
- // Write the library flags to the build rule.
- fout << linkLibs;
-
- // Add the linker runtime search path if any.
- std::string rpath_link = cli.GetRPathLinkString();
- if (!cli.GetRPathLinkFlag().empty() && !rpath_link.empty()) {
- fout << cli.GetRPathLinkFlag();
- fout << this->EscapeForShell(rpath_link, escapeAllowMakeVars);
- fout << " ";
- }
-
- // Add standard libraries for this language.
- std::string standardLibsVar = "CMAKE_";
- standardLibsVar += cli.GetLinkLanguage();
- standardLibsVar += "_STANDARD_LIBRARIES";
- if (const char* stdLibs = this->Makefile->GetDefinition(standardLibsVar)) {
- fout << stdLibs << " ";
- }
-
- linkLibraries = fout.str();
+ return linkFlags;
}
void cmLocalGenerator::AddArchitectureFlags(std::string& flags,
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 19469be..69c4101 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -19,11 +19,13 @@
#include <string>
#include <vector>
+class cmComputeLinkInformation;
class cmCustomCommandGenerator;
class cmGeneratorTarget;
class cmGlobalGenerator;
class cmMakefile;
class cmSourceFile;
+class cmLinkLineComputer;
/** \class cmLocalGenerator
* \brief Create required build files for a directory.
@@ -82,6 +84,9 @@ public:
return this->GlobalGenerator;
}
+ std::string GetLinkLibsCMP0065(std::string const& linkLanguage,
+ cmGeneratorTarget& tgt) const;
+
cmState* GetState() const;
cmState::Snapshot GetStateSnapshot() const;
@@ -309,10 +314,11 @@ public:
/** Fill out these strings for the given target. Libraries to link,
* flags, and linkflags. */
- void GetTargetFlags(const std::string& config, std::string& linkLibs,
+ void GetTargetFlags(cmLinkLineComputer* linkLineComputer,
+ const std::string& config, std::string& linkLibs,
std::string& flags, std::string& linkFlags,
std::string& frameworkPath, std::string& linkPath,
- cmGeneratorTarget* target, bool useWatcomQuote);
+ cmGeneratorTarget* target);
void GetTargetDefines(cmGeneratorTarget const* target,
std::string const& config, std::string const& lang,
std::set<std::string>& defines) const;
@@ -342,10 +348,10 @@ public:
protected:
///! put all the libraries for a target on into the given stream
- void OutputLinkLibraries(std::string& linkLibraries,
- std::string& frameworkPath, std::string& linkPath,
- cmGeneratorTarget&, bool relink,
- bool forResponseFile, bool useWatcomQuote);
+ void OutputLinkLibraries(cmComputeLinkInformation* pcli,
+ cmLinkLineComputer* linkLineComputer,
+ std::string& linkLibraries,
+ std::string& frameworkPath, std::string& linkPath);
// Expand rule variables in CMake of the type found in language rules
void ExpandRuleVariables(std::string& string,
@@ -367,10 +373,6 @@ protected:
std::string& CreateSafeUniqueObjectFileName(const std::string& sin,
std::string const& dir_max);
- virtual std::string ConvertToLinkReference(
- std::string const& lib,
- cmOutputConverter::OutputFormat format = cmOutputConverter::SHELL);
-
/** Check whether the native build system supports the given
definition. Issues a warning. */
virtual bool CheckDefinition(std::string const& define) const;
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index 11b87e3..e25eb0f 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -120,13 +120,6 @@ cmGlobalNinjaGenerator* cmLocalNinjaGenerator::GetGlobalNinjaGenerator()
// Virtual protected methods.
-std::string cmLocalNinjaGenerator::ConvertToLinkReference(
- std::string const& lib, cmOutputConverter::OutputFormat format)
-{
- std::string path = this->GetGlobalNinjaGenerator()->ConvertToNinjaPath(lib);
- return this->ConvertToOutputFormat(path, format);
-}
-
std::string cmLocalNinjaGenerator::ConvertToIncludeReference(
std::string const& path, cmOutputConverter::OutputFormat format,
bool forceFullPaths)
@@ -489,15 +482,12 @@ std::string cmLocalNinjaGenerator::MakeCustomLauncher(
std::string output;
const std::vector<std::string>& outputs = ccg.GetOutputs();
if (!outputs.empty()) {
+ output = outputs[0];
if (ccg.GetWorkingDirectory().empty()) {
- output = this->ConvertToOutputFormat(
- this->ConvertToRelativePath(this->GetCurrentBinaryDirectory(),
- outputs[0]),
- cmOutputConverter::SHELL);
- } else {
output =
- this->ConvertToOutputFormat(outputs[0], cmOutputConverter::SHELL);
+ this->ConvertToRelativePath(this->GetCurrentBinaryDirectory(), output);
}
+ output = this->ConvertToOutputFormat(output, cmOutputConverter::SHELL);
}
vars.Output = output.c_str();
diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h
index 875f8c6..b04788d 100644
--- a/Source/cmLocalNinjaGenerator.h
+++ b/Source/cmLocalNinjaGenerator.h
@@ -76,10 +76,6 @@ public:
void AppendCustomCommandDeps(cmCustomCommandGenerator const& ccg,
cmNinjaDeps& ninjaDeps);
- std::string ConvertToLinkReference(std::string const& lib,
- cmOutputConverter::OutputFormat format =
- cmOutputConverter::SHELL) CM_OVERRIDE;
-
void ComputeObjectFilenames(
std::map<cmSourceFile const*, std::string>& mapping,
cmGeneratorTarget const* gt = CM_NULLPTR) CM_OVERRIDE;
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 8825b46..02eef59 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -141,7 +141,7 @@ void cmLocalUnixMakefileGenerator3::ComputeHomeRelativeOutputPath()
{
// Compute the path to use when referencing the current output
// directory from the top output directory.
- this->HomeRelativeOutputPath = this->ConvertToRelativePath(
+ this->HomeRelativeOutputPath = this->MaybeConvertToRelativePath(
this->GetBinaryDirectory(), this->GetCurrentBinaryDirectory());
if (this->HomeRelativeOutputPath == ".") {
this->HomeRelativeOutputPath = "";
@@ -230,7 +230,9 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefile()
// Open the rule file. This should be copy-if-different because the
// rules may depend on this file itself.
std::string ruleFileNameFull = this->ConvertToFullPath(ruleFileName);
- cmGeneratedFileStream ruleFileStream(ruleFileNameFull.c_str());
+ cmGeneratedFileStream ruleFileStream(
+ ruleFileNameFull.c_str(), false,
+ this->GlobalGenerator->GetMakefileEncoding());
if (!ruleFileStream) {
return;
}
@@ -548,7 +550,8 @@ void cmLocalUnixMakefileGenerator3::WriteMakeRule(
// Construct the left hand side of the rule.
std::string tgt = cmSystemTools::ConvertToOutputPath(
- this->ConvertToRelativePath(this->GetBinaryDirectory(), target).c_str());
+ this->MaybeConvertToRelativePath(this->GetBinaryDirectory(), target)
+ .c_str());
const char* space = "";
if (tgt.size() == 1) {
@@ -577,7 +580,7 @@ void cmLocalUnixMakefileGenerator3::WriteMakeRule(
dep != depends.end(); ++dep) {
replace = *dep;
replace = cmSystemTools::ConvertToOutputPath(
- this->ConvertToRelativePath(binDir, replace).c_str());
+ this->MaybeConvertToRelativePath(binDir, replace).c_str());
os << cmMakeSafe(tgt) << space << ": " << cmMakeSafe(replace) << "\n";
}
}
@@ -969,7 +972,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand(
// working directory will be the start-output directory.
bool had_slash = cmd.find('/') != cmd.npos;
if (workingDir.empty()) {
- cmd = this->ConvertToRelativePath(currentBinDir, cmd);
+ cmd = this->MaybeConvertToRelativePath(currentBinDir, cmd);
}
bool has_slash = cmd.find('/') != cmd.npos;
if (had_slash && !has_slash) {
@@ -992,16 +995,13 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand(
std::string output;
const std::vector<std::string>& outputs = ccg.GetOutputs();
if (!outputs.empty()) {
+ output = outputs[0];
if (workingDir.empty()) {
- output = this->ConvertToOutputFormat(
- this->ConvertToRelativePath(this->GetCurrentBinaryDirectory(),
- outputs[0]),
- cmOutputConverter::SHELL);
-
- } else {
- output = this->ConvertToOutputFormat(outputs[0],
- cmOutputConverter::SHELL);
+ output = this->MaybeConvertToRelativePath(
+ this->GetCurrentBinaryDirectory(), output);
}
+ output =
+ this->ConvertToOutputFormat(output, cmOutputConverter::SHELL);
}
vars.Output = output.c_str();
@@ -1082,14 +1082,15 @@ void cmLocalUnixMakefileGenerator3::AppendCleanCommand(
fout << "file(REMOVE_RECURSE\n";
for (std::vector<std::string>::const_iterator f = files.begin();
f != files.end(); ++f) {
- std::string fc = this->ConvertToRelativePath(currentBinDir, *f);
+ std::string fc = this->MaybeConvertToRelativePath(currentBinDir, *f);
fout << " " << cmOutputConverter::EscapeForCMake(fc) << "\n";
}
fout << ")\n";
}
std::string remove = "$(CMAKE_COMMAND) -P ";
remove += this->ConvertToOutputFormat(
- this->ConvertToRelativePath(this->GetCurrentBinaryDirectory(), cleanfile),
+ this->MaybeConvertToRelativePath(this->GetCurrentBinaryDirectory(),
+ cleanfile),
cmOutputConverter::SHELL);
commands.push_back(remove);
@@ -1415,7 +1416,9 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies(
// because the make tool may try to reload it needlessly otherwise.
std::string ruleFileNameFull = dir;
ruleFileNameFull += "/depend.make";
- cmGeneratedFileStream ruleFileStream(ruleFileNameFull.c_str());
+ cmGeneratedFileStream ruleFileStream(
+ ruleFileNameFull.c_str(), false,
+ this->GlobalGenerator->GetMakefileEncoding());
ruleFileStream.SetCopyIfDifferent(true);
if (!ruleFileStream) {
return false;
@@ -1427,7 +1430,8 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies(
std::string internalRuleFileNameFull = dir;
internalRuleFileNameFull += "/depend.internal";
cmGeneratedFileStream internalRuleFileStream(
- internalRuleFileNameFull.c_str());
+ internalRuleFileNameFull.c_str(), false,
+ this->GlobalGenerator->GetMakefileEncoding());
if (!internalRuleFileStream) {
return false;
}
@@ -1858,7 +1862,8 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo(
}
for (std::vector<std::string>::iterator i = includes.begin();
i != includes.end(); ++i) {
- cmakefileStream << " \"" << this->ConvertToRelativePath(binaryDir, *i)
+ cmakefileStream << " \""
+ << this->MaybeConvertToRelativePath(binaryDir, *i)
<< "\"\n";
}
cmakefileStream << " )\n";
@@ -1923,7 +1928,7 @@ std::string cmLocalUnixMakefileGenerator3::GetRecursiveMakeCall(
if (!tgt.empty()) {
// The make target is always relative to the top of the build tree.
std::string tgt2 =
- this->ConvertToRelativePath(this->GetBinaryDirectory(), tgt);
+ this->MaybeConvertToRelativePath(this->GetBinaryDirectory(), tgt);
// The target may have been written with windows paths.
cmSystemTools::ConvertToOutputSlashes(tgt2);
@@ -2095,3 +2100,13 @@ void cmLocalUnixMakefileGenerator3::CreateCDCommand(
std::bind1st(std::plus<std::string>(), prefix));
}
}
+
+std::string cmLocalUnixMakefileGenerator3::MaybeConvertToRelativePath(
+ std::string const& base, std::string const& path)
+{
+ if (!cmOutputConverter::ContainedInDirectory(
+ base, path, this->GetStateSnapshot().GetDirectory())) {
+ return path;
+ }
+ return cmOutputConverter::ForceToRelativePath(base, path);
+}
diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h
index fc5c8e7..c3ecda4 100644
--- a/Source/cmLocalUnixMakefileGenerator3.h
+++ b/Source/cmLocalUnixMakefileGenerator3.h
@@ -184,6 +184,9 @@ public:
// Eclipse generator.
void GetIndividualFileTargets(std::vector<std::string>& targets);
+ std::string MaybeConvertToRelativePath(std::string const& base,
+ std::string const& path);
+
protected:
void WriteLocalMakefile();
diff --git a/Source/cmMSVC60LinkLineComputer.cxx b/Source/cmMSVC60LinkLineComputer.cxx
new file mode 100644
index 0000000..2b6df2a
--- /dev/null
+++ b/Source/cmMSVC60LinkLineComputer.cxx
@@ -0,0 +1,36 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmMSVC60LinkLineComputer.h"
+
+#include "cmSystemTools.h"
+
+cmMSVC60LinkLineComputer::cmMSVC60LinkLineComputer(
+ cmOutputConverter* outputConverter, cmState::Directory stateDir)
+ : cmLinkLineComputer(outputConverter, stateDir)
+{
+}
+
+std::string cmMSVC60LinkLineComputer::ConvertToLinkReference(
+ std::string const& lib) const
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ // Work-ardound command line parsing limitations in MSVC 6.0
+ // Search for the last space.
+ std::string::size_type pos = lib.rfind(' ');
+ if (pos != lib.npos) {
+ // Find the slash after the last space, if any.
+ pos = lib.find('/', pos);
+
+ // Convert the portion of the path with a space to a short path.
+ std::string sp;
+ if (cmSystemTools::GetShortPath(lib.substr(0, pos).c_str(), sp)) {
+ // Append the rest of the path with no space.
+ sp += lib.substr(pos);
+ return sp;
+ }
+ }
+#endif
+
+ return cmLinkLineComputer::ConvertToLinkReference(lib);
+}
diff --git a/Source/cmMSVC60LinkLineComputer.h b/Source/cmMSVC60LinkLineComputer.h
new file mode 100644
index 0000000..ca9da31
--- /dev/null
+++ b/Source/cmMSVC60LinkLineComputer.h
@@ -0,0 +1,19 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#ifndef cmMSVC60LinkLineComputer_h
+#define cmMSVC60LinkLineComputer_h
+
+#include "cmLinkLineComputer.h"
+
+class cmMSVC60LinkLineComputer : public cmLinkLineComputer
+{
+public:
+ cmMSVC60LinkLineComputer(cmOutputConverter* outputConverter,
+ cmState::Directory stateDir);
+
+ std::string ConvertToLinkReference(std::string const& input) const
+ CM_OVERRIDE;
+};
+
+#endif
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index df993ce..c3111c0 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -1207,71 +1207,6 @@ bool cmMakefile::ParseDefineFlag(std::string const& def, bool remove)
return true;
}
-void cmMakefile::AddLinkLibrary(const std::string& lib,
- cmTargetLinkLibraryType llt)
-{
- cmTarget::LibraryID tmp;
- tmp.first = lib;
- tmp.second = llt;
- this->LinkLibraries.push_back(tmp);
-}
-
-void cmMakefile::AddLinkLibraryForTarget(const std::string& target,
- const std::string& lib,
- cmTargetLinkLibraryType llt)
-{
- cmTargets::iterator i = this->Targets.find(target);
- if (i != this->Targets.end()) {
- cmTarget* tgt = this->GetGlobalGenerator()->FindTarget(lib);
- if (tgt) {
- // if it is not a static or shared library then you can not link to it
- if (!((tgt->GetType() == cmState::STATIC_LIBRARY) ||
- (tgt->GetType() == cmState::SHARED_LIBRARY) ||
- (tgt->GetType() == cmState::INTERFACE_LIBRARY) ||
- tgt->IsExecutableWithExports())) {
- std::ostringstream e;
- e << "Target \"" << lib << "\" of type "
- << cmState::GetTargetTypeName(tgt->GetType())
- << " may not be linked into another target. "
- << "One may link only to STATIC or SHARED libraries, or "
- << "to executables with the ENABLE_EXPORTS property set.";
- this->IssueMessage(cmake::FATAL_ERROR, e.str());
- }
- }
- i->second.AddLinkLibrary(*this, target, lib, llt);
- } else {
- std::ostringstream e;
- e << "Attempt to add link library \"" << lib << "\" to target \"" << target
- << "\" which is not built in this directory.";
- this->IssueMessage(cmake::FATAL_ERROR, e.str());
- }
-}
-
-void cmMakefile::AddLinkDirectoryForTarget(const std::string& target,
- const std::string& d)
-{
- cmTargets::iterator i = this->Targets.find(target);
- if (i != this->Targets.end()) {
- if (this->IsAlias(target)) {
- std::ostringstream e;
- e << "ALIAS target \"" << target << "\" "
- << "may not be linked into another target.";
- this->IssueMessage(cmake::FATAL_ERROR, e.str());
- return;
- }
- i->second.AddLinkDirectory(d);
- } else {
- cmSystemTools::Error(
- "Attempt to add link directories to non-existent target: ",
- target.c_str(), " for directory ", d.c_str());
- }
-}
-
-void cmMakefile::AddLinkLibrary(const std::string& lib)
-{
- this->AddLinkLibrary(lib, GENERAL_LibraryType);
-}
-
void cmMakefile::InitializeFromParent(cmMakefile* parent)
{
this->SystemIncludeDirectories = parent->SystemIncludeDirectories;
@@ -1303,7 +1238,7 @@ void cmMakefile::InitializeFromParent(cmMakefile* parent)
}
// link libraries
- this->LinkLibraries = parent->LinkLibraries;
+ this->SetProperty("LINK_LIBRARIES", parent->GetProperty("LINK_LIBRARIES"));
// link directories
this->SetProperty("LINK_DIRECTORIES",
@@ -1835,8 +1770,7 @@ void cmMakefile::SetProjectName(std::string const& p)
this->StateSnapshot.SetProjectName(p);
}
-void cmMakefile::AddGlobalLinkInformation(const std::string& name,
- cmTarget& target)
+void cmMakefile::AddGlobalLinkInformation(cmTarget& target)
{
// for these targets do not add anything
switch (target.GetType()) {
@@ -1857,13 +1791,34 @@ void cmMakefile::AddGlobalLinkInformation(const std::string& name,
if (*j->rbegin() == '/') {
newdir = j->substr(0, j->size() - 1);
}
- if (std::find(this->LinkDirectories.begin(), this->LinkDirectories.end(),
- newdir) == this->LinkDirectories.end()) {
- target.AddLinkDirectory(*j);
+ target.AddLinkDirectory(*j);
+ }
+ }
+
+ if (const char* linkLibsProp = this->GetProperty("LINK_LIBRARIES")) {
+ std::vector<std::string> linkLibs;
+ cmSystemTools::ExpandListArgument(linkLibsProp, linkLibs);
+
+ for (std::vector<std::string>::iterator j = linkLibs.begin();
+ j != linkLibs.end(); ++j) {
+ std::string libraryName = *j;
+ cmTargetLinkLibraryType libType = GENERAL_LibraryType;
+ if (libraryName == "optimized") {
+ libType = OPTIMIZED_LibraryType;
+ ++j;
+ libraryName = *j;
+ } else if (libraryName == "debug") {
+ libType = DEBUG_LibraryType;
+ ++j;
+ libraryName = *j;
}
+ // This is equivalent to the target_link_libraries plain signature.
+ target.AddLinkLibrary(*this, libraryName, libType);
+ target.AppendProperty(
+ "INTERFACE_LINK_LIBRARIES",
+ target.GetDebugGeneratorExpressions(libraryName, libType).c_str());
}
}
- target.MergeLinkLibraries(*this, name, this->LinkLibraries);
}
void cmMakefile::AddAlias(const std::string& lname, std::string const& tgtName)
@@ -1877,14 +1832,9 @@ cmTarget* cmMakefile::AddLibrary(const std::string& lname,
const std::vector<std::string>& srcs,
bool excludeFromAll)
{
- // wrong type ? default to STATIC
- if ((type != cmState::STATIC_LIBRARY) && (type != cmState::SHARED_LIBRARY) &&
- (type != cmState::MODULE_LIBRARY) && (type != cmState::OBJECT_LIBRARY) &&
- (type != cmState::INTERFACE_LIBRARY)) {
- this->IssueMessage(cmake::INTERNAL_ERROR,
- "cmMakefile::AddLibrary given invalid target type.");
- type = cmState::STATIC_LIBRARY;
- }
+ assert(type == cmState::STATIC_LIBRARY || type == cmState::SHARED_LIBRARY ||
+ type == cmState::MODULE_LIBRARY || type == cmState::OBJECT_LIBRARY ||
+ type == cmState::INTERFACE_LIBRARY);
cmTarget* target = this->AddNewTarget(type, lname);
// Clear its dependencies. Otherwise, dependencies might persist
@@ -1895,7 +1845,7 @@ cmTarget* cmMakefile::AddLibrary(const std::string& lname,
target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
}
target->AddSources(srcs);
- this->AddGlobalLinkInformation(lname, *target);
+ this->AddGlobalLinkInformation(*target);
return target;
}
@@ -1908,7 +1858,7 @@ cmTarget* cmMakefile::AddExecutable(const char* exeName,
target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
}
target->AddSources(srcs);
- this->AddGlobalLinkInformation(exeName, *target);
+ this->AddGlobalLinkInformation(*target);
return target;
}
@@ -2125,19 +2075,32 @@ void cmMakefile::ExpandVariablesCMP0019()
}
}
}
- for (cmTarget::LinkLibraryVectorType::iterator l =
- this->LinkLibraries.begin();
- l != this->LinkLibraries.end(); ++l) {
- if (mightExpandVariablesCMP0019(l->first.c_str())) {
- std::string orig = l->first;
- this->ExpandVariablesInString(l->first, true, true);
- if (pol == cmPolicies::WARN && l->first != orig) {
- /* clang-format off */
+
+ if (const char* linkLibsProp = this->GetProperty("LINK_LIBRARIES")) {
+ std::vector<std::string> linkLibs;
+ cmSystemTools::ExpandListArgument(linkLibsProp, linkLibs);
+
+ for (std::vector<std::string>::iterator l = linkLibs.begin();
+ l != linkLibs.end(); ++l) {
+ std::string libName = *l;
+ if (libName == "optimized") {
+ ++l;
+ libName = *l;
+ } else if (libName == "debug") {
+ ++l;
+ libName = *l;
+ }
+ if (mightExpandVariablesCMP0019(libName.c_str())) {
+ std::string orig = libName;
+ this->ExpandVariablesInString(libName, true, true);
+ if (pol == cmPolicies::WARN && libName != orig) {
+ /* clang-format off */
w << "Evaluated link library\n"
<< " " << orig << "\n"
<< "as\n"
- << " " << l->first << "\n";
- /* clang-format on */
+ << " " << libName << "\n";
+ /* clang-format on */
+ }
}
}
}
@@ -3970,10 +3933,8 @@ cmPolicies::PolicyStatus cmMakefile::GetPolicyStatus(
bool cmMakefile::PolicyOptionalWarningEnabled(std::string const& var)
{
// Check for an explicit CMAKE_POLICY_WARNING_CMP<NNNN> setting.
- if (!var.empty()) {
- if (const char* val = this->GetDefinition(var)) {
- return cmSystemTools::IsOn(val);
- }
+ if (const char* val = this->GetDefinition(var)) {
+ return cmSystemTools::IsOn(val);
}
// Enable optional policy warnings with --debug-output, --trace,
// or --trace-expand.
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 40344ce..0116ce1 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -197,15 +197,6 @@ public:
const char* comment = CM_NULLPTR, bool uses_terminal = false);
/**
- * Add a link library to the build.
- */
- void AddLinkLibrary(const std::string&);
- void AddLinkLibrary(const std::string&, cmTargetLinkLibraryType type);
- void AddLinkLibraryForTarget(const std::string& tgt, const std::string&,
- cmTargetLinkLibraryType type);
- void AddLinkDirectoryForTarget(const std::string& tgt, const std::string& d);
-
- /**
* Add a subdirectory to the build.
*/
void AddSubDirectory(const std::string& fullSrcDir,
@@ -447,7 +438,7 @@ public:
/**
* Get a list of preprocessor define flags.
*/
- const char* GetDefineFlags() const { return this->DefineFlags.c_str(); }
+ std::string GetDefineFlags() const { return this->DefineFlags; }
/**
* Make sure CMake can write this file
@@ -781,7 +772,7 @@ public:
protected:
// add link libraries and directories to the target
- void AddGlobalLinkInformation(const std::string& name, cmTarget& target);
+ void AddGlobalLinkInformation(cmTarget& target);
// Check for a an unused variable
void LogUnused(const char* reason, const std::string& name) const;
@@ -805,9 +796,6 @@ protected:
// Tests
std::map<std::string, cmTest*> Tests;
- // The link-library paths. Order matters, use std::vector (not std::set).
- std::vector<std::string> LinkDirectories;
-
// The set of include directories that are marked as system include
// directories.
std::set<std::string> SystemIncludeDirectories;
@@ -815,8 +803,6 @@ protected:
std::vector<std::string> ListFiles;
std::vector<std::string> OutputFiles;
- cmTarget::LinkLibraryVectorType LinkLibraries;
-
std::vector<cmInstallGenerator*> InstallGenerators;
std::vector<cmTestGenerator*> TestGenerators;
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index cb20117..bfc4857 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -5,6 +5,7 @@
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalUnixMakefileGenerator3.h"
+#include "cmLinkLineComputer.h"
#include "cmLocalGenerator.h"
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
@@ -130,16 +131,16 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
targetFullPathPDB, cmOutputConverter::SHELL);
// Convert to the output path to use in constructing commands.
std::string targetOutPath = this->LocalGenerator->ConvertToOutputFormat(
- this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPath),
cmOutputConverter::SHELL);
std::string targetOutPathReal = this->LocalGenerator->ConvertToOutputFormat(
- this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathReal),
cmOutputConverter::SHELL);
std::string targetOutPathImport =
this->LocalGenerator->ConvertToOutputFormat(
- this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(),
targetFullPathImport),
cmOutputConverter::SHELL);
@@ -192,6 +193,11 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
this->LocalGenerator->AppendFlags(
linkFlags, this->Makefile->GetDefinition(export_flag_var));
}
+
+ this->LocalGenerator->AppendFlags(linkFlags,
+ this->LocalGenerator->GetLinkLibsCMP0065(
+ linkLanguage, *this->GeneratorTarget));
+
if (this->GeneratorTarget->GetProperty("LINK_WHAT_YOU_USE")) {
this->LocalGenerator->AppendFlags(linkFlags, " -Wl,--no-as-needed");
}
@@ -210,32 +216,39 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
this->LocalGenerator->AppendFlags(
linkFlags, this->GeneratorTarget->GetProperty(linkFlagsConfig));
- this->AddModuleDefinitionFlag(linkFlags);
+ {
+ CM_AUTO_PTR<cmLinkLineComputer> linkLineComputer(
+ this->CreateLinkLineComputer(
+ this->LocalGenerator,
+ this->LocalGenerator->GetStateSnapshot().GetDirectory()));
+
+ this->AddModuleDefinitionFlag(linkLineComputer.get(), linkFlags);
+ }
// Construct a list of files associated with this executable that
// may need to be cleaned.
std::vector<std::string> exeCleanFiles;
- exeCleanFiles.push_back(this->LocalGenerator->ConvertToRelativePath(
+ exeCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPath));
#ifdef _WIN32
// There may be a manifest file for this target. Add it to the
// clean set just in case.
- exeCleanFiles.push_back(this->LocalGenerator->ConvertToRelativePath(
+ exeCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(),
(targetFullPath + ".manifest").c_str()));
#endif
if (targetNameReal != targetName) {
- exeCleanFiles.push_back(this->LocalGenerator->ConvertToRelativePath(
+ exeCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathReal));
}
if (!targetNameImport.empty()) {
- exeCleanFiles.push_back(this->LocalGenerator->ConvertToRelativePath(
+ exeCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(),
targetFullPathImport));
std::string implib;
if (this->GeneratorTarget->GetImplibGNUtoMS(targetFullPathImport,
implib)) {
- exeCleanFiles.push_back(this->LocalGenerator->ConvertToRelativePath(
+ exeCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), implib));
}
}
@@ -243,7 +256,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// List the PDB for cleaning only when the whole target is
// cleaned. We do not want to delete the .pdb file just before
// linking the target.
- this->CleanFiles.push_back(this->LocalGenerator->ConvertToRelativePath(
+ this->CleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathPDB));
// Add the pre-build and pre-link rules building but not when relinking.
@@ -291,10 +304,18 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// Set path conversion for link script shells.
this->LocalGenerator->SetLinkScriptShell(useLinkScript);
+ CM_AUTO_PTR<cmLinkLineComputer> linkLineComputer(
+ this->CreateLinkLineComputer(
+ this->LocalGenerator,
+ this->LocalGenerator->GetStateSnapshot().GetDirectory()));
+ linkLineComputer->SetForResponse(useResponseFileForLibs);
+ linkLineComputer->SetUseWatcomQuote(useWatcomQuote);
+ linkLineComputer->SetRelink(relink);
+
// Collect up flags to link in needed libraries.
std::string linkLibs;
- this->CreateLinkLibs(linkLibs, relink, useResponseFileForLibs, depends,
- useWatcomQuote);
+ this->CreateLinkLibs(linkLineComputer.get(), linkLibs,
+ useResponseFileForLibs, depends);
// Construct object file lists that may be needed to expand the
// rule.
@@ -318,7 +339,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
objectDir = this->LocalGenerator->ConvertToOutputFormat(
- this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), objectDir),
cmOutputConverter::SHELL);
vars.ObjectDir = objectDir.c_str();
@@ -326,7 +347,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
? cmOutputConverter::WATCOMQUOTE
: cmOutputConverter::SHELL;
std::string target = this->LocalGenerator->ConvertToOutputFormat(
- this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathReal),
output);
vars.Target = target.c_str();
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index b969bfb..8a621ea 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -5,6 +5,7 @@
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalUnixMakefileGenerator3.h"
+#include "cmLinkLineComputer.h"
#include "cmLocalGenerator.h"
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
@@ -159,7 +160,13 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
this->LocalGenerator->AddConfigVariableFlags(
extraFlags, "CMAKE_SHARED_LINKER_FLAGS", this->ConfigName);
- this->AddModuleDefinitionFlag(extraFlags);
+
+ CM_AUTO_PTR<cmLinkLineComputer> linkLineComputer(
+ this->CreateLinkLineComputer(
+ this->LocalGenerator,
+ this->LocalGenerator->GetStateSnapshot().GetDirectory()));
+
+ this->AddModuleDefinitionFlag(linkLineComputer.get(), extraFlags);
if (this->GeneratorTarget->GetProperty("LINK_WHAT_YOU_USE")) {
this->LocalGenerator->AppendFlags(extraFlags, " -Wl,--no-as-needed");
@@ -184,7 +191,13 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink)
extraFlags, this->GeneratorTarget->GetProperty(linkFlagsConfig));
this->LocalGenerator->AddConfigVariableFlags(
extraFlags, "CMAKE_MODULE_LINKER_FLAGS", this->ConfigName);
- this->AddModuleDefinitionFlag(extraFlags);
+
+ CM_AUTO_PTR<cmLinkLineComputer> linkLineComputer(
+ this->CreateLinkLineComputer(
+ this->LocalGenerator,
+ this->LocalGenerator->GetStateSnapshot().GetDirectory()));
+
+ this->AddModuleDefinitionFlag(linkLineComputer.get(), extraFlags);
this->WriteLibraryRules(linkRuleVar, extraFlags, relink);
}
@@ -305,20 +318,20 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
targetFullPathPDB, cmOutputConverter::SHELL);
std::string targetOutPath = this->LocalGenerator->ConvertToOutputFormat(
- this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPath),
cmOutputConverter::SHELL);
std::string targetOutPathSO = this->LocalGenerator->ConvertToOutputFormat(
- this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathSO),
cmOutputConverter::SHELL);
std::string targetOutPathReal = this->LocalGenerator->ConvertToOutputFormat(
- this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathReal),
cmOutputConverter::SHELL);
std::string targetOutPathImport =
this->LocalGenerator->ConvertToOutputFormat(
- this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(),
targetFullPathImport),
cmOutputConverter::SHELL);
@@ -352,38 +365,26 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
commands, buildEcho, cmLocalUnixMakefileGenerator3::EchoLink, &progress);
}
- const char* forbiddenFlagVar = CM_NULLPTR;
- switch (this->GeneratorTarget->GetType()) {
- case cmState::SHARED_LIBRARY:
- forbiddenFlagVar = "_CREATE_SHARED_LIBRARY_FORBIDDEN_FLAGS";
- break;
- case cmState::MODULE_LIBRARY:
- forbiddenFlagVar = "_CREATE_SHARED_MODULE_FORBIDDEN_FLAGS";
- break;
- default:
- break;
- }
-
// Clean files associated with this library.
std::vector<std::string> libCleanFiles;
- libCleanFiles.push_back(this->LocalGenerator->ConvertToRelativePath(
+ libCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPath));
if (targetNameReal != targetName) {
- libCleanFiles.push_back(this->LocalGenerator->ConvertToRelativePath(
+ libCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathReal));
}
if (targetNameSO != targetName && targetNameSO != targetNameReal) {
- libCleanFiles.push_back(this->LocalGenerator->ConvertToRelativePath(
+ libCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathSO));
}
if (!targetNameImport.empty()) {
- libCleanFiles.push_back(this->LocalGenerator->ConvertToRelativePath(
+ libCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(),
targetFullPathImport));
std::string implib;
if (this->GeneratorTarget->GetImplibGNUtoMS(targetFullPathImport,
implib)) {
- libCleanFiles.push_back(this->LocalGenerator->ConvertToRelativePath(
+ libCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), implib));
}
}
@@ -391,14 +392,14 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
// List the PDB for cleaning only when the whole target is
// cleaned. We do not want to delete the .pdb file just before
// linking the target.
- this->CleanFiles.push_back(this->LocalGenerator->ConvertToRelativePath(
+ this->CleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathPDB));
#ifdef _WIN32
// There may be a manifest file for this target. Add it to the
// clean set just in case.
if (this->GeneratorTarget->GetType() != cmState::STATIC_LIBRARY) {
- libCleanFiles.push_back(this->LocalGenerator->ConvertToRelativePath(
+ libCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(),
(targetFullPath + ".manifest").c_str()));
}
@@ -491,8 +492,17 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
// Collect up flags to link in needed libraries.
std::string linkLibs;
if (this->GeneratorTarget->GetType() != cmState::STATIC_LIBRARY) {
- this->CreateLinkLibs(linkLibs, relink, useResponseFileForLibs, depends,
- useWatcomQuote);
+
+ CM_AUTO_PTR<cmLinkLineComputer> linkLineComputer(
+ this->CreateLinkLineComputer(
+ this->LocalGenerator,
+ this->LocalGenerator->GetStateSnapshot().GetDirectory()));
+ linkLineComputer->SetForResponse(useResponseFileForLibs);
+ linkLineComputer->SetUseWatcomQuote(useWatcomQuote);
+ linkLineComputer->SetRelink(relink);
+
+ this->CreateLinkLibs(linkLineComputer.get(), linkLibs,
+ useResponseFileForLibs, depends);
}
// Construct object file lists that may be needed to expand the
@@ -537,7 +547,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
objectDir = this->LocalGenerator->ConvertToOutputFormat(
- this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), objectDir),
cmOutputConverter::SHELL);
@@ -546,7 +556,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
? cmOutputConverter::WATCOMQUOTE
: cmOutputConverter::SHELL;
std::string target = this->LocalGenerator->ConvertToOutputFormat(
- this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathReal),
output);
vars.Target = target.c_str();
@@ -585,11 +595,6 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
this->LocalGenerator->AddArchitectureFlags(
langFlags, this->GeneratorTarget, linkLanguage, this->ConfigName);
- // remove any language flags that might not work with the
- // particular os
- if (forbiddenFlagVar) {
- this->RemoveForbiddenFlags(forbiddenFlagVar, linkLanguage, langFlags);
- }
vars.LanguageCompileFlags = langFlags.c_str();
// Construct the main link rule and expand placeholders.
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index e70f09e..84ae726 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -10,6 +10,7 @@
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalUnixMakefileGenerator3.h"
+#include "cmLinkLineComputer.h"
#include "cmLocalGenerator.h"
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
@@ -110,7 +111,8 @@ void cmMakefileTargetGenerator::CreateRuleFile()
// Open the rule file. This should be copy-if-different because the
// rules may depend on this file itself.
this->BuildFileStream =
- new cmGeneratedFileStream(this->BuildFileNameFull.c_str());
+ new cmGeneratedFileStream(this->BuildFileNameFull.c_str(), false,
+ this->GlobalGenerator->GetMakefileEncoding());
this->BuildFileStream->SetCopyIfDifferent(true);
if (!this->BuildFileStream) {
return;
@@ -166,7 +168,7 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
for (std::vector<std::string>::const_iterator o = outputs.begin();
o != outputs.end(); ++o) {
this->CleanFiles.push_back(
- this->LocalGenerator->ConvertToRelativePath(currentBinDir, *o));
+ this->LocalGenerator->MaybeConvertToRelativePath(currentBinDir, *o));
}
}
}
@@ -209,8 +211,8 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
<< this->GlobalGenerator->IncludeDirective << " " << root
<< cmSystemTools::ConvertToOutputPath(
this->LocalGenerator
- ->ConvertToRelativePath(this->LocalGenerator->GetBinaryDirectory(),
- dependFileNameFull)
+ ->MaybeConvertToRelativePath(
+ this->LocalGenerator->GetBinaryDirectory(), dependFileNameFull)
.c_str())
<< "\n\n";
@@ -221,7 +223,7 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
<< this->GlobalGenerator->IncludeDirective << " " << root
<< cmSystemTools::ConvertToOutputPath(
this->LocalGenerator
- ->ConvertToRelativePath(
+ ->MaybeConvertToRelativePath(
this->LocalGenerator->GetBinaryDirectory(),
this->ProgressFileNameFull)
.c_str())
@@ -231,7 +233,9 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
// make sure the depend file exists
if (!cmSystemTools::FileExists(dependFileNameFull.c_str())) {
// Write an empty dependency file.
- cmGeneratedFileStream depFileStream(dependFileNameFull.c_str());
+ cmGeneratedFileStream depFileStream(
+ dependFileNameFull.c_str(), false,
+ this->GlobalGenerator->GetMakefileEncoding());
depFileStream << "# Empty dependencies file for "
<< this->GeneratorTarget->GetName() << ".\n"
<< "# This may be replaced when dependencies are built."
@@ -243,7 +247,8 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
this->FlagFileNameFull = this->TargetBuildDirectoryFull;
this->FlagFileNameFull += "/flags.make";
this->FlagFileStream =
- new cmGeneratedFileStream(this->FlagFileNameFull.c_str());
+ new cmGeneratedFileStream(this->FlagFileNameFull.c_str(), false,
+ this->GlobalGenerator->GetMakefileEncoding());
this->FlagFileStream->SetCopyIfDifferent(true);
if (!this->FlagFileStream) {
return;
@@ -256,8 +261,9 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
<< this->GlobalGenerator->IncludeDirective << " " << root
<< cmSystemTools::ConvertToOutputPath(
this->LocalGenerator
- ->ConvertToRelativePath(this->LocalGenerator->GetBinaryDirectory(),
- this->FlagFileNameFull)
+ ->MaybeConvertToRelativePath(
+ this->LocalGenerator->GetBinaryDirectory(),
+ this->FlagFileNameFull)
.c_str())
<< "\n\n";
}
@@ -314,9 +320,9 @@ void cmMakefileTargetGenerator::MacOSXContentGeneratorType::operator()(
output += "/";
output += cmSystemTools::GetFilenameName(input);
this->Generator->CleanFiles.push_back(
- this->Generator->LocalGenerator->ConvertToRelativePath(
+ this->Generator->LocalGenerator->MaybeConvertToRelativePath(
this->Generator->LocalGenerator->GetCurrentBinaryDirectory(), output));
- output = this->Generator->LocalGenerator->ConvertToRelativePath(
+ output = this->Generator->LocalGenerator->MaybeConvertToRelativePath(
this->Generator->LocalGenerator->GetBinaryDirectory(), output);
// Create a rule to copy the content into the bundle.
@@ -518,13 +524,13 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
}
targetOutPathReal = this->LocalGenerator->ConvertToOutputFormat(
- this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathReal),
cmOutputConverter::SHELL);
targetOutPathPDB = this->LocalGenerator->ConvertToOutputFormat(
targetFullPathPDB, cmOutputConverter::SHELL);
targetOutPathCompilePDB = this->LocalGenerator->ConvertToOutputFormat(
- this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(),
targetFullPathCompilePDB),
cmOutputConverter::SHELL);
@@ -550,13 +556,13 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
vars.Object = shellObj.c_str();
std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
objectDir = this->LocalGenerator->ConvertToOutputFormat(
- this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), objectDir),
cmOutputConverter::SHELL);
vars.ObjectDir = objectDir.c_str();
std::string objectFileDir = cmSystemTools::GetFilenamePath(obj);
objectFileDir = this->LocalGenerator->ConvertToOutputFormat(
- this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), objectFileDir),
cmOutputConverter::SHELL);
vars.ObjectFileDir = objectFileDir.c_str();
@@ -904,7 +910,7 @@ bool cmMakefileTargetGenerator::WriteMakeRule(
// Touch the extra output so "make" knows that it was updated,
// but only if the output was acually created.
std::string const out = this->LocalGenerator->ConvertToOutputFormat(
- this->LocalGenerator->ConvertToRelativePath(binDir, *o),
+ this->LocalGenerator->MaybeConvertToRelativePath(binDir, *o),
cmOutputConverter::SHELL);
std::vector<std::string> output_commands;
@@ -1200,10 +1206,9 @@ void cmMakefileTargetGenerator::WriteObjectsVariable(
for (std::vector<std::string>::const_iterator i =
this->ExternalObjects.begin();
i != this->ExternalObjects.end(); ++i) {
- object = this->LocalGenerator->ConvertToRelativePath(currentBinDir, *i);
- *this->BuildFileStream << " " << lineContinue << "\n"
- << this->Makefile->GetSafeDefinition(
- "CMAKE_OBJECT_NAME");
+ object =
+ this->LocalGenerator->MaybeConvertToRelativePath(currentBinDir, *i);
+ *this->BuildFileStream << " " << lineContinue << "\n";
*this->BuildFileStream << this->LocalGenerator->ConvertToQuotedOutputPath(
i->c_str(), useWatcomQuote);
}
@@ -1211,21 +1216,16 @@ void cmMakefileTargetGenerator::WriteObjectsVariable(
<< "\n";
}
-void cmMakefileTargetGenerator::WriteObjectsString(std::string& buildObjs)
-{
- std::vector<std::string> objStrings;
- this->WriteObjectsStrings(objStrings);
- buildObjs = objStrings[0];
-}
-
class cmMakefileTargetGeneratorObjectStrings
{
public:
cmMakefileTargetGeneratorObjectStrings(std::vector<std::string>& strings,
- cmLocalUnixMakefileGenerator3* lg,
+ cmOutputConverter* outputConverter,
+ cmState::Directory stateDir,
std::string::size_type limit)
: Strings(strings)
- , LocalGenerator(lg)
+ , OutputConverter(outputConverter)
+ , StateDir(stateDir)
, LengthLimit(limit)
{
this->Space = "";
@@ -1233,10 +1233,8 @@ public:
void Feed(std::string const& obj)
{
// Construct the name of the next object.
- this->NextObject = this->LocalGenerator->ConvertToOutputFormat(
- this->LocalGenerator->ConvertToRelativePath(
- this->LocalGenerator->GetCurrentBinaryDirectory(), obj),
- cmOutputConverter::RESPONSE);
+ this->NextObject = this->OutputConverter->ConvertToOutputFormat(
+ this->MaybeConvertToRelativePath(obj), cmOutputConverter::RESPONSE);
// Roll over to next string if the limit will be exceeded.
if (this->LengthLimit != std::string::npos &&
@@ -1256,8 +1254,19 @@ public:
}
void Done() { this->Strings.push_back(this->CurrentString); }
private:
+ std::string MaybeConvertToRelativePath(std::string const& obj)
+ {
+ if (!cmOutputConverter::ContainedInDirectory(
+ this->StateDir.GetCurrentBinary(), obj, this->StateDir)) {
+ return obj;
+ }
+ return cmOutputConverter::ForceToRelativePath(
+ this->StateDir.GetCurrentBinary(), obj);
+ }
+
std::vector<std::string>& Strings;
- cmLocalUnixMakefileGenerator3* LocalGenerator;
+ cmOutputConverter* OutputConverter;
+ cmState::Directory StateDir;
std::string::size_type LengthLimit;
std::string CurrentString;
std::string NextObject;
@@ -1267,8 +1276,9 @@ private:
void cmMakefileTargetGenerator::WriteObjectsStrings(
std::vector<std::string>& objStrings, std::string::size_type limit)
{
- cmMakefileTargetGeneratorObjectStrings helper(objStrings,
- this->LocalGenerator, limit);
+ cmMakefileTargetGeneratorObjectStrings helper(
+ objStrings, this->LocalGenerator,
+ this->LocalGenerator->GetStateSnapshot().GetDirectory(), limit);
for (std::vector<std::string>::const_iterator i = this->Objects.begin();
i != this->Objects.end(); ++i) {
helper.Feed(*i);
@@ -1289,7 +1299,7 @@ void cmMakefileTargetGenerator::WriteTargetDriverRule(
this->LocalGenerator->GetRelativeTargetDirectory(this->GeneratorTarget);
std::string buildTargetRuleName = dir;
buildTargetRuleName += relink ? "/preinstall" : "/build";
- buildTargetRuleName = this->LocalGenerator->ConvertToRelativePath(
+ buildTargetRuleName = this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetBinaryDirectory(), buildTargetRuleName);
// Build the list of target outputs to drive.
@@ -1410,52 +1420,6 @@ void cmMakefileTargetGenerator::CloseFileStreams()
delete this->FlagFileStream;
}
-void cmMakefileTargetGenerator::RemoveForbiddenFlags(
- const char* flagVar, const std::string& linkLang, std::string& linkFlags)
-{
- // check for language flags that are not allowed at link time, and
- // remove them, -w on darwin for gcc -w -dynamiclib sends -w to libtool
- // which fails, there may be more]
-
- std::string removeFlags = "CMAKE_";
- removeFlags += linkLang;
- removeFlags += flagVar;
- std::string removeflags = this->Makefile->GetSafeDefinition(removeFlags);
- std::vector<std::string> removeList;
- cmSystemTools::ExpandListArgument(removeflags, removeList);
-
- for (std::vector<std::string>::iterator i = removeList.begin();
- i != removeList.end(); ++i) {
- std::string tmp;
- std::string::size_type lastPosition = 0;
-
- for (;;) {
- std::string::size_type position = linkFlags.find(*i, lastPosition);
-
- if (position == std::string::npos) {
- tmp += linkFlags.substr(lastPosition);
- break;
- } else {
- std::string::size_type prefixLength = position - lastPosition;
- tmp += linkFlags.substr(lastPosition, prefixLength);
- lastPosition = position + i->length();
-
- bool validFlagStart =
- position == 0 || isspace(linkFlags[position - 1]);
-
- bool validFlagEnd =
- lastPosition == linkFlags.size() || isspace(linkFlags[lastPosition]);
-
- if (!validFlagStart || !validFlagEnd) {
- tmp += *i;
- }
- }
- }
-
- linkFlags = tmp;
- }
-}
-
void cmMakefileTargetGenerator::CreateLinkScript(
const char* name, std::vector<std::string> const& link_commands,
std::vector<std::string>& makefile_commands,
@@ -1479,7 +1443,7 @@ void cmMakefileTargetGenerator::CreateLinkScript(
// Create the makefile command to invoke the link script.
std::string link_command = "$(CMAKE_COMMAND) -E cmake_link_script ";
link_command += this->LocalGenerator->ConvertToOutputFormat(
- this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), linkScriptName),
cmOutputConverter::SHELL);
link_command += " --verbose=$(VERBOSE)";
@@ -1577,15 +1541,28 @@ std::string cmMakefileTargetGenerator::CreateResponseFile(
return responseFileName;
}
+cmLinkLineComputer* cmMakefileTargetGenerator::CreateLinkLineComputer(
+ cmOutputConverter* outputConverter, cmState::Directory stateDir)
+{
+ if (this->Makefile->IsOn("MSVC60")) {
+ return this->GlobalGenerator->CreateMSVC60LinkLineComputer(outputConverter,
+ stateDir);
+ }
+ return this->GlobalGenerator->CreateLinkLineComputer(outputConverter,
+ stateDir);
+}
+
void cmMakefileTargetGenerator::CreateLinkLibs(
- std::string& linkLibs, bool relink, bool useResponseFile,
- std::vector<std::string>& makefile_depends, bool useWatcomQuote)
+ cmLinkLineComputer* linkLineComputer, std::string& linkLibs,
+ bool useResponseFile, std::vector<std::string>& makefile_depends)
{
std::string frameworkPath;
std::string linkPath;
- this->LocalGenerator->OutputLinkLibraries(linkLibs, frameworkPath, linkPath,
- *this->GeneratorTarget, relink,
- useResponseFile, useWatcomQuote);
+ std::string config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+ cmComputeLinkInformation* pcli =
+ this->GeneratorTarget->GetLinkInformation(config);
+ this->LocalGenerator->OutputLinkLibraries(pcli, linkLineComputer, linkLibs,
+ frameworkPath, linkPath);
linkLibs = frameworkPath + linkPath + linkLibs;
if (useResponseFile && linkLibs.find_first_not_of(' ') != linkLibs.npos) {
@@ -1659,7 +1636,9 @@ void cmMakefileTargetGenerator::CreateObjectLists(
}
} else if (useLinkScript) {
if (!useArchiveRules) {
- this->WriteObjectsString(buildObjs);
+ std::vector<std::string> objStrings;
+ this->WriteObjectsStrings(objStrings);
+ buildObjs = objStrings[0];
}
} else {
buildObjs = "$(";
@@ -1716,14 +1695,14 @@ void cmMakefileTargetGenerator::GenDefFile(
cmd, cmOutputConverter::SHELL);
cmd += " -E __create_def ";
cmd += this->LocalGenerator->ConvertToOutputFormat(
- this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), name_of_def_file),
cmOutputConverter::SHELL);
cmd += " ";
std::string objlist_file = name_of_def_file;
objlist_file += ".objs";
cmd += this->LocalGenerator->ConvertToOutputFormat(
- this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), objlist_file),
cmOutputConverter::SHELL);
real_link_commands.insert(real_link_commands.begin(), cmd);
@@ -1744,7 +1723,7 @@ void cmMakefileTargetGenerator::GenDefFile(
linkFlags += " ";
linkFlags += this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG");
linkFlags += this->LocalGenerator->ConvertToOutputFormat(
- this->LocalGenerator->ConvertToRelativePath(
+ this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), name_of_def_file),
cmOutputConverter::SHELL);
linkFlags += " ";
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index df7b6aa..4c61011 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -20,6 +20,7 @@ class cmGeneratedFileStream;
class cmGeneratorTarget;
class cmGlobalUnixMakefileGenerator3;
class cmSourceFile;
+class cmLinkLineComputer;
/** \class cmMakefileTargetGenerator
* \brief Support Routines for writing makefiles
@@ -112,7 +113,6 @@ protected:
void WriteObjectsVariable(std::string& variableName,
std::string& variableNameExternal,
bool useWatcomQuote);
- void WriteObjectsString(std::string& buildObjs);
void WriteObjectsStrings(std::vector<std::string>& objStrings,
std::string::size_type limit = std::string::npos);
@@ -140,6 +140,9 @@ protected:
std::vector<std::string>& makefile_commands,
std::vector<std::string>& makefile_depends);
+ cmLinkLineComputer* CreateLinkLineComputer(
+ cmOutputConverter* outputConverter, cmState::Directory stateDir);
+
/** Create a response file with the given set of options. Returns
the relative path from the target build working directory to the
response file name. */
@@ -150,9 +153,9 @@ protected:
bool CheckUseResponseFileForLibraries(std::string const& l) const;
/** Create list of flags for link libraries. */
- void CreateLinkLibs(std::string& linkLibs, bool relink, bool useResponseFile,
- std::vector<std::string>& makefile_depends,
- bool useWatcomQuote);
+ void CreateLinkLibs(cmLinkLineComputer* linkLineComputer,
+ std::string& linkLibs, bool useResponseFile,
+ std::vector<std::string>& makefile_depends);
/** Create lists of object files for linking and cleaning. */
void CreateObjectLists(bool useLinkScript, bool useArchiveRules,
@@ -168,8 +171,6 @@ protected:
const std::string& lang) CM_OVERRIDE;
virtual void CloseFileStreams();
- void RemoveForbiddenFlags(const char* flagVar, const std::string& linkLang,
- std::string& linkFlags);
cmLocalUnixMakefileGenerator3* LocalGenerator;
cmGlobalUnixMakefileGenerator3* GlobalGenerator;
diff --git a/Source/cmMakefileUtilityTargetGenerator.cxx b/Source/cmMakefileUtilityTargetGenerator.cxx
index f40c8fa..ecb29cb 100644
--- a/Source/cmMakefileUtilityTargetGenerator.cxx
+++ b/Source/cmMakefileUtilityTargetGenerator.cxx
@@ -46,7 +46,7 @@ void cmMakefileUtilityTargetGenerator::WriteRuleFiles()
<< this->GlobalGenerator->IncludeDirective << " " << root
<< cmSystemTools::ConvertToOutputPath(
this->LocalGenerator
- ->ConvertToRelativePath(
+ ->MaybeConvertToRelativePath(
this->LocalGenerator->GetBinaryDirectory(),
this->ProgressFileNameFull)
.c_str())
diff --git a/Source/cmNinjaLinkLineComputer.cxx b/Source/cmNinjaLinkLineComputer.cxx
new file mode 100644
index 0000000..3dcb20b
--- /dev/null
+++ b/Source/cmNinjaLinkLineComputer.cxx
@@ -0,0 +1,19 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmNinjaLinkLineComputer.h"
+#include "cmGlobalNinjaGenerator.h"
+
+cmNinjaLinkLineComputer::cmNinjaLinkLineComputer(
+ cmOutputConverter* outputConverter, cmState::Directory stateDir,
+ cmGlobalNinjaGenerator const* gg)
+ : cmLinkLineComputer(outputConverter, stateDir)
+ , GG(gg)
+{
+}
+
+std::string cmNinjaLinkLineComputer::ConvertToLinkReference(
+ std::string const& lib) const
+{
+ return GG->ConvertToNinjaPath(lib);
+}
diff --git a/Source/cmNinjaLinkLineComputer.h b/Source/cmNinjaLinkLineComputer.h
new file mode 100644
index 0000000..a108568
--- /dev/null
+++ b/Source/cmNinjaLinkLineComputer.h
@@ -0,0 +1,26 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#ifndef cmNinjaLinkLineComputer_h
+#define cmNinjaLinkLineComputer_h
+
+#include "cmLinkLineComputer.h"
+#include "cmState.h"
+
+class cmGlobalNinjaGenerator;
+
+class cmNinjaLinkLineComputer : public cmLinkLineComputer
+{
+public:
+ cmNinjaLinkLineComputer(cmOutputConverter* outputConverter,
+ cmState::Directory stateDir,
+ cmGlobalNinjaGenerator const* gg);
+
+ std::string ConvertToLinkReference(std::string const& input) const
+ CM_OVERRIDE;
+
+private:
+ cmGlobalNinjaGenerator const* GG;
+};
+
+#endif
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 095c703..ab086eb 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -8,6 +8,7 @@
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalNinjaGenerator.h"
+#include "cmLinkLineComputer.h"
#include "cmLocalGenerator.h"
#include "cmLocalNinjaGenerator.h"
#include "cmMakefile.h"
@@ -470,9 +471,15 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
vars["TARGET_FILE"] =
localGen.ConvertToOutputFormat(targetOutputReal, cmOutputConverter::SHELL);
- localGen.GetTargetFlags(this->GetConfigName(), vars["LINK_LIBRARIES"],
- vars["FLAGS"], vars["LINK_FLAGS"], frameworkPath,
- linkPath, &genTarget, useWatcomQuote);
+ CM_AUTO_PTR<cmLinkLineComputer> linkLineComputer(
+ this->GetGlobalGenerator()->CreateLinkLineComputer(
+ this->GetLocalGenerator(),
+ this->GetLocalGenerator()->GetStateSnapshot().GetDirectory()));
+ linkLineComputer->SetUseWatcomQuote(useWatcomQuote);
+
+ localGen.GetTargetFlags(
+ linkLineComputer.get(), this->GetConfigName(), vars["LINK_LIBRARIES"],
+ vars["FLAGS"], vars["LINK_FLAGS"], frameworkPath, linkPath, &genTarget);
if (this->GetMakefile()->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS") &&
(gt.GetType() == cmState::SHARED_LIBRARY ||
gt.IsExecutableWithExports())) {
@@ -497,7 +504,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
this->addPoolNinjaVariable("JOB_POOL_LINK", &gt, vars);
- this->AddModuleDefinitionFlag(vars["LINK_FLAGS"]);
+ this->AddModuleDefinitionFlag(linkLineComputer.get(), vars["LINK_FLAGS"]);
vars["LINK_FLAGS"] =
cmGlobalNinjaGenerator::EncodeLiteral(vars["LINK_FLAGS"]);
diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx
index 2ef603b..84a433c 100644
--- a/Source/cmOutputConverter.cxx
+++ b/Source/cmOutputConverter.cxx
@@ -76,44 +76,35 @@ static bool cmOutputConverterNotAbove(const char* a, const char* b)
cmSystemTools::IsSubDirectory(a, b));
}
-std::string cmOutputConverter::ConvertToRelativePath(
- const std::vector<std::string>& local, const std::string& in_remote,
- bool force) const
+bool cmOutputConverter::ContainedInDirectory(std::string const& local_path,
+ std::string const& remote_path,
+ cmState::Directory directory)
{
- std::string local_path = cmSystemTools::JoinPath(local);
- return force ? this->ForceToRelativePath(local_path, in_remote)
- : this->ConvertToRelativePath(local_path, in_remote);
+ const std::string relativePathTopBinary =
+ directory.GetRelativePathTopBinary();
+ const std::string relativePathTopSource =
+ directory.GetRelativePathTopSource();
+
+ const bool bothInBinary =
+ cmOutputConverterNotAbove(local_path.c_str(),
+ relativePathTopBinary.c_str()) &&
+ cmOutputConverterNotAbove(remote_path.c_str(),
+ relativePathTopBinary.c_str());
+
+ const bool bothInSource =
+ cmOutputConverterNotAbove(local_path.c_str(),
+ relativePathTopSource.c_str()) &&
+ cmOutputConverterNotAbove(remote_path.c_str(),
+ relativePathTopSource.c_str());
+
+ return bothInSource || bothInBinary;
}
std::string cmOutputConverter::ConvertToRelativePath(
std::string const& local_path, std::string const& remote_path) const
{
- // The paths should never be quoted.
- assert(local_path[0] != '\"');
- assert(remote_path[0] != '\"');
-
- // The local path should never have a trailing slash.
- assert(local_path.empty() || local_path[local_path.size() - 1] != '/');
-
- // If the path is already relative then just return the path.
- if (!cmSystemTools::FileIsFullPath(remote_path.c_str())) {
- return remote_path;
- }
-
- // Skip conversion if the path and local are not both in the source
- // or both in the binary tree.
- if (!((cmOutputConverterNotAbove(
- local_path.c_str(),
- this->StateSnapshot.GetDirectory().GetRelativePathTopBinary()) &&
- cmOutputConverterNotAbove(
- remote_path.c_str(),
- this->StateSnapshot.GetDirectory().GetRelativePathTopBinary())) ||
- (cmOutputConverterNotAbove(
- local_path.c_str(),
- this->StateSnapshot.GetDirectory().GetRelativePathTopSource()) &&
- cmOutputConverterNotAbove(
- remote_path.c_str(),
- this->StateSnapshot.GetDirectory().GetRelativePathTopSource())))) {
+ if (!ContainedInDirectory(local_path, remote_path,
+ this->StateSnapshot.GetDirectory())) {
return remote_path;
}
@@ -248,10 +239,11 @@ std::string cmOutputConverter::EscapeForShell(const std::string& str,
if (this->GetState()->UseNMake()) {
flags |= Shell_Flag_NMake;
}
+ if (!this->GetState()->UseWindowsShell()) {
+ flags |= Shell_Flag_IsUnix;
+ }
- return this->GetState()->UseWindowsShell()
- ? Shell_GetArgumentForWindows(str.c_str(), flags)
- : Shell_GetArgumentForUnix(str.c_str(), flags);
+ return Shell__GetArgument(str.c_str(), flags);
}
std::string cmOutputConverter::EscapeForCMake(const std::string& str)
@@ -280,7 +272,7 @@ std::string cmOutputConverter::EscapeForCMake(const std::string& str)
std::string cmOutputConverter::EscapeWindowsShellArgument(const char* arg,
int shell_flags)
{
- return Shell_GetArgumentForWindows(arg, shell_flags);
+ return Shell__GetArgument(arg, shell_flags);
}
cmOutputConverter::FortranFormat cmOutputConverter::GetFortranFormat(
@@ -366,10 +358,10 @@ int cmOutputConverter::Shell__CharNeedsQuotesOnWindows(char c)
(c == '>') || (c == '|') || (c == '^'));
}
-int cmOutputConverter::Shell__CharNeedsQuotes(char c, int isUnix, int flags)
+int cmOutputConverter::Shell__CharNeedsQuotes(char c, int flags)
{
/* On Windows the built-in command shell echo never needs quotes. */
- if (!isUnix && (flags & Shell_Flag_EchoWindows)) {
+ if (!(flags & Shell_Flag_IsUnix) && (flags & Shell_Flag_EchoWindows)) {
return 0;
}
@@ -378,7 +370,7 @@ int cmOutputConverter::Shell__CharNeedsQuotes(char c, int isUnix, int flags)
return 1;
}
- if (isUnix) {
+ if (flags & Shell_Flag_IsUnix) {
/* On UNIX several special characters need quotes to preserve them. */
if (Shell__CharNeedsQuotesOnUnix(c)) {
return 1;
@@ -436,8 +428,7 @@ flag later when we understand applications of this better.
*/
#define KWSYS_SYSTEM_SHELL_QUOTE_MAKE_VARIABLES 0
-int cmOutputConverter::Shell__ArgumentNeedsQuotes(const char* in, int isUnix,
- int flags)
+int cmOutputConverter::Shell__ArgumentNeedsQuotes(const char* in, int flags)
{
/* The empty string needs quotes. */
if (!*in) {
@@ -469,14 +460,14 @@ int cmOutputConverter::Shell__ArgumentNeedsQuotes(const char* in, int isUnix,
}
/* Check whether this character needs quotes. */
- if (Shell__CharNeedsQuotes(*c, isUnix, flags)) {
+ if (Shell__CharNeedsQuotes(*c, flags)) {
return 1;
}
}
}
/* On Windows some single character arguments need quotes. */
- if (!isUnix && *in && !*(in + 1)) {
+ if (flags & Shell_Flag_IsUnix && *in && !*(in + 1)) {
char c = *in;
if ((c == '?') || (c == '&') || (c == '^') || (c == '|') || (c == '#')) {
return 1;
@@ -486,8 +477,7 @@ int cmOutputConverter::Shell__ArgumentNeedsQuotes(const char* in, int isUnix,
return 0;
}
-std::string cmOutputConverter::Shell__GetArgument(const char* in, int isUnix,
- int flags)
+std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags)
{
std::ostringstream out;
@@ -498,11 +488,11 @@ std::string cmOutputConverter::Shell__GetArgument(const char* in, int isUnix,
int windows_backslashes = 0;
/* Whether the argument must be quoted. */
- int needQuotes = Shell__ArgumentNeedsQuotes(in, isUnix, flags);
+ int needQuotes = Shell__ArgumentNeedsQuotes(in, flags);
if (needQuotes) {
/* Add the opening quote for this argument. */
if (flags & Shell_Flag_WatcomQuote) {
- if (isUnix) {
+ if (flags & Shell_Flag_IsUnix) {
out << '"';
}
out << '\'';
@@ -534,7 +524,7 @@ std::string cmOutputConverter::Shell__GetArgument(const char* in, int isUnix,
}
/* Check whether this character needs escaping for the shell. */
- if (isUnix) {
+ if (flags & Shell_Flag_IsUnix) {
/* On Unix a few special characters need escaping even inside a
quoted argument. */
if (*c == '\\' || *c == '"' || *c == '`' || *c == '$') {
@@ -631,7 +621,7 @@ std::string cmOutputConverter::Shell__GetArgument(const char* in, int isUnix,
/* Add the closing quote for this argument. */
if (flags & Shell_Flag_WatcomQuote) {
out << '\'';
- if (isUnix) {
+ if (flags & Shell_Flag_IsUnix) {
out << '"';
}
} else {
@@ -641,15 +631,3 @@ std::string cmOutputConverter::Shell__GetArgument(const char* in, int isUnix,
return out.str();
}
-
-std::string cmOutputConverter::Shell_GetArgumentForWindows(const char* in,
- int flags)
-{
- return Shell__GetArgument(in, 0, flags);
-}
-
-std::string cmOutputConverter::Shell_GetArgumentForUnix(const char* in,
- int flags)
-{
- return Shell__GetArgument(in, 1, flags);
-}
diff --git a/Source/cmOutputConverter.h b/Source/cmOutputConverter.h
index 5979eaa..71cacab 100644
--- a/Source/cmOutputConverter.h
+++ b/Source/cmOutputConverter.h
@@ -33,8 +33,7 @@ public:
void SetLinkScriptShell(bool linkScriptShell);
/**
- * Flags to pass to Shell_GetArgumentForWindows or
- * Shell_GetArgumentForUnix. These modify the generated
+ * Flags to pass to Shell_GetArgument. These modify the generated
* quoting and escape sequences to work under alternative
* environments.
*/
@@ -67,18 +66,10 @@ public:
Shell_Flag_AllowMakeVariables = (1 << 6),
/** The target shell quoting uses extra single Quotes for Watcom tools. */
- Shell_Flag_WatcomQuote = (1 << 7)
- };
+ Shell_Flag_WatcomQuote = (1 << 7),
- /**
- * Transform the given command line argument for use in a Windows or
- * Unix shell. Returns a pointer to the end of the command line
- * argument in the provided output buffer. Flags may be passed to
- * modify the generated quoting and escape sequences to work under
- * alternative environments.
- */
- static std::string Shell_GetArgumentForWindows(const char* in, int flags);
- static std::string Shell_GetArgumentForUnix(const char* in, int flags);
+ Shell_Flag_IsUnix = (1 << 8)
+ };
std::string EscapeForShell(const std::string& str, bool makeVars = false,
bool forEcho = false,
@@ -99,16 +90,9 @@ public:
};
static FortranFormat GetFortranFormat(const char* value);
- /**
- * Convert the given remote path to a relative path with respect to
- * the given local path. The local path must be given in component
- * form (see SystemTools::SplitPath) without a trailing slash. The
- * remote path must use forward slashes and not already be escaped
- * or quoted.
- */
- std::string ConvertToRelativePath(const std::vector<std::string>& local,
- const std::string& in_remote,
- bool force = false) const;
+ static bool ContainedInDirectory(std::string const& local_path,
+ std::string const& remote_path,
+ cmState::Directory directory);
/**
* Convert the given remote path to a relative path with respect to
@@ -134,11 +118,11 @@ private:
static int Shell__CharIsWhitespace(char c);
static int Shell__CharNeedsQuotesOnUnix(char c);
static int Shell__CharNeedsQuotesOnWindows(char c);
- static int Shell__CharNeedsQuotes(char c, int isUnix, int flags);
+ static int Shell__CharNeedsQuotes(char c, int flags);
static int Shell__CharIsMakeVariableName(char c);
static const char* Shell__SkipMakeVariables(const char* c);
- static int Shell__ArgumentNeedsQuotes(const char* in, int isUnix, int flags);
- static std::string Shell__GetArgument(const char* in, int isUnix, int flags);
+ static int Shell__ArgumentNeedsQuotes(const char* in, int flags);
+ static std::string Shell__GetArgument(const char* in, int flags);
private:
cmState::Snapshot StateSnapshot;
diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx
index a2bdf49..e0fcb75 100644
--- a/Source/cmServerProtocol.cxx
+++ b/Source/cmServerProtocol.cxx
@@ -7,6 +7,7 @@
#include "cmFileMonitor.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmLinkLineComputer.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
@@ -728,8 +729,10 @@ static Json::Value DumpTarget(cmGeneratorTarget* target,
std::string linkLanguageFlags;
std::string frameworkPath;
std::string linkPath;
- lg->GetTargetFlags(config, linkLibs, linkLanguageFlags, linkFlags,
- frameworkPath, linkPath, target, false);
+ cmLinkLineComputer linkLineComputer(lg,
+ lg->GetStateSnapshot().GetDirectory());
+ lg->GetTargetFlags(&linkLineComputer, config, linkLibs, linkLanguageFlags,
+ linkFlags, frameworkPath, linkPath, target);
linkLibs = cmSystemTools::TrimWhitespace(linkLibs);
linkFlags = cmSystemTools::TrimWhitespace(linkFlags);
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 3d8fdf5..d800ef8 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -2518,9 +2518,9 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
std::swap(se[0], se[1]);
}
- // Get the size of the dynamic section header.
- unsigned int count = elf.GetDynamicEntryCount();
- if (count == 0) {
+ // Obtain a copy of the dynamic entries
+ cmELF::DynamicEntryList dentries = elf.GetDynamicEntries();
+ if (dentries.empty()) {
// This should happen only for invalid ELF files where a DT_NULL
// appears before the end of the table.
if (emsg) {
@@ -2536,40 +2536,46 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
zeroSize[i] = se[i]->Size;
}
- // Get the range of file positions corresponding to each entry and
- // the rest of the table after them.
- unsigned long entryBegin[3] = { 0, 0, 0 };
- unsigned long entryEnd[2] = { 0, 0 };
- for (int i = 0; i < se_count; ++i) {
- entryBegin[i] = elf.GetDynamicEntryPosition(se[i]->IndexInSection);
- entryEnd[i] = elf.GetDynamicEntryPosition(se[i]->IndexInSection + 1);
- }
- entryBegin[se_count] = elf.GetDynamicEntryPosition(count);
-
- // The data are to be written over the old table entries starting at
- // the first one being removed.
- bytesBegin = entryBegin[0];
- unsigned long bytesEnd = entryBegin[se_count];
+ // Get size of one DYNAMIC entry
+ unsigned long const sizeof_dentry =
+ elf.GetDynamicEntryPosition(1) - elf.GetDynamicEntryPosition(0);
- // Allocate a buffer to hold the part of the file to be written.
- // Initialize it with zeros.
- bytes.resize(bytesEnd - bytesBegin, 0);
-
- // Read the part of the DYNAMIC section header that will move.
- // The remainder of the buffer will be left with zeros which
- // represent a DT_NULL entry.
- char* data = &bytes[0];
- for (int i = 0; i < se_count; ++i) {
- // Read data between the entries being removed.
- unsigned long sz = entryBegin[i + 1] - entryEnd[i];
- if (sz > 0 && !elf.ReadBytes(entryEnd[i], sz, data)) {
- if (emsg) {
- *emsg = "Failed to read DYNAMIC section header.";
+ // Adjust the entry list as necessary to remove the run path
+ unsigned long entriesErased = 0;
+ for (cmELF::DynamicEntryList::iterator it = dentries.begin();
+ it != dentries.end();) {
+ if (it->first == cmELF::TagRPath || it->first == cmELF::TagRunPath) {
+ it = dentries.erase(it);
+ entriesErased++;
+ continue;
+ } else {
+ if (cmELF::TagMipsRldMapRel != 0 &&
+ it->first == cmELF::TagMipsRldMapRel) {
+ // Background: debuggers need to know the "linker map" which contains
+ // the addresses each dynamic object is loaded at. Most arches use
+ // the DT_DEBUG tag which the dynamic linker writes to (directly) and
+ // contain the location of the linker map, however on MIPS the
+ // .dynamic section is always read-only so this is not possible. MIPS
+ // objects instead contain a DT_MIPS_RLD_MAP tag which contains the
+ // address where the dyanmic linker will write to (an indirect
+ // version of DT_DEBUG). Since this doesn't work when using PIE, a
+ // relative equivalent was created - DT_MIPS_RLD_MAP_REL. Since this
+ // version contains a relative offset, moving it changes the
+ // calculated address. This may cause the dyanmic linker to write
+ // into memory it should not be changing.
+ //
+ // To fix this, we adjust the value of DT_MIPS_RLD_MAP_REL here. If
+ // we move it up by n bytes, we add n bytes to the value of this tag.
+ it->second += entriesErased * sizeof_dentry;
}
- return false;
+
+ it++;
}
- data += sz;
}
+
+ // Encode new entries list
+ bytes = elf.EncodeDynamicEntries(dentries);
+ bytesBegin = elf.GetDynamicEntryPosition(0);
}
// Open the file for update.
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 54e0bea..651bcc8 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -102,6 +102,7 @@ cmTarget::cmTarget(std::string const& name, cmState::TargetType type,
this->SetPropertyDefault("ANDROID_JAR_DEPENDENCIES", CM_NULLPTR);
this->SetPropertyDefault("ANDROID_ASSETS_DIRECTORIES", CM_NULLPTR);
this->SetPropertyDefault("ANDROID_ANT_ADDITIONAL_OPTIONS", CM_NULLPTR);
+ this->SetPropertyDefault("BUILD_RPATH", CM_NULLPTR);
this->SetPropertyDefault("INSTALL_NAME_DIR", CM_NULLPTR);
this->SetPropertyDefault("INSTALL_RPATH", "");
this->SetPropertyDefault("INSTALL_RPATH_USE_LINK_PATH", "OFF");
@@ -475,23 +476,6 @@ cmSourceFile* cmTarget::AddSource(const std::string& src)
return this->Makefile->GetOrCreateSource(src);
}
-void cmTarget::MergeLinkLibraries(cmMakefile& mf, const std::string& selfname,
- const LinkLibraryVectorType& libs)
-{
- // Only add on libraries we haven't added on before.
- // Assumption: the global link libraries could only grow, never shrink
- LinkLibraryVectorType::const_iterator i = libs.begin();
- i += this->PrevLinkedLibraries.size();
- for (; i != libs.end(); ++i) {
- // This is equivalent to the target_link_libraries plain signature.
- this->AddLinkLibrary(mf, selfname, i->first, i->second);
- this->AppendProperty(
- "INTERFACE_LINK_LIBRARIES",
- this->GetDebugGeneratorExpressions(i->first, i->second).c_str());
- }
- this->PrevLinkedLibraries = libs;
-}
-
void cmTarget::AddLinkDirectory(const std::string& d)
{
// Make sure we don't add unnecessary search directories.
@@ -594,8 +578,7 @@ void cmTarget::GetTllSignatureTraces(std::ostream& s, TLLSignature sig) const
}
}
-void cmTarget::AddLinkLibrary(cmMakefile& mf, const std::string& target,
- const std::string& lib,
+void cmTarget::AddLinkLibrary(cmMakefile& mf, const std::string& lib,
cmTargetLinkLibraryType llt)
{
cmTarget* tgt = this->Makefile->FindTargetToUse(lib);
@@ -613,7 +596,7 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf, const std::string& target,
if (cmGeneratorExpression::Find(lib) != std::string::npos ||
(tgt && tgt->GetType() == cmState::INTERFACE_LIBRARY) ||
- (target == lib)) {
+ (this->Name == lib)) {
return;
}
@@ -631,7 +614,7 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf, const std::string& target,
// and we removing one instance will break the link line. Duplicates
// will be appropriately eliminated at emit time.
if (this->RecordDependencies) {
- std::string targetEntry = target;
+ std::string targetEntry = this->Name;
targetEntry += "_LIB_DEPENDS";
std::string dependencies;
const char* old_val = mf.GetDefinition(targetEntry);
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index dd9097a..3d88688 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -142,8 +142,8 @@ public:
*/
void ClearDependencyInformation(cmMakefile& mf, const std::string& target);
- void AddLinkLibrary(cmMakefile& mf, const std::string& target,
- const std::string& lib, cmTargetLinkLibraryType llt);
+ void AddLinkLibrary(cmMakefile& mf, const std::string& lib,
+ cmTargetLinkLibraryType llt);
enum TLLSignature
{
KeywordTLLSignature,
@@ -153,9 +153,6 @@ public:
cmListFileContext const& lfc);
void GetTllSignatureTraces(std::ostream& s, TLLSignature sig) const;
- void MergeLinkLibraries(cmMakefile& mf, const std::string& selfname,
- const LinkLibraryVectorType& libs);
-
const std::vector<std::string>& GetLinkDirectories() const;
void AddLinkDirectory(const std::string& d);
@@ -299,7 +296,6 @@ private:
std::vector<cmCustomCommand> PreLinkCommands;
std::vector<cmCustomCommand> PostBuildCommands;
std::vector<std::pair<TLLSignature, cmListFileContext> > TLLCommands;
- LinkLibraryVectorType PrevLinkedLibraries;
LinkLibraryVectorType OriginalLinkLibraries;
cmMakefile* Makefile;
cmTargetInternalPointer Internal;
diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx
index e714309..d1de7ef 100644
--- a/Source/cmTargetLinkLibrariesCommand.cxx
+++ b/Source/cmTargetLinkLibrariesCommand.cxx
@@ -338,7 +338,35 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib,
// Handle normal case first.
if (this->CurrentProcessingState != ProcessingKeywordLinkInterface &&
this->CurrentProcessingState != ProcessingPlainLinkInterface) {
- this->Makefile->AddLinkLibraryForTarget(this->Target->GetName(), lib, llt);
+
+ cmTarget* t =
+ this->Makefile->FindLocalNonAliasTarget(this->Target->GetName());
+ if (!t) {
+ std::ostringstream e;
+ e << "Attempt to add link library \"" << lib << "\" to target \""
+ << this->Target->GetName()
+ << "\" which is not built in this directory.";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ } else {
+
+ cmTarget* tgt = this->Makefile->GetGlobalGenerator()->FindTarget(lib);
+
+ if (tgt && (tgt->GetType() != cmState::STATIC_LIBRARY) &&
+ (tgt->GetType() != cmState::SHARED_LIBRARY) &&
+ (tgt->GetType() != cmState::INTERFACE_LIBRARY) &&
+ !tgt->IsExecutableWithExports()) {
+ std::ostringstream e;
+ e << "Target \"" << lib << "\" of type "
+ << cmState::GetTargetTypeName(tgt->GetType())
+ << " may not be linked into another target. "
+ << "One may link only to STATIC or SHARED libraries, or "
+ << "to executables with the ENABLE_EXPORTS property set.";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ }
+
+ this->Target->AddLinkLibrary(*this->Makefile, lib, llt);
+ }
+
if (this->CurrentProcessingState == ProcessingLinkLibraries) {
this->Target->AppendProperty(
"INTERFACE_LINK_LIBRARIES",
diff --git a/Source/cm_codecvt.cxx b/Source/cm_codecvt.cxx
new file mode 100644
index 0000000..869dd32
--- /dev/null
+++ b/Source/cm_codecvt.cxx
@@ -0,0 +1,215 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cm_codecvt.hxx"
+#include <limits>
+
+#if defined(_WIN32)
+#include <windows.h>
+#undef max
+#include <cmsys/Encoding.hxx>
+#endif
+
+codecvt::codecvt(Encoding e)
+ : m_lastState(0)
+#if defined(_WIN32)
+ , m_codepage(0)
+#endif
+{
+ switch (e) {
+ case codecvt::ANSI:
+#if defined(_WIN32)
+ m_noconv = false;
+ m_codepage = CP_ACP;
+ break;
+#endif
+ // We don't know which ANSI encoding to use for other platforms than
+ // Windows so we don't do any conversion there
+ case codecvt::UTF8:
+ // Assume internal encoding is UTF-8
+ case codecvt::None:
+ // No encoding
+ default:
+ m_noconv = true;
+ }
+}
+
+codecvt::~codecvt(){};
+
+bool codecvt::do_always_noconv() const throw()
+{
+ return m_noconv;
+};
+
+std::codecvt_base::result codecvt::do_out(mbstate_t& state, const char* from,
+ const char* from_end,
+ const char*& from_next, char* to,
+ char* to_end, char*& to_next) const
+{
+ if (m_noconv) {
+ return noconv;
+ }
+ std::codecvt_base::result res = error;
+#if defined(_WIN32)
+ from_next = from;
+ to_next = to;
+ bool convert = true;
+ size_t count = from_end - from;
+ const char* data = from;
+ unsigned int& stateId = reinterpret_cast<unsigned int&>(state);
+ if (count == 0) {
+ return codecvt::ok;
+ } else if (count == 1) {
+ if (stateId == 0) {
+ // decode first byte for UTF-8
+ if ((*from & 0xF8) == 0xF0 || // 1111 0xxx; 4 bytes for codepoint
+ (*from & 0xF0) == 0xE0 || // 1110 xxxx; 3 bytes for codepoint
+ (*from & 0xE0) == 0xC0) // 110x xxxx; 2 bytes for codepoint
+ {
+ stateId = findStateId();
+ codecvt::State& s = m_states.at(stateId - 1);
+ s.bytes[0] = *from;
+ convert = false;
+ if ((*from & 0xF8) == 0xF0) {
+ s.totalBytes = 4;
+ } else if ((*from & 0xF0) == 0xE0) {
+ s.totalBytes = 3;
+ } else if ((*from & 0xE0) == 0xC0) {
+ s.totalBytes = 2;
+ }
+ s.bytesLeft = s.totalBytes - 1;
+ };
+ // else 1 byte for codepoint
+ } else {
+ codecvt::State& s = m_states.at(stateId - 1);
+ s.bytes[s.totalBytes - s.bytesLeft] = *from;
+ s.bytesLeft--;
+ data = s.bytes;
+ count = s.totalBytes - s.bytesLeft;
+ if ((*from & 0xC0) == 0x80) { // 10xx xxxx
+ convert = s.bytesLeft == 0;
+ } else {
+ // invalid multi-byte
+ convert = true;
+ }
+ if (convert) {
+ s.used = false;
+ if (stateId == m_lastState) {
+ m_lastState--;
+ }
+ stateId = 0;
+ }
+ }
+ if (convert) {
+ std::wstring wide = cmsys::Encoding::ToWide(std::string(data, count));
+ int r = WideCharToMultiByte(m_codepage, 0, wide.c_str(),
+ static_cast<int>(wide.size()), to,
+ to_end - to, NULL, NULL);
+ if (r > 0) {
+ from_next = from_end;
+ to_next = to + r;
+ res = ok;
+ }
+ } else {
+ res = partial;
+ from_next = from_end;
+ to_next = to;
+ }
+ }
+#else
+ static_cast<void>(state);
+ static_cast<void>(from);
+ static_cast<void>(from_end);
+ static_cast<void>(from_next);
+ static_cast<void>(to);
+ static_cast<void>(to_end);
+ static_cast<void>(to_next);
+ res = codecvt::noconv;
+#endif
+ return res;
+};
+
+std::codecvt_base::result codecvt::do_unshift(mbstate_t& state, char* to,
+ char* to_end,
+ char*& to_next) const
+{
+ std::codecvt_base::result res = error;
+ to_next = to;
+#if defined(_WIN32)
+ unsigned int& stateId = reinterpret_cast<unsigned int&>(state);
+ if (stateId > 0) {
+ codecvt::State& s = m_states.at(stateId - 1);
+ s.used = false;
+ if (stateId == m_lastState) {
+ m_lastState--;
+ }
+ stateId = 0;
+ std::wstring wide = cmsys::Encoding::ToWide(
+ std::string(s.bytes, s.totalBytes - s.bytesLeft));
+ int r = WideCharToMultiByte(m_codepage, 0, wide.c_str(),
+ static_cast<int>(wide.size()), to, to_end - to,
+ NULL, NULL);
+ if (r > 0) {
+ to_next = to + r;
+ res = ok;
+ }
+ } else {
+ res = ok;
+ }
+#else
+ static_cast<void>(state);
+ static_cast<void>(to_end);
+ res = ok;
+#endif
+ return res;
+};
+
+int codecvt::do_max_length() const throw()
+{
+ return 4;
+};
+
+int codecvt::do_encoding() const throw()
+{
+ return 0;
+};
+
+unsigned int codecvt::findStateId() const
+{
+ unsigned int stateId = 0;
+ bool add = false;
+ const unsigned int maxSize = std::numeric_limits<unsigned int>::max();
+ if (m_lastState >= maxSize) {
+ m_lastState = 0;
+ }
+ if (m_states.size() <= m_lastState) {
+ add = true;
+ } else {
+ unsigned int i = m_lastState;
+ while (i < maxSize) {
+ codecvt::State& s = m_states.at(i);
+ i++;
+ if (!s.used) {
+ m_lastState = i;
+ stateId = m_lastState;
+ s.used = true;
+ s.totalBytes = 0;
+ s.bytesLeft = 0;
+ break;
+ }
+ if (i >= m_states.size()) {
+ i = 0;
+ }
+ if (i == m_lastState) {
+ add = true;
+ break;
+ }
+ }
+ };
+ if (add) {
+ codecvt::State s = { true, 0, 0, { 0, 0, 0, 0 } };
+ m_states.push_back(s);
+ m_lastState = (unsigned int)m_states.size();
+ stateId = m_lastState;
+ }
+ return stateId;
+};
diff --git a/Source/cm_codecvt.hxx b/Source/cm_codecvt.hxx
new file mode 100644
index 0000000..5f16bd8
--- /dev/null
+++ b/Source/cm_codecvt.hxx
@@ -0,0 +1,57 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cm_codecvt_hxx
+#define cm_codecvt_hxx
+
+#include <cmConfigure.h> // IWYU pragma: keep
+
+#include <locale>
+#include <vector>
+
+class codecvt : public std::codecvt<char, char, mbstate_t>
+{
+public:
+ enum Encoding
+ {
+ None,
+ UTF8,
+ ANSI
+ };
+
+#ifdef CMAKE_BUILD_WITH_CMAKE
+
+ codecvt(Encoding e);
+
+protected:
+ ~codecvt() CM_OVERRIDE;
+ bool do_always_noconv() const throw() CM_OVERRIDE;
+ result do_out(mbstate_t& state, const char* from, const char* from_end,
+ const char*& from_next, char* to, char* to_end,
+ char*& to_next) const CM_OVERRIDE;
+ result do_unshift(mbstate_t& state, char* to, char*,
+ char*& to_next) const CM_OVERRIDE;
+ int do_max_length() const throw() CM_OVERRIDE;
+ int do_encoding() const throw() CM_OVERRIDE;
+
+private:
+ typedef struct
+ {
+ bool used;
+ unsigned char totalBytes;
+ unsigned char bytesLeft;
+ char bytes[4];
+ } State;
+
+ unsigned int findStateId() const;
+
+ bool m_noconv;
+ mutable std::vector<State> m_states;
+ mutable unsigned int m_lastState;
+#if defined(_WIN32)
+ unsigned int m_codepage;
+#endif
+
+#endif
+};
+
+#endif
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index c8cf465..5936d77 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -12,6 +12,7 @@
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmGlobalGeneratorFactory.h"
+#include "cmLinkLineComputer.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessenger.h"
@@ -568,7 +569,7 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
cmSystemTools::ExpandListArgument(libs, libList);
for (std::vector<std::string>::const_iterator libIt = libList.begin();
libIt != libList.end(); ++libIt) {
- mf->AddLinkLibraryForTarget(targetName, *libIt, GENERAL_LibraryType);
+ tgt->AddLinkLibrary(*mf, *libIt, GENERAL_LibraryType);
}
std::string buildType = mf->GetSafeDefinition("CMAKE_BUILD_TYPE");
@@ -582,8 +583,10 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
gg->CreateGenerationObjects();
cmGeneratorTarget* gtgt = gg->FindGeneratorTarget(tgt->GetName());
cmLocalGenerator* lg = gtgt->GetLocalGenerator();
- lg->GetTargetFlags(buildType, linkLibs, flags, linkFlags, frameworkPath,
- linkPath, gtgt, false);
+ cmLinkLineComputer linkLineComputer(lg,
+ lg->GetStateSnapshot().GetDirectory());
+ lg->GetTargetFlags(&linkLineComputer, buildType, linkLibs, flags,
+ linkFlags, frameworkPath, linkPath, gtgt);
linkLibs = frameworkPath + linkPath + linkLibs;
printf("%s\n", linkLibs.c_str());
@@ -1310,54 +1313,7 @@ int cmake::ActualConfigure()
cmSystemTools::SetForceUnixPaths(
this->GlobalGenerator->GetForceUnixPaths());
} else {
-#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(CMAKE_BOOT_MINGW)
- std::string installedCompiler;
- // Try to find the newest VS installed on the computer and
- // use that as a default if -G is not specified
- const std::string vsregBase =
- "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\";
- std::vector<std::string> vsVerions;
- vsVerions.push_back("VisualStudio\\");
- vsVerions.push_back("VCExpress\\");
- vsVerions.push_back("WDExpress\\");
- struct VSRegistryEntryName
- {
- const char* MSVersion;
- const char* GeneratorName;
- };
- VSRegistryEntryName version[] = {
- /* clang-format needs this comment to break after the opening brace */
- { "7.1", "Visual Studio 7 .NET 2003" },
- { "8.0", "Visual Studio 8 2005" },
- { "9.0", "Visual Studio 9 2008" },
- { "10.0", "Visual Studio 10 2010" },
- { "11.0", "Visual Studio 11 2012" },
- { "12.0", "Visual Studio 12 2013" },
- { "14.0", "Visual Studio 14 2015" },
- { "15.0", "Visual Studio 15" },
- { 0, 0 }
- };
- for (int i = 0; version[i].MSVersion != 0; i++) {
- for (size_t b = 0; b < vsVerions.size(); b++) {
- std::string reg = vsregBase + vsVerions[b] + version[i].MSVersion;
- reg += ";InstallDir]";
- cmSystemTools::ExpandRegistryValues(reg, cmSystemTools::KeyWOW64_32);
- if (!(reg == "/registry")) {
- installedCompiler = version[i].GeneratorName;
- break;
- }
- }
- }
- cmGlobalGenerator* gen =
- this->CreateGlobalGenerator(installedCompiler.c_str());
- if (!gen) {
- gen = new cmGlobalNMakeMakefileGenerator(this);
- }
- this->SetGlobalGenerator(gen);
- std::cout << "-- Building for: " << gen->GetName() << "\n";
-#else
- this->SetGlobalGenerator(new cmGlobalUnixMakefileGenerator3(this));
-#endif
+ this->CreateDefaultGlobalGenerator();
}
if (!this->GlobalGenerator) {
cmSystemTools::Error("Could not create generator");
@@ -1485,6 +1441,63 @@ int cmake::ActualConfigure()
return 0;
}
+void cmake::CreateDefaultGlobalGenerator()
+{
+#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(CMAKE_BOOT_MINGW)
+ std::string found;
+ // Try to find the newest VS installed on the computer and
+ // use that as a default if -G is not specified
+ const std::string vsregBase = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\";
+ static const char* const vsVariants[] = {
+ /* clang-format needs this comment to break after the opening brace */
+ "VisualStudio\\", "VCExpress\\", "WDExpress\\"
+ };
+ struct VSVersionedGenerator
+ {
+ const char* MSVersion;
+ const char* GeneratorName;
+ };
+ static VSVersionedGenerator const vsGenerators[] = {
+ { "15.0", "Visual Studio 15" }, //
+ { "14.0", "Visual Studio 14 2015" }, //
+ { "12.0", "Visual Studio 12 2013" }, //
+ { "11.0", "Visual Studio 11 2012" }, //
+ { "10.0", "Visual Studio 10 2010" }, //
+ { "9.0", "Visual Studio 9 2008" }, //
+ { "8.0", "Visual Studio 8 2005" }, //
+ { "7.1", "Visual Studio 7 .NET 2003" }
+ };
+ static const char* const vsEntries[] = {
+ "\\Setup\\VC;ProductDir", //
+ ";InstallDir" //
+ };
+ for (VSVersionedGenerator const* g = cmArrayBegin(vsGenerators);
+ found.empty() && g != cmArrayEnd(vsGenerators); ++g) {
+ for (const char* const* v = cmArrayBegin(vsVariants);
+ found.empty() && v != cmArrayEnd(vsVariants); ++v) {
+ for (const char* const* e = cmArrayBegin(vsEntries);
+ found.empty() && e != cmArrayEnd(vsEntries); ++e) {
+ std::string const reg = vsregBase + *v + g->MSVersion + *e;
+ std::string dir;
+ if (cmSystemTools::ReadRegistryValue(reg, dir,
+ cmSystemTools::KeyWOW64_32) &&
+ cmSystemTools::PathExists(dir)) {
+ found = g->GeneratorName;
+ }
+ }
+ }
+ }
+ cmGlobalGenerator* gen = this->CreateGlobalGenerator(found);
+ if (!gen) {
+ gen = new cmGlobalNMakeMakefileGenerator(this);
+ }
+ this->SetGlobalGenerator(gen);
+ std::cout << "-- Building for: " << gen->GetName() << "\n";
+#else
+ this->SetGlobalGenerator(new cmGlobalUnixMakefileGenerator3(this));
+#endif
+}
+
void cmake::PreLoadCMakeFiles()
{
std::vector<std::string> args;
diff --git a/Source/cmake.h b/Source/cmake.h
index ae1a502..865748b 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -500,6 +500,8 @@ private:
// Print a list of valid generators to stderr.
void PrintGeneratorList();
+ void CreateDefaultGlobalGenerator();
+
/**
* Convert a message type between a warning and an error, based on the state
* of the error output CMake variables, in the cache.
diff --git a/Source/ctest.cxx b/Source/ctest.cxx
index 1fb39ff..8ab17b9 100644
--- a/Source/ctest.cxx
+++ b/Source/ctest.cxx
@@ -163,11 +163,7 @@ int main(int argc, char const* const* argv)
doc.SetSection("Name", cmDocumentationName);
doc.SetSection("Usage", cmDocumentationUsage);
doc.PrependSection("Options", cmDocumentationOptions);
-#ifdef cout
-#undef cout
-#endif
return doc.PrintRequestedDocumentation(std::cout) ? 0 : 1;
-#define cout no_cout_use_cmCTestLog
}
}
diff --git a/Tests/FindPackageModeMakefileTest/CMakeLists.txt b/Tests/FindPackageModeMakefileTest/CMakeLists.txt
index 56fcc5d..23832da 100644
--- a/Tests/FindPackageModeMakefileTest/CMakeLists.txt
+++ b/Tests/FindPackageModeMakefileTest/CMakeLists.txt
@@ -20,16 +20,9 @@ if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Makefile" AND
configure_file(FindFoo.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/FindFoo.cmake @ONLY)
# now set up the test:
- if (NOT CMAKE_VERSION VERSION_LESS 2.8.12)
- file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/cmakeExecutable.mk"
- CONTENT "CMAKE = \"$<TARGET_FILE:cmake>\"\n"
- )
- else()
- get_target_property(cmakeLocation cmake LOCATION)
- file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cmakeExecutable.mk"
- "CMAKE = \"${cmakeLocation}\"\n"
- )
- endif()
+ file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/cmakeExecutable.mk"
+ CONTENT "CMAKE = \"$<TARGET_FILE:cmake>\"\n"
+ )
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Makefile.in ${CMAKE_CURRENT_BINARY_DIR}/ConfMakefile @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/main.cpp ${CMAKE_CURRENT_BINARY_DIR}/main.cpp COPYONLY)
diff --git a/Tests/MacRuntimePath/A/CMakeLists.txt b/Tests/MacRuntimePath/A/CMakeLists.txt
index ade0a3c..bf937e6 100644
--- a/Tests/MacRuntimePath/A/CMakeLists.txt
+++ b/Tests/MacRuntimePath/A/CMakeLists.txt
@@ -40,21 +40,30 @@ target_link_libraries(test3 framework)
add_executable(test4 test1.cpp)
target_link_libraries(test4 shared2)
+# executable to test a shared library dependency with build rpath
+add_executable(test5 test1.cpp)
+
+# avoid linking by 'target_link_libraries' so CMake
+# will not be able to set correct RPATH automatically
+add_dependencies(test5 shared)
+target_link_libraries(test5 "$<TARGET_FILE:shared>")
+set_target_properties(test5 PROPERTIES BUILD_RPATH "@loader_path/../lib")
+
set_target_properties(shared shared2 framework PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib")
-set_target_properties(test1 test2 test3 test4 PROPERTIES
+set_target_properties(test1 test2 test3 test4 test5 PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
foreach(config ${CMAKE_CONFIGURATION_TYPES})
string(TOUPPER ${config} CONFIG)
set_target_properties(shared shared2 framework PROPERTIES
LIBRARY_OUTPUT_DIRECTORY_${CONFIG}
"${CMAKE_CURRENT_BINARY_DIR}/${config}/lib")
- set_target_properties(test1 test2 test3 test4 PROPERTIES
+ set_target_properties(test1 test2 test3 test4 test5 PROPERTIES
RUNTIME_OUTPUT_DIRECTORY_${CONFIG}
"${CMAKE_CURRENT_BINARY_DIR}/${config}/bin")
endforeach()
-foreach(test test1 test2 test3 test4)
+foreach(test test1 test2 test3 test4 test5)
add_custom_target(${test}_run ALL
COMMAND ${test}
DEPENDS ${test}
diff --git a/Tests/RunCMake/CPack/MAIN_COMPONENT.cmake b/Tests/RunCMake/CPack/MAIN_COMPONENT.cmake
new file mode 100644
index 0000000..99c6cae
--- /dev/null
+++ b/Tests/RunCMake/CPack/MAIN_COMPONENT.cmake
@@ -0,0 +1,14 @@
+set(CPACK_RPM_COMPONENT_INSTALL "ON")
+
+install(FILES CMakeLists.txt DESTINATION foo COMPONENT applications)
+install(FILES CMakeLists.txt DESTINATION bar COMPONENT headers)
+install(FILES CMakeLists.txt DESTINATION bas COMPONENT libs)
+
+if(RunCMake_SUBTEST_SUFFIX STREQUAL "invalid")
+ set(CPACK_RPM_MAIN_COMPONENT "")
+else()
+ set(CPACK_RPM_MAIN_COMPONENT "applications")
+ set(CPACK_RPM_APPLICATIONS_FILE_NAME "RPM-DEFAULT")
+endif()
+
+set(CPACK_PACKAGE_NAME "main_component")
diff --git a/Tests/RunCMake/CPack/RPM/MAIN_COMPONENT-ExpectedFiles.cmake b/Tests/RunCMake/CPack/RPM/MAIN_COMPONENT-ExpectedFiles.cmake
new file mode 100644
index 0000000..69603dd
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/MAIN_COMPONENT-ExpectedFiles.cmake
@@ -0,0 +1,13 @@
+set(whitespaces_ "[\t\n\r ]*")
+
+set(EXPECTED_FILES_COUNT "0")
+
+if(NOT RunCMake_SUBTEST_SUFFIX STREQUAL "invalid")
+ set(EXPECTED_FILES_COUNT "3")
+ set(EXPECTED_FILE_1 "main_component-0.1.1-1.*.rpm")
+ set(EXPECTED_FILE_CONTENT_1 "^/usr/foo${whitespaces_}/usr/foo/CMakeLists.txt$")
+ set(EXPECTED_FILE_2 "main_component*-headers.rpm")
+ set(EXPECTED_FILE_CONTENT_2 "^/usr/bar${whitespaces_}/usr/bar/CMakeLists.txt$")
+ set(EXPECTED_FILE_3 "main_component*-libs.rpm")
+ set(EXPECTED_FILE_CONTENT_3 "^/usr/bas${whitespaces_}/usr/bas/CMakeLists.txt$")
+endif()
diff --git a/Tests/RunCMake/CPack/RPM/MAIN_COMPONENT-found-stderr.txt b/Tests/RunCMake/CPack/RPM/MAIN_COMPONENT-found-stderr.txt
new file mode 100644
index 0000000..dff163d
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/MAIN_COMPONENT-found-stderr.txt
@@ -0,0 +1,3 @@
+^CPackRPM: Will use GENERATED spec file: .*/Tests/RunCMake/RPM/CPack/MAIN_COMPONENT-build-found-subtest/_CPack_Packages/.*/RPM/SPECS/main_component-headers.spec
+CPackRPM: Will use GENERATED spec file: .*/Tests/RunCMake/RPM/CPack/MAIN_COMPONENT-build-found-subtest/_CPack_Packages/.*/RPM/SPECS/main_component-libs.spec
+CPackRPM: Will use GENERATED spec file: .*/Tests/RunCMake/RPM/CPack/MAIN_COMPONENT-build-found-subtest/_CPack_Packages/.*/RPM/SPECS/main_component.spec$
diff --git a/Tests/RunCMake/CPack/RPM/MAIN_COMPONENT-invalid-stderr.txt b/Tests/RunCMake/CPack/RPM/MAIN_COMPONENT-invalid-stderr.txt
new file mode 100644
index 0000000..4d8ac6e
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/MAIN_COMPONENT-invalid-stderr.txt
@@ -0,0 +1 @@
+CPACK_RPM_MAIN_COMPONENT set to non existing component.
diff --git a/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-ExpectedFiles.cmake b/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-ExpectedFiles.cmake
new file mode 100644
index 0000000..dc49343
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-ExpectedFiles.cmake
@@ -0,0 +1,30 @@
+set(whitespaces_ "[\t\n\r ]*")
+
+set(EXPECTED_FILES_COUNT "0")
+
+if(RunCMake_SUBTEST_SUFFIX STREQUAL "valid" OR RunCMake_SUBTEST_SUFFIX STREQUAL "no_debuginfo")
+ set(EXPECTED_FILES_COUNT "4")
+ set(EXPECTED_FILE_1 "single_debuginfo-0.1.1-1.*.rpm")
+ set(EXPECTED_FILE_CONTENT_1 "^/usr/foo${whitespaces_}/usr/foo/test_prog$")
+ set(EXPECTED_FILE_2 "single_debuginfo*-headers.rpm")
+ set(EXPECTED_FILE_CONTENT_2 "^/usr/bar${whitespaces_}/usr/bar/CMakeLists.txt$")
+ set(EXPECTED_FILE_3 "single_debuginfo*-libs.rpm")
+ set(EXPECTED_FILE_CONTENT_3 "^/usr/bas${whitespaces_}/usr/bas/libtest_lib.so$")
+
+ set(EXPECTED_FILE_4 "single_debuginfo-debuginfo*.rpm")
+ set(EXPECTED_FILE_CONTENT_4 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/main.cpp${whitespaces_}/src/src_1/test_lib.cpp.*")
+elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "one_component" OR RunCMake_SUBTEST_SUFFIX STREQUAL "one_component_no_debuginfo")
+ set(EXPECTED_FILES_COUNT "2")
+ set(EXPECTED_FILE_1 "single_debuginfo-0*-applications.rpm")
+ set(EXPECTED_FILE_CONTENT_1 "^/usr/foo${whitespaces_}/usr/foo/test_prog$")
+
+ set(EXPECTED_FILE_2 "single_debuginfo-applications-debuginfo*.rpm")
+ set(EXPECTED_FILE_CONTENT_2 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/main.cpp.*")
+elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "one_component_main" OR RunCMake_SUBTEST_SUFFIX STREQUAL "no_components")
+ set(EXPECTED_FILES_COUNT "2")
+ set(EXPECTED_FILE_1 "single_debuginfo-0*.rpm")
+ set(EXPECTED_FILE_CONTENT_1 "^/usr/foo${whitespaces_}/usr/foo/test_prog$")
+
+ set(EXPECTED_FILE_2 "single_debuginfo-debuginfo*.rpm")
+ set(EXPECTED_FILE_CONTENT_2 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/main.cpp.*")
+endif()
diff --git a/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-no_components-stderr.txt b/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-no_components-stderr.txt
new file mode 100644
index 0000000..d80939f
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-no_components-stderr.txt
@@ -0,0 +1 @@
+^CPackRPM: Will use GENERATED spec file: .*/Tests/RunCMake/RPM/CPack/SINGLE_DEBUGINFO-build-no_components-subtest/_CPack_Packages/.*/RPM/SPECS/single_debuginfo.spec$
diff --git a/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-no_debuginfo-stderr.txt b/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-no_debuginfo-stderr.txt
new file mode 100644
index 0000000..86396db
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-no_debuginfo-stderr.txt
@@ -0,0 +1,3 @@
+^CPackRPM: Will use GENERATED spec file: .*/Tests/RunCMake/RPM/CPack/SINGLE_DEBUGINFO-build-no_debuginfo-subtest/_CPack_Packages/.*/RPM/SPECS/single_debuginfo-headers.spec
+CPackRPM: Will use GENERATED spec file: .*/Tests/RunCMake/RPM/CPack/SINGLE_DEBUGINFO-build-no_debuginfo-subtest/_CPack_Packages/.*/RPM/SPECS/single_debuginfo-libs.spec
+CPackRPM: Will use GENERATED spec file: .*/Tests/RunCMake/RPM/CPack/SINGLE_DEBUGINFO-build-no_debuginfo-subtest/_CPack_Packages/.*/RPM/SPECS/single_debuginfo.spec$
diff --git a/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-no_main_component-stderr.txt b/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-no_main_component-stderr.txt
new file mode 100644
index 0000000..454283c
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-no_main_component-stderr.txt
@@ -0,0 +1 @@
+CPack Error: CPACK_RPM_MAIN_COMPONENT not set but it is mandatory with CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE being set.
diff --git a/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-one_component-stderr.txt b/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-one_component-stderr.txt
new file mode 100644
index 0000000..080c4ff
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-one_component-stderr.txt
@@ -0,0 +1 @@
+^CPackRPM: Will use GENERATED spec file: .*/Tests/RunCMake/RPM/CPack/SINGLE_DEBUGINFO-build-one_component-subtest/_CPack_Packages/.*/RPM/SPECS/single_debuginfo-applications.spec$
diff --git a/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-one_component_main-stderr.txt b/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-one_component_main-stderr.txt
new file mode 100644
index 0000000..665597c
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-one_component_main-stderr.txt
@@ -0,0 +1 @@
+^CPackRPM: Will use GENERATED spec file: .*/Tests/RunCMake/RPM/CPack/SINGLE_DEBUGINFO-build-one_component_main-subtest/_CPack_Packages/.*/RPM/SPECS/single_debuginfo.spec$
diff --git a/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-one_component_no_debuginfo-stderr.txt b/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-one_component_no_debuginfo-stderr.txt
new file mode 100644
index 0000000..b64b1f5
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-one_component_no_debuginfo-stderr.txt
@@ -0,0 +1 @@
+^CPackRPM: Will use GENERATED spec file: .*/Tests/RunCMake/RPM/CPack/SINGLE_DEBUGINFO-build-one_component_no_debuginfo-subtest/_CPack_Packages/.*/RPM/SPECS/single_debuginfo-applications.spec$
diff --git a/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-valid-stderr.txt b/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-valid-stderr.txt
new file mode 100644
index 0000000..f4c1bef
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-valid-stderr.txt
@@ -0,0 +1,3 @@
+^CPackRPM: Will use GENERATED spec file: .*/Tests/RunCMake/RPM/CPack/SINGLE_DEBUGINFO-build-valid-subtest/_CPack_Packages/.*/RPM/SPECS/single_debuginfo-headers.spec
+CPackRPM: Will use GENERATED spec file: .*/Tests/RunCMake/RPM/CPack/SINGLE_DEBUGINFO-build-valid-subtest/_CPack_Packages/.*/RPM/SPECS/single_debuginfo-libs.spec
+CPackRPM: Will use GENERATED spec file: .*/Tests/RunCMake/RPM/CPack/SINGLE_DEBUGINFO-build-valid-subtest/_CPack_Packages/.*/RPM/SPECS/single_debuginfo.spec$
diff --git a/Tests/RunCMake/CPack/RunCMakeTest.cmake b/Tests/RunCMake/CPack/RunCMakeTest.cmake
index 60d42ac..474ee33 100644
--- a/Tests/RunCMake/CPack/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CPack/RunCMakeTest.cmake
@@ -12,11 +12,13 @@ run_cpack_test(DEPENDENCIES "RPM;DEB" true)
run_cpack_test(EMPTY_DIR "RPM;DEB;TGZ" true)
run_cpack_test(COMPONENTS_EMPTY_DIR "RPM;DEB;TGZ" true)
run_cpack_test(CUSTOM_NAMES "RPM;DEB" true)
+run_cpack_test_subtests(MAIN_COMPONENT "invalid;found" "RPM" false)
run_cpack_test(PER_COMPONENT_FIELDS "RPM;DEB" false)
run_cpack_test(RPM_DIST "RPM" false)
run_cpack_test(INSTALL_SCRIPTS "RPM" false)
run_cpack_test(DEB_GENERATE_SHLIBS "DEB" true)
run_cpack_test(DEB_GENERATE_SHLIBS_LDCONFIG "DEB" true)
run_cpack_test(DEBUGINFO "RPM" true)
+run_cpack_test_subtests(SINGLE_DEBUGINFO "no_main_component;one_component;one_component_main;no_debuginfo;one_component_no_debuginfo;no_components;valid" "RPM" true)
run_cpack_test(LONG_FILENAMES "DEB" false)
run_cpack_test_subtests(PACKAGE_CHECKSUM "invalid;MD5;SHA1;SHA224;SHA256;SHA384;SHA512" "TGZ" false)
diff --git a/Tests/RunCMake/CPack/SINGLE_DEBUGINFO.cmake b/Tests/RunCMake/CPack/SINGLE_DEBUGINFO.cmake
new file mode 100644
index 0000000..ae4995e
--- /dev/null
+++ b/Tests/RunCMake/CPack/SINGLE_DEBUGINFO.cmake
@@ -0,0 +1,56 @@
+set(CMAKE_BUILD_WITH_INSTALL_RPATH 1)
+
+# PGI compiler doesn't add build id to binaries by default
+if(CMAKE_CXX_COMPILER_ID STREQUAL "PGI")
+ string(APPEND CMAKE_EXE_LINKER_FLAGS "-Wl,--build-id")
+ string(APPEND CMAKE_SHARED_LINKER_FLAGS "-Wl,--build-id")
+endif()
+
+if(NOT RunCMake_SUBTEST_SUFFIX STREQUAL "no_components")
+ set(CPACK_RPM_COMPONENT_INSTALL "ON")
+endif()
+
+set(CMAKE_BUILD_TYPE Debug)
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test_lib.hpp"
+ "int test_lib();\n")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test_lib.cpp"
+ "#include \"test_lib.hpp\"\nint test_lib() {return 0;}\n")
+add_library(test_lib SHARED "${CMAKE_CURRENT_BINARY_DIR}/test_lib.cpp")
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/main.cpp"
+ "#include \"test_lib.hpp\"\nint main() {return test_lib();}\n")
+add_executable(test_prog "${CMAKE_CURRENT_BINARY_DIR}/main.cpp")
+target_link_libraries(test_prog test_lib)
+
+install(TARGETS test_prog DESTINATION foo COMPONENT applications)
+
+if(RunCMake_SUBTEST_SUFFIX STREQUAL "valid"
+ OR RunCMake_SUBTEST_SUFFIX STREQUAL "no_main_component"
+ OR RunCMake_SUBTEST_SUFFIX STREQUAL "no_debuginfo")
+ install(FILES CMakeLists.txt DESTINATION bar COMPONENT headers)
+ install(TARGETS test_lib DESTINATION bas COMPONENT libs)
+elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "one_component"
+ OR RunCMake_SUBTEST_SUFFIX STREQUAL "one_component_no_debuginfo")
+ set(CPACK_COMPONENTS_ALL applications)
+endif()
+
+set(CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE ON)
+
+if(RunCMake_SUBTEST_SUFFIX STREQUAL "valid"
+ OR RunCMake_SUBTEST_SUFFIX STREQUAL "one_component_main"
+ OR RunCMake_SUBTEST_SUFFIX STREQUAL "no_debuginfo")
+ set(CPACK_RPM_MAIN_COMPONENT "applications")
+ set(CPACK_RPM_APPLICATIONS_FILE_NAME "RPM-DEFAULT")
+endif()
+
+if(RunCMake_SUBTEST_SUFFIX STREQUAL "valid"
+ OR RunCMake_SUBTEST_SUFFIX STREQUAL "no_main_component"
+ OR RunCMake_SUBTEST_SUFFIX STREQUAL "one_component")
+ set(CPACK_RPM_APPLICATIONS_DEBUGINFO_PACKAGE ON)
+ set(CPACK_RPM_LIBS_DEBUGINFO_PACKAGE ON)
+endif()
+
+set(CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX "/src")
+
+set(CPACK_PACKAGE_NAME "single_debuginfo")
diff --git a/Tests/RunCMake/CPack/VerifyResult.cmake b/Tests/RunCMake/CPack/VerifyResult.cmake
index 8bc2a58..ad2a651 100644
--- a/Tests/RunCMake/CPack/VerifyResult.cmake
+++ b/Tests/RunCMake/CPack/VerifyResult.cmake
@@ -27,10 +27,12 @@ if(NOT EXPECTED_FILES_COUNT EQUAL 0)
expected_content_list "${PACKAGE_CONTENT}")
if(NOT expected_content_list)
+ string(REPLACE "\n" "\n actual> " msg_actual "\n${PACKAGE_CONTENT}")
+ string(REPLACE "\n" "\n expect> " msg_expected "\n${EXPECTED_FILE_CONTENT_${file_no_}}")
message(FATAL_ERROR
"Unexpected file content for file No. '${file_no_}'!\n"
- " Content: '${PACKAGE_CONTENT}'\n\n"
- " Expected: '${EXPECTED_FILE_CONTENT_${file_no_}}'"
+ "The content was:${msg_actual}\n"
+ "which does not match:${msg_expected}\n"
"${output_error_message}")
endif()
else()
diff --git a/Utilities/GitSetup/config b/Utilities/GitSetup/config
index b7d5423..d69a679 100644
--- a/Utilities/GitSetup/config
+++ b/Utilities/GitSetup/config
@@ -1,5 +1,5 @@
[hooks]
- url = http://cmake.org/cmake.git
+ url = https://cmake.org/cmake.git
[ssh]
host = cmake.org
key = id_git_cmake
diff --git a/Utilities/Release/README b/Utilities/Release/README
index ed1d52e..11de1c3 100644
--- a/Utilities/Release/README
+++ b/Utilities/Release/README
@@ -1,7 +1,7 @@
To create a cmake release, make sure the "release" tag is pointing to the
expected git commit:
-http://cmake.org/gitweb?p=cmake.git;a=shortlog;h=refs/heads/release
+https://cmake.org/gitweb?p=cmake.git;a=shortlog;h=refs/heads/release
Then as kitware@hythloth, using an up-to-date CMake:
diff --git a/Utilities/Release/linux64_release.cmake b/Utilities/Release/linux64_release.cmake
index b72fc12..b9447ca 100644
--- a/Utilities/Release/linux64_release.cmake
+++ b/Utilities/Release/linux64_release.cmake
@@ -2,6 +2,7 @@ set(PROCESSORS 4)
set(BOOTSTRAP_ARGS "--docdir=doc/cmake")
set(HOST linux64)
set(MAKE_PROGRAM "make")
+set(CPACK_BINARY_GENERATORS "STGZ TGZ")
set(CC /opt/gcc-6.1.0/bin/gcc)
set(CXX /opt/gcc-6.1.0/bin/g++)
set(CFLAGS "")
diff --git a/Utilities/Release/osx_release.cmake b/Utilities/Release/osx_release.cmake
index 27c820f..88ea39b 100644
--- a/Utilities/Release/osx_release.cmake
+++ b/Utilities/Release/osx_release.cmake
@@ -4,7 +4,7 @@ set(BOOTSTRAP_ARGS "--prefix=/ --docdir=doc/cmake")
set(HOST dragnipur)
set(MAKE_PROGRAM "make")
set(MAKE "${MAKE_PROGRAM} -j5")
-set(CPACK_BINARY_GENERATORS "DragNDrop TGZ TZ")
+set(CPACK_BINARY_GENERATORS "DragNDrop TGZ")
set(CPACK_SOURCE_GENERATORS "TGZ TZ")
set(CPACK_DMG_FORMAT "UDBZ") #build using bzip2 for smaller package size
set(CC clang)
diff --git a/bootstrap b/bootstrap
index 889cc33..fb8b1eb 100755
--- a/bootstrap
+++ b/bootstrap
@@ -297,6 +297,8 @@ CMAKE_CXX_SOURCES="\
cmFileTimeComparison \
cmGlobalUnixMakefileGenerator3 \
cmLocalUnixMakefileGenerator3 \
+ cmLinkLineComputer \
+ cmMSVC60LinkLineComputer \
cmMakefileExecutableTargetGenerator \
cmMakefileLibraryTargetGenerator \
cmMakefileTargetGenerator \