From 10e06da896809607321ea74faa151827eb99dd69 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Apr 2024 21:21:50 +0000 Subject: [PATCH] build: Tell cmake to set 'rpath' so the installed 'cmark' can find 'libcmark.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 'CMAKE_INSTALL_RPATH' is set, then it is used; this allows the user to set a single, overriding value in the expected way. * Otherwise, the base case rpath is determined by the following: "${CMAKE_INSTALL_FULL_LIBDIR}" If that path is a standard location, then the base case rpath is the empty string; otherwise, the base case rpath is that path. * The cmark executable's rpath is set to the base case rpath. * Currently, libcmark's rpath is set to the empty string. * In addition, cmake has been instructed to add to each target's rpath any directories that it thinks might contain potential dependencies from outside the project; most of the time, there will be none, and so nothing will be added. 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. --- CMakeLists.txt | 15 +++++++++++++++ src/CMakeLists.txt | 3 ++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ce54658c8..262116a1d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,6 +69,21 @@ set(CMAKE_VISIBILITY_INLINES_HIDDEN 1) set(CMAKE_INCLUDE_CURRENT_DIR ON) +if (DEFINED CMAKE_INSTALL_RPATH) + set(Base_rpath "${CMAKE_INSTALL_RPATH}") +else() + if(BUILD_SHARED_LIBS) + set(p "${CMAKE_INSTALL_FULL_LIBDIR}") + list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${p}" i) + if("${i}" STREQUAL "-1") + set(Base_rpath "${p}") + endif() + endif() +endif() + +# Append non-standard external dependency directories, if any. +set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) + # Check integrity of node structure when compiled as debug add_compile_options($<$:-DCMARK_DEBUG_NODES>) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d98a4079e..523b2cb82 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -55,7 +55,8 @@ add_executable(cmark_exe main.c) cmark_add_compile_options(cmark_exe) set_target_properties(cmark_exe PROPERTIES - OUTPUT_NAME "cmark") + OUTPUT_NAME "cmark" + INSTALL_RPATH "${Base_rpath}") target_link_libraries(cmark_exe PRIVATE cmark)