diff --git a/Help/prop_tgt/POSITION_INDEPENDENT_CODE.rst b/Help/prop_tgt/POSITION_INDEPENDENT_CODE.rst index 2ba1e6f816..85e4cf66cb 100644 --- a/Help/prop_tgt/POSITION_INDEPENDENT_CODE.rst +++ b/Help/prop_tgt/POSITION_INDEPENDENT_CODE.rst @@ -1,10 +1,11 @@ POSITION_INDEPENDENT_CODE ------------------------- -Whether to create a position-independent target +A target property that specifies whether to create a target that has +position-independent code enabled. -The ``POSITION_INDEPENDENT_CODE`` property determines whether position -independent executables or libraries will be created. This +The ``POSITION_INDEPENDENT_CODE`` target property determines whether +position-independent executables or libraries will be created. This property is ``True`` by default for ``SHARED`` and ``MODULE`` library targets. For other targets, this property is initialized by the value of the :variable:`CMAKE_POSITION_INDEPENDENT_CODE` variable if it is set @@ -14,3 +15,57 @@ when the target is created, or ``False`` otherwise. For executable targets, the link step is controlled by the :policy:`CMP0083` policy and the :module:`CheckPIESupported` module. + +Position-independent code (PIC) refers to machine code that executes +properly regardless of its absolute memory address. This is particularly +important for shared libraries, which are often loaded at different memory +addresses by different programs. Generating position-independent code +ensures that these libraries can be safely and efficiently shared among +multiple processes without causing address conflicts. On some platforms +(notably UNIX-like systems), generating PIC is also a requirement for +creating shared libraries. + +Use of position-independent code is recommended or required in the following +cases: + +* When building shared or module libraries (e.g., with + ``add_library(... SHARED)``, or ``add_library(... MODULE)``), where PIC + allows dynamic relocation at runtime. + +* When building executables as position-independent executables (PIE), which + can enhance security by enabling Address Space Layout Randomization (ASLR). + +* On platforms or toolchains that require PIC for certain types of linking + or sandboxed environments. + +Enabling PIC can result in slightly larger or slower code on some +architectures, but this is often outweighed by the benefits of flexibility +and security. + +Examples +^^^^^^^^ + +Enabling PIC for a static library target: + +.. code-block:: cmake + + add_library(foo STATIC foo.c) + set_target_properties(foo PROPERTIES POSITION_INDEPENDENT_CODE TRUE) + +Enabling PIC for an executable target: + +.. code-block:: cmake + + add_executable(app app.c) + + set_target_properties(app PROPERTIES POSITION_INDEPENDENT_CODE TRUE) + + # Additionally, pass PIE-related link-time options to executable(s). + include(CheckPIESupported) + check_pie_supported() + +See Also +^^^^^^^^ + +* The :module:`CheckPIESupported` module to pass PIE-related options to the + linker for executables. diff --git a/Help/variable/CMAKE_POSITION_INDEPENDENT_CODE.rst b/Help/variable/CMAKE_POSITION_INDEPENDENT_CODE.rst index f83246a80a..19f5e57ca1 100644 --- a/Help/variable/CMAKE_POSITION_INDEPENDENT_CODE.rst +++ b/Help/variable/CMAKE_POSITION_INDEPENDENT_CODE.rst @@ -1,9 +1,19 @@ CMAKE_POSITION_INDEPENDENT_CODE ------------------------------- -Default value for :prop_tgt:`POSITION_INDEPENDENT_CODE` of targets. +Default value for the :prop_tgt:`POSITION_INDEPENDENT_CODE` target property. This variable is used to initialize the :prop_tgt:`POSITION_INDEPENDENT_CODE` property on targets that are not ``SHARED`` or ``MODULE`` library targets. If set, its value is also used by the :command:`try_compile` command. + +The ``SHARED`` and ``MODULE`` library targets have by default position +independent code enabled regardless of this variable. To disable PIC on +these library types, only manually setting the target property disables it. + +See Also +^^^^^^^^ + +* The :module:`CheckPIESupported` module to pass PIE-related options to the + linker for executables. diff --git a/Modules/CheckPIESupported.cmake b/Modules/CheckPIESupported.cmake index 592612cbd5..b4d47f918b 100644 --- a/Modules/CheckPIESupported.cmake +++ b/Modules/CheckPIESupported.cmake @@ -7,23 +7,36 @@ CheckPIESupported .. versionadded:: 3.14 -This module provides the ``check_pie_supported()`` function to check whether the -linker supports Position Independent Code (PIE) or No Position Independent Code -(NO_PIE) for executables. +This module provides a command to check whether the linker supports Position +Independent Code (PIE) or No Position Independent Code (NO_PIE) for +executables. + +Load this module in a CMake project with: + +.. code-block:: cmake + + include(CheckPIESupported) When setting the :prop_tgt:`POSITION_INDEPENDENT_CODE` target property, PIC-related compile and link options are added when building library objects, and PIE-related compile options are added when building objects of executable targets, regardless of this module. Use this module to ensure that the -``POSITION_INDEPENDENT_CODE`` target property for executables is also honored at -link time. +``POSITION_INDEPENDENT_CODE`` target property for executables is also honored +at link time. + +Commands +^^^^^^^^ + +This module provides the following command: .. command:: check_pie_supported + Checks for PIE/NO_PIE support and prepares all executables to have link + time PIE options enabled: + .. code-block:: cmake - check_pie_supported([OUTPUT_VARIABLE ] - [LANGUAGES ...]) + check_pie_supported([OUTPUT_VARIABLE ] [LANGUAGES ...]) Options are: @@ -32,7 +45,7 @@ link time. bypassed because it uses cached results from a previous call, the output will be empty even if errors were present in the previous call. - ``LANGUAGES ...`` + ``LANGUAGES ...`` Check the linkers used for each of the specified languages. If this option is not provided, the command checks all enabled languages. @@ -50,13 +63,13 @@ link time. Variables ^^^^^^^^^ -For each language checked, the ``check_pie_supported()`` function defines two +For each language checked, the ``check_pie_supported()`` command defines two boolean cache variables: - ``CMAKE__LINK_PIE_SUPPORTED`` - Set to true if ``PIE`` is supported by the linker and false otherwise. - ``CMAKE__LINK_NO_PIE_SUPPORTED`` - Set to true if ``NO_PIE`` is supported by the linker and false otherwise. +``CMAKE__LINK_PIE_SUPPORTED`` + Set to true if ``PIE`` is supported by the linker and false otherwise. +``CMAKE__LINK_NO_PIE_SUPPORTED`` + Set to true if ``NO_PIE`` is supported by the linker and false otherwise. Examples ^^^^^^^^ @@ -82,11 +95,17 @@ Since not all linkers require or support PIE-related link options (for example, add_executable(foo ...) + message(CHECK_START "Checking for C linker PIE support") + include(CheckPIESupported) 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:\n${output}" + + if(CMAKE_C_LINK_PIE_SUPPORTED) + message(CHECK_PASS "yes") + else() + message(CHECK_FAIL "no") + message(VERBOSE "PIE is not supported at link time:\n${output}" "PIE link options will not be passed to linker.") endif() @@ -98,7 +117,6 @@ link options, which might not be sufficient in certain cases: add_executable(foo ...) set_property(TARGET foo PROPERTY POSITION_INDEPENDENT_CODE TRUE) - #]=======================================================================]