This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake".
The branch, master has been updated via d480ede35b82c540e9d93b7bb4280014875f6444 (commit) via f255280fd908e4ef1af5eba6230e81b74d339855 (commit) from 170fcebf2e866ce5266067716025a57c7e7e6ec4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=d480ede35b82c540e9d93b7bb4280014875f6444 commit d480ede35b82c540e9d93b7bb4280014875f6444 Merge: 170fceb f255280 Author: Craig Scott <craig.sc...@crascit.com> AuthorDate: Sun Dec 23 22:22:59 2018 +0000 Commit: Kitware Robot <kwro...@kitware.com> CommitDate: Sun Dec 23 17:23:11 2018 -0500 Merge topic 'link-options' f255280fd9 PIE link options: Update strategy to fix performance regression Acked-by: Kitware Robot <kwro...@kitware.com> Merge-request: !2739 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=f255280fd908e4ef1af5eba6230e81b74d339855 commit f255280fd908e4ef1af5eba6230e81b74d339855 Author: Marc Chevrier <marc.chevr...@gmail.com> AuthorDate: Thu Dec 13 16:14:59 2018 +0100 Commit: Craig Scott <craig.sc...@crascit.com> CommitDate: Wed Dec 19 19:41:27 2018 +1100 PIE link options: Update strategy to fix performance regression Fixes: #18700 diff --git a/Help/command/try_compile.rst b/Help/command/try_compile.rst index f50fcb6..cf9e06f 100644 --- a/Help/command/try_compile.rst +++ b/Help/command/try_compile.rst @@ -134,6 +134,11 @@ default values: If :policy:`CMP0056` is set to ``NEW``, then :variable:`CMAKE_EXE_LINKER_FLAGS` is passed in as well. +If :policy:`CMP0083` is set to ``NEW``, then in order to obtain correct +behavior at link time, the ``check_pie_supported()`` command from the +:module:`CheckPIESupported` module must be called before using the +:command:`try_compile` command. + The current settings of :policy:`CMP0065` and :policy:`CMP0083` are set in the generated project. diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst index 2f08a04..940186a 100644 --- a/Help/manual/cmake-modules.7.rst +++ b/Help/manual/cmake-modules.7.rst @@ -35,6 +35,7 @@ These modules are loaded using the :command:`include` command. /module/CheckIncludeFiles /module/CheckLanguage /module/CheckLibraryExists + /module/CheckPIESupported /module/CheckPrototypeDefinition /module/CheckStructHasMember /module/CheckSymbolExists diff --git a/Help/module/CheckPIESupported.rst b/Help/module/CheckPIESupported.rst new file mode 100644 index 0000000..02e7b43 --- /dev/null +++ b/Help/module/CheckPIESupported.rst @@ -0,0 +1 @@ +.. cmake-module:: ../../Modules/CheckPIESupported.cmake diff --git a/Help/policy/CMP0083.rst b/Help/policy/CMP0083.rst index 7b467b0..b26d6c8 100644 --- a/Help/policy/CMP0083.rst +++ b/Help/policy/CMP0083.rst @@ -17,8 +17,46 @@ is set: passed to the linker step. For example ``-no-pie`` for ``GCC``. * Not set: no flags are passed to the linker step. +Since a given linker may not support ``PIE`` flags in all environments in +which it is used, it is the project's responsibility to use the +:module:`CheckPIESupported` module to check for support to ensure that the +:prop_tgt:`POSITION_INDEPENDENT_CODE` target property for executables will be +honored at link time. + This policy was introduced in CMake version 3.14. CMake version |release| warns when the policy is not set and uses ``OLD`` behavior. Use the :command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly. .. include:: DEPRECATED.txt + +Examples +^^^^^^^^ + +Behave like CMake 3.13 and do not apply any ``PIE`` flags at link stage. + +.. code-block:: cmake + + cmake_minimum_required(VERSION 3.13) + project(foo) + + # ... + + add_executable(foo ...) + set_property(TARGET foo PROPERTY POSITION_INDEPENDENT_CODE TRUE) + +Use the :module:`CheckPIESupported` module to detect whether ``PIE`` is +supported by the current linker and environment. Apply ``PIE`` flags only +if the linker supports them. + +.. code-block:: cmake + + cmake_minimum_required(VERSION 3.14) # CMP0083 NEW + project(foo) + + include(CheckPIESupported) + check_pie_supported() + + # ... + + add_executable(foo ...) + set_property(TARGET foo PROPERTY POSITION_INDEPENDENT_CODE TRUE) diff --git a/Help/prop_tgt/POSITION_INDEPENDENT_CODE.rst b/Help/prop_tgt/POSITION_INDEPENDENT_CODE.rst index 54af8c6..0aaf66b 100644 --- a/Help/prop_tgt/POSITION_INDEPENDENT_CODE.rst +++ b/Help/prop_tgt/POSITION_INDEPENDENT_CODE.rst @@ -9,3 +9,8 @@ property is ``True`` by default for ``SHARED`` and ``MODULE`` library targets and ``False`` otherwise. This property is initialized by the value of the :variable:`CMAKE_POSITION_INDEPENDENT_CODE` variable if it is set when a target is created. + +.. note:: + + For executable targets, the link step is controlled by the :policy:`CMP0083` + policy and the :module:`CheckPIESupported` module. diff --git a/Help/release/dev/link-option-PIE.rst b/Help/release/dev/link-option-PIE.rst index 824ab2c..872343c 100644 --- a/Help/release/dev/link-option-PIE.rst +++ b/Help/release/dev/link-option-PIE.rst @@ -2,5 +2,8 @@ link-option-PIE --------------- * Required link options to manage Position Independent Executable are now - added when :prop_tgt:`POSITION_INDEPENDENT_CODE` is set. These flags are - controlled by policy :policy:`CMP0083`. + added when :prop_tgt:`POSITION_INDEPENDENT_CODE` is set. The project is + responsible for using the :module:`CheckPIESupported` module to check for + ``PIE`` support to ensure that the :prop_tgt:`POSITION_INDEPENDENT_CODE` + target property will be honored at link time for executables. This behavior + is controlled by policy :policy:`CMP0083`. diff --git a/Modules/CheckPIESupported.cmake b/Modules/CheckPIESupported.cmake new file mode 100644 index 0000000..720217d --- /dev/null +++ b/Modules/CheckPIESupported.cmake @@ -0,0 +1,134 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +CheckPIESupported +----------------- + +Check whether the linker supports position independent code (PIE) or no +position independent code (NO_PIE) for executables. +Use this to ensure that the :prop_tgt:`POSITION_INDEPENDENT_CODE` target +property for executables will be honored at link time. + +.. command:: check_pie_supported + + :: + + check_pie_supported([OUTPUT_VARIABLE <output>] + [LANGUAGES <lang>...]) + + Options are: + + ``OUTPUT_VARIABLE <output>`` + Set ``<output>`` variable with details about any error. + ``LANGUAGES <lang>...`` + Check the linkers used for each of the specified languages. + Supported languages are ``C``, ``CXX``, and ``Fortran``. + +It makes no sense to use this module when :policy:`CMP0083` is set to ``OLD``, +so the command will return an error in this case. See policy :policy:`CMP0083` +for details. + +Variables +^^^^^^^^^ + +For each language checked, two boolean cache variables are defined. + + ``CMAKE_<lang>_LINK_PIE_SUPPORTED`` + Set to ``YES`` if ``PIE`` is supported by the linker and ``NO`` otherwise. + ``CMAKE_<lang>_LINK_NO_PIE_SUPPORTED`` + Set to ``YES`` if ``NO_PIE`` is supported by the linker and ``NO`` otherwise. + +Examples +^^^^^^^^ + +.. code-block:: cmake + + check_pie_supported() + set_property(TARGET foo PROPERTY POSITION_INDEPENDENT_CODE TRUE) + +.. code-block:: cmake + + # Retrieve any error message. + check_pie_supported(OUTPUT_VARIABLE output LANGUAGES C) + set_property(TARGET foo PROPERTY POSITION_INDEPENDENT_CODE TRUE) + if(NOT CMAKE_C_LINK_PIE_SUPPORTED) + message(WARNING "PIE is not supported at link time: ${output}.\n" + "PIE link options will not be passed to linker.") + endif() + +#]=======================================================================] + + +include (Internal/CMakeCheckCompilerFlag) + +function (check_pie_supported) + cmake_policy(GET CMP0083 cmp0083) + + if (NOT cmp0083) + message(FATAL_ERROR "check_pie_supported: Policy CMP0083 is not set") + endif() + + if(cmp0083 STREQUAL "OLD") + message(FATAL_ERROR "check_pie_supported: Policy CMP0083 set to OLD") + endif() + + set(optional) + set(one OUTPUT_VARIABLE) + set(multiple LANGUAGES) + + cmake_parse_arguments(CHECK_PIE "${optional}" "${one}" "${multiple}" "${ARGN}") + if(CHECK_PIE_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "check_pie_supported: Unparsed arguments: ${CHECK_PIE_UNPARSED_ARGUMENTS}") + endif() + + if (CHECK_PIE_LANGUAGES) + set (unsupported_languages "${CHECK_PIE_LANGUAGES}") + list (REMOVE_ITEM unsupported_languages "C" "CXX" "Fortran") + if(unsupported_languages) + message(FATAL_ERROR "check_pie_supported: language(s) '${unsupported_languages}' not supported") + endif() + else() + # User did not set any languages, use defaults + get_property (enabled_languages GLOBAL PROPERTY ENABLED_LANGUAGES) + if (NOT enabled_languages) + return() + endif() + + list (FILTER enabled_languages INCLUDE REGEX "^(C|CXX|Fortran)$") + if (NOT enabled_languages) + return() + endif() + + set (CHECK_PIE_LANGUAGES ${enabled_languages}) + endif() + + set (outputs) + + foreach(lang IN LISTS CHECK_PIE_LANGUAGES) + if(_CMAKE_${lang}_PIE_MAY_BE_SUPPORTED_BY_LINKER) + cmake_check_compiler_flag(${lang} "${CMAKE_${lang}_LINK_OPTIONS_PIE}" + CMAKE_${lang}_LINK_PIE_SUPPORTED + OUTPUT_VARIABLE output) + if (NOT CMAKE_${lang}_LINK_PIE_SUPPORTED) + string (APPEND outputs "PIE (${lang}): ${output}\n") + endif() + + cmake_check_compiler_flag(${lang} "${CMAKE_${lang}_LINK_OPTIONS_NO_PIE}" + CMAKE_${lang}_LINK_NO_PIE_SUPPORTED + OUTPUT_VARIABLE output) + if (NOT CMAKE_${lang}_LINK_NO_PIE_SUPPORTED) + string (APPEND outputs "NO_PIE (${lang}): ${output}\n") + endif() + else() + # no support at link time. Set cache variables to NO + set(CMAKE_${lang}_LINK_PIE_SUPPORTED NO CACHE INTERNAL "PIE (${lang})") + set(CMAKE_${lang}_LINK_NO_PIE_SUPPORTED NO CACHE INTERNAL "NO_PIE (${lang})") + string (APPEND outputs "PIE and NO_PIE are not supported by linker for ${lang}") + endif() + endforeach() + + if (CHECK_PIE_OUTPUT_VARIABLE) + set (${CHECK_PIE_OUTPUT_VARIABLE} "${outputs}" PARENT_SCOPE) + endif() +endfunction() diff --git a/Modules/Compiler/AppleClang-C.cmake b/Modules/Compiler/AppleClang-C.cmake index 8754951..a48adec 100644 --- a/Modules/Compiler/AppleClang-C.cmake +++ b/Modules/Compiler/AppleClang-C.cmake @@ -1,9 +1,6 @@ include(Compiler/Clang) __compiler_clang(C) -set(CMAKE_C_LINK_OPTIONS_PIE ${CMAKE_C_COMPILE_OPTIONS_PIE} -Xlinker -pie) -set(CMAKE_C_LINK_OPTIONS_NO_PIE -Xlinker -no_pie) - if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.0) set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90") set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu90") diff --git a/Modules/Compiler/AppleClang-CXX.cmake b/Modules/Compiler/AppleClang-CXX.cmake index 54c1388..e5fd647 100644 --- a/Modules/Compiler/AppleClang-CXX.cmake +++ b/Modules/Compiler/AppleClang-CXX.cmake @@ -1,9 +1,6 @@ include(Compiler/Clang) __compiler_clang(CXX) -set(CMAKE_CXX_LINK_OPTIONS_PIE ${CMAKE_CXX_COMPILE_OPTIONS_PIE} -Xlinker -pie) -set(CMAKE_CXX_LINK_OPTIONS_NO_PIE -Xlinker -no_pie) - if(NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC") set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden") endif() diff --git a/Modules/Compiler/Clang.cmake b/Modules/Compiler/Clang.cmake index 7cee9c7..c3f13f3 100644 --- a/Modules/Compiler/Clang.cmake +++ b/Modules/Compiler/Clang.cmake @@ -23,23 +23,9 @@ else() set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE") # Link options for PIE are already set in 'Compiler/GNU.cmake' # but clang may require alternate syntax on some platforms - if (NOT CMAKE_${lang}_FLAG_PIE) - cmake_check_compiler_flag(${lang} "${CMAKE_${lang}_COMPILE_OPTIONS_PIE};-Xlinker;-pie" - CMAKE_${lang}_FLAG_XLINKER_PIE) - if (CMAKE_${lang}_FLAG_XLINKER_PIE) - set(CMAKE_${lang}_LINK_OPTIONS_PIE ${CMAKE_${lang}_COMPILE_OPTIONS_PIE} "-Xlinker" "-pie") - else() - set(CMAKE_${lang}_LINK_OPTIONS_PIE "") - endif() - endif() - if (NOT CMAKE_${lang}_FLAG_NO_PIE) - cmake_check_compiler_flag(${lang} "-Xlinker;-no_pie" - CMAKE_${lang}_FLAG_XLINKER_NO_PIE) - if (CMAKE_${lang}_FLAG_XLINKER_NO_PIE) - set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "-Xlinker" "-no_pie") - else() - set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "") - endif() + if (APPLE) + set(CMAKE_${lang}_LINK_OPTIONS_PIE ${CMAKE_${lang}_COMPILE_OPTIONS_PIE} -Xlinker -pie) + set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE -Xlinker -no_pie) endif() set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ") set(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY "-fvisibility=") diff --git a/Modules/Compiler/GNU.cmake b/Modules/Compiler/GNU.cmake index 688a1b5..6b1bd3a 100644 --- a/Modules/Compiler/GNU.cmake +++ b/Modules/Compiler/GNU.cmake @@ -15,23 +15,14 @@ macro(__compiler_gnu lang) # Feature flags. set(CMAKE_${lang}_VERBOSE_FLAG "-v") set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-fPIC") + set (_CMAKE_${lang}_PIE_MAY_BE_SUPPORTED_BY_LINKER NO) if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 3.4) set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE") # Support of PIE at link stage depends on various elements : platform, compiler, linker - # so the easiest way is to check if compiler supports these flags - cmake_check_compiler_flag(${lang} "${CMAKE_${lang}_COMPILE_OPTIONS_PIE};-pie" - CMAKE_${lang}_FLAG_PIE) - if (CMAKE_${lang}_FLAG_PIE) - set(CMAKE_${lang}_LINK_OPTIONS_PIE ${CMAKE_${lang}_COMPILE_OPTIONS_PIE} "-pie") - else() - set(CMAKE_${lang}_LINK_OPTIONS_PIE "") - endif() - cmake_check_compiler_flag(${lang} "-no-pie" CMAKE_${lang}_FLAG_NO_PIE) - if (CMAKE_${lang}_FLAG_NO_PIE) - set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "-no-pie") - else() - set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "") - endif() + # so to activate it, module CheckPIESupported must be used. + set (_CMAKE_${lang}_PIE_MAY_BE_SUPPORTED_BY_LINKER YES) + set(CMAKE_${lang}_LINK_OPTIONS_PIE ${CMAKE_${lang}_COMPILE_OPTIONS_PIE} "-pie") + set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "-no-pie") endif() if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 4.0) set(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY "-fvisibility=") diff --git a/Modules/Compiler/SunPro-C.cmake b/Modules/Compiler/SunPro-C.cmake index 75b8fe6..c4aba8e 100644 --- a/Modules/Compiler/SunPro-C.cmake +++ b/Modules/Compiler/SunPro-C.cmake @@ -7,6 +7,7 @@ set(CMAKE_C_VERBOSE_FLAG "-#") set(CMAKE_C_COMPILE_OPTIONS_PIC -KPIC) set(CMAKE_C_COMPILE_OPTIONS_PIE "") +set(_CMAKE_C_PIE_MAY_BE_SUPPORTED_BY_LINKER NO) set(CMAKE_C_LINK_OPTIONS_PIE "") set(CMAKE_C_LINK_OPTIONS_NO_PIE "") set(CMAKE_SHARED_LIBRARY_C_FLAGS "-KPIC") diff --git a/Modules/Compiler/SunPro-CXX.cmake b/Modules/Compiler/SunPro-CXX.cmake index 662ac30..5ce58b2 100644 --- a/Modules/Compiler/SunPro-CXX.cmake +++ b/Modules/Compiler/SunPro-CXX.cmake @@ -7,6 +7,7 @@ set(CMAKE_CXX_VERBOSE_FLAG "-v") set(CMAKE_CXX_COMPILE_OPTIONS_PIC -KPIC) set(CMAKE_CXX_COMPILE_OPTIONS_PIE "") +set(_CMAKE_CXX_PIE_MAY_BE_SUPPORTED_BY_LINKER NO) set(CMAKE_CXX_LINK_OPTIONS_PIE "") set(CMAKE_CXX_LINK_OPTIONS_NO_PIE "") set(CMAKE_SHARED_LIBRARY_CXX_FLAGS "-KPIC") diff --git a/Modules/Compiler/SunPro-Fortran.cmake b/Modules/Compiler/SunPro-Fortran.cmake index e110253..0c93c94 100644 --- a/Modules/Compiler/SunPro-Fortran.cmake +++ b/Modules/Compiler/SunPro-Fortran.cmake @@ -4,6 +4,7 @@ set(CMAKE_Fortran_FORMAT_FREE_FLAG "-free") set(CMAKE_Fortran_COMPILE_OPTIONS_PIC "-KPIC") set(CMAKE_Fortran_COMPILE_OPTIONS_PIE "") +set(_CMAKE_Fortran_PIE_MAY_BE_SUPPORTED_BY_LINKER NO) set(CMAKE_Fortran_LINK_OPTIONS_PIE "") set(CMAKE_Fortran_LINK_OPTIONS_NO_PIE "") set(CMAKE_SHARED_LIBRARY_Fortran_FLAGS "-KPIC") diff --git a/Modules/Internal/CMakeCheckCompilerFlag.cmake b/Modules/Internal/CMakeCheckCompilerFlag.cmake index ca9b356..9c8dfb6 100644 --- a/Modules/Internal/CMakeCheckCompilerFlag.cmake +++ b/Modules/Internal/CMakeCheckCompilerFlag.cmake @@ -12,12 +12,17 @@ The function does not use the try_compile() command so as to avoid infinite recursion. It may not work for all platforms or toolchains, the caller is responsible for ensuring it is only called in valid situations. + cmake_check_compiler_flag(<lang> <flag> <result> + [SRC_EXT <ext>] [COMMAND_PATTERN <pattern>] + [FAIL_REGEX <regex> ...] + [OUTPUT_VARIABLE <output>]) + Parameters: - lang - Language to check. - flag - The flag to add to the compile/link command line. - result - Boolean output variable. It will be stored in the cache as an - internal variable and if true, will cause future tests that assign - to that variable to be bypassed. + <lang> - Language to check. + <flag> - The flag to add to the compile/link command line. + <result> - Boolean output variable. It will be stored in the cache as an + internal variable and if true, will cause future tests that assign + to that variable to be bypassed. Optional parameters: SRC_EXT - Overrides the extension of the source file used for the @@ -28,7 +33,7 @@ Optional parameters: the output, give a failed result for the check. A common set of regular expressions will be included in addition to those given by FAIL_REGEX. - + OUTPUT_VARIABLE - Set <output> variable with details about any error. #]=] include_guard(GLOBAL) @@ -58,7 +63,7 @@ function(CMAKE_CHECK_COMPILER_FLAG lang flag result) set(check_lang ${lang}) endif() - cmake_parse_arguments(CCCF "" "SRC_EXT;COMMAND_PATTERN" "FAIL_REGEX" ${ARGN}) + cmake_parse_arguments(CCCF "" "SRC_EXT;COMMAND_PATTERN;OUTPUT_VARIABLE" "FAIL_REGEX" ${ARGN}) if (NOT CCCF_COMMAND_PATTERN) set (CCCF_COMMAND_PATTERN "<FLAG> -o <OUTPUT> <SOURCE>") @@ -95,6 +100,10 @@ function(CMAKE_CHECK_COMPILER_FLAG lang flag result) endif() endif() + if (CCCF_OUTPUT_VARIABLE) + unset(${CCCF_OUTPUT_VARIABLE} PARENT_SCOPE) + endif() + # Compute the directory in which to run the test. set(COMPILER_FLAG_DIR "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp") # Compute source and output files. @@ -139,6 +148,9 @@ function(CMAKE_CHECK_COMPILER_FLAG lang flag result) "Determining if the ${flag} option " "is supported for ${lang} language failed with the following output:\n" "${COMPILER_FLAG_OUTPUT}\n") + if (CCCF_OUTPUT_VARIABLE) + set(${CCCF_OUTPUT_VARIABLE} "${COMPILER_FLAG_OUTPUT}" PARENT_SCOPE) + endif() return() endif() diff --git a/Modules/Platform/CYGWIN-GNU.cmake b/Modules/Platform/CYGWIN-GNU.cmake index f55b80d..ca90712 100644 --- a/Modules/Platform/CYGWIN-GNU.cmake +++ b/Modules/Platform/CYGWIN-GNU.cmake @@ -27,6 +27,7 @@ macro(__cygwin_compiler_gnu lang) # No -fPIC on cygwin set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "") set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "") + set(_CMAKE_${lang}_PIE_MAY_BE_SUPPORTED_BY_LINKER NO) set(CMAKE_${lang}_LINK_OPTIONS_PIE "") set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "") set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "") diff --git a/Modules/Platform/Fuchsia.cmake b/Modules/Platform/Fuchsia.cmake index 7b33434..4b13805 100644 --- a/Modules/Platform/Fuchsia.cmake +++ b/Modules/Platform/Fuchsia.cmake @@ -3,6 +3,7 @@ set(FUCHSIA 1) set(CMAKE_DL_LIBS "") set(CMAKE_C_COMPILE_OPTIONS_PIC "-fPIC") set(CMAKE_C_COMPILE_OPTIONS_PIE "-fPIE") +set(_CMAKE_C_PIE_MAY_BE_SUPPORTED_BY_LINKER YES) set(CMAKE_C_LINK_OPTIONS_PIE ${CMAKE_C_COMPILE_OPTIONS_PIE} "-pie") set(CMAKE_C_LINK_OPTIONS_NO_PIE "-no-pie") set(CMAKE_SHARED_LIBRARY_C_FLAGS "-fPIC") diff --git a/Modules/Platform/Linux-Intel.cmake b/Modules/Platform/Linux-Intel.cmake index ab22b1d..3b5ca59 100644 --- a/Modules/Platform/Linux-Intel.cmake +++ b/Modules/Platform/Linux-Intel.cmake @@ -23,7 +23,9 @@ endif() macro(__linux_compiler_intel lang) set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-fPIC") set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE") + set(_CMAKE_${lang}_PIE_MAY_BE_SUPPORTED_BY_LINKER NO) if (NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 13.0) + set(_CMAKE_${lang}_PIE_MAY_BE_SUPPORTED_BY_LINKER YES) set(CMAKE_${lang}_LINK_OPTIONS_PIE ${CMAKE_${lang}_COMPILE_OPTIONS_PIE} "-pie") set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "-no-pie") endif() diff --git a/Modules/Platform/Linux-PGI.cmake b/Modules/Platform/Linux-PGI.cmake index 3e7e391..0341654 100644 --- a/Modules/Platform/Linux-PGI.cmake +++ b/Modules/Platform/Linux-PGI.cmake @@ -12,6 +12,7 @@ macro(__linux_compiler_pgi lang) # Shared library compile and link flags. set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-fPIC") set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "") + set(_CMAKE_${lang}_PIE_MAY_BE_SUPPORTED_BY_LINKER NO) set(CMAKE_${lang}_LINK_OPTIONS_PIE "") set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "") set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "-fPIC") diff --git a/Modules/Platform/SINIX.cmake b/Modules/Platform/SINIX.cmake index e44ceef..e3b0a05 100644 --- a/Modules/Platform/SINIX.cmake +++ b/Modules/Platform/SINIX.cmake @@ -1,5 +1,6 @@ set(CMAKE_C_COMPILE_OPTIONS_PIC -K PIC) set(CMAKE_C_COMPILE_OPTIONS_PIE "") +set(_CMAKE_C_PIE_MAY_BE_SUPPORTED_BY_LINKER NO) set(CMAKE_C_LINK_OPTIONS_PIE "") set(CMAKE_C_LINK_OPTIONS_NO_PIE "") set(CMAKE_SHARED_LIBRARY_C_FLAGS "-K PIC") diff --git a/Modules/Platform/UNIX_SV.cmake b/Modules/Platform/UNIX_SV.cmake index 433daf3..bd1ffce 100644 --- a/Modules/Platform/UNIX_SV.cmake +++ b/Modules/Platform/UNIX_SV.cmake @@ -1,5 +1,6 @@ set(CMAKE_C_COMPILE_OPTIONS_PIC -K PIC) set(CMAKE_C_COMPILE_OPTIONS_PIE "") +set(_CMAKE_C_PIE_MAY_BE_SUPPORTED_BY_LINKER NO) set(CMAKE_C_LINK_OPTIONS_PIE "") set(CMAKE_C_LINK_OPTIONS_NO_PIE "") set(CMAKE_SHARED_LIBRARY_C_FLAGS "-K PIC") diff --git a/Modules/Platform/UnixWare.cmake b/Modules/Platform/UnixWare.cmake index 8c9d430..94888d9 100644 --- a/Modules/Platform/UnixWare.cmake +++ b/Modules/Platform/UnixWare.cmake @@ -1,5 +1,6 @@ set(CMAKE_C_COMPILE_OPTIONS_PIC -K PIC) set(CMAKE_C_COMPILE_OPTIONS_PIE "") +set(_CMAKE_C_PIE_MAY_BE_SUPPORTED_BY_LINKER NO) set(CMAKE_C_LINK_OPTIONS_PIE "") set(CMAKE_C_LINK_OPTIONS_NO_PIE "") set(CMAKE_SHARED_LIBRARY_C_FLAGS "-K PIC") diff --git a/Modules/Platform/Windows-GNU.cmake b/Modules/Platform/Windows-GNU.cmake index 2e854e5..71189b1 100644 --- a/Modules/Platform/Windows-GNU.cmake +++ b/Modules/Platform/Windows-GNU.cmake @@ -72,6 +72,7 @@ macro(__windows_compiler_gnu lang) # No -fPIC on Windows set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "") set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "") + set(_CMAKE_${lang}_PIE_MAY_BE_SUPPORTED_BY_LINKER NO) set(CMAKE_${lang}_LINK_OPTIONS_PIE "") set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "") set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "") diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index 541ae76..f9b494e 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -24,10 +24,18 @@ static std::string const kCMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN = "CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN"; static std::string const kCMAKE_C_COMPILER_TARGET = "CMAKE_C_COMPILER_TARGET"; +static std::string const kCMAKE_C_LINK_NO_PIE_SUPPORTED = + "CMAKE_C_LINK_NO_PIE_SUPPORTED"; +static std::string const kCMAKE_C_LINK_PIE_SUPPORTED = + "CMAKE_C_LINK_PIE_SUPPORTED"; static std::string const kCMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN = "CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN"; static std::string const kCMAKE_CXX_COMPILER_TARGET = "CMAKE_CXX_COMPILER_TARGET"; +static std::string const kCMAKE_CXX_LINK_NO_PIE_SUPPORTED = + "CMAKE_CXX_LINK_NO_PIE_SUPPORTED"; +static std::string const kCMAKE_CXX_LINK_PIE_SUPPORTED = + "CMAKE_CXX_LINK_PIE_SUPPORTED"; static std::string const kCMAKE_ENABLE_EXPORTS = "CMAKE_ENABLE_EXPORTS"; static std::string const kCMAKE_LINK_SEARCH_END_STATIC = "CMAKE_LINK_SEARCH_END_STATIC"; @@ -633,6 +641,16 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv, vars.insert(varList.begin(), varList.end()); } + if (this->Makefile->GetPolicyStatus(cmPolicies::CMP0083) == + cmPolicies::NEW) { + // To ensure full support of PIE, propagate cache variables + // driving the link options + vars.insert(kCMAKE_C_LINK_PIE_SUPPORTED); + vars.insert(kCMAKE_C_LINK_NO_PIE_SUPPORTED); + vars.insert(kCMAKE_CXX_LINK_PIE_SUPPORTED); + vars.insert(kCMAKE_CXX_LINK_NO_PIE_SUPPORTED); + } + /* for the TRY_COMPILEs we want to be able to specify the architecture. So the user can set CMAKE_OSX_ARCHITECTURES to i386;ppc and then set CMAKE_TRY_COMPILE_OSX_ARCHITECTURES first to i386 and then to ppc to diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index da48950..8fac039 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -2044,8 +2044,14 @@ void cmLocalGenerator::AppendPositionIndependentLinkerFlags( return; } - std::string name = "CMAKE_" + lang + "_LINK_OPTIONS_"; - name += cmSystemTools::IsOn(PICValue) ? "PIE" : "NO_PIE"; + const std::string mode = cmSystemTools::IsOn(PICValue) ? "PIE" : "NO_PIE"; + + std::string supported = "CMAKE_" + lang + "_LINK_" + mode + "_SUPPORTED"; + if (cmSystemTools::IsOff(this->Makefile->GetDefinition(supported))) { + return; + } + + std::string name = "CMAKE_" + lang + "_LINK_OPTIONS_" + mode; auto pieFlags = this->Makefile->GetSafeDefinition(name); if (pieFlags.empty()) { diff --git a/Tests/RunCMake/PositionIndependentCode/CMP0083.cmake b/Tests/RunCMake/PositionIndependentCode/CMP0083.cmake index 9713ea4..749ac79 100644 --- a/Tests/RunCMake/PositionIndependentCode/CMP0083.cmake +++ b/Tests/RunCMake/PositionIndependentCode/CMP0083.cmake @@ -6,6 +6,8 @@ add_executable (cmp0083_ref main.cpp) set (CMAKE_POSITION_INDEPENDENT_CODE ON) cmake_policy(SET CMP0083 NEW) +include(CheckPIESupported) +check_pie_supported() add_executable (cmp0083_new_pie main.cpp) diff --git a/Tests/RunCMake/PositionIndependentCode/CheckPIESupported.cmake b/Tests/RunCMake/PositionIndependentCode/CheckPIESupported.cmake index 1e0a2c9..61e1b6d 100644 --- a/Tests/RunCMake/PositionIndependentCode/CheckPIESupported.cmake +++ b/Tests/RunCMake/PositionIndependentCode/CheckPIESupported.cmake @@ -1,11 +1,17 @@ -if (CMAKE_CXX_LINK_OPTIONS_PIE) +cmake_policy(SET CMP0083 NEW) + +include (CheckPIESupported) + +check_pie_supported() + +if (CMAKE_CXX_LINK_PIE_SUPPORTED) file(WRITE "${PIE_SUPPORTED}" "\nset(PIE_SUPPORTED TRUE)\n") else() file(WRITE "${PIE_SUPPORTED}" "\nset(PIE_SUPPORTED FALSE)\n") endif() -if (CMAKE_CXX_LINK_OPTIONS_NO_PIE) +if (CMAKE_CXX_LINK_NO_PIE_SUPPORTED) file(APPEND "${PIE_SUPPORTED}" "\nset(NO_PIE_SUPPORTED TRUE)\n") else() file(APPEND "${PIE_SUPPORTED}" "\nset(NO_PIE_SUPPORTED FALSE)\n") diff --git a/Tests/RunCMake/PositionIndependentCode/PIE.cmake b/Tests/RunCMake/PositionIndependentCode/PIE.cmake index a9d579d..16ed89c 100644 --- a/Tests/RunCMake/PositionIndependentCode/PIE.cmake +++ b/Tests/RunCMake/PositionIndependentCode/PIE.cmake @@ -1,6 +1,9 @@ cmake_policy(SET CMP0083 NEW) +include(CheckPIESupported) +check_pie_supported() + add_executable (pie_on main.cpp) set_property(TARGET pie_on PROPERTY POSITION_INDEPENDENT_CODE ON) ----------------------------------------------------------------------- Summary of changes: Help/command/try_compile.rst | 5 + Help/manual/cmake-modules.7.rst | 1 + Help/module/CheckPIESupported.rst | 1 + Help/policy/CMP0083.rst | 38 ++++++ Help/prop_tgt/POSITION_INDEPENDENT_CODE.rst | 5 + Help/release/dev/link-option-PIE.rst | 7 +- Modules/CheckPIESupported.cmake | 134 +++++++++++++++++++++ Modules/Compiler/AppleClang-C.cmake | 3 - Modules/Compiler/AppleClang-CXX.cmake | 3 - Modules/Compiler/Clang.cmake | 20 +-- Modules/Compiler/GNU.cmake | 19 +-- Modules/Compiler/SunPro-C.cmake | 1 + Modules/Compiler/SunPro-CXX.cmake | 1 + Modules/Compiler/SunPro-Fortran.cmake | 1 + Modules/Internal/CMakeCheckCompilerFlag.cmake | 26 ++-- Modules/Platform/CYGWIN-GNU.cmake | 1 + Modules/Platform/Fuchsia.cmake | 1 + Modules/Platform/Linux-Intel.cmake | 2 + Modules/Platform/Linux-PGI.cmake | 1 + Modules/Platform/SINIX.cmake | 1 + Modules/Platform/UNIX_SV.cmake | 1 + Modules/Platform/UnixWare.cmake | 1 + Modules/Platform/Windows-GNU.cmake | 1 + Source/cmCoreTryCompile.cxx | 18 +++ Source/cmLocalGenerator.cxx | 10 +- .../RunCMake/PositionIndependentCode/CMP0083.cmake | 2 + .../CheckPIESupported.cmake | 10 +- Tests/RunCMake/PositionIndependentCode/PIE.cmake | 3 + 28 files changed, 267 insertions(+), 50 deletions(-) create mode 100644 Help/module/CheckPIESupported.rst create mode 100644 Modules/CheckPIESupported.cmake hooks/post-receive -- CMake _______________________________________________ Cmake-commits mailing list Cmake-commits@cmake.org https://cmake.org/mailman/listinfo/cmake-commits