如何让Microchip XC16编译器直接将foo.cpp当作C代码编译?
这个问题我之前帮同行处理过类似的,核心是绕开XC16对文件后缀的死板判断,同时避免复制文件带来的版本控制和IDE同步问题。给你几个实用的解决办法:
1. 让XC16把.cpp文件当作C代码编译
XC16(和大多数GCC系编译器一样)支持通过编译选项强制指定源文件的语言类型。你只需要在XC16的构建配置里,给foo.cpp单独添加-x c参数——这个参数会告诉编译器“不管后缀是什么,把这个文件当作C代码编译”。
- 如果你用Makefile,只需要给
foo.o的编译规则加上这个选项:foo.o: foo.cpp xc16-gcc -x c $(CFLAGS) -c $< -o $@ - 如果你用IDE(比如MPLAB X),可以在文件的属性里找到“编译选项”,手动添加
-x c。
这样一来,你不需要复制文件,foo.cpp在MSVC里还是正常的C++文件,在XC16里会被当作C代码处理,完美兼容你已经写好的__cplusplus宏判断。
2. 统一文件后缀为.c,让MSVC强制按C++编译
反过来,你可以把共享文件的后缀统一改成.c,然后在MSVC的构建配置里,给这个文件添加/TP选项——这个选项会让MSVC把指定的.c文件当作C++代码编译。
- 在Visual Studio里,右键点击
foo.c→ 属性 → C/C++ → 高级 → 编译为,选择“C++代码(/TP)”。 - 如果用MSBuild脚本,直接给对应的文件添加
<CompileAs>Cpp</CompileAs>属性。
这种方案的好处是彻底消除了后缀差异,版本控制只需要管理一个文件,IDE里编辑也不会有同步问题,__cplusplus宏依然能正常工作(MSVC编译C++时会定义这个宏,XC16编译C时不会)。
3. 用构建系统自动处理文件语言属性(推荐)
如果你的项目用CMake这类跨平台构建系统,这是最优雅的解决方式。只需要在CMakeLists.txt里添加一段逻辑,根据编译器类型指定文件的编译语言:
# 假设你的共享文件是foo.cpp if(CMAKE_C_COMPILER_ID MATCHES "XC16") # 告诉XC16把foo.cpp当作C代码编译 set_source_files_properties(foo.cpp PROPERTIES LANGUAGE C) else() # 告诉其他编译器(比如MSVC)把foo.cpp当作C++代码编译 set_source_files_properties(foo.cpp PROPERTIES LANGUAGE CXX) endif()
CMake会自动帮你处理不同编译器的差异,你完全不用手动修改编译选项或者复制文件,版本控制和IDE编辑都和正常项目一样。
4. 用符号链接代替文件复制(应急方案)
如果上面的方案都暂时无法实施,你可以用符号链接代替物理复制:
- 在Windows上,用命令行创建软链接:
mklink foo.c foo.cpp(需要管理员权限,或者开启开发者模式); - 在类Unix环境下,用
ln -s foo.cpp foo.c。
然后把foo.c加入构建系统,但不要把它提交到版本控制(在.gitignore里添加foo.c)。这样IDE里编辑foo.cpp时,foo.c会自动同步,版本控制也只需要管理foo.cpp。不过这个方案要注意不同系统对符号链接的支持,不如前几个方案可靠。
内容的提问来源于stack exchange,提问作者EBlake




