Vitis 2022.2与2019.1编译器-D传头文件的编译差异问题
解决MicroBlaze mb-gcc 2021.1+版本中通过-D传递宏无法用于#include的问题
问题重现
在MicroBlaze编译环境中,2019.1版本mb-gcc可正常编译的代码,升级到2021.1及以上版本后报错:
error: #include expects "FILENAME" or
编译命令示例:
C:/Xilinx/Vitis/2022.2/gnu/microblaze/nt/bin/mb-gcc -g -Wall -mlittle-endian -nostartfiles -pedantic -DTEST_FILE="test_file.h" -I{LOCATION of the test file} -MM main.c
main.c代码:
#include TEST_FILE
原因分析
mb-gcc基于GCC构建,2021.1及以上版本对应的GCC版本收紧了预处理阶段的语法检查。旧版GCC允许#include直接引用无引号的宏展开结果,新版则严格要求#include的参数必须是带双引号的文件名或尖括号包裹的系统头文件名。
解决思路
1. 传递宏时保留引号(推荐)
修改Makefile中的-D参数,确保宏展开后包含双引号。根据不同环境调整写法:
- Windows cmd/PowerShell环境:转义双引号,避免被shell解析吃掉
-DTEST_FILE=\"test_file.h\" - Makefile中编写:需要双重转义反斜杠,确保传递给编译器的是正确的转义引号
CFLAGS += -DTEST_FILE=\\"test_file.h\\"
编译时#include TEST_FILE会被预处理为#include "test_file.h",符合语法要求。
2. 在代码中用字符串化宏处理
在main.c中添加辅助宏,将宏参数转换为带引号的字符串:
#define STRINGIFY(x) #x #define INCLUDE_HEADER(x) #include STRINGIFY(x) INCLUDE_HEADER(TEST_FILE)
预处理时,TEST_FILE先展开为test_file.h,再被STRINGIFY转换为"test_file.h",最终生成合法的#include语句。
3. 改用单引号传递宏参数
部分shell环境中,单引号不会被解析,可直接传递带单引号的宏值,编译器会自动识别为字符串边界:
-DTEST_FILE='test_file.h'
这种方式在Linux/macOS的bash环境中更可靠,Windows环境需测试兼容性。
内容的提问来源于stack exchange,提问作者Godspped
相关产品推荐
相关产品推荐

