使用VS Code编写C/C++代码时,VS Code会推荐安装C/C++插件,此插件会集成C/C++代码导航和调试等功能。前文使用VS Code调试Android C/C++代码(无需Android源码)就使用了C/C++插件做代码调试。但是在使用中发现了一些问题:1、标准库中头文件跳转到了主机的系统头文件,而不是Android NDK中的头文件;2、由于代码中使用了很多宏定义,在查看代码时编译器并没有把未定义宏包括的代码块灰度显示。
在VS code的C/C++插件文档中说明了如何修改配置文件。
如果要对C / C ++扩展进行更多控制,则可以创建一个
c_cpp_properties.json
文件,该文件将允许您更改设置,例如编译器的路径,包含路径,C ++标准(默认为C ++ 17)等。您可以通过运行命令C / C ++来查看C / C ++配置UI :从命令面板(
Ctrl + Shift + P
)编辑配置(UI)。这将打开“ C / C ++配置”页面。当您在此处进行更改时,VS Code会将其写入到文件夹中称为
c_cpp_properties.json
的.vscode文件中。仅当程序包含工作空间或标准库路径中没有的头文件时,才需要修改“ 包含路径”设置。
Visual Studio Code将这些设置放在中
.vscode/c_cpp_properties.json
。如果直接打开该文件,则它应如下所示:{ "configurations": [ { "name": "Linux", "includePath": ["${workspaceFolder}/**"], "defines": [], "compilerPath": "/usr/bin/gcc", "cStandard": "c11", "cppStandard": "c++17", "intelliSenseMode": "clang-x64" } ], "version": 4 }
首先查看项目中使用的编译信息,可以在编译时修改Android.mk
文件加上-v参数。
LOCAL_CXXFLAGS += -v
LOCAL_CFLAGS += -v
再编译一次代码,查看编译信息,从中可以得到头文件路径和Android.mk
脚本中定义的宏。
修改.vscode/c_cpp_properties.json
文件,includePath
中指定头文件路径,compilerArgs
中指定编译参数,如下所示。
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"/home/chenls/soft/android-ndk-r20/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/",
"/home/chenls/soft/android-ndk-r20/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/c++/v1",
"/home/chenls/soft/android-ndk-r20/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/aarch64-linux-android"
],
"compilerArgs": [
"-DENV_ANDROID",
"-DHAVE_PTHREADS",
"-DLOG_ON"
],
"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "clang-x64"
}
],
"version": 4
}
至此在前言中提到的两个问题都解决了,但是依然还存在其它问题,编译宏是会随着不同项目需求经常修改,若宏修改后需要同步修改c_cpp_properties.json
文件,不是很方便。
在VS code的c_cpp_properties.json文档中说明了如何设置compileCommands
属性。
compileCommands
(可选)compile_commands.json
工作空间文件的完整路径。将使用在此文件中发现的包含路径和定义代替为includePath
和defines
设置的值。如果编译命令数据库不包含与您在编辑器中打开的文件相对应的翻译单元条目,则将出现警告消息,并且扩展名将改用includePath
和defines
设置。有关文件格式的更多信息,请参见Clang文档。某些构建系统(例如
CMake
)可简化此文件的生成。
由于目前项目中未使用CMake
构建,而是使用Android.mk
脚本。
在ndk-build脚本中提到:
JSON 编译数据库
在 NDK r18 及更高版本中,ndk-build 可以生成 JSON 编译数据库。您可以使用
ndk-build compile_commands.json
生成数据库而无需构建代码,也可以使用ndk-build GEN_COMPILE_COMMANDS_DB=true
来构建和生成数据库(如果有负面影响)。
所以我们可以先使用ndk-build
生成compile_commands.json
文件,然后直接在c_cpp_properties.json
中设置。
{
"version": 4,
"configurations": [
{
"intelliSenseMode": "clang-x64",
"name": "Android",
"cppStandard": "c++17",
"cStandard": "c11",
"compileCommands": "${workspaceFolder}/compile_commands.json",
"defines": []
}
]
}
此时我们就不用每次去修改compile_commands.json
,而只需要在修改了宏定义时,重新生成compile_commands.json
文件即可。