【问题标题】:How to force Cmake execute a top-level CMakeLists.txt of a multi component dependency?如何强制 Cmake 执行多组件依赖的顶级 CMakeLists.txt?
【发布时间】:2018-09-24 06:56:08
【问题描述】:

我正在尝试让我的 android 项目支持 C。假设我有以下结构(一切都是源目录,没有二进制文件):

CMakeLists.txt
src/main/cpp/|
             |---Executable1/
             |---Executable2/
             |---deps/

在这个 CMakeLists.txt 我有:

cmake_minimum_required(VERSION 3.4.1)
project(ProjectName)
set(CMAKE_VERBOSE_MAKEFILE on)
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/src/main/assets/${ANDROID_ABI}")
add_subdirectory(src/main/cpp/deps)
add_subdirectory(src/main/cpp/Executable1)
add_subdirectory(src/main/cpp/Executable2)

在“deps”文件夹中,我有以下结构:

deps/|
     |---CMakeLists.txt
     |---Library1/
     |---LIbrary2/

在这个 CMakeLists.txt 我有:

add_subdirectory(Library1)
add_subdirectory(Library2)

在 Library2 中我有 2 个模块:

Library2/|---CMakeLists.txt
         |---Module1/
         |---Module2/

在这个 CMakeLists.txt 我有

project(Library2)
include_directories ( BEFORE SYSTEM ${CMAKE_CURRENT_BINARY_DIR}/Module1
                                ${CMAKE_CURRENT_BINARY_DIR}/Module2
                                Module1
                                . )
add_subdirectory( Module1 )
add_subdirectory( Module2 )

Module1 和 Module2 是我添加的库

add_library(Module1 STATIC sourceM1_1.c sourceM1_2.c ...)

add_library(Module2 STATIC sourceM2_1.c sourceM2_2.c ...)

分别在他们的 CMakeLists.txt 中。

Executable2 在其 CMakeLists.txt 中有:

add_executable(Executable2  sourceE2_1.c sourceE2_2.c ...)
target_link_libraries(Executable2 Module1 Module2)

如果以这种方式制作,我在编译 Module1 时会出错。

错误表示未找到某些标头。这些标头存在于“Library2”目录中。

如果我在最顶层的 CMakeLists.txt 中注释掉 Executable2,一切都可以正常编译。

所以问题是如何强制 CMake 执行“Library2/CMakeLists.txt”中的指令,或者我必须做些什么来添加所需的包含目录?我想我可以将它们直接添加到“Module1”和“Module2”的 CMakeLists.txt 但我认为这不是一个好习惯。

【问题讨论】:

  • "编译 Module1 时出现错误。" ...“如果我在最顶层的 CMakeLists.txt 中注释掉 Executable2,一切都编译得很好。” - 所以你在编译 executable Executable2 时得到错误,而不是在编译 module Module1 时,不是吗?
  • 没有。实践表明,如果我有一些依赖于某些库的可执行文件,cmake 从上到下遍历 CMakeLists.txt 的层次结构,仅提取与可执行文件的依赖项相对应的那些目标,构建它们,构建可执行文件和将可执行文件链接到库。如果库是静态的,情况就是如此。如果它们是共享的,它们也会包含在 APK 中,但过程看起来是一样的。如果我有一些库目标并且没有任何依赖于它们,则它们是根据 CMakeLists 层次结构独立构建的,如果它们被共享,它们将包含在 APK 中。
  • 我不是 Android 专家,但从 CMake 的角度来看,事情与您描述的不同。请用确切的错误消息更新您的问题,其中包括构建的目标文件的名称。
  • 嗯,实际上我自己已经找到了一种解决方法,并且无法重现完全相同的错误。我只能说 Library2 是带有来自https://github.com/pol51/OpenSSL-CMake 的 CMake 构建系统的 OpenSSL,问题出在构建加密库时,它说在第 64 行的标题 e_os.h 中它不能引用
  • build.gradle 中,您可以指定 targets 以覆盖自然 CMake 偏好以构建可执行文件。

标签: android c android-studio makefile cmake


【解决方案1】:

好吧,一段时间后,我自己找到了解决方法。我无法让 Cmake 不忽略 Library2 CMakeLists.txt,因此我只是将引用 Library2 的缺失 include_directory 添加到 Module1 和 Module2 CMakeLists.txt。

【讨论】:

  • 这意味着,在 Module1/CMakeLists.txt 你现在说 include_directories ( BEFORE SYSTEM ${CMAKE_CURRENT_BINARY_DIR))Module2 相同?
  • 这意味着我将BEFORE SYSTEM ${PROJECT_SOURCE_DIR}/src/main/cpp/Library2) 添加到include_directories。正如我在上一条评论中所说的那样,我对 OpenSSL 及其 Crypto 和 LibSSL 模块有疑问。在这一步之后我还遇到了一些其他问题,但这些问题都是类比解决的。
  • 其实更好的做法是使用target_include_directories(Module1 PUBLIC ${CMAKE_CURRENT_BINARY_DIR)/.. ),而不是乱码include_directories
猜你喜欢
  • 2015-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-22
  • 1970-01-01
  • 1970-01-01
  • 2012-08-06
  • 2019-06-07
相关资源
最近更新 更多