侧边栏壁纸
  • 累计撰写 185 篇文章
  • 累计创建 77 个标签
  • 累计收到 17 条评论

目 录CONTENT

文章目录

vscode中如何使用Makefile在Linux下编译C/C++程序

码峰
2022-09-17 / 0 评论 / 0 点赞 / 3,556 阅读 / 1,644 字 / 正在检测是否收录...
广告 广告

前言

vscode号称宇宙最强IDE,由于是插件化,非常方便支持各类应用的开发,编程体验简直好到爆,在Linux中写C/C++程序的时候,如果源文件很少,vscode是可以直接调用clang/gcc/g++编译的,如果源文件较多,则相对比较麻烦一些,还是使用原始的makefile更方便管理,也更方便在github上做自动编译。

插件安装

C/C++插件

要开发C/C程序,首先要在vscode中安装c/c插件和C/C++ Extension Pack,如下图:
image-1663422855206

Makefile Creator插件

Makefile Creator插件可以自动生成Makefile的模板(非常熟悉Makefile的可以忽略这一步)
image-1663423015568

测试工程

新建源码

  • 在vscode中,打开一个目录(这里我是在Windows中远程连接到一个Linux系统中,关于如何配置远程开发,以后有空再写文章)
  • 新建一个源代码文件main.cpp,输入Hello world经典源码,如下:
#include <iostream>
using namespace std;
int main()
{
    cout << "Hello world!" << endl;
    return 0;
}

工程初始配置

此步骤对于已经熟悉vscode的tasks.json和Launch.json的配置,可以不用,不过这一步可以自动创建处配置文件的模板,即使熟悉了我也经常这样做。
直接按“F5”,此时,会提示选择配置,直接选择第一个即可,如下图:
image-1663423547275
选择后,会提供配置配置Launch,忽略掉后,程序不会直接运行,但会创建两个json文件。

  • Launch.json是运行调试的配置文件,此时默认创建的应该是空文件,如下
{
    "version": "0.2.0",
    "configurations": []
}
  • tasks.json是编译的配置文件,此时应该是默认使用了g++命令进行编译,如下:
{
    "tasks": [
        {
            "type": "cppbuild",
            "label": "C/C++: g++ 生成活动文件",
            "command": "/usr/bin/g++",
            "args": [
                "-fdiagnostics-color=always",
                "-g",
                "${file}",
                "-o",
                "${fileDirname}/${fileBasenameNoExtension}"
            ],
            "options": {
                "cwd": "${fileDirname}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "调试器生成的任务。"
        }
    ],
    "version": "2.0.0"
}

默认编译和运行

直接按下“CTRL+ALT+B”快捷键,就会执行tasks.json中配置的默认build任务,生成可执行文件main,如下图:
image-1663424119668
在终端中执行./main,程序已经可以运行了,如下:

[ferris@cfnotes test]$ ll
total 24
-rwxrwxr-x 1 fawn fawn 19584 Sep 17 22:13 main
-rw-rw-r-- 1 fawn fawn   106 Sep 17 22:05 main.cpp
[ferris@cfnotes test]$ ./main
Hello world!

配置Launch.json和调试

菜单->运行->添加配置,此时会弹出配置模板选择,如下图:
image-1663424429013
选择第一个,会根据模板自动生成运行的配置文件,如下:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) 启动",
            "type": "cppdbg",
            "request": "launch",
            "program": "输入程序名称,例如 ${workspaceFolder}/a.out",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${fileDirname}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "为 gdb 启用整齐打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                },
                {
                    "description":  "将反汇编风格设置为 Intel",
                    "text": "-gdb-set disassembly-flavor intel",
                    "ignoreFailures": true
                }
            ]
        }

    ]
}

将program修改为:${workspaceFolder}/main就进行调试了,打上断点后,按“F5”即可启动调试,如下图:
image-1663426240713

创建Makefile

安装了Makefile Creator插件,可以在左侧空白处点击右键,弹出菜单中有“Create Makefile”,如下图:
image-1663426478712
单击后,会提示输入Makefile的名称,不输入,默认可自动创建文件名为“Makefile”的文件。
创建后的Makefile文件内容如下:

CXX = g++
CXXFLAGS = -Wall -Werror -Wextra -pedantic -std=c++17 -g -fsanitize=address
LDFLAGS =  -fsanitize=address

SRC = 
OBJ = $(SRC:.cc=.o)
EXEC = main

all: $(EXEC)

$(EXEC): $(OBJ)
	$(CXX) $(LDFLAGS) -o $@ $(OBJ) $(LBLIBS)

clean:
	rm -rf $(OBJ) $(EXEC)

Makefile中OBJ = $(SRC:.cpp=.o) 是一个Makefile替换表达式,表示SRC目录库下的所有.cpp文件都有相应的.o文件,编译时会自动编译,这样就不用一个一个指定需要编译的文件了。

此时,直接在中断中执行make,就可以直接编译生成可执行的main文件了。

启用Makefile

虽然,Makefile已经创建成功了,但vscode中还没有启动,如果直接执行编译,是不会调用Makefile的。
我们只需要将前文所述生成的tasks.json文件稍作修改即可,修改后的文件如下:

{
    "tasks": [
        {
            "type": "cppbuild",
            "label": "C/C++: g++ 生成活动文件",
            "command": "make",
            "args": [
            ],
            "options": {
                "cwd": "${fileDirname}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "调试器生成的任务。"
        }
    ],
    "version": "2.0.0"
}

以上json是将“command”修改未“make”,“args”都删除掉,将"cwd"修改为"${workspaceFolder}"。
此时,执行编译就可以直接试用makefile进行编译了。

Make前执行clean

有时候我们编译前想先执行以下clean,或者需要手动执行clean,修改tasks.json文件如下:

{
    "tasks": [
        {
            "type": "cppbuild",
            "label": "C/C++: g++ 生成活动文件",
            "command": "make",
            "args": [
            ],
            "options": {
                "cwd": "${workspaceFolder}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "调试器生成的任务。",
            "dependsOn":["make clean"]
        },        
        {
            "type": "shell",
            "label": "make clean",
            "command": "make",
            "args": [
                "clean"
            ],
            "options": {
                "cwd": "${workspaceFolder}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "none",
                "isDefault": false
            },
        }
    ],
    "version": "2.0.0"
}

我们添加了一个"make clean"的task,执行命令"make clean",此外在之前的编译task中增加了 “dependsOn”:[“make clean”] 字段的配置,此时,执行编译就会先执行"make clean",再执行"make"。如果不需要先“make clean”,可以将dependsOn删掉即可。

0
广告 广告

评论区