gpt4 book ai didi

c++ - 如何以正确的方式构建 CMakeLists?

转载 作者:行者123 更新时间:2023-11-30 01:01:32 27 4
gpt4 key购买 nike

我有以下问题:我有两组不同的文件(主文件和附加文件),我想将它们分开。所以,我有一组文件(主要),我是这样配置的:

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 库,然后将它包含在我的 native 库中。

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 库,一切都很好,但如果您要在 libcodec set 中使用它,你会得到这个错误:

undefined reference to `__android_log_print'

clang++.exe: error: linker command failed with exit code 1 (use -v to see invocation)

这意味着链接器没有看到这个方法的实现。

我在 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 库。

问题是 - 为什么链接器在libcodec 中看不到log 库?为什么我必须添加额外的 block ?

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 方法,我不需要将 C 包含在 B 中。将这两个库作为主项目包含在 A 中就足够了...

如果我遗漏了问题中的某些内容,请随时提问。

最佳答案

如果您的libcodec 使用log-lib 中定义的实现,您必须log-lib 链接到libcodec 显式。这个电话:

target_link_libraries( # Specifies the target library.
libplayer
libcodec
${log-lib})

libcodeclog-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

不过您可以使它更清洁。我们可以移除libplayerlog-lib之间的直接链接,并允许log-lib实现传播通过libcodeclibplayer

target_link_libraries(libcodec PUBLIC
${log-lib}
)

target_link_libraries(libplayer PRIVATE
libcodec
)

这会将依赖图简化为以下内容:

        libplayer
/
libcodec
/
log-lib

参见 this CMake 文档中有关链接时如何以及何时使用 PUBLICPRIVATE 关键字的部分。

关于c++ - 如何以正确的方式构建 CMakeLists?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58935832/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com