【问题标题】:CMAKE generate a static library that depends on shared librariesCMAKE生成依赖于共享库的静态库
【发布时间】:2021-11-21 05:43:34
【问题描述】:

首先,我正在学习,而且我对 CMake 还很陌生,所以请多多包涵。我已经对此进行了一些研究,但我没有发现任何对我真正有用的东西。我对 CMakeLists.txt 进行了许多更改,但我会尝试向您展示我正在尝试做的事情以及我如何努力实现这一目标。

我有一个像这样的项目文件夹树:

Mainfolder/:
  CMakeLists.txt (CMakeLists1.txt to identify it better)
    lib1:
      source files (.h .c)
      CMakeLists.txt (CMakeLists2.txt)
    lib2:
      source files (.h .c)
      CMakeLists.txt (CMakeLists3.txt)
    executable:
      source files (.h .c)
      CMakeLists.txt (CMakeLists4.txt)

一旦这样说,lib1 和 lib2 将被构建为静态库,并且依赖于例如“rt”和“pthread”共享库。此外,lib2 依赖于 lib1。 我正在交叉编译,所以我使用和脚本加载环境,所有变量似乎都被 CMake 正确识别(我已经打印了它们,并通过编译在目标上正确运行的 Hello world 示例来验证交叉编译)。

CMakeLists1.txt 作为入口点:

project(
  MainApp
  VERSION 0.1
  DESCRIPTION "Main Application CMake compilation project"
  LANGUAGES C)

add_subdirectory(lib1)
add_subdirectory(lib2)
add_subdirectory(executable)

如何编译 lib1 或 lib2?使用以下 CMakeLists2.txt:

cmake_minimum_required(VERSION 3.14...3.16)

project(
  lib1
  VERSION 0.1
  DESCRIPTION "lib1 library"
  LANGUAGES C)

find_library(RT_LIBRARY rt)
find_library(PTHREAD_LIBRARY pthread)

list(APPEND SRCS
        source1.c
        source2.c)

find_library(RT_LIBRARY rt)
find_library(PTHREAD_LIBRARY pthread)

add_library(lib1 ${SRCS})

# Include libraries required
target_link_libraries(lib1 ${PTHREAD_LIBRARY} ${RT_LIBRARY})

CMakelists3.txt 与 CMakelists2.txt 相同,但包含 lib1 依赖项:

find_library(LIB1_LIBRARY lib1)
add_library(lib2 ${SRCS})
target_link_libraries(lib2 ${PTHREAD_LIBRARY} ${RT_LIBRARY} ${LIB1_LIBRARY})
target_include_directories (lib2 PUBLIC {CMAKE_CURRENT_SOURCE_DIR}/../lib1)

我不得不说我也尝试使用 ${CMAKE_CURRENT_SOURCE_DIR}/../lib1/liblib1.a 包含 lib1 依赖项,但它也不起作用。

这些似乎编译得很好,我看到许多“U”未定义符号,我猜这些符号将从共享库中获得(对不起,我在这里怀疑,我不确定它是否应该被认为已经失败)。无论如何,我不确定 lib1 是否链接到 lib2,共享库(rt 和 pthread)也是如此。

最后,CMakeLists4.txt 旨在将所有内容放在一起并生成可执行文件:

cmake_minimum_required(VERSION 3.14...3.16)

project(
  Execuable
  VERSION 0.1
  DESCRIPTION "MainApp library"
  LANGUAGES C)

list(APPEND SRCS
        source1.c
        source2.c)

find_library(RT_LIBRARY rt)
find_library(PTHREAD_LIBRARY pthread)
find_library(RT_LIBRARY rt)
find_library(LIB1_LIBRARY lib1)
find_library(LIB2_LIBRARY lib2)

add_executable(Executable ${SRCS})
target_include_directories (Executable PUBLIC {CMAKE_CURRENT_SOURCE_DIR}/../lib1 {CMAKE_CURRENT_SOURCE_DIR}/../lib2)
target_link_libraries(Executable ${RT_LIBRARY} ${PTHREAD_LIBRARY} ${LIB1_LIBRARY} ${LIB2_LIBRARY})

如果我分别编译每个库,它们似乎可以正确生成 .a 文件,但是当我尝试执行 CMakeLists1.txt 时,它在链接过程中失败,例如在 lib1.a 中显示未定义的引用, shm_open (我发现它与“rt”共享库有关)。所以,我不知道如何解决这种情况。 任何帮助都将受到欢迎。

最好的问候, 福尔戈。

【问题讨论】:

  • 对于在同一个 CMake 项目中创建的库的链接,只需使用其 目标 的名称,而不是该库的路径。例如。 target_link_libraries(lib2 PUBLIC lib1)target_link_libraries(Executable PRIVATE lib2)。这样 CMake 会保留库之间的依赖关系,即使它们不是库文件的一部分。例如。文件lib2.a 不包含与lib1.a 的链接(创建静态库不涉及链接步骤)。但是如果您的可执行文件与lib2 链接,CMake 也会自动 将它与lib1 链接。
  • 但我正在使用 make CMakeLists.txt,目标 lib1 和 lib2 是否传播到顶部 CMakeLists.txt?现在有些东西不适合我。
  • CMake 中的目标具有全局可见性。如果您构建顶级CMakeLists.txt,那么任何子CMakeLists.txt 都可以使用在其他子CMakeLists.txt 中创建的库目标。
  • 你说的很对。现在一切正常。非常感谢。它有点复杂,文档不是很准确,所以出现了很多疑问......

标签: c gcc makefile cmake cross-compiling


【解决方案1】:

Tsyvarev 给了我答案。我不得不避免对同一个 CMake 项目中构建的库使用 find_library。这使我能够正确编译项目。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-03
    • 2016-06-06
    • 1970-01-01
    • 1970-01-01
    • 2021-06-04
    • 1970-01-01
    • 1970-01-01
    • 2015-10-08
    相关资源
    最近更新 更多