summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarmen Stoppels <harmenstoppels@gmail.com>2022-03-29 18:24:10 +0200
committerGitHub <noreply@github.com>2022-03-29 12:24:10 -0400
commit9516fa9447c98e5d2a8446f6fd20a8022979d2e4 (patch)
tree7c07a68622f1b1af0ccba63f52132d3d0fda0f48
parentc0b400c422832e0078c5687e4765fdda65aed66a (diff)
downloadspack-9516fa9447c98e5d2a8446f6fd20a8022979d2e4.tar.gz
spack-9516fa9447c98e5d2a8446f6fd20a8022979d2e4.tar.bz2
spack-9516fa9447c98e5d2a8446f6fd20a8022979d2e4.tar.xz
spack-9516fa9447c98e5d2a8446f6fd20a8022979d2e4.zip
cmake: use CMAKE_INSTALL_RPATH_USE_LINK_PATH (#29703)
* cmake: use CMAKE_INSTALL_RPATH_USE_LINK_PATH Spack has a heuristic to add rpaths for packages it knows are required, but it's really a heuristic, and it does not work when the dependencies put their libraries in a different folder than `<prefix>/lib{64,}`. CMake patches binaries after install with the "install rpaths", which by default are provided by Spack and its heuristic through `CMAKE_INSTALL_RPATH`. CMake however knows better what libraries are effectively being linked to, and has an option to include those in the install rpath too, through `CMAKE_INSTALL_RPATH_USE_LINK_PATH`. These two CMake options are complementary, repeated rpaths seem to be filtered, and the "use link path" paths are appended to Spack's heuristic "install rpath". So, it seems like a good idea to enable "use link path" by default, so that: - `dlopen` by library name uses Spack's heuristic search paths - linked libraries in non-standard locations within a prefix get an rpath thanks to CMake. * docs
-rw-r--r--lib/spack/docs/build_systems/cmakepackage.rst109
-rw-r--r--lib/spack/spack/build_systems/cmake.py2
2 files changed, 80 insertions, 31 deletions
diff --git a/lib/spack/docs/build_systems/cmakepackage.rst b/lib/spack/docs/build_systems/cmakepackage.rst
index c565375b14..9544a7df73 100644
--- a/lib/spack/docs/build_systems/cmakepackage.rst
+++ b/lib/spack/docs/build_systems/cmakepackage.rst
@@ -159,6 +159,85 @@ and CMake simply ignores the empty command line argument. For example the follow
will generate ``'cmake' '-DEXAMPLE=ON' ...`` when `@2.0: +example` is met, but will
result in ``'cmake' '' ...`` when the spec version is below ``2.0``.
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+CMake arguments provided by Spack
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following default arguments are controlled by Spack:
+
+
+``CMAKE_INSTALL_PREFIX``
+------------------------
+
+Is set to the the package's install directory.
+
+
+``CMAKE_PREFIX_PATH``
+---------------------
+
+CMake finds dependencies through calls to ``find_package()``, ``find_program()``,
+``find_library()``, ``find_file()``, and ``find_path()``, which use a list of search
+paths from ``CMAKE_PREFIX_PATH``. Spack sets this variable to a list of prefixes of the
+spec's transitive dependencies.
+
+For troubleshooting cases where CMake fails to find a dependency, add the
+``--debug-find`` flag to ``cmake_args``.
+
+``CMAKE_BUILD_TYPE``
+--------------------
+
+Every CMake-based package accepts a ``-DCMAKE_BUILD_TYPE`` flag to
+dictate which level of optimization to use. In order to ensure
+uniformity across packages, the ``CMakePackage`` base class adds
+a variant to control this:
+
+.. code-block:: python
+
+ variant('build_type', default='RelWithDebInfo',
+ description='CMake build type',
+ values=('Debug', 'Release', 'RelWithDebInfo', 'MinSizeRel'))
+
+However, not every CMake package accepts all four of these options.
+Grep the ``CMakeLists.txt`` file to see if the default values are
+missing or replaced. For example, the
+`dealii <https://github.com/spack/spack/blob/develop/var/spack/repos/builtin/packages/dealii/package.py>`_
+package overrides the default variant with:
+
+.. code-block:: python
+
+ variant('build_type', default='DebugRelease',
+ description='The build type to build',
+ values=('Debug', 'Release', 'DebugRelease'))
+
+For more information on ``CMAKE_BUILD_TYPE``, see:
+https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html
+
+
+``CMAKE_INSTALL_RPATH`` and ``CMAKE_INSTALL_RPATH_USE_LINK_PATH=ON``
+--------------------------------------------------------------------
+
+CMake uses different RPATHs during the build and after installation, so that executables
+can locate the libraries they're linked to during the build, and installed executables
+do not have RPATHs to build directories. In Spack, we have to make sure that RPATHs are
+set properly after installation.
+
+Spack sets ``CMAKE_INSTALL_RPATH`` to a list of ``<prefix>/lib`` or ``<prefix>/lib64``
+directories of the spec's link-type dependencies. Apart from that, it sets
+``-DCMAKE_INSTALL_RPATH_USE_LINK_PATH=ON``, which should add RPATHs for directories of
+linked libraries not in the directories covered by ``CMAKE_INSTALL_RPATH``.
+
+Usually it's enough to set only ``-DCMAKE_INSTALL_RPATH_USE_LINK_PATH=ON``, but the
+reason to provide both options is that packages may dynamically open shared libraries,
+which CMake cannot detect. In those cases, the RPATHs from ``CMAKE_INSTALL_RPATH`` are
+used as search paths.
+
+.. note::
+
+ Some packages provide stub libraries, which contain an interface for linking without
+ an implementation. When using such libraries, it's best to override the option
+ ``-DCMAKE_INSTALL_RPATH_USE_LINK_PATH=OFF`` in ``cmake_args``, so that stub libraries
+ are not used at runtime.
+
^^^^^^^^^^
Generators
@@ -196,36 +275,6 @@ generators, but it should be simple to add support for alternative
generators. For more information on CMake generators, see:
https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html
-^^^^^^^^^^^^^^^^
-CMAKE_BUILD_TYPE
-^^^^^^^^^^^^^^^^
-
-Every CMake-based package accepts a ``-DCMAKE_BUILD_TYPE`` flag to
-dictate which level of optimization to use. In order to ensure
-uniformity across packages, the ``CMakePackage`` base class adds
-a variant to control this:
-
-.. code-block:: python
-
- variant('build_type', default='RelWithDebInfo',
- description='CMake build type',
- values=('Debug', 'Release', 'RelWithDebInfo', 'MinSizeRel'))
-
-However, not every CMake package accepts all four of these options.
-Grep the ``CMakeLists.txt`` file to see if the default values are
-missing or replaced. For example, the
-`dealii <https://github.com/spack/spack/blob/develop/var/spack/repos/builtin/packages/dealii/package.py>`_
-package overrides the default variant with:
-
-.. code-block:: python
-
- variant('build_type', default='DebugRelease',
- description='The build type to build',
- values=('Debug', 'Release', 'DebugRelease'))
-
-For more information on ``CMAKE_BUILD_TYPE``, see:
-https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html
-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
CMakeLists.txt in a sub-directory
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/lib/spack/spack/build_systems/cmake.py b/lib/spack/spack/build_systems/cmake.py
index 6e6b5e20b0..f934947604 100644
--- a/lib/spack/spack/build_systems/cmake.py
+++ b/lib/spack/spack/build_systems/cmake.py
@@ -193,7 +193,7 @@ class CMakePackage(PackageBase):
# Set up CMake rpath
args.extend([
- define('CMAKE_INSTALL_RPATH_USE_LINK_PATH', False),
+ define('CMAKE_INSTALL_RPATH_USE_LINK_PATH', True),
define('CMAKE_INSTALL_RPATH',
spack.build_environment.get_rpaths(pkg)),
define('CMAKE_PREFIX_PATH',