diff options
57 files changed, 1245 insertions, 617 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/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake index bbeeeed..4ba8537 100644 --- a/Modules/ExternalProject.cmake +++ b/Modules/ExternalProject.cmake @@ -1160,7 +1160,7 @@ function(_ep_command_line_to_initial_cache var args force) endif() else() # Assume this is a list to append to the last var - list(APPEND accumulator "${line}") + string(APPEND accumulator ";${line}") endif() endforeach() # Catch the final line of the args diff --git a/Modules/FindProtobuf.cmake b/Modules/FindProtobuf.cmake index 10c07c2..14e392a 100644 --- a/Modules/FindProtobuf.cmake +++ b/Modules/FindProtobuf.cmake @@ -136,9 +136,11 @@ function(PROTOBUF_GENERATE_CPP SRCS HDRS) foreach(FIL ${ARGN}) get_filename_component(ABS_FIL ${FIL} ABSOLUTE) get_filename_component(FIL_WE ${FIL} NAME_WE) - get_filename_component(FIL_DIR ${FIL} DIRECTORY) - if(FIL_DIR) - set(FIL_WE "${FIL_DIR}/${FIL_WE}") + if(NOT PROTOBUF_GENERATE_CPP_APPEND_PATH) + get_filename_component(FIL_DIR ${FIL} DIRECTORY) + if(FIL_DIR) + set(FIL_WE "${FIL_DIR}/${FIL_WE}") + endif() endif() list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc") @@ -197,9 +199,11 @@ function(PROTOBUF_GENERATE_PYTHON SRCS) foreach(FIL ${ARGN}) get_filename_component(ABS_FIL ${FIL} ABSOLUTE) get_filename_component(FIL_WE ${FIL} NAME_WE) - get_filename_component(FIL_DIR ${FIL} DIRECTORY) - if(FIL_DIR) - set(FIL_WE "${FIL_DIR}/${FIL_WE}") + if(NOT PROTOBUF_GENERATE_CPP_APPEND_PATH) + get_filename_component(FIL_DIR ${FIL} DIRECTORY) + if(FIL_DIR) + set(FIL_WE "${FIL_DIR}/${FIL_WE}") + endif() endif() list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}_pb2.py") diff --git a/Modules/Platform/Android/ndk-stl-c++.cmake b/Modules/Platform/Android/ndk-stl-c++.cmake index cb9fd68..b27015d 100644 --- a/Modules/Platform/Android/ndk-stl-c++.cmake +++ b/Modules/Platform/Android/ndk-stl-c++.cmake @@ -6,9 +6,11 @@ macro(__android_stl_cxx lang filename) if(EXISTS "${CMAKE_ANDROID_NDK}/sources/cxx-stl/llvm-libc++/libcxx/include/cstddef") # r12 and below __android_stl_inc(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/llvm-libc++/libcxx/include" 1) + __android_stl_inc(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/llvm-libc++abi/libcxxabi/include" 1) else() # r13 and above __android_stl_inc(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/llvm-libc++/include" 1) + __android_stl_inc(${lang} "${CMAKE_ANDROID_NDK}/sources/cxx-stl/llvm-libc++abi/include" 1) endif() # Add a secondary include directory if it exists. diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index e574957..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 @@ -545,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 b28be44..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 20161009) +set(CMake_VERSION_PATCH 20161013) #set(CMake_VERSION_RC 1) 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/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx index 14ea1a9..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; @@ -76,7 +78,7 @@ void cmCommonTargetGenerator::AddModuleDefinitionFlag(std::string& flags) // vs6's "cl -link" pass it to the linker. std::string flag = defFileFlag; flag += this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->ConvertToLinkReference( + 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/cmExportBuildAndroidMKGenerator.cxx b/Source/cmExportBuildAndroidMKGenerator.cxx index bb02311..f5e6628 100644 --- a/Source/cmExportBuildAndroidMKGenerator.cxx +++ b/Source/cmExportBuildAndroidMKGenerator.cxx @@ -9,6 +9,8 @@ #include "cmMakefile.h" #include "cmTargetExport.h" +#include <algorithm> + cmExportBuildAndroidMKGenerator::cmExportBuildAndroidMKGenerator() { this->LG = CM_NULLPTR; @@ -164,6 +166,16 @@ void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties( } } } + + // Tell the NDK build system if prebuilt static libraries use C++. + if (target->GetType() == cmState::STATIC_LIBRARY) { + cmLinkImplementation const* li = target->GetLinkImplementation(config); + if (std::find(li->Languages.begin(), li->Languages.end(), "CXX") != + li->Languages.end()) { + os << "LOCAL_HAS_CPP := true\n"; + } + } + switch (target->GetType()) { case cmState::SHARED_LIBRARY: case cmState::MODULE_LIBRARY: 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 74b4547..38eaa76 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -34,7 +34,9 @@ class cmExportBuildFileGenerator; class cmExternalMakefileProjectGenerator; class cmGeneratorTarget; class cmLocalGenerator; +class cmLinkLineComputer; class cmMakefile; +class cmOutputConverter; class cmake; /** \class cmGlobalGenerator @@ -105,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/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/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 2284cf9..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_") + @@ -1382,155 +1389,46 @@ std::string cmLocalGenerator::GetTargetFortranFlags( return std::string(); } -std::string cmLocalGenerator::ConvertToLinkReference(std::string const& lib) -{ -#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); - - return sp; - } - } - } -#endif - - // Normal behavior. - return this->ConvertToRelativePath(this->GetCurrentBinaryDirectory(), lib); -} - /** * 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; std::string linkLanguage = cli.GetLinkLanguage(); - std::string linkLibs; - std::string libPathFlag = this->Makefile->GetRequiredDefinition("CMAKE_LIBRARY_PATH_FLAG"); std::string libPathTerminator = this->Makefile->GetSafeDefinition("CMAKE_LIBRARY_PATH_TERMINATOR"); - // 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->ConvertToOutputFormat( - 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 << " "; - } - } - - // 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"; + std::string stdLibString; if (const char* stdLibs = this->Makefile->GetDefinition(standardLibsVar)) { - fout << stdLibs << " "; + stdLibString = stdLibs; } - linkLibraries = fout.str(); + // 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( diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index e16ddab..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. @@ -312,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; @@ -345,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, @@ -370,8 +373,6 @@ protected: std::string& CreateSafeUniqueObjectFileName(const std::string& sin, std::string const& dir_max); - virtual std::string ConvertToLinkReference(std::string const& lib); - /** 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 5736581..e25eb0f 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -120,12 +120,6 @@ cmGlobalNinjaGenerator* cmLocalNinjaGenerator::GetGlobalNinjaGenerator() // Virtual protected methods. -std::string cmLocalNinjaGenerator::ConvertToLinkReference( - std::string const& lib) -{ - return this->GetGlobalNinjaGenerator()->ConvertToNinjaPath(lib); -} - std::string cmLocalNinjaGenerator::ConvertToIncludeReference( std::string const& path, cmOutputConverter::OutputFormat format, bool forceFullPaths) @@ -488,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 3061b57..b04788d 100644 --- a/Source/cmLocalNinjaGenerator.h +++ b/Source/cmLocalNinjaGenerator.h @@ -76,8 +76,6 @@ public: void AppendCustomCommandDeps(cmCustomCommandGenerator const& ccg, cmNinjaDeps& ninjaDeps); - std::string ConvertToLinkReference(std::string const& lib) 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 eb2852c..02eef59 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -995,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->MaybeConvertToRelativePath( - 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(); 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 79168d8..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" @@ -215,7 +216,14 @@ 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. @@ -296,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. diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 5db5c24..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); } @@ -479,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 diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 9f5bda9..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" @@ -1215,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 = ""; @@ -1237,10 +1233,8 @@ public: void Feed(std::string const& obj) { // Construct the name of the next object. - this->NextObject = this->LocalGenerator->ConvertToOutputFormat( - this->LocalGenerator->MaybeConvertToRelativePath( - 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 && @@ -1260,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; @@ -1271,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); @@ -1535,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) { @@ -1617,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 = "$("; diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index 222161a..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, 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", >, 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/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/cmTarget.cxx b/Source/cmTarget.cxx index 13a4744..651bcc8 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -476,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. @@ -595,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); @@ -614,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; } @@ -632,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/cmVS140CLFlagTable.h b/Source/cmVS140CLFlagTable.h new file mode 100644 index 0000000..317cc18 --- /dev/null +++ b/Source/cmVS140CLFlagTable.h @@ -0,0 +1,237 @@ +static cmVS7FlagTable cmVS140CLFlagTable[] = { + + // Enum Properties + { "DebugInformationFormat", "", "None", "None", 0 }, + { "DebugInformationFormat", "Z7", "C7 compatible", "OldStyle", 0 }, + { "DebugInformationFormat", "Zi", "Program Database", "ProgramDatabase", 0 }, + { "DebugInformationFormat", "ZI", "Program Database for Edit And Continue", + "EditAndContinue", 0 }, + + { "WarningLevel", "W0", "Turn Off All Warnings", "TurnOffAllWarnings", 0 }, + { "WarningLevel", "W1", "Level1", "Level1", 0 }, + { "WarningLevel", "W2", "Level2", "Level2", 0 }, + { "WarningLevel", "W3", "Level3", "Level3", 0 }, + { "WarningLevel", "W4", "Level4", "Level4", 0 }, + { "WarningLevel", "Wall", "EnableAllWarnings", "EnableAllWarnings", 0 }, + + { "Optimization", "", "Custom", "Custom", 0 }, + { "Optimization", "Od", "Disabled", "Disabled", 0 }, + { "Optimization", "O1", "Minimize Size", "MinSpace", 0 }, + { "Optimization", "O2", "Maximize Speed", "MaxSpeed", 0 }, + { "Optimization", "Ox", "Full Optimization", "Full", 0 }, + + { "InlineFunctionExpansion", "", "Default", "Default", 0 }, + { "InlineFunctionExpansion", "Ob0", "Disabled", "Disabled", 0 }, + { "InlineFunctionExpansion", "Ob1", "Only __inline", "OnlyExplicitInline", + 0 }, + { "InlineFunctionExpansion", "Ob2", "Any Suitable", "AnySuitable", 0 }, + + { "FavorSizeOrSpeed", "Os", "Favor small code", "Size", 0 }, + { "FavorSizeOrSpeed", "Ot", "Favor fast code", "Speed", 0 }, + { "FavorSizeOrSpeed", "", "Neither", "Neither", 0 }, + + { "ExceptionHandling", "EHa", "Yes with SEH Exceptions", "Async", 0 }, + { "ExceptionHandling", "EHsc", "Yes", "Sync", 0 }, + { "ExceptionHandling", "EHs", "Yes with Extern C functions", "SyncCThrow", + 0 }, + { "ExceptionHandling", "", "No", "false", 0 }, + + { "BasicRuntimeChecks", "RTCs", "Stack Frames", "StackFrameRuntimeCheck", + 0 }, + { "BasicRuntimeChecks", "RTCu", "Uninitialized variables", + "UninitializedLocalUsageCheck", 0 }, + { "BasicRuntimeChecks", "RTC1", "Both (/RTC1, equiv. to /RTCsu)", + "EnableFastChecks", 0 }, + { "BasicRuntimeChecks", "", "Default", "Default", 0 }, + + { "RuntimeLibrary", "MT", "Multi-threaded", "MultiThreaded", 0 }, + { "RuntimeLibrary", "MTd", "Multi-threaded Debug", "MultiThreadedDebug", 0 }, + { "RuntimeLibrary", "MD", "Multi-threaded DLL", "MultiThreadedDLL", 0 }, + { "RuntimeLibrary", "MDd", "Multi-threaded Debug DLL", + "MultiThreadedDebugDLL", 0 }, + + { "StructMemberAlignment", "Zp1", "1 Byte", "1Byte", 0 }, + { "StructMemberAlignment", "Zp2", "2 Bytes", "2Bytes", 0 }, + { "StructMemberAlignment", "Zp4", "4 Byte", "4Bytes", 0 }, + { "StructMemberAlignment", "Zp8", "8 Bytes", "8Bytes", 0 }, + { "StructMemberAlignment", "Zp16", "16 Bytes", "16Bytes", 0 }, + { "StructMemberAlignment", "", "Default", "Default", 0 }, + + { "BufferSecurityCheck", "GS-", "Disable Security Check", "false", 0 }, + { "BufferSecurityCheck", "GS", "Enable Security Check", "true", 0 }, + + { "EnableEnhancedInstructionSet", "arch:SSE", "Streaming SIMD Extensions", + "StreamingSIMDExtensions", 0 }, + { "EnableEnhancedInstructionSet", "arch:SSE2", "Streaming SIMD Extensions 2", + "StreamingSIMDExtensions2", 0 }, + { "EnableEnhancedInstructionSet", "arch:AVX", "Advanced Vector Extensions", + "AdvancedVectorExtensions", 0 }, + { "EnableEnhancedInstructionSet", "arch:AVX2", + "Advanced Vector Extensions 2", "AdvancedVectorExtensions2", 0 }, + { "EnableEnhancedInstructionSet", "arch:IA32", "No Enhanced Instructions", + "NoExtensions", 0 }, + { "EnableEnhancedInstructionSet", "", "Not Set", "NotSet", 0 }, + + { "FloatingPointModel", "fp:precise", "Precise", "Precise", 0 }, + { "FloatingPointModel", "fp:strict", "Strict", "Strict", 0 }, + { "FloatingPointModel", "fp:fast", "Fast", "Fast", 0 }, + + { "PrecompiledHeader", "Yc", "Create", "Create", + cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue }, + { "PrecompiledHeader", "Yu", "Use", "Use", + cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue }, + { "PrecompiledHeader", "", "Not Using Precompiled Headers", "NotUsing", 0 }, + + { "AssemblerOutput", "", "No Listing", "NoListing", 0 }, + { "AssemblerOutput", "FA", "Assembly-Only Listing", "AssemblyCode", 0 }, + { "AssemblerOutput", "FAc", "Assembly With Machine Code", + "AssemblyAndMachineCode", 0 }, + { "AssemblerOutput", "FAs", "Assembly With Source Code", + "AssemblyAndSourceCode", 0 }, + { "AssemblerOutput", "FAcs", "Assembly, Machine Code and Source", "All", 0 }, + + { "CallingConvention", "Gd", "__cdecl", "Cdecl", 0 }, + { "CallingConvention", "Gr", "__fastcall", "FastCall", 0 }, + { "CallingConvention", "Gz", "__stdcall", "StdCall", 0 }, + { "CallingConvention", "Gv", "__vectorcall", "VectorCall", 0 }, + + { "CompileAs", "", "Default", "Default", 0 }, + { "CompileAs", "TC", "Compile as C Code", "CompileAsC", 0 }, + { "CompileAs", "TP", "Compile as C++ Code", "CompileAsCpp", 0 }, + + { "ErrorReporting", "errorReport:none", "Do Not Send Report", "None", 0 }, + { "ErrorReporting", "errorReport:prompt", "Prompt Immediately", "Prompt", + 0 }, + { "ErrorReporting", "errorReport:queue", "Queue For Next Login", "Queue", + 0 }, + { "ErrorReporting", "errorReport:send", "Send Automatically", "Send", 0 }, + + { "CompileAsManaged", "", "No Common Language RunTime Support", "false", 0 }, + { "CompileAsManaged", "clr", "Common Language RunTime Support", "true", 0 }, + { "CompileAsManaged", "clr:pure", + "Pure MSIL Common Language RunTime Support", "Pure", 0 }, + { "CompileAsManaged", "clr:safe", + "Safe MSIL Common Language RunTime Support", "Safe", 0 }, + { "CompileAsManaged", "clr:oldSyntax", + "Common Language RunTime Support, Old Syntax", "OldSyntax", 0 }, + + { "CppLanguageStandard", "", "Default", "Default", 0 }, + { "CppLanguageStandard", "std=c++98", "C++03", "c++98", 0 }, + { "CppLanguageStandard", "std=c++11", "C++11", "c++11", 0 }, + { "CppLanguageStandard", "std=c++1y", "C++14", "c++1y", 0 }, + { "CppLanguageStandard", "std=c++14", "C++14", "c++1y", 0 }, + { "CppLanguageStandard", "std=gnu++98", "C++03 (GNU Dialect)", "gnu++98", + 0 }, + { "CppLanguageStandard", "std=gnu++11", "C++11 (GNU Dialect)", "gnu++11", + 0 }, + { "CppLanguageStandard", "std=gnu++1y", "C++14 (GNU Dialect)", "gnu++1y", + 0 }, + { "CppLanguageStandard", "std=gnu++14", "C++14 (GNU Dialect)", "gnu++1y", + 0 }, + + // Bool Properties + { "CompileAsWinRT", "ZW", "", "true", 0 }, + { "WinRTNoStdLib", "ZW:nostdlib", "", "true", 0 }, + { "SuppressStartupBanner", "nologo", "", "true", 0 }, + { "TreatWarningAsError", "WX-", "", "false", 0 }, + { "TreatWarningAsError", "WX", "", "true", 0 }, + { "SDLCheck", "sdl-", "", "false", 0 }, + { "SDLCheck", "sdl", "", "true", 0 }, + { "IntrinsicFunctions", "Oi", "", "true", 0 }, + { "OmitFramePointers", "Oy-", "", "false", 0 }, + { "OmitFramePointers", "Oy", "", "true", 0 }, + { "EnableFiberSafeOptimizations", "GT", "", "true", 0 }, + { "WholeProgramOptimization", "GL", "", "true", 0 }, + { "UndefineAllPreprocessorDefinitions", "u", "", "true", 0 }, + { "IgnoreStandardIncludePath", "X", "", "true", 0 }, + { "PreprocessToFile", "P", "", "true", 0 }, + { "PreprocessSuppressLineNumbers", "EP", "", "true", 0 }, + { "PreprocessKeepComments", "C", "", "true", 0 }, + { "StringPooling", "GF-", "", "false", 0 }, + { "StringPooling", "GF", "", "true", 0 }, + { "MinimalRebuild", "Gm-", "", "false", 0 }, + { "MinimalRebuild", "Gm", "", "true", 0 }, + { "SmallerTypeCheck", "RTCc", "", "true", 0 }, + { "FunctionLevelLinking", "Gy-", "", "false", 0 }, + { "FunctionLevelLinking", "Gy", "", "true", 0 }, + { "EnableParallelCodeGeneration", "Qpar-", "", "false", 0 }, + { "EnableParallelCodeGeneration", "Qpar", "", "true", 0 }, + { "FloatingPointExceptions", "fp:except-", "", "false", 0 }, + { "FloatingPointExceptions", "fp:except", "", "true", 0 }, + { "CreateHotpatchableImage", "hotpatch", "", "true", 0 }, + { "DisableLanguageExtensions", "Za", "", "true", 0 }, + { "TreatWChar_tAsBuiltInType", "Zc:wchar_t-", "", "false", 0 }, + { "TreatWChar_tAsBuiltInType", "Zc:wchar_t", "", "true", 0 }, + { "ForceConformanceInForLoopScope", "Zc:forScope-", "", "false", 0 }, + { "ForceConformanceInForLoopScope", "Zc:forScope", "", "true", 0 }, + { "RuntimeTypeInfo", "GR-", "", "false", 0 }, + { "RuntimeTypeInfo", "GR", "", "true", 0 }, + { "OpenMPSupport", "openmp-", "", "false", 0 }, + { "OpenMPSupport", "openmp", "", "true", 0 }, + { "ExpandAttributedSource", "Fx", "", "true", 0 }, + { "UseUnicodeForAssemblerListing", "FAu", "", "true", 0 }, + { "ShowIncludes", "showIncludes", "", "true", 0 }, + { "EnablePREfast", "analyze-", "", "false", 0 }, + { "EnablePREfast", "analyze", "", "true", 0 }, + { "UseFullPaths", "FC", "", "true", 0 }, + { "OmitDefaultLibName", "Zl", "", "true", 0 }, + + // Bool Properties With Argument + { "MultiProcessorCompilation", "MP", "", "true", + cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue }, + { "ProcessorNumber", "MP", "Multi-processor Compilation", "", + cmVS7FlagTable::UserValueRequired }, + { "GenerateXMLDocumentationFiles", "doc", "", "true", + cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue }, + { "XMLDocumentationFileName", "doc", "Generate XML Documentation Files", "", + cmVS7FlagTable::UserValueRequired }, + { "BrowseInformation", "FR", "", "true", + cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue }, + { "BrowseInformationFile", "FR", "Enable Browse Information", "", + cmVS7FlagTable::UserValueRequired }, + + // String List Properties + { "AdditionalIncludeDirectories", "I", "Additional Include Directories", "", + cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable }, + { "AdditionalUsingDirectories", "AI", "Additional #using Directories", "", + cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable }, + { "PreprocessorDefinitions", "D ", "Preprocessor Definitions", "", + cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable }, + { "UndefinePreprocessorDefinitions", "U", + "Undefine Preprocessor Definitions", "", + cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable }, + { "DisableSpecificWarnings", "wd", "Disable Specific Warnings", "", + cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable }, + { "ForcedIncludeFiles", "FI", "Forced Include File", "", + cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable }, + { "ForcedUsingFiles", "FU", "Forced #using File", "", + cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable }, + { "PREfastLog", "analyze:log", "Code Analysis Log", "", + cmVS7FlagTable::UserFollowing }, + { "PREfastAdditionalPlugins", "analyze:plugin", + "Additional Code Analysis Native plugins", "", + cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable }, + { "TreatSpecificWarningsAsErrors", "we", "Treat Specific Warnings As Errors", + "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable }, + + // String Properties + // Skip [TrackerLogDirectory] - no command line Switch. + { "PreprocessOutputPath", "Fi", "Preprocess Output Path", "", + cmVS7FlagTable::UserValue }, + { "PrecompiledHeaderFile", "Yc", "Precompiled Header Name", "", + cmVS7FlagTable::UserValueRequired }, + { "PrecompiledHeaderFile", "Yu", "Precompiled Header Name", "", + cmVS7FlagTable::UserValueRequired }, + { "PrecompiledHeaderOutputFile", "Fp", "Precompiled Header Output File", "", + cmVS7FlagTable::UserValue }, + { "AssemblerListingLocation", "Fa", "ASM List Location", "", + cmVS7FlagTable::UserValue }, + { "ObjectFileName", "Fo", "Object File Name", "", + cmVS7FlagTable::UserValue }, + { "ProgramDataBaseFileName", "Fd", "Program Database File Name", "", + cmVS7FlagTable::UserValue }, + // Skip [XMLDocumentationFileName] - no command line Switch. + // Skip [BrowseInformationFile] - no command line Switch. + // Skip [AdditionalOptions] - no command line Switch. + { 0, 0, 0, 0, 0 } +}; diff --git a/Source/cmVS14CLFlagTable.h b/Source/cmVS141CLFlagTable.h index c48db68..895b3e8 100644 --- a/Source/cmVS14CLFlagTable.h +++ b/Source/cmVS141CLFlagTable.h @@ -1,4 +1,4 @@ -static cmVS7FlagTable cmVS14CLFlagTable[] = { +static cmVS7FlagTable cmVS141CLFlagTable[] = { // Enum Properties { "DebugInformationFormat", "", "None", "None", 0 }, diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 6690bfa..82f4b99 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -25,7 +25,8 @@ #include "cmVS12LinkFlagTable.h" #include "cmVS12MASMFlagTable.h" #include "cmVS12RCFlagTable.h" -#include "cmVS14CLFlagTable.h" +#include "cmVS140CLFlagTable.h" +#include "cmVS141CLFlagTable.h" #include "cmVS14LibFlagTable.h" #include "cmVS14LinkFlagTable.h" #include "cmVS14MASMFlagTable.h" @@ -43,7 +44,13 @@ cmIDEFlagTable const* cmVisualStudio10TargetGenerator::GetClFlagTable() const cmGlobalVisualStudioGenerator::VSVersion v = this->LocalGenerator->GetVersion(); if (v >= cmGlobalVisualStudioGenerator::VS14) { - return cmVS14CLFlagTable; + // FIXME: All flag table selection should be based on the toolset name. + // See issue #16153. For now, treat VS 15's toolset as a special case. + const char* toolset = this->GlobalGenerator->GetPlatformToolset(); + if (toolset && cmHasLiteralPrefix(toolset, "v141")) { + return cmVS141CLFlagTable; + } + return cmVS140CLFlagTable; } else if (v >= cmGlobalVisualStudioGenerator::VS12) { return cmVS12CLFlagTable; } else if (v == cmGlobalVisualStudioGenerator::VS11) { diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 14124f8..fc35414 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()); @@ -929,7 +932,7 @@ void cmake::GetRegisteredGenerators( gen != genList.end(); ++gen) { GeneratorInfo info; info.name = cmExternalMakefileProjectGenerator::CreateFullGeneratorName( - (*i)->GetName(), *gen); + *gen, (*i)->GetName()); info.baseName = *gen; info.extraName = (*i)->GetName(); info.supportsPlatform = false; diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index c97af25..5da715f 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -2716,17 +2716,15 @@ unsigned long SystemTools::FileLength(const std::string& filename) return length; } -int SystemTools::Strucmp(const char *s1, const char *s2) -{ - // lifted from Graphvis http://www.graphviz.org - while ((*s1 != '\0') - && (tolower(*s1) == tolower(*s2))) - { - s1++; - s2++; - } - - return tolower(*s1) - tolower(*s2); +int SystemTools::Strucmp(const char* l, const char* r) +{ + int lc; + int rc; + do { + lc = tolower(*l++); + rc = tolower(*r++); + } while(lc == rc && lc); + return lc - rc; } // return file's modified time 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/RunCMake/Android/android.cxx b/Tests/RunCMake/Android/android.cxx index e6a6cda..2dee8f9 100644 --- a/Tests/RunCMake/Android/android.cxx +++ b/Tests/RunCMake/Android/android.cxx @@ -6,6 +6,9 @@ #ifndef STL_SYSTEM #include <exception> #include <typeinfo> +#ifndef STL_STLPORT +#include <cxxabi.h> +#endif #ifndef STL_GABI #include <iostream> #include <string> diff --git a/Tests/RunCMake/Android/common.cmake b/Tests/RunCMake/Android/common.cmake index 6ea0909..d803c98 100644 --- a/Tests/RunCMake/Android/common.cmake +++ b/Tests/RunCMake/Android/common.cmake @@ -43,6 +43,8 @@ elseif(CMAKE_ANDROID_STL_TYPE STREQUAL "system") add_definitions(-DSTL_SYSTEM) elseif(CMAKE_ANDROID_STL_TYPE MATCHES [[^gabi\+\+]]) add_definitions(-DSTL_GABI) +elseif(CMAKE_ANDROID_STL_TYPE MATCHES [[^stlport]]) + add_definitions(-DSTL_STLPORT) endif() string(REPLACE "-" "_" abi "${CMAKE_ANDROID_ARCH_ABI}") diff --git a/Tests/RunCMake/AndroidMK/AndroidMK.cmake b/Tests/RunCMake/AndroidMK/AndroidMK.cmake index ed21e58..2596e8c 100644 --- a/Tests/RunCMake/AndroidMK/AndroidMK.cmake +++ b/Tests/RunCMake/AndroidMK/AndroidMK.cmake @@ -2,7 +2,7 @@ project(build) set(CMAKE_BUILD_TYPE Debug) add_library(foo foo.cxx) add_library(car foo.cxx) -add_library(bar foo.cxx) +add_library(bar bar.c) add_library(dog foo.cxx) target_link_libraries(foo car bar dog debug -lm) export(TARGETS bar dog car foo ANDROID_MK diff --git a/Tests/RunCMake/AndroidMK/bar.c b/Tests/RunCMake/AndroidMK/bar.c new file mode 100644 index 0000000..e1f4df6 --- /dev/null +++ b/Tests/RunCMake/AndroidMK/bar.c @@ -0,0 +1,3 @@ +void bar(void) +{ +} diff --git a/Tests/RunCMake/AndroidMK/expectedBuildAndroidMK.txt b/Tests/RunCMake/AndroidMK/expectedBuildAndroidMK.txt index def8fcb..bbf67a5 100644 --- a/Tests/RunCMake/AndroidMK/expectedBuildAndroidMK.txt +++ b/Tests/RunCMake/AndroidMK/expectedBuildAndroidMK.txt @@ -7,11 +7,13 @@ include.*PREBUILT_STATIC_LIBRARY.* include.*CLEAR_VARS.* LOCAL_MODULE.*dog LOCAL_SRC_FILES.*.*dog.* +LOCAL_HAS_CPP := true include.*PREBUILT_STATIC_LIBRARY.* .* include.*CLEAR_VARS.* LOCAL_MODULE.*car LOCAL_SRC_FILES.*.*car.* +LOCAL_HAS_CPP := true include.*PREBUILT_STATIC_LIBRARY.* .* include.*CLEAR_VARS.* @@ -20,4 +22,5 @@ LOCAL_SRC_FILES.*.*foo.* LOCAL_CPP_FEATURES.*rtti exceptions LOCAL_STATIC_LIBRARIES.*car bar dog LOCAL_EXPORT_LDLIBS := -lm +LOCAL_HAS_CPP := true include.*PREBUILT_STATIC_LIBRARY.* diff --git a/Tests/RunCMake/AndroidMK/expectedInstallAndroidMK.txt b/Tests/RunCMake/AndroidMK/expectedInstallAndroidMK.txt index 1bdb308..3515fb9 100644 --- a/Tests/RunCMake/AndroidMK/expectedInstallAndroidMK.txt +++ b/Tests/RunCMake/AndroidMK/expectedInstallAndroidMK.txt @@ -9,11 +9,13 @@ include.*PREBUILT_STATIC_LIBRARY.* include.*CLEAR_VARS. LOCAL_MODULE.*dog LOCAL_SRC_FILES.*_IMPORT_PREFIX./lib.*dog.* +LOCAL_HAS_CPP := true include.*PREBUILT_STATIC_LIBRARY.* include.*CLEAR_VARS.* LOCAL_MODULE.*car LOCAL_SRC_FILES.*_IMPORT_PREFIX./lib.*car.* +LOCAL_HAS_CPP := true include.*PREBUILT_STATIC_LIBRARY.* include.*CLEAR_VARS.* @@ -22,4 +24,5 @@ LOCAL_SRC_FILES.*_IMPORT_PREFIX\)/lib.*foo.* LOCAL_CPP_FEATURES.*rtti exceptions LOCAL_STATIC_LIBRARIES.*car bar dog LOCAL_EXPORT_LDLIBS := -lm +LOCAL_HAS_CPP := true include.*PREBUILT_STATIC_LIBRARY.* 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/Tests/RunCMake/ExternalProject/CMAKE_CACHE_ARGS-check.cmake b/Tests/RunCMake/ExternalProject/CMAKE_CACHE_ARGS-check.cmake index c350a63..cb48be7 100644 --- a/Tests/RunCMake/ExternalProject/CMAKE_CACHE_ARGS-check.cmake +++ b/Tests/RunCMake/ExternalProject/CMAKE_CACHE_ARGS-check.cmake @@ -15,3 +15,12 @@ if(NOT "${CMAKE_MATCH_0}" MATCHES FORCE) set(RunCMake_TEST_FAILED "Expected forced FOO argument") return() endif() + +if(NOT "${_cache}" MATCHES "set\\(TEST_LIST \"A;B;C\".+\\)") + set(RunCMake_TEST_FAILED "Cannot find TEST_LIST argument in cache") + return() +endif() +if(NOT "${CMAKE_MATCH_0}" MATCHES FORCE) + set(RunCMake_TEST_FAILED "Expected forced TEST_LIST argument") + return() +endif() diff --git a/Tests/RunCMake/ExternalProject/CMAKE_CACHE_ARGS.cmake b/Tests/RunCMake/ExternalProject/CMAKE_CACHE_ARGS.cmake index 62b1640..1f76fd0 100644 --- a/Tests/RunCMake/ExternalProject/CMAKE_CACHE_ARGS.cmake +++ b/Tests/RunCMake/ExternalProject/CMAKE_CACHE_ARGS.cmake @@ -5,4 +5,6 @@ include(ExternalProject) ExternalProject_Add(FOO TMP_DIR "${CMAKE_CURRENT_BINARY_DIR}/tmp" DOWNLOAD_COMMAND "" - CMAKE_CACHE_ARGS "-DFOO:STRING=$<1:BAR>$<0:BAD>") + CMAKE_CACHE_ARGS + "-DFOO:STRING=$<1:BAR>$<0:BAD>" + "-DTEST_LIST:STRING=A;B;C") diff --git a/Tests/RunCMake/ExternalProject/CMAKE_CACHE_DEFAULT_ARGS-check.cmake b/Tests/RunCMake/ExternalProject/CMAKE_CACHE_DEFAULT_ARGS-check.cmake index aeee11f..c84932d 100644 --- a/Tests/RunCMake/ExternalProject/CMAKE_CACHE_DEFAULT_ARGS-check.cmake +++ b/Tests/RunCMake/ExternalProject/CMAKE_CACHE_DEFAULT_ARGS-check.cmake @@ -15,3 +15,12 @@ if("${CMAKE_MATCH_0}" MATCHES FORCE) set(RunCMake_TEST_FAILED "Expected not forced FOO argument") return() endif() + +if(NOT "${_cache}" MATCHES "set\\(TEST_LIST \"A;B;C\".+\\)") + set(RunCMake_TEST_FAILED "Cannot find TEST_LIST argument in cache") + return() +endif() +if("${CMAKE_MATCH_0}" MATCHES FORCE) + set(RunCMake_TEST_FAILED "Expected not forced TEST_LIST argument") + return() +endif() diff --git a/Tests/RunCMake/ExternalProject/CMAKE_CACHE_DEFAULT_ARGS.cmake b/Tests/RunCMake/ExternalProject/CMAKE_CACHE_DEFAULT_ARGS.cmake index 3a83dbe..1b619c8 100644 --- a/Tests/RunCMake/ExternalProject/CMAKE_CACHE_DEFAULT_ARGS.cmake +++ b/Tests/RunCMake/ExternalProject/CMAKE_CACHE_DEFAULT_ARGS.cmake @@ -5,4 +5,6 @@ include(ExternalProject) ExternalProject_Add(FOO TMP_DIR "${CMAKE_CURRENT_BINARY_DIR}/tmp" DOWNLOAD_COMMAND "" - CMAKE_CACHE_DEFAULT_ARGS "-DFOO:STRING=$<1:BAR>$<0:BAD>") + CMAKE_CACHE_DEFAULT_ARGS + "-DFOO:STRING=$<1:BAR>$<0:BAD>" + "-DTEST_LIST:STRING=A;B;C") @@ -297,6 +297,8 @@ CMAKE_CXX_SOURCES="\ cmFileTimeComparison \ cmGlobalUnixMakefileGenerator3 \ cmLocalUnixMakefileGenerator3 \ + cmLinkLineComputer \ + cmMSVC60LinkLineComputer \ cmMakefileExecutableTargetGenerator \ cmMakefileLibraryTargetGenerator \ cmMakefileTargetGenerator \ |