Pre-defined C/C++ Compiler Macros

C/C++编译器预定义宏详解及应用
本文详细介绍了C/C++编译器预定义宏的使用方法,包括标准、编译器、操作系统、架构和基本运行库识别。通过实际例子展示了如何在不同环境下正确使用这些宏,确保软件的跨平台兼容性和稳定性。


The macros are found here:

General guidelines are found here:

Please send updates/corrections to predef-contribute.

Introduction

C and C++ compilers automatically define certain macros that can be used to check for compiler or operating system features. This is useful when writing portable software.

These pages lists various pre-defined compiler macros that can be used to identify standards, compilers, operating systems, hardware architectures, and even basic run-time libraries at compile-time.

For example, if we want to use a generic or opaque pointer type, we use void pointers. However, ancient K&R compilers (from the time before the first ANSI C standard) do not support void pointers. Instead we can define our own type:

#if defined(__STDC__) || defined(__cplusplus) || defined(_MSC_EXTENSIONS)
typedef void * t_pointer;
#else
typedef char * t_pointer;
#endif

Another example, Microsoft Visual C++ version 4.2 added a pragma to reduce compilation times by only including a file once (if _MSC_VER is not defined then it will evaluate to 0 (zero) — however, some compilers may complain about an undefined macro)

#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif

The macros contained in these pages have been obtained through vendor documentation, the defines script, contributors, and third-party source code. No guarantee about the correctness of the macros is given.

An often-used alternative is Autoconf, which is a more powerful tool to examine various types of features, including compilation options. However, Autoconf is fairly Unix-centric, and requires a Unix layer on other platforms (e.g. Cygwin on Windows). Other alternatives are BuildtoolCMakeSConsPMKJamAnt, andBakefile.

Contributors

Bjorn Reese, Daniel Stenberg, Greg Roelofs, Steven G. Johnson, Wlodzimierz ABX Skiba, Marc Finet, Philip Newton, Mitchell Charity, Christian Klutz, Seo Sanghyeon, Chris Adami, Geoff Clare, Dan Fandrich, Mike Gorchak, Yuri D'Elia, Gynvael Coldwind, Alain Tauch, Vadim Zeitlin, Steve White, Thomas David Rivers, Tom Honermann, Martin Mitas, Dinesh Chhadwa, Erik Faye-Lund, Leo Davis, Paul Hsieh, Roland Schwarz, Darko Kolakovic, Andy Buonviri, Ming Kin Lai, Kent Johnson, Helmut Bauer, Oliver Schneider, Ron Pimblett, Jose Luis Rodriguez Garcia, Jeroen Ruigrok van der Werven, Uffe Jakobsen, Bryan Ashby, Bruno Haible, Artur Bac, Terry Schwarz, Leo Davis, Markus Duft, William Dang, Paul Green, Ruben Van Boxem, Pau Garcia i Quiles, Mikulas Patocka, Leo Davis, Mark Ferry, Holger Machens, Simon Watts, Paul Hargrove, Hans-Christoph Steiner, Gerald Combs, Denys Bulant, Massimo Morara, Jeremy Bennett, Guillem Jover, Riku Voipio, Jacques Pelletier, Mark Jarvin, Georg Sauthoff, Scot Jenkins, Grzegorz Brzęczyszczykiewicz, John Dallman, Gianmichele Toglia.


Related

Wiki: VersionNormalization
Wiki: FeatureMacros
Wiki: Endianness
Wiki: Standards
Wiki: Compilers
Wiki: Libraries
Wiki: OperatingSystems
Wiki: Architectures

