如何在 Visual Studio Code 中的构建目标之间切换?

Gun*_*ter 5 c c++ makefile visual-studio-code

我们正在尝试从 Code::Blocks 迁移到 Visual Studio Code 进行 C/C++ 开发。主要原因是通过 IntelliSense 提供了更好的代码完成方式。但两者的比较不是这里的主题。

为了编译旧项目,我们在 Visual Studio Code 中设置了 makefile 和任务。到目前为止效果很好。

事情变得复杂的是不同的构建目标。假设我们有一个示例项目,其中我们需要编译程序的两个版本,它们大约有 95% 相同。因此,在 Code::Blocks-time 中,我们决定将所有内容保留在一个项目中,但通过 Defines 和 ifdef 区分不同的源代码位。因此,您选择正确的构建目标,它将定义附加到 gcc 调用中,并构建两者的正确版本。为了让事情变得更复杂,每个版本还有一个调试和发布目标。所以总共有四个构建目标:

  • 版本 1 DEBUG,构建于-DVERSION1 -DDEBUG
  • 版本 1 RELEASE,构建于-DVERSION1 -DRELEASE
  • 版本 2 DEBUG,构建于-DVERSION2 -DDEBUG
  • 版本 2 RELEASE,构建于-DVERSION2 -DRELEASE

因此,我们在 VS Code 中使用的 makefile 已设置好,我们还可以选择构建目标并构建正确的版本。到目前为止,一切都很好。

现在 C/C++ 扩展和 IntelliSense 开始发挥作用。他们使用 clang 动态“编译”代码,以自动完成并突出显示实际使用的代码部分。因为我们的#define不同版本的 s(VERSION1 或 VERSION2)仅在 makefile 中提供给 gcc 编译器,所以 clang 不知道它们。在不了解它们的情况下,代码部分会变灰(这没什么大不了的),而且自动完成对于恰好在这样的部分中声明的变量也不起作用。

当然,我们可以在 中指定定义c_cpp_properties.json,并在那里创建不同的构建目标。但这意味着我们需要在构建目标之间切换两次:第一次是 C/C++ 扩展,第二次是 makefile。我很确定人们会忘记其中之一并感到沮丧。

长话短说:有没有办法在 Visual Studio Code 中切换构建目标,这会影响 IntelliSense 和实际构建?

Gun*_*ter 7

最后我们找到了解决方案。事实上,我的一个同事确实发现了它。

我们需要调整三个文件才能使其正常工作。

c_cpp_properties.json需要不同构建目标的定义 - 在此文件中称为“配置”。这允许您在进入 c 文件后在 VS Code 右下角选择不同的配置。

{
    "configurations": [
        {
            "name": "DEBUG",
            "includePath": [
                 //...
            ],
            "defines": [
                 //...
            ],
            "compilerPath": "path/to/compiler",
            "cStandard": "c11",
            "cppStandard": "c++17",
            "intelliSenseMode": "clang-x64"
        },
        {
            "name": "RELEASE",
            "includePath": [
                 //...
            ],
            "defines": [
                 //...
            ],
            "compilerPath": "path/to/compiler",
            "cStandard": "c11",
            "cppStandard": "c++17",
            "intelliSenseMode": "clang-x64"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

tasks.json需要一个任务,该任务读取当前使用的 c_cpp 配置并将其作为参数传递给 make 文件。

{
    //...
    "tasks": [
        {
            "label": "build",
            "type": "shell",
            "command": "make
            "args": [
                "CONFIG_NAME=${command:cpptools.activeConfigName}"
            ]
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

最后,makefile您可以在您的中检查CONFIG_NAME并进行最终调整。下面只是一个例子,它并不完整(从没有找到“DEBUG”推断出我​​们想要构建“RELEASE”可能有点大胆,但你明白了)。当然,您还可以检查其他内容,或者可以匹配完整的配置名称。我们有很多 c_cpp 配置,它们遵循一定的内部命名方案。下面显示的 makefile 中的概念使我们能够检查配置名称的不同部分并在 makefile 中构建相应的标志。

# ...
ifneq (,$(findstring DEBUG,$(CONFIG_NAME)))
    CFLAGS += -DDEBUG
else
    CFLAGS += -DRELEASE
endif
# ...
Run Code Online (Sandbox Code Playgroud)

再次,我需要承认这个解决方案实际上是我的同事找到的。