iarsystems/cmake-tutorial
GitHub: iarsystems/cmake-tutorial
IAR Systems 提供的官方教程,指导开发者使用 CMake 配合 IAR 编译器从命令行构建和测试嵌入式 C/C++ 项目。
Stars: 104 | Forks: 19
# 使用 IAR 构建 CMake 项目
[](https://github.com/iarsystems/cmake-tutorial/actions/workflows/ci.yml) [](https://github.com/iarsystems/cmake-tutorial/actions/workflows/codeql.yml)
CMake 是由 Kitware 维护和支持的一系列开源、跨平台工具。在其众多功能中,它主要提供了 [Makefile 生成器](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id11) 和 [Ninja 生成器](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id12),这些生成器能够基于一个或多个 `CMakeLists.txt` 配置文件,生成用于交叉编译 C/C++ 嵌入式软件项目的脚本。
本教程旨在为希望了解如何从命令行开始将 IAR C/C++ Compiler 与 CMake 结合使用的读者提供简短介绍。如需深入了解,请访问 [__cmake-tutorial wiki__](https://github.com/iarsystems/cmake-tutorial/wiki)。
## 前置条件
在开始之前,您需要下载并安装 IAR 产品和 CMake,然后克隆此仓库。
1. 下载、安装并激活[^1]您的 IAR 产品
2. 下载并安装 [CMake](https://github.com/Kitware/CMake/releases/latest)。
3. 将此仓库克隆到您的计算机。有关更多信息,请参阅 [“克隆仓库”](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository)。
## 构建基础 CMake 项目
最基础的 CMake 项目是由单个源代码文件构建的可执行文件。对于像这样的简单项目,只需要一个包含大约六条命令的 `CMakeLists.txt` 文件即可。
任何项目最顶层的 `CMakeLists.txt` 都必须首先使用 [`cmake_minimum_required()`][url-help-cmake_minimum_required] 命令指定最低的 CMake 版本。这会建立策略设置,并确保项目中使用的 CMake 功能在兼容的 CMake 版本下运行。
要启动项目,请使用 [`project()`][url-help-project] 命令设置项目名称。每个项目都需要进行此调用,并且应在 `cmake_minimum_required()` 之后立即调用。此命令还可用于指定其他项目级别的信息,例如使用的语言或版本号。
使用 [`add_executable()`][url-help-add_executable] 命令告诉 CMake 使用指定的源代码文件创建一个可执行文件。
然后使用 [`target_sources()`][url-help-target_sources] 列出构建 target 所需的源文件。
使用 [`target_compile_options()`][url-help-target_compile_options] 来设置构建 target 的编译器选项。
最后,使用 [`target_link_options()`][url-help-target_link_options] 设置 target 的链接器选项:
```
# 设置 CMake 的最低要求版本为 3.20
cmake_minimum_required(VERSION 3.20)
# 设置项目名称
project(Tutorial)
# 添加 executable target
add_executable(tutorial)
# target sources
target_sources(tutorial PRIVATE tutorial.c)
# compiler options
target_compile_options(tutorial PRIVATE
--dlib_config full
--cpu=cortex-m4)
# linker options
target_link_options(tutorial PRIVATE
--cpu=cortex-m4
--semihosting)
```
### 启用 IAR Compiler
CMake 默认使用宿主平台的编译器。在交叉编译嵌入式应用程序时,必须通过 [`CMAKE__COMPILER`](https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER.html) 变量为每种支持的语言手动设置编译器。此外,还可以通过 [`CMAKE_MAKE_PROGRAM`]() 指定构建工具:
| 变量 | 描述 | 示例 (用于 Arm)
| - | - | -
| `CMAKE_C_COMPILER` | 必须指向 C 编译器可执行文件 | `"/opt/iar/cxarm/arm/bin/iccarm"`
`"/opt/iarsystems/bxarm/arm/bin/iccarm"`
`"C:/iar/..../arm/bin/iccarm.exe"` | `CMAKE_CXX_COMPILER` | 必须指向 C++ 编译器可执行文件 | `"/opt/iar/cxarm/arm/bin/iccarm"`
`"/opt/iarsystems/bxarm/arm/bin/iccarm"`
`"C:/iar/..../arm/bin/iccarm.exe"`
`"${CMAKE_C_COMPILER}"` | `CMAKE_ASM_COMPILER` | 必须指向汇编器可执行文件 | `"/opt/iar/cxarm/arm/bin/iasmarm"`
`"/opt/iarsystems/bxarm/arm/bin/iasmarm"`
`"C:/iar/..../arm/bin/iasmarm.exe"` | `CMAKE_MAKE_PROGRAM` | 必须指向构建工具可执行文件 | `"/opt/iar/cxarm/common/bin/ninja"`
`"/opt/iarsystems/bxarm/common/bin/ninja"`
`"C:/iar/..../common/bin/ninja.exe"` - 一个单独的名为“toolchain file”的文件,您可以在调用 `cmake` 时加上 `--toolchain /path/to/.cmake`(参见提供的示例文件 [cxarm.cmake](tutorial/cxarm.cmake)、[bxarm.cmake](tutorial/bxarm.cmake) 和 [ewarm.cmake](tutorial/ewarm.cmake)) -或者-
- [`CMAKE_TOOLCHAIN_FILE`](https://cmake.org/cmake/help/latest/variable/CMAKE_TOOLCHAIN_FILE.html) 变量,当您在调用 `cmake` 时加上 `-DCMAKE_TOOLCHAIN_FILE=/path/to/.cmake`(适用于 CMake < 3.21 版本) -或者-
- 在调用 `cmake` 时加上 `-DCMAKE__COMPILER=/path/to/icc` -或者-
- 用户/系统环境变量 [`CC`](https://cmake.org/cmake/help/latest/envvar/CC.html)、[`CXX`](https://cmake.org/cmake/help/latest/envvar/CXX.html) 和 [`ASM`](https://cmake.org/cmake/help/latest/envvar/ASM.html),可用于覆盖平台的默认编译器 -或者-
- IAR Embedded Workbench IDE 9.3 或更高版本(自 IAR Embedded Workbench for Arm 9.50 起随 IAR 产品附带),其中可用的 IAR toolchain 环境会自动为 CMake 项目设置(详见[此文](https://github.com/IARSystems/cmake-tutorial/wiki/Building-and-Debugging-from-the-Embedded-Workbench))。
### 配置和构建
我们已经准备好构建第一个项目了!运行 CMake 配置项目,然后使用您选择的构建工具进行构建。
- 在开始使用 CMake 之前,请确保您的编译器正常工作。下面是一个单行命令,它会尝试编译一个简单的模块:
```
$ echo "main(){}" | /opt/iar/cxarm/arm/bin/iccarm --output $(mktemp) -
IAR ANSI C/C++ Compiler V9.70.2.500/LNX for ARM
Copyright 1999-2025 IAR Systems AB.
LMS Cloud License (LMSC 2.1.1)
4 bytes of CODE memory
Errors: none
Warnings: none
```
- 在终端中,导航到 [tutorial](tutorial) 目录并创建一个构建目录:
```
mkdir build
```
- 接下来,导航到该构建目录并运行 CMake 以配置项目,并使用 `cxarm.cmake` toolchain 文件中指定的编译器生成本地构建系统(如有必要,请编辑提供的 toolchain 文件以匹配您的工具):
```
cd build
cmake .. -G Ninja --toolchain ../cxarm.cmake
```
- 然后调用 CMake 使用构建系统构建可执行文件:
```
cmake --build .
```
## 运行
让我们测试一下该应用程序。要运行可执行文件,您将需要用于 IAR C-SPY Debugger (`cspybat`) 的非交互式[^4]命令行界面,以及适用于所需 target 的正确驱动程序。在众多实现方法中,让我们利用 `add_test()` 在 Arm Cortex-M4 模拟 target 上测试该应用程序。
本节是交互式的。在这个示例中,我们将使用 Arm。因此,您需要更新 Tutorial 的 `CMakeLists.txt`:
- 首先添加 [`enable_testing()`](https://cmake.org/cmake/help/latest/command/enable_testing.html) 以启用测试:
```
enable_testing()
```
- 然后使用 [`add_test()`](https://cmake.org/cmake/help/latest/command/add_test.html) 封装 `cspybat` 所需的命令行。在下面的示例中,参数已调整为用于模拟通用的 Arm Cortex-M4 target 环境:
```
# 从 CMAKE_C_COMPILER 推断附加信息
cmake_path(GET CMAKE_C_COMPILER PARENT_PATH BIN_DIR)
cmake_path(GET BIN_DIR PARENT_PATH TOOLKIT_DIR)
cmake_path(GET TOOLKIT_DIR FILENAME TOOLKIT)
add_test(NAME tutorialTest
COMMAND ${BIN_DIR}/../../common/bin/CSpyBat
# C-SPY drivers for the Arm simulator via command line interface
${BIN_DIR}/${CMAKE_SHARED_LIBRARY_PREFIX}${TOOLKIT}PROC${CMAKE_SHARED_LIBRARY_SUFFIX}
${BIN_DIR}/${CMAKE_SHARED_LIBRARY_PREFIX}${TOOLKIT}SIM2${CMAKE_SHARED_LIBRARY_SUFFIX}
--plugin=${BIN_DIR}/${CMAKE_SHARED_LIBRARY_PREFIX}${TOOLKIT}LibsupportUniversal${CMAKE_SHARED_LIBRARY_SUFFIX}
# The target executable (built with debug information)
--debug_file=$
# C-SPY driver options
--backend
--cpu=cortex-m4
--semihosting)
```
- 现在使用 [`PASS_REGULAR_EXPRESSION`](https://cmake.org/cmake/help/latest/prop_test/PASS_REGULAR_EXPRESSION.html) 测试属性来验证程序是否向标准输出(`stdout`)输出了预期的字符串。在这种情况下,即验证 `printf()` 是否打印了预期的消息。
```
set_tests_properties(tutorialTest PROPERTIES PASS_REGULAR_EXPRESSION "Hello world!")
```
- 由于 `CMakeLists.txt` 已被修改,因此需要重新配置构建系统。重新构建项目将自动强制进行重新配置,并创建 `CTestTestfile.cmake` 文件:
```
cmake --build .
```
- 最后我们调用 CMake 的 [`ctest`](https://cmake.org/cmake/help/latest/manual/ctest.1.html),随后它将使用 IAR C-SPY Debugger for Arm 执行 `Tutorial.elf`:
```
ctest
```
## 总结
本教程涵盖了从命令行使用 CMake 和 IAR 工具的基础知识。请前往 [wiki](https://github.com/IARSystems/cmake-tutorial/wiki) 获取更多交互式示例和提示与技巧!
## 问题
如需报告 CMake 软件缺陷,请使用 [CMake 问题追踪器](https://gitlab.kitware.com/cmake/cmake/-/issues/)。
有关本教程的问题:请尝试查阅 [wiki][url-repo-wiki] 或查看[过往的 issue][url-repo-issue-old]。如果这些都没有帮助,请创建一个包含详细信息[新 issue][url-repo-issue-new]。
`"/opt/iarsystems/bxarm/arm/bin/iccarm"`
`"C:/iar/..../arm/bin/iccarm.exe"` | `CMAKE_CXX_COMPILER` | 必须指向 C++ 编译器可执行文件 | `"/opt/iar/cxarm/arm/bin/iccarm"`
`"/opt/iarsystems/bxarm/arm/bin/iccarm"`
`"C:/iar/..../arm/bin/iccarm.exe"`
`"${CMAKE_C_COMPILER}"` | `CMAKE_ASM_COMPILER` | 必须指向汇编器可执行文件 | `"/opt/iar/cxarm/arm/bin/iasmarm"`
`"/opt/iarsystems/bxarm/arm/bin/iasmarm"`
`"C:/iar/..../arm/bin/iasmarm.exe"` | `CMAKE_MAKE_PROGRAM` | 必须指向构建工具可执行文件 | `"/opt/iar/cxarm/common/bin/ninja"`
`"/opt/iarsystems/bxarm/common/bin/ninja"`
`"C:/iar/..../common/bin/ninja.exe"` - 一个单独的名为“toolchain file”的文件,您可以在调用 `cmake` 时加上 `--toolchain /path/to/
标签:Bash脚本, UML