【问题标题】:How to write "CMakeLists.txt" for a big project with multiple subdirectories?如何为具有多个子目录的大项目编写“CMakeLists.txt”?
【发布时间】:2023-03-16 22:38:01
【问题描述】:

我正在从事一个模拟项目:从目标平台获取嵌入式 C 代码库,并尝试在主机计算机上对其进行模拟以进行调试或单步执行代码。

操作系统:Ubuntu Linux 14.04,IDE:CodeLite,Makefile 生成器:Cmake。我对如何为项目编写 CMakeLists.txt 感到困惑。以下是代码库的结构(全部用C编写):

|ARQSim\  
|-->ARQSim.h  
|-->ARQSim.c  
|-->BaseStationCode\  
|   |->downlink.c  
|   |->neoncopy.c  
|   |->armCore\  
|   |  |->common\  
|   |  |  |->Bsconfig.h  
|   |  |  |->config.h  
|   |  |->MacSource\  
|   |  |  |->lib\  
|   |  |  |  |->arqCommon.h  
|   |  |  |  |->OverTheAir.h  
|   |  |  |->source\  
|   |  |  |  |->beacon.c  
|   |  |  |  |->proxyDhcp.c  
|   |  |  |  |->ARQ\  
|   |  |  |  |  |->arqCommon.c  
|   |  |  |  |  |->arqInterface.c  
|   |  |  |  |  |->fragmentation\  
|   |  |  |  |  |  |->fragBookkeeping.c  
|   |  |  |  |  |  |->fragProcessAck.c  
|   |  |  |  |  |->reassembly\  
|   |  |  |  |  |  |->reasmBookkeeping.c  
|   |  |  |  |  |  |->reasmProcessAck.c

我对 Cmake 完全陌生。我在 StackOverflow 上阅读了很多关于 CMake 和线程的资源。但我每次都感到困惑。我有几个问题:

  1. 我需要根目录下只有一个 CMakeLists.txt 还是每个目录都需要一个不同的 CMakeLists.txt 文件?
  2. 如何在 CMakeLists.txt 中递归添加源文件?
  3. 为了生成 MakeFile,我需要在 CMakeLists.txt 中放入哪些基本命令?

基于上述代码结构的示例将不胜感激。

【问题讨论】:

  • 上面列出的结构似乎一团糟。您可能需要先将其分成几个项目。
  • 你的目标没有调试器吗?
  • @VTT 是的,我同意,结构混乱了,我还没有在这里发布整棵树。我希望我有时间来组织它,但我需要尽快开始调试,因此我采用了嵌入式代码库。谢谢
  • @ChristianGibbons :我们在嵌入式平台上有一个调试器。但是,它在 No-OS-Bare-Metal-while(1) 上运行并且在平台上进行调试非常疯狂。目标平台 (OMAP) 依赖于来自板载 FPGA 和 DSP 的持续中断反馈。单步停止此反馈(无线调制停止,因此没有来自 DSP 的反馈)。我要调试的边缘情况需要始终打开无线调制。这就是为什么我们试图在主机 PC 上模拟场景并单步进入它的原因。

标签: c linux makefile cmake codelite


【解决方案1】:

我是在根目录中只需要一个CMakeLists.txt,还是每个目录都需要一个不同的CMakeLists.txt 文件?

你通常会在树的每一层都有一个有意义的地方

例如:

root/
+--- CMakeLists.txt             // your root CMakeLists
+--- foo/
|    +--- CMakeLists.txt        // foo component's CMakeLists
|    +--- foo.c
|    +--- tests/
|         +--- CMakeLists.txt   // foo test's CMakeLists
|         +--- foo_tests.c
+--- bar/
     +--- CMakeLists.txt        // bar component's CMakeLists
     +--- bar.c
     +--- bar_impl/             // no CMakeLists for this dir, it is part of bar
     |    +--- bar_impl.c
     +--- tests/
          +--- CMakeLists.txt   // bar test's CMakeLists
          +--- bar_tests.c

项目根 CMakeLists.txt:

在您的项目根CMakeLists.txt 中,您指定最低 cmake 要求、项目名称,并包括包含您的各种组件的子目录

root/CMakeLists.txt:

cmake_minimum_required (VERSION 3.5)
project (my_project C)

add_subdirectory(foo)
add_subdirectory(bar)

组件 CMakeLists.txt:

然后在每个组件子目录中,您有另一个 CMakeLists.txt 文件,您可以在其中添加库、可执行文件等

root/foo/CMakeLists.txt:

add_library(foo foo.c)
target_include_directories(foo PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

add_subdirectory(tests)

root/foo/tests/CMakeLists.txt:

add_executable(foo_test foo_tests.c)
target_link_libraries(foo_test foo)

你按照这个结构来做酒吧等......

root/bar/CMakeLists.txt:

add_library(bar 
    bar.c 
    bar_impl/bar_impl.c)
target_include_directories(bar PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(bar foo)

add_subdirectory(tests)

root/bar/tests/CMakeLists.txt:

add_executable(bar_test bar_tests.c)
target_link_libraries(bar_test bar)

生成构建文件:

要引导您的构建,请将 cmake 指向您的 root/CMakeLists.txt

cd root
mkdir build
cd build
cmake ..

(或使用您 ide 的构建管理器生成其构建配置)

进一步阅读

有关我在这里使用的各种功能的详细信息,请参阅文档:

最后,回答你的第二个问题:

如何在 CMakeLists.txt 中递归添加源文件?

不建议这样做(有关详细信息,请参阅this discussion)。

最好明确列出要包含在目标中的每个文件。

请注意,如果您在多个单独的目录中有源文件,但它们都属于同一个逻辑目标,那么您不需要为每个目录创建一个 CMakeLists.txt 文件 - 只需在文件名中列出子目录

示例:

foo/
+--- foo.c
+--- bar.c
+--- baz/
     +--- baz.c
     +--- bang.c

如果您想为上述所有文件创建一个目标 foo,您可以按如下方式创建它:

add_library(foo 
   foo.c
   bar.c
   baz/baz.c
   baz/bang.c)

或者如果你真的想用一个变量来存储SRCS的列表

set(SRCS 
   foo.c
   bar.c
   baz/baz.c
   baz/bang.c)

add_library(foo ${SRCS})

【讨论】:

  • 感谢史蒂夫的详细说明。现在对我来说更清楚了。现在我可以从某个地方开始,连同您提供的文档,希望我能够快速深入研究。非常感谢您的反馈。
  • @Steve : 我能知道这个project (my_project C) 行是什么意思吗?
  • @AkshayRaiyani 它是 project 定义 - my_project 是项目的名称(可在变量 ${PROJECT_NAME} 中访问,并由一些构建系统(如 Visual Studio)使用。)C表示该项目是 C 语言项目(您也可以使用,例如,CXX 来表示 C++ 语言项目)。 cmake 要求项目的顶级 CMakeLists.txt 必须包含对此的文字调用
【解决方案2】:

我还在寻找一种更通用的方法来将 CMakeLists.txt 文件添加到我的项目中。我决定编写一个 CMake 生成器(部分原因是我想了解 CMake 的工作原理):

https://github.com/Aenteas/cmake-generator

它有几个附加功能,例如创建 python 包装器 (SWIG)。

编写适合所有人的生成器是不可能的,但我希望它能给你一个想法,以防你想制作你的定制版本。

【讨论】:

    猜你喜欢
    • 2020-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-10
    • 1970-01-01
    相关资源
    最近更新 更多