[C++]-VSCode+Makefile编译C++

本文介绍了如何在VSCode中通过Makefile编译C++程序,包括设置Makefile以编译子文件夹的源文件,配置VSCode的任务和属性以支持C++17标准,并展示了C++中关于vector、weak_ptr和optional的使用示例。


在《 VSCode+WSL开发环境》中,已经介绍了VSCode+WSL如何进行开发;本文将介绍如何使用makefile来编译C++程序。

开发

以编译子文件夹下的文件为例,目录结构如下:
VSCode-C++目录结构

C++源文件

源文件中,以vector为例,如何使用移动构造,以及快速清空vector:

#include <iostream>
#include <vector>
#include <memory>
#include <optional>
#include <unistd.h>

class DemoPrint
{
    int data{0};

public:
    DemoPrint(int init) : data(init)
    {
        std::cout << "DemoPrint constructor " << data << std::endl;
    }

    DemoPrint(DemoPrint &&demo) : data(demo.data + 10)
    {
        std::cout << "DemoPrint move-structor " << data << std::endl;
    }

    ~DemoPrint()
    {
        std::cout << "DemoPrint destructor " << data << std::endl;
    }
};

void vectorClearTest()
{
    std::vector<DemoPrint> vec;
    vec.push_back(DemoPrint(1));
    std::cout << "after push back, size:" << vec.size() << ", capacity:" << vec.capacity() << std::endl;
    vec = decltype(vec){};
    std::cout << "after assigned, size:" << vec.size() << ", capacity:" << vec.capacity() << std::endl;

    vec.push_back(DemoPrint(2));
    std::cout << "after re-push back, size:" << vec.size() << ", capacity:" << vec.capacity() << std::endl;
    (decltype(vec){}).swap(vec);
    std::cout << "after swapped, size:" << vec.size() << ", capacity:" << vec.capacity() << std::endl;

    vec.push_back(DemoPrint(3));
    vec.clear();
}

void weakPtrTest()
{
    std::weak_ptr<int> wp{};
    if (wp.expired())
    {
        std::cout << "Empty WP expired" << std::endl;
    }

    {
        std::shared_ptr<int> sp(new int(1));
        wp = sp;
        if (wp.expired())
        {
            std::cout << "Inscope WP expired" << std::endl;
        }
        if (sp)
        {
        }
    }

    if (wp.expired())
    {
        std::cout << "Outscope WP expired" << std::endl;
    }
}

int main()
{
    vectorClearTest();
    
    std::optional<int> oi;
    if (!oi)
    {
        std::cout << "optional is empty" << std::endl;
    }

    oi = 12;
    if (oi)
    {
        std::cout << "optional value: " << oi.value() << std::endl;
    }

    sleep(10);
    std::cout << "main quit." << std::endl;
    return 0;
}

Makefile

VSCode启动运行时,只会调用最顶层的Makefile,为能编译子文件下的文件,需要在顶层Makefile中调用子文件夹下的Makefile。

顶层Makefile(调用子文件夹下Makefile):

subsystem:
	cd learning && make

clean:
	cd learning && make clean

运行make会自动编译,而运行make clean会做清理;

子文件夹Makefile(真正编译文件):

CFLAGS=-c -Wall -std=c++17
LFLAGS = -Wall -std=c++17
CXXFLAGS = -Wall -std=c++17


hello: hello.o
	g++ -g -std=c++17 -o hello hello.o

hello.o: hello.cpp
	g++ -g -std=c++17 -o hello.o -c hello.cpp
	
clean:
	rm -rf hello
	rm -rf *.o

为保证能支持C++17,必须设定标志CXXFLAGS,否则即使g++中添加了-std=c++17也无效。

VSCode配置

为例使用make编译,需要修改.vscode目录下的tasks.json文件

task

默认生成的task使用g++编译,需要修改为使用make:

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "build", 
            "command": "make", 
            "type": "shell",
            "group": {
                "kind": "build",
                "isDefault": true
            }
        },
        {
            "label": "clean",
            "command": "make", // 在shell中使用命令,如需加参数,可再添加args属性
            "args": [
                "clean"
            ],
            "type": "shell",
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]
}

同时要保证launch.json中preLaunchTask的值与此文件中label的值相同。

properties

为使vscode识别C++17,需要修改c_cpp_properties.json中cppStandard:

