mirror of https://github.com/Kitware/CMake.git
Browse Source
RPATH: Add option for using $ORIGIN in build tree
RPATH: Add option for using $ORIGIN in build tree
This makes binaries independent of the build directory by not embedding the build directory via RPATH. The tests are partially based on the existing RuntimePath test, but with the check moved into a POST_BUILD command such that it can be skipped when the platform lacks support. Fixes: #18413pull/324/head

committed by
Brad King

12 changed files with 159 additions and 4 deletions
-
1Help/manual/cmake-properties.7.rst
-
1Help/manual/cmake-variables.7.rst
-
24Help/prop_tgt/BUILD_RPATH_USE_ORIGIN.rst
-
8Help/release/dev/relative-rpath.rst
-
7Help/variable/CMAKE_BUILD_RPATH_USE_ORIGIN.rst
-
1Modules/Platform/Linux.cmake
-
29Source/cmComputeLinkInformation.cxx
-
1Source/cmTarget.cxx
-
69Tests/RunCMake/RuntimePath/Relative.cmake
-
4Tests/RunCMake/RuntimePath/RelativeCheck.cmake
-
14Tests/RunCMake/RuntimePath/RunCMakeTest.cmake
-
4Tests/RunCMake/RuntimePath/main.c
@ -0,0 +1,24 @@ |
|||
BUILD_RPATH_USE_ORIGIN |
|||
---------------------- |
|||
|
|||
Whether to use relative paths for the build ``RPATH``. |
|||
|
|||
This property is initialized by the value of the variable |
|||
:variable:`CMAKE_BUILD_RPATH_USE_ORIGIN`. |
|||
|
|||
On platforms that support runtime paths (``RPATH``) with the |
|||
``$ORIGIN`` token, setting this property to ``TRUE`` enables relative |
|||
paths in the build ``RPATH`` for executables that point to shared |
|||
libraries in the same build tree. |
|||
|
|||
Normally the build ``RPATH`` of an executable contains absolute paths |
|||
to the directory of shared libraries. Directories contained within the |
|||
build tree can be made relative to enable relocatable builds and to |
|||
help achieving reproducible builds by omitting the build directory |
|||
from the build environment. |
|||
|
|||
This property has no effect on platforms that do not support the |
|||
``$ORIGIN`` token in ``RPATH``, or when the :variable:`CMAKE_SKIP_RPATH` |
|||
variable is set. The runtime path set through the |
|||
:prop_tgt:`BUILD_RPATH` target property is also unaffected by this |
|||
property. |
@ -0,0 +1,8 @@ |
|||
relative-rpath |
|||
-------------- |
|||
|
|||
* A :variable:`CMAKE_BUILD_RPATH_USE_ORIGIN` variable and corresponding |
|||
:prop_tgt:`BUILD_RPATH_USE_ORIGIN` target property were added to |
|||
enable use of relative runtime paths (RPATHs). This helps achieving |
|||
relocatable and reproducible builds that are invariant of the build |
|||
directory. |
@ -0,0 +1,7 @@ |
|||
CMAKE_BUILD_RPATH_USE_ORIGIN |
|||
---------------------------- |
|||
|
|||
Whether to use relative paths for the build ``RPATH``. |
|||
|
|||
This is used to initialize the :prop_tgt:`BUILD_RPATH_USE_ORIGIN` target |
|||
property for all targets, see that property for more details. |
@ -0,0 +1,69 @@ |
|||
enable_language(C) |
|||
|
|||
if(NOT CMAKE_SHARED_LIBRARY_RPATH_ORIGIN_TOKEN) |
|||
if(CMAKE_C_PLATFORM_ID STREQUAL "Linux") |
|||
# Sanity check for platform that is definitely known to support $ORIGIN. |
|||
message(FATAL_ERROR "Platform fails to report relative RPATH support") |
|||
else() |
|||
message(STATUS "Platform does not support relative RPATHs, skipping") |
|||
endif() |
|||
return() |
|||
endif() |
|||
set(CMAKE_BUILD_RPATH_USE_ORIGIN ON) |
|||
|
|||
function(CheckRpath target rpath) |
|||
add_custom_command( |
|||
TARGET ${target} |
|||
POST_BUILD |
|||
COMMAND ${CMAKE_COMMAND} -Dfile=$<TARGET_FILE:${target}> -Drpath=${rpath} |
|||
-P "${CMAKE_CURRENT_SOURCE_DIR}/RelativeCheck.cmake" |
|||
VERBATIM |
|||
) |
|||
endfunction() |
|||
|
|||
if(CMAKE_C_COMPILER_ID STREQUAL "XL" AND CMAKE_BINARY_DIR MATCHES " ") |
|||
# XL 16.1.0.0 fails building the library if the output path contains a space. |
|||
set(externDir) |
|||
message(STATUS "Skipping external library test because of a toolchain bug") |
|||
else() |
|||
get_filename_component(externDir "${CMAKE_BINARY_DIR}" DIRECTORY) |
|||
set(externDir "${externDir}/Relative-extern") |
|||
endif() |
|||
|
|||
add_library(utils SHARED A.c) |
|||
add_library(utils-sub SHARED A.c) |
|||
set_property(TARGET utils-sub PROPERTY LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/libs) |
|||
if(externDir) |
|||
add_library(utils-extern SHARED A.c) |
|||
set_property(TARGET utils-extern PROPERTY LIBRARY_OUTPUT_DIRECTORY ${externDir}) |
|||
endif() |
|||
|
|||
add_executable(main main.c) |
|||
target_link_libraries(main utils) |
|||
CheckRpath(main "\$ORIGIN") |
|||
|
|||
add_executable(main-norel main.c) |
|||
target_link_libraries(main-norel utils) |
|||
set_property(TARGET main-norel PROPERTY BUILD_RPATH_USE_ORIGIN OFF) |
|||
CheckRpath(main-norel "${CMAKE_CURRENT_BINARY_DIR}") |
|||
|
|||
add_executable(mainsub main.c) |
|||
target_link_libraries(mainsub utils) |
|||
set_property(TARGET mainsub PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin) |
|||
CheckRpath(mainsub "\$ORIGIN/../") |
|||
|
|||
add_executable(main-sub main.c) |
|||
target_link_libraries(main-sub utils-sub) |
|||
CheckRpath(main-sub "\$ORIGIN/libs") |
|||
|
|||
add_executable(mainsub-sub main.c) |
|||
target_link_libraries(mainsub-sub utils-sub) |
|||
set_property(TARGET mainsub-sub PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin) |
|||
CheckRpath(mainsub-sub "\$ORIGIN/../libs") |
|||
|
|||
if(externDir) |
|||
# Binaries linking to libraries outside the build tree should have an absolute RPATH. |
|||
add_executable(main-extern main.c) |
|||
target_link_libraries(main-extern utils-extern) |
|||
CheckRpath(main-extern "${externDir}") |
|||
endif() |
@ -0,0 +1,4 @@ |
|||
file(RPATH_CHECK FILE "${file}" RPATH "${rpath}") |
|||
if(NOT EXISTS "${file}") |
|||
message(FATAL_ERROR "RPATH for ${file} did not contain the expected value") |
|||
endif() |
@ -1,4 +1,6 @@ |
|||
extern int libA(void); |
|||
|
|||
int main(void) |
|||
{ |
|||
return 0; |
|||
return libA(); |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue