使用CMake链接共享库

18

我正在尝试链接一个预编译的共享库文件,名为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() 给出了以下说明:

所命名的 library 必须已由诸如 add_executable() 或 add_library() 等命令在当前目录中创建。

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

6个回答

28

什么是“导入库”? - zwcloud
3
针对多架构,请将 armeabi-v7a 替换为 ${CMAKE_ANDROID_ARCH_ABI}。 - Matthew Grivich

9

add_library创建一个新的库。

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

假设

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

这应该已经可以正常工作了。

2
你应该有:

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(),而不是已经编译好的库。
您需要自己的源代码,因为通常您构建的内容(库或可执行文件)需要链接到某些已经存在的库。
否则,您会构建什么?什么东西来链接库?谁会使用那个库?

1
但是我没有任何源代码。整个重点是链接一个预编译的 .so 文件。 - Dimitri Lozovoy
2
你想要将一个库链接到什么?什么都不需要吗? - fedepad

0
我找到了另一个解决方法,即在将库链接到可执行文件时提及库所在的路径。
INCLUDE_DIRECTORIES(/path/to/headers)     
ADD_EXECUTABLE(TARGET target.c)     
TARGET_LINK_LIBRARIES(TARGET_FILE "-L/path/to/shared/library" SHARED_LIB_name)

这是一种间接包含库搜索路径标志的方法。在使用库时,可能还需要链接头文件的位置。


0

正确的做法是:

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

7
那绝对不是正确的方法。你永远不应该直接输入路径,而是找到库,将结果存储在变量中,并将变量传递给target_link_libraries函数。 - usr1234567
4
当然最好将其放入变量中。重点是,上述代码“有效”,而其他答案均无法实现。你在纠缠于不必要的细节。 - Dimitri Lozovoy
当直接下载/克隆库时,我发现这是最简单的方法。还要注意,这种方法在官方文档的第二个要点中提到:https://cmake.org/cmake/help/latest/command/target_link_libraries.html#target-link-libraries - undefined

0
这是另一种(稍微更清晰)的方式(Derekref):
# -----
# Shared Library for runtime: your SO file(s) without directory
# The actual file should be "libtest-lib.so", but you put without "lib" in here. (you could still put "libtest-lib.so" in here) 
# This is guide from my reference link
set ( PROJECT_LINK_LIBS test-lib.so )
link_directories( /projectspath/LinkTest/TestLib/app/build/intermediates/cmake/debug/obj/armeabi-v7a )
.
.
.
# -----
# Compiling CPP code
set ( SOURCES <your CPP file with directory> )
add_executable ( testlib ${SOURCE} )
# Calling Shared Library
# Please match the executable with above "add_executable"
target_link_libraries( testlib PROJECT_LINK_LIBS )

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接