PIE link options: Update strategy to fix performance regression

Fixes: #18700
This commit is contained in:
Marc Chevrier 2018-12-13 16:14:59 +01:00 committed by Craig Scott
parent 3bd8144601
commit f255280fd9
28 changed files with 267 additions and 50 deletions

View File

@ -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.

View File

@ -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

View File

@ -0,0 +1 @@
.. cmake-module:: ../../Modules/CheckPIESupported.cmake

View File

@ -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)

View File

@ -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.

View File

@ -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`.

View File

@ -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()

View File

@ -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")

View File

@ -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()

View File

@ -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=")

View File

@ -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=")

View File

@ -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")

View File

@ -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")

View File

@ -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")

View File

@ -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()

View File

@ -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 "")

View File

@ -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")

View File

@ -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()

View File

@ -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")

View File

@ -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")

View File

@ -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")

View File

@ -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")

View File

@ -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 "")

View File

@ -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

View File

@ -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()) {

View File

@ -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)

View File

@ -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")

View File

@ -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)