Commit ddb967cc authored by Craig Scott's avatar Craig Scott Committed by Kitware Robot
Browse files

Merge topic 'pie-link-options'

c4b4d8b3 POSITION_INDEPENDENT_CODE: Manage link flags for executables
724a0346 POSITION_INDEPENDENT_CODE: Fix erroneous '-fPIE' flag for Sun Studio
023188ff

 INTERFACE_POSITION_INDEPENDENT_CODE: add generator expressions support
Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Merge-request: !2465
parents c310480c c4b4d8b3
Pipeline #123682 failed with stage
in 0 seconds
......@@ -57,6 +57,7 @@ Policies Introduced by CMake 3.14
.. toctree::
:maxdepth: 1
CMP0083: Add PIE options when linking executable. </policy/CMP0083>
CMP0082: Install rules from add_subdirectory() are interleaved with those in caller. </policy/CMP0082>
Policies Introduced by CMake 3.13
......
CMP0083
-------
To control generation of Position Independent Executable (``PIE``) or not, some
flags are required at link time.
CMake 3.13 and lower did not add these link flags when
:prop_tgt:`POSITION_INDEPENDENT_CODE` is set.
The ``OLD`` behavior for this policy is to not manage ``PIE`` link flags. The
``NEW`` behavior is to add link flags if :prop_tgt:`POSITION_INDEPENDENT_CODE`
is set:
* Set to ``TRUE``: flags to produce a position independent executable are
passed to the linker step. For example ``-pie`` for ``GCC``.
* Set to ``FALSE``: flags not to produce a position independent executable are
passed to the linker step. For example ``-no-pie`` for ``GCC``.
* Not set: no flags are passed to the linker step.
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
......@@ -14,3 +14,9 @@ undefined, then consumers will determine their
:prop_tgt:`POSITION_INDEPENDENT_CODE` property by other means. Consumers
must ensure that the targets that they link to have a consistent
requirement for their ``INTERFACE_POSITION_INDEPENDENT_CODE`` property.
Contents of ``INTERFACE_POSITION_INDEPENDENT_CODE`` may use
"generator expressions" with the syntax ``$<...>``. See the
:manual:`cmake-generator-expressions(7)` manual for available expressions.
See the :manual:`cmake-buildsystem(7)` manual for more on defining buildsystem
properties.
INTERFACE_POSITION_INDEPENDENT_CODE
-----------------------------------
* :prop_tgt:`INTERFACE_POSITION_INDEPENDENT_CODE` target property gains the
support of :manual:`generator expressions <cmake-generator-expressions(7)>`.
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`.
......@@ -105,6 +105,12 @@ endif()
if(NOT CMAKE_CXX_COMPILE_OPTIONS_PIE)
set(CMAKE_CXX_COMPILE_OPTIONS_PIE ${CMAKE_C_COMPILE_OPTIONS_PIE})
endif()
if(NOT CMAKE_CXX_LINK_OPTIONS_PIE)
set(CMAKE_CXX_LINK_OPTIONS_PIE ${CMAKE_C_LINK_OPTIONS_PIE})
endif()
if(NOT CMAKE_CXX_LINK_OPTIONS_NO_PIE)
set(CMAKE_CXX_LINK_OPTIONS_NO_PIE ${CMAKE_C_LINK_OPTIONS_NO_PIE})
endif()
if(NOT CMAKE_CXX_COMPILE_OPTIONS_DLL)
set(CMAKE_CXX_COMPILE_OPTIONS_DLL ${CMAKE_C_COMPILE_OPTIONS_DLL})
......@@ -269,4 +275,3 @@ CMAKE_VERBOSE_MAKEFILE
)
set(CMAKE_CXX_INFORMATION_LOADED 1)
......@@ -74,6 +74,12 @@ endif()
if(NOT CMAKE_Fortran_COMPILE_OPTIONS_PIE)
set(CMAKE_Fortran_COMPILE_OPTIONS_PIE ${CMAKE_C_COMPILE_OPTIONS_PIE})
endif()
if(NOT CMAKE_Fortran_LINK_OPTIONS_PIE)
set(CMAKE_Fortran_LINK_OPTIONS_PIE ${CMAKE_C_LINK_OPTIONS_PIE})
endif()
if(NOT CMAKE_Fortran_LINK_OPTIONS_NO_PIE)
set(CMAKE_Fortran_LINK_OPTIONS_NO_PIE ${CMAKE_C_LINK_OPTIONS_NO_PIE})
endif()
if(NOT CMAKE_Fortran_COMPILE_OPTIONS_DLL)
set(CMAKE_Fortran_COMPILE_OPTIONS_DLL ${CMAKE_C_COMPILE_OPTIONS_DLL})
......
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")
......
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()
......
......@@ -21,6 +21,26 @@ else()
macro(__compiler_clang lang)
__compiler_gnu(${lang})
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()
endif()
set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ")
set(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY "-fvisibility=")
if(CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 3.4.0)
......
......@@ -9,6 +9,7 @@ endif()
set(__COMPILER_GNU 1)
include(Compiler/CMakeCommonCompilerMacros)
include(Internal/CMakeCheckCompilerFlag)
macro(__compiler_gnu lang)
# Feature flags.
......@@ -16,6 +17,21 @@ macro(__compiler_gnu lang)
set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-fPIC")
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()
endif()
if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 4.0)
set(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY "-fvisibility=")
......
......@@ -6,6 +6,9 @@ include(Compiler/SunPro)
set(CMAKE_C_VERBOSE_FLAG "-#")
set(CMAKE_C_COMPILE_OPTIONS_PIC -KPIC)
set(CMAKE_C_COMPILE_OPTIONS_PIE "")
set(CMAKE_C_LINK_OPTIONS_PIE "")
set(CMAKE_C_LINK_OPTIONS_NO_PIE "")
set(CMAKE_SHARED_LIBRARY_C_FLAGS "-KPIC")
set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-G")
set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-R")
......
......@@ -6,6 +6,9 @@ include(Compiler/SunPro)
set(CMAKE_CXX_VERBOSE_FLAG "-v")
set(CMAKE_CXX_COMPILE_OPTIONS_PIC -KPIC)
set(CMAKE_CXX_COMPILE_OPTIONS_PIE "")
set(CMAKE_CXX_LINK_OPTIONS_PIE "")
set(CMAKE_CXX_LINK_OPTIONS_NO_PIE "")
set(CMAKE_SHARED_LIBRARY_CXX_FLAGS "-KPIC")
set(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "-G")
set(CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG "-R")
......
......@@ -3,6 +3,9 @@ set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-fixed")
set(CMAKE_Fortran_FORMAT_FREE_FLAG "-free")
set(CMAKE_Fortran_COMPILE_OPTIONS_PIC "-KPIC")
set(CMAKE_Fortran_COMPILE_OPTIONS_PIE "")
set(CMAKE_Fortran_LINK_OPTIONS_PIE "")
set(CMAKE_Fortran_LINK_OPTIONS_NO_PIE "")
set(CMAKE_SHARED_LIBRARY_Fortran_FLAGS "-KPIC")
set(CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS "-G")
set(CMAKE_SHARED_LIBRARY_RUNTIME_Fortran_FLAG "-R")
......
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#[=[
NOTE: This function is used internally by CMake. Projects should not include
this file directly.
The cmake_check_compiler_flag() function can be used to compile and link a
source file to check whether a specific compiler or linker flag is supported.
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.
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.
Optional parameters:
SRC_EXT - Overrides the extension of the source file used for the
check. Defaults are 'c' (C), 'cxx' (CXX), 'F' (Fortran).
COMMAND_PATTERN - Pattern to be used for the command line. The default is
'<FLAG> -o <OUTPUT> <SOURCE>'
FAIL_REGEX - List of additional regular expressions that, if matched by
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.
#]=]
include_guard(GLOBAL)
include(CMakeCheckCompilerFlagCommonPatterns)
function(CMAKE_CHECK_COMPILER_FLAG lang flag result)
# Cache results between runs similar to check_<lang>_source_compiles()
if(DEFINED ${result})
return()
endif()
set(comment "Is the '${flag}' option(s) supported")
string(REPLACE ";" " " comment "${comment}")
if (NOT lang MATCHES "^(C|CXX|Fortran|ASM)$")
# other possible languages are not supported
# log message to keep trace of this problem...
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Function 'CMAKE_CHECK_COMPILER_FLAG' called with unsupported language: ${lang}\n")
set(${result} FALSE CACHE INTERNAL ${comment})
return()
endif()
if (lang STREQUAL "ASM")
# assume ASM compiler is a multi-language compiler, so supports C language as well
set(check_lang C)
else()
set(check_lang ${lang})
endif()
cmake_parse_arguments(CCCF "" "SRC_EXT;COMMAND_PATTERN" "FAIL_REGEX" ${ARGN})
if (NOT CCCF_COMMAND_PATTERN)
set (CCCF_COMMAND_PATTERN "<FLAG> -o <OUTPUT> <SOURCE>")
endif()
list (APPEND CCCF_FAIL_REGEX "argument unused during compilation") # clang
if (check_lang STREQUAL "C")
list(APPEND CCCF_FAIL_REGEX
"command line option .* is valid for .* but not for C") # GNU
elseif(check_lang STREQUAL "CXX")
list(APPEND CCCF_FAIL_REGEX
"command line option .* is valid for .* but not for C\\+\\+") # GNU
elseif(check_lang STREQUAL "Fortran")
list(APPEND CCCF_FAIL_REGEX
"command line option .* is valid for .* but not for Fortran") # GNU
endif()
# Add patterns for common errors
check_compiler_flag_common_patterns(COMPILER_FLAG_COMMON_PATTERNS)
foreach(arg IN LISTS COMPILER_FLAG_COMMON_PATTERNS)
if(arg MATCHES "^FAIL_REGEX$")
continue()
endif()
list(APPEND CCCF_FAIL_REGEX "${arg}")
endforeach()
if(NOT CCCF_SRC_EXT)
if (check_lang STREQUAL "C")
set(CCCF_SRC_EXT c)
elseif(check_lang STREQUAL "CXX")
set(CCCF_SRC_EXT cxx)
elseif(check_lang STREQUAL "Fortran")
set(CCCF_SRC_EXT F)
endif()
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.
set(COMPILER_FLAG_SRC
"${COMPILER_FLAG_DIR}/CompilerFlag${lang}.${CCCF_SRC_EXT}")
if(check_lang STREQUAL "Fortran")
file(WRITE "${COMPILER_FLAG_SRC}"
" program simple\n end program simple\n")
else()
file(WRITE "${COMPILER_FLAG_SRC}" "int main (void)\n{ return 0; }\n")
endif()
get_filename_component(COMPILER_FLAG_EXE "${COMPILER_FLAG_SRC}" NAME_WE)
string(APPEND COMPILER_FLAG_EXE "${CMAKE_EXECUTABLE_SUFFIX}")
# Build command line
separate_arguments(CCCF_COMMAND_PATTERN UNIX_COMMAND
"${CCCF_COMMAND_PATTERN}")
list(TRANSFORM CCCF_COMMAND_PATTERN REPLACE "<SOURCE>" "${COMPILER_FLAG_SRC}")
list(TRANSFORM CCCF_COMMAND_PATTERN REPLACE "<OUTPUT>" "${COMPILER_FLAG_EXE}")
list(TRANSFORM CCCF_COMMAND_PATTERN REPLACE "<FLAG>" "${flag}")
execute_process(
COMMAND "${CMAKE_COMMAND}" -E env LC_ALL=C LC_MESSAGES=C LANG=C
"${CMAKE_${lang}_COMPILER}" ${CCCF_COMMAND_PATTERN}
WORKING_DIRECTORY "${COMPILER_FLAG_DIR}"
OUTPUT_VARIABLE COMPILER_FLAG_OUTPUT
ERROR_VARIABLE COMPILER_FLAG_OUTPUT
RESULT_VARIABLE COMPILER_FLAG_RESULT)
# Record result in the cache so we can avoid re-testing every CMake run
if (COMPILER_FLAG_RESULT)
set(${result} FALSE CACHE INTERNAL ${comment})
else()
foreach(regex IN LISTS CCCF_FAIL_REGEX)
if(COMPILER_FLAG_OUTPUT MATCHES "${regex}")
set(${result} FALSE CACHE INTERNAL ${comment})
endif()
endforeach()
endif()
if (DEFINED ${result})
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the ${flag} option "
"is supported for ${lang} language failed with the following output:\n"
"${COMPILER_FLAG_OUTPUT}\n")
return()
endif()
set(${result} TRUE CACHE INTERNAL ${comment})
endfunction()
......@@ -12,10 +12,6 @@ if(NOT DEFINED CMAKE_POSITION_INDEPENDENT_CODE
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
endif()
if(CMAKE_POSITION_INDEPENDENT_CODE)
string(APPEND _ANDROID_ABI_INIT_EXE_LDFLAGS " -fPIE -pie")
endif()
string(APPEND _ANDROID_ABI_INIT_EXE_LDFLAGS " -Wl,--gc-sections")
if(NOT _ANDROID_ABI_INIT_EXE_LDFLAGS_NO_nocopyreloc)
......
......@@ -27,6 +27,8 @@ macro(__cygwin_compiler_gnu lang)
# No -fPIC on cygwin
set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "")
set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "")
set(CMAKE_${lang}_LINK_OPTIONS_PIE "")
set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "")
set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "")
# Initialize C link type selection flags. These flags are used when
......
set(CMAKE_DL_LIBS "")
set(CMAKE_C_COMPILE_OPTIONS_PIC "-fPIC")
set(CMAKE_C_COMPILE_OPTIONS_PIE "-fPIE")
# PIE link options are managed in Compiler/<compiler>.cmake file
set(CMAKE_SHARED_LIBRARY_C_FLAGS "-fPIC") # -pic
set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-shared") # -shared
set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") # +s, flag for exe link to use shared lib
......
......@@ -3,6 +3,8 @@ set(FUCHSIA 1)
set(CMAKE_DL_LIBS "")
set(CMAKE_C_COMPILE_OPTIONS_PIC "-fPIC")
set(CMAKE_C_COMPILE_OPTIONS_PIE "-fPIE")
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")
set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-shared")
set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,-rpath,")
......
......@@ -23,6 +23,10 @@ endif()
macro(__linux_compiler_intel lang)
set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-fPIC")
set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE")
if (NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 13.0)
set(CMAKE_${lang}_LINK_OPTIONS_PIE ${CMAKE_${lang}_COMPILE_OPTIONS_PIE} "-pie")
set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "-no-pie")
endif()
set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "-fPIC")
set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-shared")
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment