如何使用cmake管理多个构建配置

时间:2019-08-20 03:17:27

标签: c++ cmake

我正在尝试思考如何设计新的项目构建系统。
我想使用CMake为Windows和Linux进行编译。我想要发布和调试版本,这很简单。

问题是我将在接下来的几年中将这个软件部署到多个硬件项目中。这意味着我将拥有预处理器定义来打开/关闭和/或更改C ++程序中的功能。我还将要链接配置特定的库。当前的旧项目使用带有定义列表的标头,然后链接所有可能的项目依赖项。

示例标头:

// projects.h

//#define project1
//#define project2
#define project3

这意味着要更改硬件/项目配置,必须编辑此文件以确保选择了正确的硬件配置。
我要做的是为每个项目都有一个配置,也可以为发布或调试版本进行配置。

关于如何在CMake中更好地处理此问题,是否有任何建议?

1 个答案:

答案 0 :(得分:0)

  

用于多个硬件项目

对我来说,它变得凌乱,并且很快变得凌乱。

我的目标是:

  • 我不喜欢单个大config.h文件。我不想重新编译100%的文件,因为我在中央config.h文件中添加了一个空格
  • 所有开发板都公开了用户应用程序可以使用的API。董事会不能混在一起。
  • 我可以轻松添加新的开发板,并拥有一个测试应用程序的开发板。

我发现的是:

  • cmake用于为您的项目配置不同的配置。因此,cmake不会存储一个配置,而是用来选择一个配置。
  • 因此您需要“外部”位置来存储当前项目的配置
  • 我有多个应用程序和多个开发板,所选的应用程序配置选项存储在makefile中。然后,此makefile配置cmake,进而配置构建系统,然后可以使用该构建系统来构建应用程序。之所以如此,是因为cmake每个工具链支持一种配置。因此,对于具有不同编译器/编译器选项的体系结构,我必须重新运行cmake。

我基本上有这样的目录结构:

- app
  - CMakeLists.txt
  - main.c
  - lib.c
- boards               # this is actually git submodule shared between multiple projects
  - boardapi           # generic board api library
    - CMakeLists.txt
    - uart_api.h       # exposes an api to access uart
    - spi_api.h
    - timer_api.h
    - board_api.h
    - some_defines.h    # includes some_defines_impl.h
  - BOARD1
    - toolchain.cmake
    - CMakeLists.txt
    - implementation1.c
    - implementation2.c
    - some_defines_impl.h
  - BOARD2
    - toolchain.cmake
    - CMakeLists.txt
    - implementation1.c
    - implementation2.c
    - some_defines_impl.h
  - linux
    - ... as above ...
  - armv5te
    - ... as above ...
  - CMakeLists.txt
- CMakeLists.txt
- Makefile
  • 我有一个boards目录,每块板有多个文件夹。
  • 每个文件夹都有自己的toolchain.cmake文件和CMakeLists.txt文件
  • 在board文件夹中的每个CMakeLists.txt中,都会添加一个带有该文件夹名称的库。
  • 我有一个makefile,它会为我要为其编译该应用程序的所有电路板进行迭代,并为每个电路板运行cmake + make。基本上是BOARDS=BOARD1 BOARD2,然后是all: $(foreach board,$(BOARDS),cmake;make;)
  • 为cmake配置了cmake -DCMAKE_TOOLCHAIN_FILE=board/$(BOARD)/toolchain.cmake -DBOARD=$(BOARD)
  • board/CMakeLists.txt文件的全部作用是add_subdirectory(${BOARD})add_library(board INTERFACE ${BOARD})
  • 主要CMakeLists.txt执行add_subdirectory(boards),然后执行link_libraries(boards)。那应该将所有库与板库链接起来。
  • 每个board目录依次控制特定的电路板配置。
  • 如果您有多个项目配置,则就像对待普通项目一样,不关心开发板。示例:在app/CMakeLists.txt中对其进行迭代,如下所示:

foreach(i IN LISTS project1 project2 project3) 
    add_executable(main+${i} main.c app.c)
    target_add_definitions(${i}) 
endforeach()

或者,如果是。宏很多,您可以创建另一个结构projects/{project1,project2,project3}并重新创建与电路板相同的结构,但是没有toolchain.cmake文件。然后,只需迭代foreach项目并执行target_link_libraries(main+${i} ${i}),即可有效地将所有宏定义引入主应用程序。