1- #.rst:
2- # AddInstallRPATHSupport
3- # ----------------------
4- #
5- # Add support to RPATH during installation to your project::
6- #
7- # add_install_rpath_support([BIN_DIRS dir [dir]]
8- # [LIB_DIRS dir [dir]]
9- # [INSTALL_NAME_DIR [dir]]
10- # [DEPENDS condition [condition]]
11- # [USE_LINK_PATH])
12- #
13- # Normally (depending on the platform) when you install a shared
14- # library you can either specify its absolute path as the install name,
15- # or leave just the library name itself. In the former case the library
16- # will be correctly linked during run time by all executables and other
17- # shared libraries, but it must not change its install location. This
18- # is often the case for libraries installed in the system default
19- # library directory (e.g. ``/usr/lib``).
20- # In the latter case, instead, the library can be moved anywhere in the
21- # file system but at run time the dynamic linker must be able to find
22- # it. This is often accomplished by setting environmental variables
23- # (i.e. ``LD_LIBRARY_PATH`` on Linux).
24- # This procedure is usually not desirable for two main reasons:
25- #
26- # - by setting the variable you are changing the default behaviour
27- # of the dynamic linker thus potentially breaking executables (not as
28- # destructive as ``LD_PRELOAD``)
29- # - the variable will be used only by applications spawned by the shell
30- # and not by other processes.
31- #
32- # RPATH is aimed to solve the issues introduced by the second
33- # installation method. Using run-path dependent libraries you can
34- # create a directory structure containing executables and dependent
35- # libraries that users can relocate without breaking it.
36- # A run-path dependent library is a dependent library whose complete
37- # install name is not known when the library is created.
38- # Instead, the library specifies that the dynamic loader must resolve
39- # the library’s install name when it loads the executable that depends
40- # on the library. The executable or the other shared library will
41- # hardcode in the binary itself the additional search directories
42- # to be passed to the dynamic linker. This works great in conjunction
43- # with relative paths.
44- # This command will enable support to RPATH to your project.
45- # It will enable the following things:
46- #
47- # - If the project builds shared libraries it will generate a run-path
48- # enabled shared library, i.e. its install name will be resolved
49- # only at run time.
50- # - In all cases (building executables and/or shared libraries)
51- # dependent shared libraries with RPATH support will be properly
52- #
53- # The command has the following parameters:
54- #
55- # Options:
56- # - ``USE_LINK_PATH``: if passed the command will automatically adds to
57- # the RPATH the path to all the dependent libraries.
58- #
59- # Arguments:
60- # - ``BIN_DIRS`` list of directories when the targets (executable and
61- # plugins) will be installed.
62- # - ``LIB_DIRS`` list of directories to be added to the RPATH. These
63- # directories will be added "relative" w.r.t. the ``BIN_DIRS`` and
64- # ``LIB_DIRS``.
65- # - ``INSTALL_NAME_DIR`` directory where the libraries will be installed.
66- # This variable will be used only if ``CMAKE_SKIP_RPATH`` or
67- # ``CMAKE_SKIP_INSTALL_RPATH`` is set to ``TRUE`` as it will set the
68- # ``INSTALL_NAME_DIR`` on all targets
69- # - ``DEPENDS`` list of conditions that should be ``TRUE`` to enable
70- # RPATH, for example ``FOO; NOT BAR``.
71- #
72- # Note: see https://gitlab.kitware.com/cmake/cmake/issues/16589 for further
73- # details.
74-
75- #=======================================================================
76- # Copyright 2014 Istituto Italiano di Tecnologia (IIT)
77- # @author Francesco Romano <[email protected] > 78- #
79- # Distributed under the OSI-approved BSD License (the "License");
80- # see accompanying file Copyright.txt for details.
81- #
82- # This software is distributed WITHOUT ANY WARRANTY; without even the
83- # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
84- # See the License for more information.
85- #=======================================================================
86- # (To distribute this file outside of CMake, substitute the full
87- # License text for the above reference.)
88-
1+ # SPDX-FileCopyrightText: 2012-2021 Istituto Italiano di Tecnologia (IIT)
2+ # SPDX-License-Identifier: BSD-3-Clause
3+
4+ #[=======================================================================[.rst:
5+ AddInstallRPATHSupport
6+ ----------------------
7+
8+ Add support to RPATH during installation to the project and the targets
9+
10+ .. command:: add_install_rpath_support
11+
12+ Add support to RPATH during installation to the project::
13+
14+ .. code-block:: cmake
15+ add_install_rpath_support([BIN_DIRS dir [dir]]
16+ [LIB_DIRS dir [dir]]
17+ [INSTALL_NAME_DIR [dir]]
18+ [DEPENDS condition [condition]]
19+ [USE_LINK_PATH])
20+
21+ Normally (depending on the platform) when you install a shared
22+ library you can either specify its absolute path as the install name,
23+ or leave just the library name itself. In the former case the library
24+ will be correctly linked during run time by all executables and other
25+ shared libraries, but it must not change its install location. This
26+ is often the case for libraries installed in the system default
27+ library directory (e.g. ``/usr/lib``).
28+ In the latter case, instead, the library can be moved anywhere in the
29+ file system but at run time the dynamic linker must be able to find
30+ it. This is often accomplished by setting environmental variables
31+ (i.e. ``LD_LIBRARY_PATH`` on Linux).
32+ This procedure is usually not desirable for two main reasons:
33+
34+ - by setting the variable you are changing the default behaviour
35+ of the dynamic linker thus potentially breaking executables (not as
36+ destructive as ``LD_PRELOAD``)
37+ - the variable will be used only by applications spawned by the shell
38+ and not by other processes.
39+
40+ RPATH aims in solving the issues introduced by the second
41+ installation method. Using run-path dependent libraries you can
42+ create a directory structure containing executables and dependent
43+ libraries that users can relocate without breaking it.
44+ A run-path dependent library is a dependent library whose complete
45+ install name is not known when the library is created.
46+ Instead, the library specifies that the dynamic loader must resolve
47+ the library’s install name when it loads the executable that depends
48+ on the library. The executable or the other shared library will
49+ hardcode in the binary itself the additional search directories
50+ to be passed to the dynamic linker. This works great in conjunction
51+ with relative paths.
52+ This command will enable support to RPATH to your project.
53+ It will enable the following things:
54+
55+ - If the project builds shared libraries it will generate a run-path
56+ enabled shared library, i.e. its install name will be resolved
57+ only at run time.
58+ - In all cases (building executables and/or shared libraries)
59+ dependent shared libraries with RPATH support will have their name
60+ resolved only at run time, by embedding the search path directly
61+ into the built binary.
62+
63+ The command has the following parameters:
64+
65+ Options:
66+ - ``USE_LINK_PATH``: if passed the command will automatically adds to
67+ the RPATH the path to all the dependent libraries.
68+
69+ Arguments:
70+ - ``BIN_DIRS`` list of directories when the targets (executable and
71+ plugins) will be installed.
72+ - ``LIB_DIRS`` list of directories to be added to the RPATH. These
73+ directories will be added "relative" w.r.t. the ``BIN_DIRS`` and
74+ ``LIB_DIRS``.
75+ - ``INSTALL_NAME_DIR`` directory where the libraries will be installed.
76+ This variable will be used only if ``CMAKE_SKIP_RPATH`` or
77+ ``CMAKE_SKIP_INSTALL_RPATH`` is set to ``TRUE`` as it will set the
78+ ``INSTALL_NAME_DIR`` on all targets
79+ - ``DEPENDS`` list of conditions that should be ``TRUE`` to enable
80+ RPATH, for example ``FOO; NOT BAR``.
81+
82+ Note: see https://gitlab.kitware.com/cmake/cmake/issues/16589 for further
83+ details.
84+
85+ .. command:: target_append_install_rpath
86+
87+ Add extra paths to RPATH for a specific target::
88+
89+ .. code-block:: cmake
90+
91+ target_append_install_rpath(<target>
92+ <INSTALL_DESTINATION destination>
93+ [LIB_DIRS dir [dir]]
94+ [DEPENDS condition [condition]])
95+
96+ Arguments:
97+ - ``INSTALL_DESTINATION`` path where the target will be installed.
98+ - ``LIB_DIRS`` list of directories to be added to the RPATH. These
99+ directories will be added "relative" w.r.t. the ``INSTALL_DESTINATION``.
100+ - ``DEPENDS`` list of conditions that should be ``TRUE`` to enable
101+ RPATH, for example ``FOO; NOT BAR``.
102+ #]=======================================================================]
89103
90104include (CMakeParseArguments)
91105
92106
107+ macro (__AddInstallRPATHSupport_GET_SYSTEM_LIB_DIRS _var)
108+ # Find system implicit lib directories
109+ set (${_var} ${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES} )
110+ if (EXISTS "/etc/debian_version" ) # is this a debian system ?
111+ if (CMAKE_LIBRARY_ARCHITECTURE )
112+ list (APPEND ${_var} "/lib/${CMAKE_LIBRARY_ARCHITECTURE} "
113+ "/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE} " )
114+ endif ()
115+ endif ()
116+ endmacro ()
117+
118+
119+ macro (__AddInstallRPATHSupport_APPEND_RELATIVE_RPATH _var _bin_dir _lib_dir)
120+ file (RELATIVE_PATH _rel_path ${_bin_dir} ${_lib_dir} )
121+ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin" )
122+ list (APPEND ${_var} "@loader_path/${_rel_path} " )
123+ else ()
124+ list (APPEND ${_var} "\$ ORIGIN/${_rel_path} " )
125+ endif ()
126+ endmacro ()
127+
128+
129+
93130function (ADD_INSTALL_RPATH_SUPPORT)
94131
95132 set (_options USE_LINK_PATH)
@@ -131,25 +168,14 @@ function(ADD_INSTALL_RPATH_SUPPORT)
131168 # Enable RPATH on OSX.
132169 set (CMAKE_MACOSX_RPATH TRUE PARENT_SCOPE)
133170
134- # Find system implicit lib directories
135- set (_system_lib_dirs ${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES} )
136- if (EXISTS "/etc/debian_version" ) # is this a debian system ?
137- if (CMAKE_LIBRARY_ARCHITECTURE )
138- list (APPEND _system_lib_dirs "/lib/${CMAKE_LIBRARY_ARCHITECTURE} "
139- "/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE} " )
140- endif ()
141- endif ()
171+ __AddInstallRPATHSupport_get_system_lib_dirs(_system_lib_dirs)
172+
142173 # This is relative RPATH for libraries built in the same project
143174 foreach (lib_dir ${_ARS_LIB_DIRS} )
144175 list (FIND _system_lib_dirs "${lib_dir} " isSystemDir)
145176 if ("${isSystemDir} " STREQUAL "-1" )
146177 foreach (bin_dir ${_ARS_LIB_DIRS} ${_ARS_BIN_DIRS} )
147- file (RELATIVE_PATH _rel_path ${bin_dir} ${lib_dir} )
148- if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin" )
149- list (APPEND CMAKE_INSTALL_RPATH "@loader_path/${_rel_path} " )
150- else ()
151- list (APPEND CMAKE_INSTALL_RPATH "\$ ORIGIN/${_rel_path} " )
152- endif ()
178+ __AddInstallRPATHSupport_append_relative_rpath(CMAKE_INSTALL_RPATH ${bin_dir} ${lib_dir} )
153179 endforeach ()
154180 endif ()
155181 endforeach ()
@@ -165,3 +191,45 @@ function(ADD_INSTALL_RPATH_SUPPORT)
165191 endif ()
166192
167193endfunction ()
194+
195+
196+ function (TARGET_APPEND_INSTALL_RPATH _target)
197+ set (_options )
198+ set (_oneValueArgs INSTALL_DESTINATION)
199+ set (_multiValueArgs LIB_DIRS
200+ DEPENDS )
201+
202+ if (CMAKE_SKIP_RPATH OR (CMAKE_SKIP_INSTALL_RPATH AND CMAKE_SKIP_BUILD_RPATH ))
203+ return ()
204+ endif ()
205+
206+ cmake_parse_arguments (_ARS "${_options} "
207+ "${_oneValueArgs} "
208+ "${_multiValueArgs} "
209+ "${ARGN} " )
210+
211+ set (_rpath_available 1)
212+ if (DEFINED _ARS_DEPENDS)
213+ foreach (_dep ${_ARS_DEPENDS} )
214+ string (REGEX REPLACE " +" ";" _dep "${_dep} " )
215+ if (NOT (${_dep} ))
216+ set (_rpath_available 0)
217+ endif ()
218+ endforeach ()
219+ endif ()
220+
221+ if (_rpath_available)
222+
223+ __AddInstallRPATHSupport_get_system_lib_dirs(_system_lib_dirs)
224+
225+ get_target_property (_current_rpath ${_target} INSTALL_RPATH )
226+ foreach (lib_dir ${_ARS_LIB_DIRS} )
227+ list (FIND _system_lib_dirs "${lib_dir} " isSystemDir)
228+ if ("${isSystemDir} " STREQUAL "-1" )
229+ __AddInstallRPATHSupport_append_relative_rpath(_current_rpath ${_ARS_INSTALL_DESTINATION} ${lib_dir} )
230+ endif ()
231+ endforeach ()
232+ set_target_properties (${_target} PROPERTIES INSTALL_RPATH "${_current_rpath} " )
233+ endif ()
234+
235+ endfunction ()
0 commit comments