20231212 cmake 编译中间库

CMake中INSTALL_RPATH与BUILD_RPATH问题

遇到的问题:
将整个编译多个动态链接库,各自调用第三方库,最终可执行程序再调用中间封装库。
cmake 生成makefile文件时find_library,然后连接生成中间库文件时报错:

 Find FCL_LIB : /home/hit/cmakeproject/plantest/thirdparty/lib/fcl/libfcl.so
[cmake] -- Find CCD_LIB : /home/hit/cmakeproject/plantest/thirdparty/lib/ccd/libccd.so
[cmake] -- Find OMPL_LIB : /home/hit/cmakeproject/plantest/thirdparty/lib/ompl/libompl.so
[cmake] -- Find RUCKIG_LIB : /home/hit/cmakeproject/plantest/thirdparty/lib/ruckig/libruckig.so
[cmake] -- Find RBDL_LIB : /home/hit/cmakeproject/plantest/thirdparty/lib/rbdl/librbdl.so
[cmake] -- Find DYNURDF_LIB : /home/hit/cmakeproject/plantest/thirdparty/lib/rbdl/librbdl_urdfreader.so
[cmake] -- Find VREP_LIB : /home/hit/cmakeproject/plantest/thirdparty/lib/vrep/libremoteApi.so
[cmake] -- Find PAGMO_LIB : /home/hit/cmakeproject/plantest/thirdparty/lib/pagmo/libpagmo.so
[cmake] -- Find TBB_LIB : /usr/local/lib/libpagmo.so
[cmake] -- Find CASADI_LIB : /home/hit/cmakeproject/plantest/thirdparty/lib/casadi/libcasadi.so
[cmake] -- Find IPOPT_LIB : /home/hit/cmakeproject/plantest/thirdparty/lib/casadi/libipopt.so
[cmake] -- Find ODE_LIB : /home/hit/cmakeproject/plantest/thirdparty/lib/casadi/libode.so
[cmake] -- Find COBALT_LIB  : /home/hit/cmakeproject/plantest/thirdparty/lib/xeno/libcobalt.so
[cmake] -- Find BOOST_LIB : /home/hit/cmakeproject/plantest/thirdparty/lib/boost/libboost_serialization.so
[cmake] -- Executable dir : /home/hit/cmakeproject/plantest/bin
[cmake] -- Configuring done
[cmake] CMake Warning at CMakeLists.txt:153 (add_library):
[cmake]   Cannot generate a safe runtime search path for target i_robot because there
[cmake]   is a cycle in the constraint graph:
[cmake] 
[cmake]     dir 0 is [/home/hit/cmakeproject/plantest/thirdparty/lib/pagmo]
[cmake]       dir 1 must precede it due to runtime library [libpagmo.so.9]
[cmake]     dir 1 is [/usr/local/lib]
[cmake]       dir 0 must precede it due to runtime library [libpagmo.so.9]
[cmake]       dir 3 must precede it due to runtime library [libompl.so.16]
[cmake]       dir 4 must precede it due to runtime library [libboost_serialization.so.1.82.0]
[cmake]       dir 5 must precede it due to runtime library [libfcl.so.0.7]
[cmake]       dir 6 must precede it due to runtime library [libccd.so.2]
[cmake]       dir 8 must precede it due to runtime library [libcasadi.so.3.7]
[cmake]       dir 9 must precede it due to runtime library [libruckig.so]
[cmake]     dir 2 is [/home/hit/cmakeproject/plantest/build]
[cmake]     dir 3 is [/home/hit/cmakeproject/plantest/thirdparty/lib/ompl]
[cmake]     dir 4 is [/home/hit/cmakeproject/plantest/thirdparty/lib/boost]
[cmake]     dir 5 is [/home/hit/cmakeproject/plantest/thirdparty/lib/fcl]
[cmake]     dir 6 is [/home/hit/cmakeproject/plantest/thirdparty/lib/ccd]
[cmake]     dir 7 is [/home/hit/cmakeproject/plantest/thirdparty/lib/rbdl]
[cmake]     dir 8 is [/home/hit/cmakeproject/plantest/thirdparty/lib/casadi]
[cmake]     dir 9 is [/home/hit/cmakeproject/plantest/thirdparty/lib/ruckig]
[cmake]     dir 10 is [/home/hit/cmakeproject/plantest/thirdparty/lib/vrep]
[cmake]     dir 11 is [/home/hit/cmakeproject/plantest/thirdparty/lib/xeno]
[cmake] 
[cmake]   Some of these libraries may not be found correctly.
[cmake] 
[cmake] 
[cmake] CMake Warning at CMakeLists.txt:156 (add_executable):
[cmake]   Cannot generate a safe runtime search path for target icontroller because
[cmake]   there is a cycle in the constraint graph:

