extra rpath missing from modules #1071

Closed
opened 2026-10-05 05:01:37 +02:00 by adam · 8 comments
Owner

I'm the packager for the SynoCommunity ZNC package
Current PR: https://github.com/SynoCommunity/spksrc/pull/6636

I've been hunting down an issue when, looking in more details at rpath (as I'm using multiple rpath when cross-comliling) - the resulting bin/znc binary has my two expected rpaths (using libtree tool to track from my build system which shows libraries as not found as expected, but most importantly shows the actual rpath detail):

libtree work-x64-7.1/install/var/packages/znc/target/bin/znc
work-x64-7.1/install/var/packages/znc/target/bin/znc 
├── libz.so.1 [ld.so.conf]
├── libargon2.so.1 [ld.so.conf]
├── libcrypto.so.3 [ld.so.conf]
├── libssl.so.3 [ld.so.conf]
│   └── libcrypto.so.3 [ld.so.conf]
├── libpthread.so.0 [ld.so.conf]
├── librt.so.1 [ld.so.conf]
├── libicuuc.so.77 not found
└── libboost_locale.so.1.86.0 not found
    ┊ Paths considered in this order:
    ┊ 1. rpath:
    ┊    depth 1
    ┊    /var/packages/znc/target/lib
    ┊    /var/packages/python312/target/lib
    ┊ 2. LD_LIBRARY_PATH was not set
    ┊ 3. runpath was not set
    ┊ 4. ld config files:
    ┊    /usr/lib/x86_64-linux-gnu/libfakeroot
    ┊    /usr/local/lib
    ┊    /usr/local/lib/x86_64-linux-gnu
    ┊    /lib/x86_64-linux-gnu
    ┊    /usr/lib/x86_64-linux-gnu
    ┊    /lib32
    ┊    /usr/lib32
    ┊    /libx32
    ┊    /usr/libx32
    ┊ 5. Standard paths:
    ┊    /lib
    ┊    /lib64
    ┊    /usr/lib
    ┊    /usr/lib64

Although all the libraries are missing that second rpath:

libtree work-x64-7.1/install/var/packages/znc/target/lib/znc/log.so 
work-x64-7.1/install/var/packages/znc/target/lib/znc/log.so 
├── libssl.so.3 [ld.so.conf]
│   └── libcrypto.so.3 [ld.so.conf]
├── libcrypto.so.3 [ld.so.conf]
└── libicuuc.so.77 not found
    ┊ Paths considered in this order:
    ┊ 1. rpath:
    ┊    depth 1
    ┊    /var/packages/znc/target/lib
    ┊ 2. LD_LIBRARY_PATH was not set
    ┊ 3. runpath was not set
    ┊ 4. ld config files:
    ┊    /usr/lib/x86_64-linux-gnu/libfakeroot
    ┊    /usr/local/lib
    ┊    /usr/local/lib/x86_64-linux-gnu
    ┊    /lib/x86_64-linux-gnu
    ┊    /usr/lib/x86_64-linux-gnu
    ┊    /lib32
    ┊    /usr/lib32
    ┊    /libx32
    ┊    /usr/libx32
    ┊ 5. Standard paths:
    ┊    /lib
    ┊    /lib64
    ┊    /usr/lib
    ┊    /usr/lib64

I wasn't able to find how to patch things in the ZNC CMake code but I did added an extra --set-rpath into my build definition file: https://github.com/SynoCommunity/spksrc/pull/6636/commits/3fa91aba853782f5eaec9d5b0ddb67a26d3384a1 such as:

$ find $(STAGING_INSTALL_PREFIX)/lib/znc -name "*.so" -exec patchelf --set-rpath "$(INSTALL_PREFIX)/lib:$(PYTHON_PREFIX)/lib" {} \;

EDIT: Hopefully this can help someone else facing the same issue... I can easily test patches as needed. Cheers!

