【发布时间】:2020-03-15 01:52:31
【问题描述】:
我有以下问题:我有两组不同的文件(主要文件和附加文件),我想将它们分开。所以,我有一组文件(主要),我是这样配置的:
set(libplayersource
....
)
add_library( # Sets the name of the library.
libplayer
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
${libplayersource})
然后我有第二组文件(附加),我是这样配置的:
set(codec_source
...)
add_library(libcodec SHARED ${codec_source})
最终,我需要链接这两组文件:
target_link_libraries( # Specifies the target library.
libplayer
libcodec)
在这个配置之后,我还需要包含log lib 以使其工作。首先,我需要找到这个log 库,然后将它包含在我的原生库中。
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log)
另外,我应该编辑target_link_libraries 以包含log lib:
target_link_libraries( # Specifies the target library.
libplayer
libcodec
${log-lib})
如果你打算在libplayer 中使用这个log 库,一切都很好,但是如果你打算在libcodec 集合中使用它,你会得到这个错误:
对 `__android_log_print' 的未定义引用
clang++.exe:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)
这意味着链接器没有看到这个方法的实现。
我在 SO 上找到了这个答案:
https://stackoverflow.com/a/47803975/5709159
为了解决这个问题,我在我的CMakeLists 文件中添加了这一行:
target_link_libraries( # Specifies the target library.
libcodec
android
${log-lib}
)
主要 CMake 文件实现:
...
#Main module
set(libplayersource
....
)
add_library( # Sets the name of the library.
libplayer
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
${libplayersource})
#Additional module
set(codec_source
...)
add_library(libcodec SHARED ${codec_source})
#Log lib
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log)
#Linking
target_link_libraries( # Specifies the target library.
libcodec
${log-lib}
)
target_link_libraries( # Specifies the target library.
libplayer
libcodec
${log-lib})
...
所以,我需要在两个库中提及 log lib。
问题是 - 为什么链接器在libcodec 中看不到log lib?为什么我必须添加额外的块?
target_link_libraries( # Specifies the target library.
libcodec
${log-lib}
)
使log lib 对libcodec 中的链接器可见?
P.S 在 Visual Studio 中,如果你有主项目 A 和两个库 B 和 C,你将这些 B 和 C 库包含在 A 中,就是这样;每个人都知道每个人。我可以从 C 调用 B 中的方法等等。为了从 C 调用 B 方法,我不需要在 B 中包含 C。将这两个库作为主项目包含在 A 中就足够了...
如果我错过了问题中的某些内容,请随时提问。
【问题讨论】:
-
因为
libcodec是与程序的其余部分分开编译和链接的。为什么 CMake 应该为您猜测? -
@Botje 编辑了我的问题,添加了 P.S 块
-
你确定 Visual Studio 会为 static 库 (
.libs) AND shared 库 ( DLL)?我希望共享情况在 VS 中同样会失败。 -
@Botje 你的意思是其中一个库应该是静态的,而另一个应该是共享的?我不确定,但如果是其中两个静态 (.lib) ,那么他们可以互相交谈
-
他们不会“互相交谈”。编译器可能会生成带有未满足符号引用的静态库(
.lib文件)。只有当您将可执行文件或另一个共享库中的所有内容链接在一起时,才能解决未满足的符号。如果您在 CMakeLists.txt 中创建libplayer和libcodecSTATIC,您将看到相同的结果。
标签: c++ cmake android-ndk linker