【问题标题】:CMake/CMakeLists.txt: how to list files explicitly (to avoid the use of GLOB)CMake/CMakeLists.txt:如何显式列出文件(避免使用 GLOB)
【发布时间】:2021-09-13 08:29:10
【问题描述】:

我是 CMake 的新手。今天,我在我的 Android/Java/JNI/CMake 项目中使用了我的 CMakeLists.txt 文件中的以下代码:

include_directories(lib1)
file(GLOB_RECURSE LIB1_SOURCES
"bund.cc"
"bund.h"
"bund_io.cc"
"bund_io.h"
"cam.cc"
"cam.h"
"defines.h"
)

include_directories(lib2)
file(GLOB_RECURSE LIB2_SOURCES
"allocator.h"
"memory.h"
"arguments.cc"
"arguments.h"
"defines.h"
)

add_library(native-lib SHARED ${LIB1_SOURCES} ${LIB2_SOURCES} native-lib.cpp)
find_library(log-lib log)
target_link_libraries(native-lib ${log-lib})

作为CMake documentation'不建议使用GLOB 从源代码树中收集源文件列表',我想知道在我的CMakeLists.txt 中替换此代码的推荐方法是什么。请注意,我在 lib1 和 lib2 目录中都有一个“defines.h”,可能需要采取一些特定的预防措施。

我的项目结构是:

-cpp (with mib-native.cpp and CMakeLists.txt inside)
--lib1 (with .h and .cc files mixed inside)
--lib2 (with .h and .cc files mixed inside)

如果您能提供我必须放入我的 Android 项目中的详细代码,我将不胜感激。

【问题讨论】:

  • 只在add_library 命令中明确列出源文件和头文件?

标签: java c++ cmake android-ndk java-native-interface


【解决方案1】:

假设您有一些在库之间共享的依赖项,为什么不创建一个单独的依赖项并在其他两个目标中使用它?

此外,明确的源规范可能是目前最好的做法。在大型项目中,不鼓励使用 glob,而是创建更小的目标,然后将其添加到更大的目标中。在您的情况下,我将创建两个库(就像您一样),但明确列出来源。

我会这样做:(首先尝试将代码拆分为库的目录,最好为共享标题创建一个文件夹)

# put all finds in one place
find_library(LOG_LIB log)

add_libary(LIB_1 STATIC
           ${CMAKE_CURRENT_LIST_DIR}/"bund.cc"
           ${CMAKE_CURRENT_LIST_DIR}/"bund_io.cc"
           ${CMAKE_CURRENT_LIST_DIR}/"cam.cc")

target_include_directories(LIB_1 
                           ${CMAKE_CURRENT_SOURCE_DIR}/lib1_includes
                           ${CMAKE_CURRENT_SOURCE_DIR}/common_includes)

add_libary(LIB_2 STATIC
           ${CMAKE_CURRENT_LIST_DIR}/"arguments.cc")

target_include_directories(LIB_2 
                           ${CMAKE_CURRENT_SOURCE_DIR}/lib2_includes
                           ${CMAKE_CURRENT_SOURCE_DIR}/common_includes)

add_library(NATIVE_LIB SHARED
            ${CMAKE_CURRENT_LIST_DIR}/native-lib.cpp)

target_link_libraries(NATIVE_LIB
                      PRIVATE 
                      ${LIB_1} ${LIB_2} ${LOG_LIB}) # I also prefer to use upper case for targets, otherwise you can have nasty to spot linking errors 

另一个想法是为库创建单独的目录树并为它们创建 CMakeFiles.txt 并将它们用作目标。在here 和随附的blog post 中查看它是如何完成的。

您还将在那里了解 PRIVATE 关键字名称的含义(简而言之,它不会公开链接到您创建的库之外的库的符号。

【讨论】:

  • 非常感谢您的帮助。我不明白什么是 lib1_includes ?您是否将 lib 的所有 .h 文件放在同一个文件夹中,而将 .cc 文件放在另一个文件夹中?我也不明白什么是 common_includes ;你能提供更多细节吗?了解有关您想到的项目结构(文件夹)的更多详细信息也会有所帮助。我用我的项目结构更新了我的问题。谢谢。
  • 如果您能回答这个问题,我将不胜感激:stackoverflow.com/questions/68210898/… 我完全迷失在这些疯狂的 CMakeLists 文件中!
  • @Regis_AG 您可以将标头与源一起保留,但更好的方法是将源和标头拆分到不同的目录。 Common includes 将是这两个库之间共享的公共标头的附加目录。所以最后你会为每个库创建一个目录,并在每个库中拆分 src/include 目录。还有一个用于 common 包含的特殊文件夹,其中仅包含包含目录。
  • 一定要阅读链接资源,你会很快精通 CMake 文件(或者至少有一些必要的工作知识来设置你自己的项目)
猜你喜欢
  • 2021-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-14
  • 2013-03-11
  • 2016-04-24
  • 2011-08-18
  • 1970-01-01
相关资源
最近更新 更多