I'm the packager for the SynoCommunity ZNC package Current PR: https://github.com/SynoCommunity/spksrc/pull/6636 I've been hunting down an issue when, looking in more details at rpath (as I'm using multiple rpath when cross-comliling) - the resulting `bin/znc` binary has my two expected rpaths (using libtree tool to track from my build system which shows libraries as not found as expected, but most importantly shows the actual rpath detail): ``` libtree work-x64-7.1/install/var/packages/znc/target/bin/znc work-x64-7.1/install/var/packages/znc/target/bin/znc ├── libz.so.1 [ld.so.conf] ├── libargon2.so.1 [ld.so.conf] ├── libcrypto.so.3 [ld.so.conf] ├── libssl.so.3 [ld.so.conf] │ └── libcrypto.so.3 [ld.so.conf] ├── libpthread.so.0 [ld.so.conf] ├── librt.so.1 [ld.so.conf] ├── libicuuc.so.77 not found └── libboost_locale.so.1.86.0 not found ┊ Paths considered in this order: ┊ 1. rpath: ┊ depth 1 ┊ /var/packages/znc/target/lib ┊ /var/packages/python312/target/lib ┊ 2. LD_LIBRARY_PATH was not set ┊ 3. runpath was not set ┊ 4. ld config files: ┊ /usr/lib/x86_64-linux-gnu/libfakeroot ┊ /usr/local/lib ┊ /usr/local/lib/x86_64-linux-gnu ┊ /lib/x86_64-linux-gnu ┊ /usr/lib/x86_64-linux-gnu ┊ /lib32 ┊ /usr/lib32 ┊ /libx32 ┊ /usr/libx32 ┊ 5. Standard paths: ┊ /lib ┊ /lib64 ┊ /usr/lib ┊ /usr/lib64 ``` Although all the libraries are missing that second rpath: ``` libtree work-x64-7.1/install/var/packages/znc/target/lib/znc/log.so work-x64-7.1/install/var/packages/znc/target/lib/znc/log.so ├── libssl.so.3 [ld.so.conf] │ └── libcrypto.so.3 [ld.so.conf] ├── libcrypto.so.3 [ld.so.conf] └── libicuuc.so.77 not found ┊ Paths considered in this order: ┊ 1. rpath: ┊ depth 1 ┊ /var/packages/znc/target/lib ┊ 2. LD_LIBRARY_PATH was not set ┊ 3. runpath was not set ┊ 4. ld config files: ┊ /usr/lib/x86_64-linux-gnu/libfakeroot ┊ /usr/local/lib ┊ /usr/local/lib/x86_64-linux-gnu ┊ /lib/x86_64-linux-gnu ┊ /usr/lib/x86_64-linux-gnu ┊ /lib32 ┊ /usr/lib32 ┊ /libx32 ┊ /usr/libx32 ┊ 5. Standard paths: ┊ /lib ┊ /lib64 ┊ /usr/lib ┊ /usr/lib64 ``` I wasn't able to find how to patch things in the ZNC CMake code but I did added an extra `--set-rpath` into my build definition file: https://github.com/SynoCommunity/spksrc/pull/6636/commits/3fa91aba853782f5eaec9d5b0ddb67a26d3384a1 such as: ``` $ find $(STAGING_INSTALL_PREFIX)/lib/znc -name "*.so" -exec patchelf --set-rpath "$(INSTALL_PREFIX)/lib:$(PYTHON_PREFIX)/lib" {} \; ``` EDIT: Hopefully this can help someone else facing the same issue... I can easily test patches as needed. Cheers! <!-- github-sync-id:3210166670 -->
adam closed this issue 2026-10-05 05:01:38 +02:00
Author
Owner

How are you calling cmake?

How are you calling cmake? <!-- github-comment-id:3046444179 -->
Author
Owner

Using a toolchain file. See toolchain file (renamed with txt)

x64-toolchain.cmake.txt

and build logs.

build-x64-7.1.log

Using a toolchain file. See toolchain file (renamed with txt) [x64-toolchain.cmake.txt](https://github.com/user-attachments/files/21109939/x64-toolchain.cmake.txt) and build logs. [build-x64-7.1.log](https://github.com/user-attachments/files/21109914/build-x64-7.1.log) <!-- github-comment-id:3046471673 -->
Author
Owner

I see the toolchain file only has one of these paths in CMAKE_INSTALL_RPATH (line 52). I suspect the --rpath option you're passing in ..._FLAGS are simply overridden by that setting, which sets only 1 path.

Try setting both paths there? https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_RPATH.html

I see the toolchain file only has one of these paths in CMAKE_INSTALL_RPATH (line 52). I suspect the --rpath option you're passing in ..._FLAGS are simply overridden by that setting, which sets only 1 path. Try setting both paths there? https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_RPATH.html <!-- github-comment-id:3046488253 -->
Author
Owner

fair point, I'll look into this, and requires adjustment to the framework to properly automate. Although note :

  1. I had tried enforcing it both in CMakeList.txt (quick & dirty patch) or passing that in parameter to cmake with no success.
  2. Still, what I forgot to mention is that LDFLAGS is being set properly with all the additional rpath info, something normally cmake handles really well (as we don't have any other cases like this one).

What makes it even more odd is the fact that the znc binary has both rpath as to be expected, but libraries doesn't... making me beleive that issue relies elsewhere.

fair point, I'll look into this, and requires adjustment to the framework to properly automate. Although note : 1. I had tried enforcing it both in CMakeList.txt (quick & dirty patch) or passing that in parameter to cmake with no success. 2. Still, what I forgot to mention is that `LDFLAGS` is being set properly with all the additional rpath info, something normally cmake handles really well (as we don't have any other cases like this one). What makes it even more odd is the fact that the `znc` binary has both rpath as to be expected, but libraries doesn't... making me beleive that issue relies elsewhere. <!-- github-comment-id:3046569411 -->
Author
Owner

You might have compiled it with these flags, and I'm sure even successfully. But then during "make install" step, cmake uses the value of CMAKE_INSTALL_RPATH, and replaces the rpath in the binaries. It's possible that somehow it only applies it to .so files, but not in znc, no idea.

You might have *compiled* it with these flags, and I'm sure even successfully. But then during "make install" step, cmake uses the value of CMAKE_INSTALL_RPATH, and replaces the rpath in the binaries. It's possible that somehow it only applies it to .so files, but not in `znc`, no idea. <!-- github-comment-id:3046577991 -->
Author
Owner

food for thoughts, exceptionnally in this case I had to enforce the following (using spksrc framework preset variables):

CMAKE_ARGS += -DOPENSSL_INCLUDE_DIR=$(OPENSSL_STAGING_PREFIX)/include
CMAKE_ARGS += -DOPENSSL_SSL_LIBRARY=$(OPENSSL_STAGING_PREFIX)/lib/libssl.so
CMAKE_ARGS += -DOPENSSL_CRYPTO_LIBRARY=$(OPENSSL_STAGING_PREFIX)/lib/libcrypto.so
ADDITIONAL_CPPFLAGS += -I$(PYTHON_STAGING_PREFIX)/include/python3.$(subst python3,,$(PYTHON_PACKAGE))
ADDITIONAL_CPPFLAGS += -I$(OPENSSL_STAGING_PREFIX)/include/openssl

From the get-go what I found strange is that python and openssl prefixes are already part of the known includes and ld flags and should have been found through the pkg-config, but it did not...

As mentionned, I don't see that behavior elsewhere, although you're right, still CMAKE_INSTALL_RPATH needs to be set to avoid unecessary confusion. I'll try that and see if it resolves things or not.

food for thoughts, exceptionnally in this case I had to enforce the following (using spksrc framework preset variables): ``` CMAKE_ARGS += -DOPENSSL_INCLUDE_DIR=$(OPENSSL_STAGING_PREFIX)/include CMAKE_ARGS += -DOPENSSL_SSL_LIBRARY=$(OPENSSL_STAGING_PREFIX)/lib/libssl.so CMAKE_ARGS += -DOPENSSL_CRYPTO_LIBRARY=$(OPENSSL_STAGING_PREFIX)/lib/libcrypto.so ADDITIONAL_CPPFLAGS += -I$(PYTHON_STAGING_PREFIX)/include/python3.$(subst python3,,$(PYTHON_PACKAGE)) ADDITIONAL_CPPFLAGS += -I$(OPENSSL_STAGING_PREFIX)/include/openssl ``` From the get-go what I found strange is that python and openssl prefixes are already part of the known includes and ld flags and should have been found through the pkg-config, but it did not... As mentionned, I don't see that behavior elsewhere, although you're right, still `CMAKE_INSTALL_RPATH` needs to be set to avoid unecessary confusion. I'll try that and see if it resolves things or not. <!-- github-comment-id:3046590660 -->
Author
Owner

@DarthGandalf So I was able to modify the spksrc framework in order to have all rpath part of CMAKE_INSTALL_RPATH, which in turn did solved the issue on the library modules shared objects side of things but had the counter effect to duplicate the rpath part of the znc binary.

Further reading, my understanding (and I may well be wrong) is that LDFLAGS defined rpath are not being considered for static libraries, as is being defined in the CMakeList.txt :

if(CYGWIN)
        set(znc_link "znclib")
        set(lib_type "SHARED")
        set(install_lib "znclib")
        set(znclib_pc "-L${CMAKE_INSTALL_FULL_LIBDIR} -lznc")
else()
        set(znc_link "znc")
        set(lib_type "STATIC")
        set(install_lib)
        set(znclib_pc)
endif()

Reading the comment above that code and playing a bit with the cmake definition files there must be good reasons for that (and as I was able to workaround that and set that up to SHARED). This makes me believe that at this point that the easiest fix may well be to set rpath on libraries after the fact like I'm currently doing...

Edit: I'm confusing things here as that part is for ensuring znc library is statically built into the znc binary ... While I'm rather referring to znc modules under lib/znc/*.so missing additional rpath...

@DarthGandalf So I was able to modify the spksrc framework in order to have all rpath part of `CMAKE_INSTALL_RPATH`, which in turn did solved the issue on the <s>library</s> modules shared objects side of things but had the counter effect to duplicate the rpath part of the znc binary. <s>Further reading, my understanding (and I may well be wrong) is that `LDFLAGS` defined rpath are not being considered for static libraries, as is being defined in the `CMakeList.txt` : ``` if(CYGWIN) set(znc_link "znclib") set(lib_type "SHARED") set(install_lib "znclib") set(znclib_pc "-L${CMAKE_INSTALL_FULL_LIBDIR} -lznc") else() set(znc_link "znc") set(lib_type "STATIC") set(install_lib) set(znclib_pc) endif() ``` Reading the comment above that code and playing a bit with the cmake definition files there must be good reasons for that (and as I was able to workaround that and set that up to `SHARED`). This makes me believe that at this point that the easiest fix may well be to set rpath on libraries after the fact like I'm currently doing...</s> Edit: I'm confusing things here as that part is for ensuring znc library is statically built into the znc binary ... While I'm rather referring to znc modules under lib/znc/*.so missing additional rpath... <!-- github-comment-id:3050739725 -->
Author
Owner

I have now found a working solution making all rpath to fully appear in every modules *.so files:

--- modules/CMakeLists.txt-orig	2025-07-01 21:17:15.000000000 +0000
+++ modules/CMakeLists.txt	2025-07-09 11:18:52.139294029 +0000
@@ -17,6 +17,8 @@
 # This is not recommended, but whatever.
 file(GLOB all_modules LIST_DIRECTORIES FALSE "*")
 
+set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}")
+
 function(add_cxx_module mod modpath)
 	znc_add_library("module_${mod}" MODULE "${modpath}")
 	set_target_properties("module_${mod}" PROPERTIES

Here an example of resuting rpath info from module cross-compilation now properly shown two rpath as expected:

$ libtree work-x64-7.1/install/var/packages/znc/target/lib/znc/adminlog.so 
work-x64-7.1/install/var/packages/znc/target/lib/znc/adminlog.so 
├── libssl.so.3 [ld.so.conf]
│   └── libcrypto.so.3 [ld.so.conf]
├── libcrypto.so.3 [ld.so.conf]
└── libicuuc.so.77 not found
    ┊ Paths considered in this order:
    ┊ 1. rpath:
    ┊    depth 1
    ┊    /var/packages/znc/target/lib
    ┊    /var/packages/python312/target/lib
    ┊ 2. LD_LIBRARY_PATH was not set
    ┊ 3. runpath was not set
    ┊ 4. ld config files:
    ┊    /usr/lib/x86_64-linux-gnu/libfakeroot
    ┊    /usr/local/lib
    ┊    /usr/local/lib/x86_64-linux-gnu
    ┊    /lib/x86_64-linux-gnu
    ┊    /usr/lib/x86_64-linux-gnu
    ┊    /lib32
    ┊    /usr/lib32
    ┊    /libx32
    ┊    /usr/libx32
    ┊ 5. Standard paths:
    ┊    /lib
    ┊    /lib64
    ┊    /usr/lib
    ┊    /usr/lib64
Error [work-x64-7.1/install/var/packages/znc/target/lib/znc/adminlog.so]: Not all dependencies were found

EDIT: related commit on my SynoCommunity PR https://github.com/SynoCommunity/spksrc/pull/6636/commits/edfd5905aae0e9c7208591c680ecc124b053d586

I have now found a working solution making all rpath to fully appear in every modules *.so files: ``` --- modules/CMakeLists.txt-orig 2025-07-01 21:17:15.000000000 +0000 +++ modules/CMakeLists.txt 2025-07-09 11:18:52.139294029 +0000 @@ -17,6 +17,8 @@ # This is not recommended, but whatever. file(GLOB all_modules LIST_DIRECTORIES FALSE "*") +set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}") + function(add_cxx_module mod modpath) znc_add_library("module_${mod}" MODULE "${modpath}") set_target_properties("module_${mod}" PROPERTIES ``` Here an example of resuting rpath info from module cross-compilation now properly shown two rpath as expected: ``` $ libtree work-x64-7.1/install/var/packages/znc/target/lib/znc/adminlog.so work-x64-7.1/install/var/packages/znc/target/lib/znc/adminlog.so ├── libssl.so.3 [ld.so.conf] │ └── libcrypto.so.3 [ld.so.conf] ├── libcrypto.so.3 [ld.so.conf] └── libicuuc.so.77 not found ┊ Paths considered in this order: ┊ 1. rpath: ┊ depth 1 ┊ /var/packages/znc/target/lib ┊ /var/packages/python312/target/lib ┊ 2. LD_LIBRARY_PATH was not set ┊ 3. runpath was not set ┊ 4. ld config files: ┊ /usr/lib/x86_64-linux-gnu/libfakeroot ┊ /usr/local/lib ┊ /usr/local/lib/x86_64-linux-gnu ┊ /lib/x86_64-linux-gnu ┊ /usr/lib/x86_64-linux-gnu ┊ /lib32 ┊ /usr/lib32 ┊ /libx32 ┊ /usr/libx32 ┊ 5. Standard paths: ┊ /lib ┊ /lib64 ┊ /usr/lib ┊ /usr/lib64 Error [work-x64-7.1/install/var/packages/znc/target/lib/znc/adminlog.so]: Not all dependencies were found ``` EDIT: related commit on my SynoCommunity PR https://github.com/SynoCommunity/spksrc/pull/6636/commits/edfd5905aae0e9c7208591c680ecc124b053d586 <!-- github-comment-id:3052282838 -->
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: adam/znc#1071