【问题标题】:Link a shared library with CMake使用 CMake 链接共享库
【发布时间】:2017-05-29 06:45:47
【问题描述】:

我正在尝试链接一个名为 libtest-lib.so 的预编译共享库文件。这是我在 CMakeLists.txt 底部的内容:

link_directories("/projectspath/LinkTest/TestLib/app/build/intermediates/cmake/debug/obj/armeabi-v7a")

add_library(testlib libtest-lib.so)

target_link_libraries(testlib libtest-lib.so)

如上,我收到以下错误:

CMake Error at CMakeLists.txt:49 (add_library):
  Cannot find source file:
    libtest-lib.so
  Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm     .hpp
  .hxx .in .txx
 CMake Error: CMake can not determine linker language for target:    testlib

如果我注释掉 add_library 行,我会得到以下信息:

CMake Error at CMakeLists.txt:51 (target_link_libraries):
Cannot specify link libraries for target "testlib" which is not built by this project.

在库中链接时似乎绝对需要源文件(.c、cpp 等)。但是如何在 .so 文件中进行链接?文档对 target_link_libraries() 说了以下内容:

named 必须是通过 add_executable() 或 add_library() 等命令在当前目录中创建的。

如果我用 add_executable() 替换 add_library() 我会得到同样的错误。在 CMake 中链接 .so 文件的正确方法是什么?

【问题讨论】:

    标签: c++ cmake shared-libraries


    【解决方案1】:

    我认为你想要的是为 CMake 导入一个库:

     add_library(testlib SHARED IMPORTED)
     set_property(TARGET testlib PROPERTY IMPORTED_LOCATION "/projectspath/LinkTest/TestLib/app/build/intermediates/cmake/debug/obj/armeabi-v7a/libtest-lib.so")
    

    更多信息请参见https://gitlab.kitware.com/cmake/community/wikis/doc/tutorials/Exporting-and-Importing-Targets

    【讨论】:

    • 什么是“导入库”?
    • 对于多架构,将 armeabi-v7a 替换为 ${CMAKE_ANDROID_ARCH_ABI}
    【解决方案2】:

    add_library 创建一个新库。

    相反,您希望将您的库链接到其他目标。

    我们说

    add_executable(main main.cpp)
    target_link_libraries(main libtest-lib)
    

    这应该已经可以了。

    【讨论】:

      【解决方案3】:

      你应该有:

      link_directories("/projectspath/LinkTest/TestLib/app/build/intermediates/cmake/debug/obj/armeabi-v7a")
      set(MY_SOURCES mylib.cpp)
      add_library(testlib ${MY_SOURCES})
      target_link_libraries(testlib libtest-lib)
      

      这意味着您应该将您的库的来源指定为add_library()add_executable() 的第二个参数,而不是已经编译的库。
      您需要源代码,因为通常您构建的东西(库或可执行文件)需要链接到某个已经存在的库。
      否则,你会建造什么?没有?并将图书馆链接到什么?谁会是那个图书馆的消费者?

      【讨论】:

      • 但我没有任何消息来源。重点是链接一个预编译的 .so 文件。
      • ?您想将库链接到什么?什么都没有?
      【解决方案4】:

      我找到了另一种解决方法,在将 lib 链接到可执行文件时提及库所在的路径。

      INCLUDE_DIRECTORIES(/path/to/headers)     
      ADD_EXECUTABLE(TARGET target.c)     
      TARGET_LINK_LIBRARIES(TARGET_FILE "-L/path/to/shared/library" SHARED_LIB_name)
      

      这是间接的,包括库搜索路径标志。在使用库时,可能还必须链接头文件的位置。

      【讨论】:

        【解决方案5】:

        正确的做法是:

        target_link_libraries(native-lib "/projectspath/LinkTest/TestLib/app/build/intermediates/cmake/debug/obj/${ANDROID_ABI}/libtest-lib.so")
        

        【讨论】:

        • 这绝对不是正确的方法。您永远不会输入直接路径,但您会找到库,将结果存储在变量中并将变量传递给 target_link_libraries。
        • 当然最好放在变量中。关键是,上面的有效,而其他答案都没有。你执着于不重要的细节。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-04
        • 1970-01-01
        • 1970-01-01
        • 2021-07-25
        • 2013-10-09
        • 2016-01-08
        相关资源
        最近更新 更多