<think>我们正在处理一个关于CMake配置错误的问题,具体错误是“BOARD not defined”。用户希望使用交叉编译器为ARM构建libgcc和stdc++的静态库。根据用户提供的信息,错误发生在配置阶段,因为CMake变量BOARD未定义。 首先,我们需要明确BOARD变量在CMake脚本中的作用。通常,在嵌入式开发中,BOARD变量用于指定目标硬件平台,以便选择正确的编译器选项、链接脚本和特定于板的配置。 根据用户的问题,他正在尝试构建libgcc和stdc++的静态库。这通常发生在构建交叉工具链或为特定目标构建标准库时。 解决方案步骤: 1. 检查CMake命令是否提供了定义BOARD变量的选项。例如,在CMake中,可以通过-D选项定义变量: ``` cmake -DBOARD=your_board_name .. ``` 2. 如果用户不知道具体的BOARD值,需要查看项目的文档或CMakeLists.txt文件,了解支持哪些板以及如何设置。 3. 另一种可能性是项目期望通过环境变量设置BOARD。在这种情况下,可以在运行CMake之前设置环境变量: - 在Linux/macOS上:`export BOARD=your_board_name` - 在Windows上:`set BOARD=your_board_name` 4. 如果项目本身没有要求BOARD变量,那么可能是CMake脚本中的一个错误。需要检查CMakeLists.txt,看看在什么条件下会使用BOARD变量,以及在没有定义时是否提供了合理的默认值。 5. 用户的问题中提到“交叉编译器”,因此我们还需要确保交叉编译工具链已正确设置。通常,在运行CMake之前,需要指定工具链文件(toolchain file)。工具链文件中会设置编译器路径、目标平台等。例如: ``` cmake -DCMAKE_TOOLCHAIN_FILE=path/to/toolchain-file.cmake .. ``` 6. 在工具链文件中,可能需要设置BOARD变量,或者确保工具链文件中的设置与BOARD变量无关。 7. 如果用户的项目是某个已知的嵌入式项目(如Zephyr RTOS),那么BOARD变量是必须的。Zephyr项目就需要在构建时指定BOARD。 由于用户没有提供具体的项目信息,我们只能给出一般性的建议。 考虑到用户上一次的问题是关于构建libgcc和stdc++静态库,我们可以推测他可能在构建交叉编译工具链或者是为某个嵌入式项目构建标准库。 如果用户正在构建的是gcc本身,那么通常不需要BOARD变量。因此,这个错误可能出现在一个特定的项目中。 建议用户: - 检查项目的README或文档,看是否有关于BOARD设置的说明。 - 查看CMakeLists.txt文件,搜索BOARD变量,了解其用途和期望的值。 如果用户能够提供更多信息(例如项目来源),我们可以给出更具体的指导。 现在,生成相关问题: 1. 如何为ARM交叉编译设置CMake工具链文件? 2. 在嵌入式项目中,BOARD变量通常用于什么目的? 3. 如何解决CMake中未定义的变量错误? 4. 构建libgcc和stdc++静态库的常见步骤是什么?</think>### 解决CMake配置错误:BOARD未定义问题 当为ARM交叉编译构建libgcc和stdc++静态库时出现`BOARD not defined`错误,通常是因为CMake缺少关键平台定义。以下是系统解决方案: #### 核心解决步骤 1. **显式定义BOARD变量** 在CMake命令中通过`-D`参数指定目标板: ```bash cmake -DBOARD=your_target_board_name -DCMAKE_TOOLCHAIN_FILE=arm-toolchain.cmake .. ``` 将`your_target_board_name`替换为实际开发板名称(如`stm32f4-discovery`) 2. **配置工具链文件** 创建`arm-toolchain.cmake`文件(示例): ```cmake set(CMAKE_SYSTEM_NAME Generic) set(CMAKE_SYSTEM_PROCESSOR arm) set(CMAKE_C_COMPILER arm-none-eabi-gcc) set(CMAKE_CXX_COMPILER arm-none-eabi-g++) set(CMAKE_ASM_COMPILER arm-none-eabi-gcc) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) ``` 3. **添加标准库配置** 在CMakeLists.txt中强制链接静态库: ```cmake # 添加静态库目标 add_library(libgcc STATIC IMPORTED) set_target_properties(libgcc PROPERTIES IMPORTED_LOCATION "${TOOLCHAIN_DIR}/lib/gcc/arm-none-eabi/12.2.1/libgcc.a" ) # 链接到可执行文件 target_link_libraries(your_target PRIVATE libgcc -lc -lstdc++ ) ``` 4. **验证构建环境** 检查工具链路径是否包含libgcc.a: ```bash find $ARM_TOOLCHAIN_DIR -name libgcc.a ``` #### 常见错误原因 - **交叉编译器未配置**:缺少`-DCMAKE_TOOLCHAIN_FILE`参数 - **板级支持包(BSP)缺失**:开发板定义未包含在工程中 - **路径错误**:工具链路径未正确导出,需设置: ```bash export PATH=$PATH:/opt/arm/gcc-arm-none-eabi-12.2/bin ``` > **关键提示**:对于ARM Cortex-M系列,建议添加`-specs=nosys.specs`链接器标志以处理系统调用[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值