Ric*_*ins 5 linker cmake shared-libraries
我有一个供应商库,需要包含在我的项目的安装程序中,我正在使用INSTALL(FILES ...)
. 该库与源代码一起存储,问题是链接路径(由 readelf 显示)是相对的,并且该前缀在安装过程中不会被删除,因此动态链接器不是搜索hhlib.so
它的../hhlib-linux-64bit/hhlib.so
.
如何获得可用的已安装二进制文件?我可以获取安装步骤或 CPack 来删除该库的相对路径吗?
\n我已将问题简化为一个简单的示例:
\n.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 build\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 CMakeLists.txt\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 hhlib-linux-64bit\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 hhlib.h\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 hhlib.so\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 use_hydroharp.c\n
Run Code Online (Sandbox Code Playgroud)\n.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 build\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 CMakeLists.txt\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 hhlib-linux-64bit\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 hhlib.h\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 hhlib.so\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 use_hydroharp.c\n
Run Code Online (Sandbox Code Playgroud)\n内置:
\ncmake_minimum_required (VERSION 3.19)\n\n# These sets have no effect on the issue\n\n# use, i.e. don\'t skip the full RPATH for the build tree\n#SET(CMAKE_SKIP_BUILD_RPATH FALSE)\n# when building, don\'t use the install RPATH already\n# (but later on when installing)\n#SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) \n# the RPATH to be used when installing\n#SET(CMAKE_INSTALL_RPATH "")\n# don\'t add the automatically determined parts of the RPATH\n# which point to directories outside the build tree to the install RPATH\n#SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)\n\nenable_language(C)\n# Find the header files\nfind_path(HydroHarp_INCLUDEDIR\n NAMES hhlib.h\n PATHS "${CMAKE_CURRENT_SOURCE_DIR}/hhlib-linux-64bit"\n )\n# Find the shared library\nfind_library(HydroHarp_LIBRARY\n NAMES hhlib.so\n HINTS "${CMAKE_CURRENT_SOURCE_DIR}/hhlib-linux-64bit"\n )\n\nif(HydroHarp_INCLUDEDIR AND HydroHarp_LIBRARY)\n message("Found HyroHarp library")\n # Get the containing folder for the library\n get_filename_component(HydroHarp_LIBDIR ${HydroHarp_LIBRARY} DIRECTORY)\n \n # Import the library\n add_library(HydroHarp SHARED IMPORTED)\n\n set_target_properties(HydroHarp PROPERTIES\n INTERFACE_INCLUDE_DIRECTORIES ${HydroHarp_INCLUDEDIR}\n IMPORTED_LOCATION ${HydroHarp_LIBRARY}\n )\n # copy the library when installing\n install(FILES ${HydroHarp_LIBRARY} TYPE LIB)\n\nelse()\n message(WARNING "Failed to find HydroHarp")\nendif()\n\nproject(extlink)\nadd_executable(${PROJECT_NAME} use_hydroharp.c)\ntarget_link_libraries(${PROJECT_NAME} PRIVATE HydroHarp)\n\n# install the library\ninstall(TARGETS ${PROJECT_NAME}\n RUNTIME DESTINATION bin\n )\n\nset(CPACK_GENERATOR DEB CACHE INTERNAL "")\n\nSET(CPACK_PACKAGE_CONTACT "asdaksd@kjhk.com")\nSET(CPACK_PACKAGE_VENDOR "asdfasd")\n\ninclude(CPack)\n
Run Code Online (Sandbox Code Playgroud)\n该程序使用相对路径引用共享库(这对于构建树来说很好,但由于 RUNPATH 而不需要):
\nbuild$ cmake .. && make package\n
Run Code Online (Sandbox Code Playgroud)\n但make install
在它仍然存在并且 RUNPATH 已被删除之后:
build$ readelf -d extlink\nDynamic section at offset 0x2da8 contains 29 entries:\n Tag Type Name/Value\n 0x0000000000000001 (NEEDED) Shared library: [../hhlib-linux-64bit/hhlib.so]\n 0x0000000000000001 (NEEDED) Shared library: [libc.so.6]\n 0x000000000000001d (RUNPATH) Library runpath: [/code/hhlib-linux-64bit:]\n 0x000000000000000c (INIT) 0x1000\n...\n
Run Code Online (Sandbox Code Playgroud)\n我正在使用 CMake 3.16.3 在 Ubuntu 20.04 上构建,但也使用最新的 CMake 版本 3.19.4 进行了测试\n起初我认为这个问题提供了解决方案,但这些 RPATH 变量的组合没有解决问题。
\n在我最喜欢的尖叫枕头上发出一声美妙而漫长的尖叫后,我有了另一个想法:
添加该属性IMPORTED_NO_SONAME
会删除有问题的路径,但链接器无法找到它 - 即使该路径明确包含在 中LINK_DIRECTORIES
,为什么?因为供应商库不遵循命名约定!
将库重命名为libhh.so
并添加set_target_properties(HydroHarp PROPERTIES IMPORTED_NO_SONAME TRUE)
可以解决该问题。别问我为什么。
完整的工作 CMakeLists.txt:
cmake_minimum_required (VERSION 3.19)
enable_language(C)
# Find the header files
find_path(HydroHarp_INCLUDEDIR
NAMES hhlib.h
PATHS "${CMAKE_CURRENT_SOURCE_DIR}/hhlib-linux-64bit"
)
# Find the shared library
find_library(HydroHarp_LIBRARY
NAMES hh # <-- Note removed .so so standard extensions are searched
HINTS "${CMAKE_CURRENT_SOURCE_DIR}/hhlib-linux-64bit"
)
if(HydroHarp_INCLUDEDIR AND HydroHarp_LIBRARY)
message("Found HyroHarp library")
# Import the library
add_library(HydroHarp SHARED IMPORTED)
set_target_properties(HydroHarp PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES ${HydroHarp_INCLUDEDIR}
IMPORTED_NO_SONAME TRUE # <-- This lib wasn't built with an SONAME
IMPORTED_LOCATION ${HydroHarp_LIBRARY}
)
# copy the library when installing
install(FILES ${HydroHarp_LIBRARY} TYPE LIB)
else()
message(WARNING "Failed to find HydroHarp")
endif()
project(extlink)
add_executable(${PROJECT_NAME} use_hydroharp.c)
target_link_libraries(${PROJECT_NAME} PRIVATE HydroHarp)
# install the library
install(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION bin
)
set(CPACK_GENERATOR DEB CACHE INTERNAL "")
SET(CPACK_PACKAGE_CONTACT "asdaksd@adssd.com")
SET(CPACK_PACKAGE_VENDOR "asdfasd")
include(CPack)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1341 次 |
最近记录: |