Skip to content

Commit

Permalink
build: Tell cmake to set 'rpath' so the installed 'cmark' can find 'l…
Browse files Browse the repository at this point in the history
…ibcmark.so'

Before this commit, the 'cmark' executable didn't inform the
dynamic linker where to look for the 'libcmark' shared object;
this becomes an irritation when 'libcmark' is installed in an
unorthodox location:

  $ ldd /path/to/installed/files/bin/cmark
          linux-gate.so.1 (0xb7ed7000)
          libcmark.so.0.31.0 => not found
          libc.so.6 => /usr/lib/libc.so.6 (0xb7cf3000)
          /lib/ld-linux.so.2 => /usr/lib/ld-linux.so.2 (0xb7ed8000)

Because of this commit, the 'cmark' executable's 'rpath' setting
(or equivalent) is set upon installation, thereby providing the
required search directory:

  $ ldd /path/to/installed/files/bin/cmark
          linux-gate.so.1 (0xb7ef2000)
          libcmark.so.0.31.0 => /path/to/installed/files/lib/libcmark.so.0.31.0 (0xb7e95000)
          libc.so.6 => /usr/lib/libc.so.6 (0xb7cbc000)
          /lib/ld-linux.so.2 => /usr/lib/ld-linux.so.2 (0xb7ef3000)

There is some intelligence behind whether 'rpath' is set at all:

  * If a shared object (e.g., 'libcmark') is going to be installed
    in a standard location, then such location is not added to 'rpath'.

  * A non-standard installation will cause 'rpath' to include at least
    the following path provided by cmake:

      "${CMAKE_INSTALL_PREFIX_FULL_LIBDIR}"

  * Also, cmake has been instructed to append any non-standard path
    to 'rpath' if cmake is aware of an external dependency from
    such a path.

Of course, this will only help on a system that supports an 'rpath'
feature known to cmake; for example, Windows has no such feature,
and so all of this will presumably be ignored when building under
that system.
  • Loading branch information
mfwitten committed Mar 8, 2024
1 parent dfb8243 commit 278aa59
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 1 deletion.
5 changes: 4 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ project(cmark
LANGUAGES C CXX
VERSION 0.31.0)

list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/modules)

if(CMAKE_BUILD_TYPE MATCHES "asan|ubsan")
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/modules)
include(FindAsan)
endif()

Expand Down Expand Up @@ -69,6 +70,8 @@ set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

include(SetRPATH)

# Check integrity of node structure when compiled as debug
add_compile_options($<$<CONFIG:Debug>:-DCMARK_DEBUG_NODES>)

Expand Down
15 changes: 15 additions & 0 deletions cmake/modules/SetRPATH.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
set(CMAKE_SKIP_BUILD_RPATH FALSE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)

# Append non-standard external dependency directories
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

# CMake 3.25 has a better scoping solution: 'block()'
function(SetRPATH)
set(p "${CMAKE_INSTALL_FULL_LIBDIR}")
list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${p}" i)
if("${i}" STREQUAL "-1")
set(CMAKE_INSTALL_RPATH "${p}" PARENT_SCOPE)
endif()
endfunction()
SetRPATH()

0 comments on commit 278aa59

Please sign in to comment.