VS Code中混合编译C++与C文件及重建报错问题排查
问题描述
我在VS Code中尝试编译包含cJSON.c和cJSON.h(来自cJSON库)的test.cpp文件,代码如下:
#include <iostream> #include <sstream> #include "cJSON.h" int main() { std::cout << "ello world" <<std::endl; cJSON *fmt = NULL; cJSON* root = cJSON_CreateObject(); cJSON_AddItemToObject(root, "name", cJSON_CreateString("Jack (\"Bee\") Nimble")); cJSON_AddItemToObject(root, "format", fmt = cJSON_CreateObject()); cJSON_AddStringToObject(fmt, "type", "rect"); cJSON_AddNumberToObject(fmt, "width", 1920); cJSON_AddNumberToObject(fmt, "height", 1080); cJSON_AddFalseToObject (fmt, "interlace"); cJSON_AddNumberToObject(fmt, "frame rate", 24); char *tmp_json = cJSON_Print(root); std::stringstream myStreamString; myStreamString << tmp_json; std::string myString = myStreamString.str(); std::cout << " json string is " << myString << std::endl; cJSON_Delete(root); free(tmp_json ); return 0; }
首次编译成功,但重建时出现如下错误:
Starting build... /usr/bin/g++ -fdiagnostics-color=always -g /home/xx/test/* -o /home/xx/test/test g++: fatal error: input file ‘/home/xx/test/test’ is the same as output file compilation terminated.
我只能删除之前生成的可执行文件后重新编译才能解决问题。以下是我的配置文件:
c_cpp_properties.json
{ "configurations": [ { "name": "Linux", "includePath": [ "${workspaceFolder}/**" ], "defines": [], "compilerPath": "/usr/bin/gcc", "cStandard": "gnu17", "cppStandard": "gnu++14", "intelliSenseMode": "linux-gcc-x64" } ], "version": 4 }
tasks.json
{ "tasks": [ { "type": "cppbuild", "label": "C/C++: g++ build active file", "command": "/usr/bin/g++", "args": [ "-fdiagnostics-color=always", "-g", "${workspaceFolder}/*", "-o", "${fileDirname}/${fileBasenameNoExtension}" ], "options": { "cwd": "${fileDirname}" }, "problemMatcher": [ "$gcc" ], "group": { "kind": "build", "isDefault": true }, "detail": "Task generated by Debugger." } ], "version": "2.0.0" }
请问我是否遗漏了某些设置?这种方式是否是混合C/C++开发的正确编译方式?
解决方案
1. 重建编译错误的修复
错误根源是tasks.json中的${workspaceFolder}/*会匹配工作目录下所有文件,包括首次编译生成的可执行文件test。第二次编译时,g++会把这个可执行文件当作输入源文件处理,导致输入输出文件冲突。
修复方法:
- 精准指定源文件类型,只编译
.cpp和.c文件,修改tasks.json的args数组,将"${workspaceFolder}/*"替换为:"${workspaceFolder}/*.cpp", "${workspaceFolder}/*.c" - 可选优化:添加
-Wall参数开启编译警告,提前排查潜在问题。
修改后的tasks.json示例:
{ "tasks": [ { "type": "cppbuild", "label": "C/C++: g++ build active file", "command": "/usr/bin/g++", "args": [ "-fdiagnostics-color=always", "-g", "-Wall", "${workspaceFolder}/*.cpp", "${workspaceFolder}/*.c", "-o", "${fileDirname}/${fileBasenameNoExtension}" ], "options": { "cwd": "${fileDirname}" }, "problemMatcher": [ "$gcc" ], "group": { "kind": "build", "isDefault": true }, "detail": "Task generated by Debugger." } ], "version": "2.0.0" }
2. 混合C/C++开发的编译规范
当前的编译方式可行,但有更规范的优化方向:
- 直接用g编译C文件是允许的,g会自动以C兼容方式处理C代码,但如果C代码包含C不兼容的语法,可能出现问题。
- 更稳妥的做法是分两步编译:先用gcc编译C文件为目标文件(
.o),再用g链接C目标文件与C代码,确保C代码严格遵循C标准编译。
示例命令:
- 编译cJSON.c为目标文件:
gcc -c cJSON.c -o cJSON.o -g - 编译test.cpp并链接目标文件:
g++ test.cpp cJSON.o -o test -g
如果要集成到VS Code的tasks.json,可合并为一个任务:
"args": [ "-fdiagnostics-color=always", "-g", "-Wall", "${workspaceFolder}/test.cpp", "${workspaceFolder}/cJSON.c", "-o", "${fileDirname}/${fileBasenameNoExtension}" ]
这种写法和直接用g编译所有源文件效果一致,因为g会自动调用gcc处理C文件。
另外,c_cpp_properties.json的配置基本没问题,${workspaceFolder}/**已覆盖cJSON.h所在目录,无需额外调整。
内容的提问来源于stack exchange,提问作者user1538798
相关产品推荐
相关产品推荐