生成可执行程序后可以正常运行。

参考上文,使用ldd icontroller查看可执行文件最终动态链接的库文件所在位置,因为为了方便移植将各个依赖库均复制到了工程文件夹中。

hit@hit:~/cmakeproject/plantest/bin$ ldd icontroller 
        linux-vdso.so.1 (0x00007ffd1d589000)
        libcobalt.so.2 => /usr/xenomai/lib/libcobalt.so.2 (0x00007eff4d3e3000)
        libmodechk.so.0 => /usr/xenomai/lib/libmodechk.so.0 (0x00007eff4d1e1000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007eff4cfc2000)
        librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007eff4cdba000)
        libi_robot.so => /home/hit/cmakeproject/plantest/build/libi_robot.so (0x00007eff4cb75000)
        libpagmo.so.9 => /usr/local/lib/libpagmo.so.9 (0x00007eff4b64a000)
        libi_planner.so => /home/hit/cmakeproject/plantest/build/libi_planner.so (0x00007eff4b43f000)

发现

 libpagmo.so.9 => /usr/local/lib/libpagmo.so.9 (0x00007eff4b64a000)

并不是文件夹中的库,而是系统路径的库

原来是find_library 复制时改错了搜索路径

find_library(TBB_LIB pagmo HINTS ${PROJECT_SOURCE_DIR}/thirdparty/lib/tbb)
MESSAGE(STATUS "Find TBB_LIB : " ${TBB_LIB})

Find TBB_LIB : /usr/local/lib/libpagmo.so
tbb是 pagmo的依赖库,在该文件夹中未找到pagmo,因此又找到了系统路径的pagmo库,以TBB_LIB的名字替代了原本工程文件夹路径下的pagmo库,参与了最终编译。

cmake搜索库的优先级:

搜索.so的优先级顺序
RPATH: 写在elf文件中
LD_LIBRARY_PATH: 环境变量
RUNPATH: 写在elf文件中
ldconfig的缓存: 配置/etc/ld.conf*可改变
默认的/lib, /usr/lib(#对于C:echo | gcc -v -x c -E -, #对于C++:echo | g++ -v -x c++ -E -

所幸本机系统路径下存在该库因此运行正常,在另一台新系统中测试无法运行!

修正 pagmo --> tbb后,需要删除build文件夹中的 makefile 文件,重新生成即可。

使用 readelf -d icontroller 可以查看可执行程序运行时搜索库的路径。确保每个库所在的文件夹都有,即可。

 0x0000000000000001 (NEEDED)             共享库:[libruckig.so]
 0x0000000000000001 (NEEDED)             共享库:[libi_vrep.so]
 0x0000000000000001 (NEEDED)             共享库:[libremoteApi.so.1]
 0x0000000000000001 (NEEDED)             共享库:[libi_fileopt.so]
 0x0000000000000001 (NEEDED)             共享库:[libi_iddp.so]
 0x0000000000000001 (NEEDED)             共享库:[libstdc++.so.6]
 0x0000000000000001 (NEEDED)             共享库:[libm.so.6]
 0x0000000000000001 (NEEDED)             共享库:[libgcc_s.so.1]
 0x0000000000000001 (NEEDED)             共享库:[libc.so.6]
 0x000000000000001d (RUNPATH)            Library runpath: [/home/hit/cmakeproject/plantest/build:/home/hit/cmakeproject/plantest/thirdparty/lib/pagmo:/home/hit/cmakeproject/plantest/thirdparty/lib/tbb:/home/hit/cmakeproject/plantest/thirdparty/lib/ompl:/home/hit/cmakeproject/plantest/thirdparty/lib/boost:/home/hit/cmakeproject/plantest/thirdparty/lib/fcl:/home/hit/cmakeproject/plantest/thirdparty/lib/ccd:/home/hit/cmakeproject/plantest/thirdparty/lib/rbdl:/home/hit/cmakeproject/plantest/thirdparty/lib/casadi:/home/hit/cmakeproject/plantest/thirdparty/lib/ruckig:/home/hit/cmakeproject/plantest/thirdparty/lib/vrep:/home/hit/cmakeproject/plantest/thirdparty/lib/xeno]
 0x000000000000000c (INIT)               0x8908

你可能感兴趣的:(学习笔记,c++,c++,cmake)