{
    "configurations": [
        {
            "name": "Linux",
            "includePath": [
                "${workspaceFolder}/**"
            ],
            "defines": [],
            "compilerPath": "/usr/bin/gcc",
            "cStandard": "c11",
            "cppStandard": "c++17",
            "intelliSenseMode": "linux-gcc-x64"
        }
    ],
    "version": 4
}
<think>首先,用户的问题是:“我想查找在VSCode中使用Makefile失败的解决方案 请问VSCode使用Makefile失败的解决办法”。这是在询问如何在VSCode中解决使用Makefile编译项目失败的问题。 现在,我需要参考提供的站内引用。引用中有三个部分: - 引用[1]:关于在VSCode中安装clangd时出现的pp_file_not_found错误,解决方案是使用bear命令生成compile_commands.json文件,并在clangd设置中指定路径。 - 引用[2]:关于在VSCode中使用CMake时命令找不到的错误,提到了code server环境下的问题。 - 引用[3]:关于使用Amazon-Q开发GUI时遇到的NameError。 用户的问题是针对Makefile失败的,所以引用[1]是最相关的,因为它提到了makefile编译的项目,并使用bear命令生成compile_commands.json来帮助clangd解析依赖。 用户的上一个问题或对话历史是:“参考站内引用:引用[1]:... 引用[2]:... 引用[3]:... 我想查找在VSCode中使用Makefile失败的解决方案 请问VSCode使用Makefile失败的解决办法”。系统指令说“请尽可能多的参考用户上一次的问题和你的回答”,但这里没有之前的对话历史;这是一个新的查询。所以,我应该基于当前问题和引用回答。 关键点:用户的问题是关于VSCode中使用Makefile失败。引用[1]直接涉及makefile项目,并提供了一个解决方案。 可能的解决方案: - 从引用[1]:使用bear命令生成compile_commands.json来解决依赖问题。 - 其他常见原因:路径设置错误、环境变量问题、安装缺失的工具链(如gcc、make等)。 系统指令要求: - 使用中文回答。 - 结构清晰,帮助用户逐步解决问题。 - 回答中引用的段落末尾自然地添加引用标识,例如[^1]。 - 所有行内数学表达式使用$...$格式,独立公式用$$...$$。但在这个问题中,可能没有数学表达式,所以如果需要,才添加。 - 生成相关问题:在回答结束时,生成相关问题。 回答结构: 1. 简要确认问题。 2. 提供解决方案步骤。 3. 基于引用[1]解释bear命令的用法。 4. 建议其他常见检查点。 5. 添加引用标识。 6. 生成相关问题。 最终回答应真实可靠。 </think>### VSCode中使用Makefile失败的解决方案 在VSCode中使用Makefile编译项目时失败,可能是由于依赖解析错误、环境配置问题或路径设置不当引起的。以下我将基于您的查询和站内引用(特别是引用[1]中提到的makefile项目解决方案),提供逐步的解决指南。这里假设您使用的是Linux或类Unix系统(如macOS),如果环境不同(如Windows),请确保已安装兼容的工具链(如MinGW或WSL)。 #### 步骤1: 检查基本设置和环境 首先,确保您的开发环境已正确配置: - **安装必要工具**:确认已安装`make`编译工具和编译器(如`gcc`或`clang`)。在终端运行以下命令检查: ```bash make --version gcc --version # 或 clang --version ``` 如果未安装,可使用包管理器安装(例如,Ubuntu下:`sudo apt install build-essential`)。 - **VSCode扩展**:安装相关扩展以支持Makefile项目: - **C/C++** 扩展(提供语法高亮和调试支持)。 - **clangd** 扩展(用于智能提示和错误检查,引用[1]中提到的)。 在VSCode扩展市场搜索并安装这些扩展。 如果上述检查通过但问题依旧,可能是依赖关系未被正确解析(常见错误如头文件缺失或路径错误),此时参考引用[1]的方案。 #### 步骤2: 使用bear生成编译数据库(compile_commands.json) 在makefile项目中,VSCode的clangd扩展可能无法自动找到所有依赖,导致编译失败或代码飘红(如`pp_file_not_found`错误)。引用[1]建议使用`bear`命令捕获编译过程并生成`compile_commands.json`文件,这能帮助clangd正确解析依赖关系: 1. **安装bear工具**:在终端运行: ```bash sudo apt install bear # Ubuntu/Debian # 或 brew install bear # macOS ``` 确认安装成功:`bear --version`。 2. **生成compile_commands.json**: - 切换到您的项目根目录(含Makefile)。 - 运行bear命令捕获编译过程: ```bash bear -- make # 或 bear make all(替换为您的make目标) ``` 这会在当前目录生成`compile_commands.json`文件,包含所有编译指令和依赖路径。 3. **在VSCode中配置clangd**: - 打开VSCode,按`Ctrl+,`打开设置。 - 搜索“clangd”并进入扩展设置。 - 找到“Clangd: Arguments”或“Compile Flags Path”,添加路径配置: ```json "clangd.arguments": [ "--compile-commands-dir=/your/project/path" // 替换为您的绝对路径 ] ``` 例如,如果项目在`/home/user/project`,则设置为`--compile-commands-dir=/home/user/project`。 - 保存设置并重新加载VSCode窗口(按`Ctrl+Shift+P`输入“Reload Window”)。 此方法解决了大多数依赖错误(如头文件找不到),因为它让clangd直接从JSON文件中读取编译上下文[^1]。 #### 步骤3: 检查Makefile和环境变量 如果问题未解决,可能是Makefile本身或环境问题: - **验证Makefile语法**:在终端手动运行`make`命令,查看输出错误: ```bash make clean # 清理旧编译 make # 手动编译 ``` 常见错误包括路径错误、变量未定义或缺失文件(如`.c`文件)。修复Makefile后重试。 - **设置环境变量**:确保VSCode终端使用正确的Shell环境(如bash)。在VSCode设置中,搜索“Terminal › Integrated › Shell”,指定路径(如Linux下`"/bin/bash"`)。同时,检查`PATH`变量是否包含编译器路径: ```bash echo $PATH # 在VSCode终端运行 ``` - **参考其他引用**:如果涉及CMake或GUI开发(如引用[2]和引用[3]),确保没有冲突扩展。例如,禁用不必要的扩展(如CMake Tools),避免命令冲突(引用[2]中提到类似错误)[^2]。 #### 步骤4: 其他常见故障排除 - **清理项目**:运行`make clean`后重启VSCode- **日志和错误分析**:查看VSCode问题面板(`Ctrl+Shift+M`)中的详细错误。如果出现类似引用[3]的`NameError`(如命名错误),检查代码是否有语法问题[^3]。 - **路径问题**:确保项目路径不含空格或特殊字符,并使用绝对路径配置。 - **调试工具**:安装VSCodeMakefile支持扩展(如“Makefile Tools”),提供图形化编译选项。 如果以上步骤无效,提供更多错误细节(如终端输出或截图),我可以进一步协助。 ###
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值