【问题标题】:CMake linking 2 libraries with relative pathCMake用相对路径链接2个库
【发布时间】:2018-10-15 20:20:21
【问题描述】:

我的项目结构:

...
CMakeLists.txt
src/
    project/
        libA/
            CMakeLists.txt
            libA.h
            libA.cpp
        libB/
            CMakeLists.txt
            libB.h
            libB.cpp        
build/

CMakelists.txt

project(project)

# set some global dirs
set(LIB_A_DIR "src/project/libA")
set(LIB_B_DIR "src/project/libB")

# include header directories
include_directories(${LIB_A_DIR})
include_directories(${LIB_B_DIR})

# generating linkable libraries
add_subdirectory(${LIB_A_DIR})
add_subdirectory(${LIB_B_DIR})

src/project/libA/CMakeLists.txt

# define libA sources
set(LIB_A_SOURCES libA.cpp libA.h)

# generate libA library
add_library(libA SHARED ${LIB_A_SOURCES})

src/project/libB/CMakeLists.txt

# define libB sources
set(LIB_B_SOURCES libB.cpp libB.h)

# generate libB library
add_library(libB SHARED ${LIB_B_SOURCES})

# link libraries
target_link_libraries(libB PRIVATE libA)

现在,如果我从 build 文件夹运行 cmake .. && make,则从 libB 进行的任何函数调用都可以正常工作。但是一旦我想移动这个文件结构,链接就会中断。

例如,当我执行cp -r build/ build_copy/ 并使用rm -rf build/* 清除build 目录时,任何包含libB 的代码都会抛出error while loading shared libraries: liblibB.so: cannot open shared object file: No such file or directory

如何让我的链接使用相对文件路径?

旁注:我需要它们是 2 个独立的共享库并结合一个链接

【问题讨论】:

    标签: c++ cmake


    【解决方案1】:

    您需要将libAruntime-path 设置为安装位置。这是通过-rpath 链接器选项完成的。

    由于链接时将使用 C++ 前端 g++clang++,因此您需要使用 -Wl 标志将 -rpath 选项传递给链接器。

    您可以使用set_target_properties 命令为libB 设置带有LINK_FLAGS 目标属性的标志:

    set_target_properties(libB
        PROPERTIES LINK_FLAGS "-Wl,-rpath,/path/to/libA/installation")
    

    【讨论】:

    • 这是否适用于 -rpath,../libA ?如果是这样,它属于哪个文件? libB 的 CMakelists?
    • @user2255757 不,它确实需要是绝对路径。有很多 CMake variables 可以帮助您解决这个问题。
    • @Some 程序员老兄 RPATH 可以是相对的。例如,$ORIGIN 否则不会很有用。
    • @JesperJuhl 您知道一种将 cmake 命令合并到我的 libB CMakeLists 中的方法,以便无论此文件结构位于何处,它都可以使用 ../libA 来查找 libA?不确定 $ORIGIN 是什么 echo $ORIGIN 什么都不做
    • @Some 程序员伙计显然。但是,当您有 /opt/myapp/bin/myapp 之类的安装结构和 /opt/myapp/lib64/libmylib.so 等中的库时,将 rpath 设置为 $ORIGIN/../lib64 之类的东西仍然非常有用,从那时起 /opt/ myapp 文件夹作为一个实体变得可重定位。
    【解决方案2】:

    CMake linking 2 libraries with relative path评论:

    用库的相对路径的绝对路径赋值一个变量:

    get_filename_component(LIB_A_PATH ../lib/liba.a ABSOLUTE)
    

    然后使用绝对路径链接lib(这里是静态的):

    add_library( lib_a STATIC IMPORTED )
    set_target_properties(lib_a PROPERTIES IMPORTED_LOCATION ${LIB_A_PATH})
    target_link_libraries(${PROJECT_NAME} lib_a)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-22
      • 2013-12-24
      • 2018-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多