一、起因
- 在16.04上好好的程序,复制到18.04就报错,找不到库
二、确定问题
- 16.04使用rpath,17、18.04使用runpath,使用
readelf -d <binary_name> | grep 'R.*PATH'
可以查看 - 但是runpath只负责直接依赖关系,如果依赖库a还依赖其他第三方库,而a又没有rpath和runpath(安装时默认没有他们),就会报找不到库
三、解决方法
- 修改
LD_LIBRARY_PATH
可以解决,但是会影响其他程序 - 使用编译选项
-Wl,-rpath=
无效,在18.04仍是设置runpath - 使用编译选项
add_compile_options("-Wl,--disable-new-dtags,-rpath=../lib")
无效 - 使用
patchelf --set-rpath '$ORIGIN/../lib64' <binary_name>
修改a的runpath,a的依赖对了,程序的依赖还是有问题 set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "-Wl,-rpath,../lib,-disable-new-dtags")
成功!
四、总结
- 关键在于
-disable-new-dtags
,如果自己使用g++编译是可以成功的 - 使用cmake就会出现
-disable-new-dtags
没有加到编译选项里,要使用set(CMAKE_VERBOSE_MAKEFILE ON)
查看 add_compile_options
不知道为什么加不进去,set_target_properties
可以
五、番外
- 在ros2的cmake中可以使用
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib/${PROJECT_NAME}")
设置,需要把第三方库安装在目录${CMAKE_INSTALL_PREFIX}/lib/${PROJECT_NAME}
。