如何以正确的方式构建CMakeLists?
How to build CMakeLists the right way?
>我有以下问题:我有两组不同的文件(主文件和一组附加文件),我想将它们分开。因此,我有一组文件(主文件),我以这种方式配置:
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
库才能使其工作。首先,我需要找到这个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
库:
target_link_libraries( # Specifies the target library.
libplayer
libcodec
${log-lib})
如果您要在libplayer
中使用此log
lib,一切都很好,但是如果您要在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}
)
Main 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
库。
问题是- 为什么链接器在libcodec
中看不到log
库?为什么我必须添加额外的块?
target_link_libraries( # Specifies the target library.
libcodec
${log-lib}
)
使log
库对libcodec
中的链接器可见?
P.S在Visual Studio中,如果你有主项目A和两个库B和C,你可以在A中包含这些B和C库,就是这样;每个人都知道每个人。我可以从 C 调用 B 中的方法,依此类推。为了从 C 调用 B 方法,我不需要在 B 中包含 C。这两个库都包含在 A 中作为主项目就足够了......
如果我错过了问题中的某些内容,请随时提问。
如果您的libcodec
使用log-lib
中定义的实现,则必须log-lib
显式链接到libcodec
。此调用:
target_link_libraries( # Specifies the target library.
libplayer
libcodec
${log-lib})
libcodec
和log-lib
链接到libplayer
,它不会log-lib
链接到libcodec
。它暗示了这个依赖关系图:
libplayer
/
libcodec log-lib
target_link_libraries()
调用的第一个参数是"链接到"库,以下所有目标都链接到第一个。因此,您需要将log-lib
链接到libcodec
,如下所示:
target_link_libraries( # Specifies the target library.
libcodec
${log-lib}
)
现在,libcodec
将了解log-lib
中定义的实现,这意味着这里的依赖关系图:
libplayer
/
libcodec log-lib
/
log-lib
不过,你可以让它更干净。我们可以删除libplayer
和log-lib
之间的直接链接,并允许log-lib
实现通过libcodec
传播到libplayer
。
target_link_libraries(libcodec PUBLIC
${log-lib}
)
target_link_libraries(libplayer PRIVATE
libcodec
)
这会将依赖关系图简化为以下内容:
libplayer
/
libcodec
/
log-lib
请参阅 CMake 文档中的此部分,了解如何以及何时在链接时使用PUBLIC
和PRIVATE
关键字。
- C++为构建时间获取QDateTime的可靠方法
- 无法在 CLion 中构建 C++ 项目
- 函数向量_指针有不同的原型,我可以构建一个吗
- 以现代 CMake 方式控制包含的库中的构建选项(测试等)
- 如何以正确的方式构建CMakeLists?
- 如何以链式方式在两个容器上构建迭代器
- 在编译时以增量方式构建变量指针的向量
- 我是在构建正确的组织角色的方式,以便我可以计数它们
- 以编程方式构建一个叮当作响的AST
- 干燥的方式来构建具有相同初始化器列表的数组的所有元素
- 在C 中以通用方式构建对象,设置字段并返回对象
- 如果与未使用的库链接,可执行文件的构建方式是否不同?
- Eclipse,构建共享库的最佳方式
- 以独立于路径/安装/构建的方式了解资源路径的好方法
- 在开源社区中,构建C/C++程序的最佳方式是什么
- 在C++中构建类的最佳方式
- 构建与 Android 应用程序通信的C++程序的最佳方式
- 为客户端-服务器通信构建TCP/IP服务器的最佳方式
- 将字符串构建为多个片段的最佳方式
- 在构建机器上注册.tlb的首选方式是什么