使用VsCode+makefile開發(fā)C/C++

使用VsCode+makefile開發(fā)C/C++

1. 介紹

vscode作為現(xiàn)在越來越受歡迎的編輯器之一,因?yàn)榭梢允褂貌寮寁scode支持幾乎市面上所有的編程語言,由于筆者主要接觸的是 C/C++ 方面,因此在這里簡單介紹一下如何搭建vscode編譯、調(diào)試C/C++項(xiàng)目的過程;整套環(huán)境完全使用開源軟件進(jìn)行搭建,只需要做很少的改變就可以無縫搬移到linux中;采用的方案是:vscode+git+mingw gcc+makefile;最后有詳細(xì)的技術(shù)說明和資源分享(GitHub 項(xiàng)目:vscode_c_demo);

介紹一下筆者搭建的平臺(tái)和所需要的軟件:

Windows

VsCode

Git

MinGW

C/C++插件

簡體中文包

  1. win7 以上;

  2. VS Code 官方下載地址

  3. Git (官方下載地址);

  4. mingw GUN 編譯工具 (官方下載地址);

  5. 在VS Code中你需要安裝

    5.1. C/C++ 插件(用于智能代碼提示);

    5.2. Chinese (Simplified) Language Pack(中文簡體支持包,英文好的請忽略)

下載安裝VsCode插件比較簡單;點(diǎn)擊右側(cè)圖標(biāo)搜索即可;
插件

,或者 快捷鍵 "Ctrl+Shift+X",搜索上述插件名稱即可;

筆者不建議在mingw 的官網(wǎng)下載GCC 編譯器;因?yàn)榫W(wǎng)絡(luò)的速度會(huì)很慢,會(huì)等很久;很多開源的編譯器都會(huì)自帶mingwGcc編譯器;例如DEVC++ 、Qt 等;

這里提供一個(gè)百度鏈接 https://pan.baidu.com/s/1x-jXHtiiWI0Kc1l34M_LrA 提取碼:8q0d ;里面有上述所需要的所有安裝包;截至2019年11月8日,里面的安裝包均是最新版本,里面請區(qū)分32bit和64bit;

** 2.安裝軟件**

上述所有軟件下載好之后,我們就可以開始安裝程序了,所有程序可以一起安裝,這里我們只講解安裝過程中的注意事項(xiàng);

首先安裝中,安裝路徑中不能出現(xiàn)中文;盡量避免空格 !

---------------------------------------------------------------------------------------華麗麗分割線---------------------------------------------------------------------------------------

2.1 mingw GUN GCC 編譯器

mingw 在我的百度云鏈接中是壓縮包,我們把他解壓到指定位置后(我解壓的位置是C:/mingw32 ),將編譯器的bin目錄添加到系統(tǒng)環(huán)境變量;如何添加系統(tǒng)環(huán)境變量請自行百度;

查看是否添加成功:打開 cmd(window + R 輸入cmd打開命令行窗口) 輸入 ** g++ --version ** 如果出現(xiàn)類似以下字樣表示設(shè)置環(huán)境變量成功;

查看GCC版本

---------------------------------------------------------------------------------------華麗麗分割線---------------------------------------------------------------------------------------

2.2 Git

git 的默認(rèn)編輯器是 vim 如果你從來沒有聽說過Git,那么請一路 next 安裝;如果你有聽過git ;我想我這個(gè)菜鳥也幫不了你啥~;如果你正在學(xué)習(xí)git,你可以看看這篇文章:git學(xué)習(xí)筆記--基礎(chǔ)運(yùn)用

---------------------------------------------------------------------------------------華麗麗分割線---------------------------------------------------------------------------------------

2.3 VS Code

安裝vscode 也比較簡單,只有一個(gè)需要注意

安裝VsCode

一定要將 “通過Code 打開操作” 添加到目錄的上下文菜單,后期作用會(huì)比較大;其他選項(xiàng)請自行選擇;

---------------------------------------------------------------------------------------華麗麗分割線---------------------------------------------------------------------------------------

2.4 安裝插件

安裝C語言插件

安裝中文包插件

插件安裝之后會(huì)提示重啟vscode 激活插件,重啟即可

---------------------------------------------------------------------------------------華麗麗分割線---------------------------------------------------------------------------------------

3.配置參數(shù)

** 1. 導(dǎo)入一個(gè)示例項(xiàng)目**

這邊你們可以隨便導(dǎo)入一個(gè)項(xiàng)目,可以有多個(gè)文件夾,文件夾中可以有.c/.h文件,但是有一個(gè)要求,就是在里面的文件不存在沖突;即文件夾里面的源文件都是需要用到的,就算沒有用到,也沒有命名沖突等系列問題;

因?yàn)榻酉聛淼倪@個(gè)makefile會(huì)自動(dòng)將你項(xiàng)目文件夾下所有的.c/.h文件全部編譯,如果出現(xiàn)沖突,那么請你自己解決;最好的情況是:你用到了哪些文件你就放入哪些文件,不需要的文件可以修改他的后綴名;

為了方便展示,我從github 上clone 一個(gè)項(xiàng)目到文件夾下;在文件夾空白處右鍵單擊,選擇git bash here 輸入:

git clone https://github.com/KimAlittleStar/vscode_c_demo.git

克隆成功后,右鍵點(diǎn)擊生成出來的 vscode_c_demo文件夾;open with vscode ;文件樹如下:

項(xiàng)目文件樹

---------------------------------------------------------------------------------------華麗麗分割線---------------------------------------------------------------------------------------

2.設(shè)置默認(rèn)的shell 命令行

點(diǎn)擊左下角 齒輪圖標(biāo) 選擇 設(shè)置 或者 點(diǎn)擊 文件->首選項(xiàng)->設(shè)置 打開如下界面

如果你選擇用戶,那么更改的是默認(rèn)配置,如果你選擇工作區(qū),那么你做的設(shè)置只會(huì)在這個(gè)文件夾內(nèi)部起作用;

修改shell

---------------------------------------------------------------------------------------華麗麗分割線---------------------------------------------------------------------------------------

3.讓VScode 提供智能提示

修改編譯器默認(rèn)路徑
//C:/Git/bin/bash.exe 應(yīng)該是你安裝的git的bin目錄下的bash.exe//C:/mingw32/bin/gcc.exe 應(yīng)該是你安裝的mingw下bin目錄的gcc.exe//如果你的項(xiàng)目是C++ ,請換成 g++.exe//如果復(fù)制此段單嗎到你的 setting.json文件后出錯(cuò),請刪除注釋{    "terminal.integrated.automationShell.windows":"C:/Git/bin/bash.exe",    "C_Cpp.default.compilerPath": "C:/mingw32/bin/gcc.exe"}

---------------------------------------------------------------------------------------華麗麗分割線---------------------------------------------------------------------------------------

4.設(shè)置編譯任務(wù)task.json 和 運(yùn)行設(shè)置 launch.json

{ // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format    //此 json 文件中需要注意的就是 執(zhí)行makefile的執(zhí)行文件是 mingw32-make.exe ,如果你使用qmake 或者其他make 執(zhí)行文件,替換它即可;其他不需要修改
    "version": "2.0.0",
    "tasks": [
        {
            "label": "build", //task的名字,調(diào)用方式就是 task build  
            "command": "mingw32-make.exe", //會(huì)在命令行中調(diào)用此命令  
            "args": [ //調(diào)用上述 mingw32-make.exe 傳遞給它的參數(shù)  
                "target=${workspaceRootFolderName}.exe" //${workspaceRootFolderName} 會(huì)被替換成 根目錄 即:vscode_c_demo            
            ],
            "type": "shell",
            "problemMatcher": []
        }, //此命令等效展開:mingw32-make.exe target=vscode_c_demo.exe        
        {
            "label": "build-debug",
            "command": "mingw32-make.exe",
            "args": [
                "target=${workspaceRootFolderName}.exe",
                "DEBUG=-g", //添加debug 參數(shù) 使gcc 生成調(diào)試信息
                "PREDEF=Debug" //相當(dāng)于在程序中定義了一個(gè)宏定義#define Debug            
            ],
            "type": "shell"
        }, //此命令等效展開為:mingw32-make.exe target=vscode_c_demo.exe DEBUG=-g PREDEF=Debug        
        {
            "label": "clean",
            "command": "mingw32-make.exe",
            "args": [
                "clean",
                "target=${workspaceRootFolderName}.exe"
            ],
            "type": "shell",
            "problemMatcher": []
        }, //此命令等效展開為:mingw32-make.exe clean target=vscode_c_demo.exe        
        {
            "label": "runing",
            "command": "./runExcute.sh",
            "args": [
                "${workspaceRootFolderName}.exe" // 傳給腳本的參數(shù)            
            ],
            "type": "shell"
        } //此命令等效展開為:mingw32-make.exe target=vscode_c_demo.exe  然后執(zhí)行 ./vscode_c_demo.exe    
    ]
}
{
    // 使用 IntelliSense 了解相關(guān)屬性。 
    // 懸停以查看現(xiàn)有屬性的描述。
    // 欲了解更多信息,請?jiān)L問: https://go.microsoft.com/fwlink/?linkid=830387
    // 
    //這里我們需要注意修改的是:"miDebuggerPath": "C:/Qt/Tools/mingw730_64/bin/gdb.exe"
    //
    //這里gdb的路徑應(yīng)該是你自己的gdb 文件路徑
    // 
    // "program": "${workspaceFolder}/${workspaceRootFolderName}.exe"
    // 這里調(diào)用的exe 應(yīng)就是 task build-debug 中生成的可執(zhí)行文件;
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) 啟動(dòng)", //名字,會(huì)顯示在debug 的選項(xiàng)中
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/${workspaceRootFolderName}.exe", //表示要調(diào)試的可執(zhí)行文件在當(dāng)前打開的文件下下的這個(gè)文件,此名稱需要和task 中的target=<>,一一對應(yīng);
            "args": [],
            "stopAtEntry": false, //時(shí)候要在main函數(shù)處自動(dòng)停止,false表示不會(huì)停止,true表示會(huì)在main函數(shù)處自動(dòng)停止;
            "cwd": "${workspaceFolder}", //表示首先要切換到當(dāng)前目錄下
            "environment": [],
            "externalConsole": false, //為true時(shí),會(huì)新建一個(gè)黑窗口運(yùn)行程序,如果為false ,就會(huì)在vscode中新建終端,
            //不過這樣就需要在用戶設(shè)置中設(shè)置默認(rèn)bash 為 gitbash,否則會(huì)報(bào)錯(cuò)
            "MIMode": "gdb",
            "miDebuggerPath": "E:/userFile/userSoftware/Qt/Tools/mingw730_64/bin/gdb.exe", // 這里填寫的應(yīng)該是你自己gdb.exe文件的路徑;一般與g++.exe minwg32-make.exe 在同一文件夾下
            "setupCommands": [
                {
                    "description": "為 gdb 啟用整齊打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "build-debug" //在執(zhí)行這個(gè)gdb launcher 之前,首先執(zhí)行task build-debug;
        }
    ]
}
調(diào)用 task

貼一下task.josn 和 launch.json 的代碼

---------------------------------------------------------------------------------------華麗麗分割線---------------------------------------------------------------------------------------

5.嘗試運(yùn)行

快捷鍵 CTRL + P 打開命令行 輸入 task+空格+任務(wù)命令 即可執(zhí)行相應(yīng)命令

task.json中一共創(chuàng)建了4個(gè)命令; 分別是 build build-debug clean running

task build #創(chuàng)建一個(gè)文件夾名字相同的可執(zhí)行文件;并且所有的中間文件都會(huì)生成放在build文件夾下;

task build-debug #與build類似,但是會(huì)生成調(diào)試信息,如果你想使用gdb等工具調(diào)試,那么必須使用此選項(xiàng);

task clean #清除所有由build帶來的文件

task runing #一共分兩步,首先build ,其次調(diào)用其可執(zhí)行文件;
運(yùn)行

---------------------------------------------------------------------------------------華麗麗分割線---------------------------------------------------------------------------------------

** 6 DEBUG 選項(xiàng)**

vscode Debug使用的是mingw32中的gdb.exe調(diào)試,與平常的斷點(diǎn)調(diào)試并無太大差異;

具體使用方法如下:點(diǎn)擊左側(cè)導(dǎo)航鍵 蟲子的圖標(biāo),選擇(gdb)啟動(dòng),點(diǎn)擊右方綠色的開始圖標(biāo),vscode會(huì)自動(dòng)開始編譯,運(yùn)行到斷點(diǎn)處會(huì)自動(dòng)停止,更多設(shè)置請參考上文launch.json中的注釋

debug單步調(diào)試

---------------------------------------------------------------------------------------華麗麗分割線---------------------------------------------------------------------------------------

4.原理分析

    整個(gè)環(huán)境搭建最主要的工作在于:**mingw32-make.exe** 中,實(shí)際上,如果你安裝了git ,并按照上述方式修改了默認(rèn)的終端為 gitbash,那么你只需要在終端中輸入 mingw32-make.exe target=a.exe ,也會(huì)自動(dòng)生成一個(gè)a.exe的可執(zhí)行文件,在終端輸入mingw32-make.exe clean target=a.exe,也可以清除所有由build帶來的所有新建的中間依賴文件;task.json的作用就在于 當(dāng)我 輸入 task build 時(shí) ,就相當(dāng)于我在gitbash中輸入了mingw32-make.exe target=DirName.exe 這個(gè)命令;

接下來我們會(huì)分析為什么mingw32-make.exe 可以做到這些,如果你仔細(xì)觀察我們的文件樹,你會(huì)發(fā)現(xiàn)文件樹中有一個(gè)沒有后綴的文件叫 makefile,我們可以打開makefile 文件,

#此項(xiàng)目源文件后綴類型
PROJECTTYPE = .c

#您想要生成可執(zhí)行文件的名字 如果外部沒有賦值,那么使用obj.out
target ?= obj.out

#是否生成DEBUG選項(xiàng)
DEBUG ?=#系統(tǒng)之外的宏定義
PREDEF ?=#獲取當(dāng)前makefile絕對路徑
pes_parent_dir:=$(dir $(abspath $(lastword $(MAKEFILE_LIST))))////#刪除路徑下最后一個(gè) / pes_parent_dir:=$(subst /////,,$(pes_parent_dir))#獲得mkfile 的實(shí)際路徑  測試使用,  沒有實(shí)際用到 可刪除
mkPath:=$(dir $(abspath $(lastword $(MAKEFILE_LIST))))////mkPath:=$(subst /////,,$(mkPath))#將所有宏定義前方加入-D指令以便給編譯器識別
DEF := $(foreach n,$(PREDEF),-D$(n))

#獲取目錄下所有子目錄
AllDirs := $(shell cd $(pes_parent_dir); ls -R | grep '^./.*:$$' | awk '{gsub(":","");print}') .

#添加成為絕對路徑
AllDirs := $(foreach n,$(AllDirs),$(subst .,$(pes_parent_dir),$(n)))

#獲取所有 .c/.cpp文件路徑
Sources := $(foreach n,$(AllDirs) , $(wildcard $(n)/*$(PROJECTTYPE)))

#設(shè)置*.o 和 *.d 文件的存放路徑
buildPath :=$(foreach n,$(Sources),$(subst $(pes_parent_dir),$(pes_parent_dir)/build,$(n)))

#處理得到*.o 后綴文件名
OBJS := $(patsubst %$(PROJECTTYPE),%.o, $(buildPath))  

#同理得到 *.d文件名
Deps := $(patsubst %$(PROJECTTYPE),%.d, $(buildPath))  

#需要用到的第三方靜態(tài)庫
StaticLib :=

#需要用到的第三方動(dòng)態(tài)鏈接庫
DynamicLib := 

#真實(shí)二進(jìn)制文件輸出路徑
Bin :=$(pes_parent_dir)/$(target)

#C語言編譯器
CC = gcc

#C++編譯器
CXX = g++

#簡化rm -f
RM = rm -f

#C語言配置參數(shù)
CFLAGS = -g  -pedantic -std=c11 -Wall -o

#C++配置參數(shù)
CXXFLAGS = -g -Wall -std=c11 

#頭文件搜索路徑
INCLUDE_PATH = $(foreach n,$(AllDirs) , -I$(n))
LDFLAGS = 

#指定AllLibs為終極目標(biāo) 即:最新的Bin 
AllLibs:$(Bin)

#聲明這個(gè)標(biāo)簽 des 用于觀察當(dāng)前的路徑是否正確
.PHONY:des
des:
    @echo OBJS =  $(OBJS)
    @echo cur_makefile_path = $(pes_parent_dir)
    @echo AllDirs = $(AllDirs)
    @echo Sources = $(Sources)
    @echo Deps = $(Deps)
    @echo makefilePath =$(mkPath)
    @echo bulidPath=$(buildPath)
    @echo PREDEF = $(DEF)
    @echo DEBUG = $(DEBUG)

#對應(yīng)關(guān)系 在本makefile中以空格隔開的后綴為.c 都會(huì)為其生成一個(gè)新的.d文件
#$(pes_parent_dir)/build/%.d :$(pes_parent_dir)/%.c  
#       @echo 'finding $< depending head file'
#       @if [ ! -d $(dir $@) ]; then mkdir -p $(dir $@); fi;
#       @$(CC) -MT"$(<:.c=.o) $@" -MM $(INCLUDE_PATH) $(CPPFLAGS) $< > $@


#對應(yīng)關(guān)系 在本makefile中以空格隔開的后綴為.c 都會(huì)為其生成一個(gè)新的.d文件
$(pes_parent_dir)/build/%.d :$(pes_parent_dir)/%.c
    @echo 'finding $< depending head file'
    @if [ ! -d $(dir $@) ]; then mkdir -p $(dir $@); fi;
    @set -e; rm -f $@; 
    $(CC) -MM $(INCLUDE_PATH) $(DEF) $(CPPFLAGS) $< > $@.$$$$; 
    sed 's,($*).o[ :]*,1.o $@ : ,g' < $@.$$$$ > $@; 
    rm -f $@.$$$$


#對于include中的*.d文件,只要里面任意有一個(gè)文件被修改,那么就會(huì)觸發(fā)此規(guī)則生成一個(gè)新的*.o文件
%.o: %.d
    @echo compile $(patsubst %.d,%.c,$(subst build/,,$<)) 
    @$(CC) -c $(patsubst %.d,%.c,$(subst build/,,$<)) $(DEBUG) $(DEF) $(INCLUDE_PATH) $(CFLAGS) $@ 



$(Bin) : $(OBJS)  
    @echo bulding....
    @$(CC) $(OBJS)  $(CFLAGS) $(Bin)
    @echo created file: $(target)    

.PHONY : clean  
clean:   
        @echo '清理所有文件ing...'
        @$(RM) -r $(pes_parent_dir)/build/
        @echo '清理可執(zhí)行文件ing...'
        @$(RM) $(Bin)
        @echo 'done'

.PHONY : cleanO
cleanO:
        @echo '清理Obj && Dep'
        @$(RM) -r $(pes_parent_dir)/build
        @echo 'done'
#main.out: $(OBJ)
#    cc -o main.out $(OBJ)

include $(buildPath:.c=.d)

在上述makefile 中,比較關(guān)鍵的語句在于

= $(shell cd $(pes_parent_dir);  -R |   |  ) .
···
#對應(yīng)關(guān)系 在本makefile中以空格隔開的后綴為.c 都會(huì)為其生成一個(gè)新的.d文件
$(pes_parent_dir)/build/%.d :$(pes_parent_dir)/%.c
@echo 'finding $< depending head file'
@if [ ! -d $(dir $@) ]; then mkdir -p $(dir $@); fi;
@set -e; rm -f $@; 
$(CC) -MM $(INCLUDE_PATH) $(DEF) $(CPPFLAGS) $< > $@.$$$$; 
sed 's,($*).o[ :]*,1.o $@ : ,g' < $@.$$$$ > $@; 
rm -f $@.$$$$

shell cd $(pes_parent_dir) 表示切換路徑到該makefile 的目錄下,然后 ls -R:遞歸輸入該目錄下的所有文件以及文件夾;如果是文件夾,那么就會(huì)單獨(dú)起一行然后文件夾名字前有 ‘.’ 作為標(biāo)記 后面的grepawkgsup 都是linux下才有的命令;

同理在 下方if [ ! -d $(dir $@) ]; then mkdir -p $(dir $@); fi;所做的邏輯就是判斷當(dāng)前想要生成的.d文件的目標(biāo)文件夾在不在, 不在則創(chuàng)建它, 其中dir mkdir 都是linux中才會(huì)有的命令,當(dāng)然windows下也有與其差不多功能的命令,但是此makefile我希望在linux下也能用,這個(gè)時(shí)候怎么辦呢,這個(gè)時(shí)候就要介紹我們的 Git 了,git在windows中使用的命令行軟件 bash.exe 就把上面的命令都覆蓋到了,也就是說,如果我們使用windows 自帶的cmd.exe 或者 powerShell.exe 里面都會(huì)使得 dir mkdir 和其他命令找不到,導(dǎo)致makefile錯(cuò)誤終止;所以我們才需要安裝Git* ,所以我們才需要將Git bash 設(shè)置成為vsCode 默認(rèn)的終端;因?yàn)?strong>只有g(shù)it bash 中才可以調(diào)用上述makefile中的幾個(gè)shell命令;

還記的我們將mingw32編譯器的路徑加入到了系統(tǒng)環(huán)境變量里面去了~為什么呢?

#C語言編譯器
CC = gcc#C++編譯器
CXX = g++

因?yàn)?在makefile 的編譯器中,gcc 、g++ 只是簡單的字符,只有將gcc 、g++ 的路徑加入了環(huán)境變量,他們才能正確的被找到;

還有,如果我們想管理C++項(xiàng)目這個(gè)時(shí)候怎么辦呢~我們只需要在 makefile中將所有的 $(CC) 替換成 $(CXX) 所有 的$(CFLAG) 替換成 $(CXXFLAG) 就可以了哦~

makefile中其他的只是我就不贅述了,你可以參考這個(gè)鏈接:一個(gè)自動(dòng)管理項(xiàng)目的makefile

最后獻(xiàn)上我整個(gè)項(xiàng)目的github地址https://github.com/KimAlittleStar/vscode_c_demo

里面有所有的項(xiàng)目文件,以及配置文件,和較為詳細(xì)的注釋;只需要修改幾個(gè)簡單的路徑就可以完成上述的配置;我都有在json文件里面說明哦~~~

---------------------------------------------------------------------------------------華麗麗分割線---------------------------------------------------------------------------------------

如果關(guān)注度還可以的話;

我會(huì)選擇更新:

一鍵/自動(dòng)轉(zhuǎn)換 C/C++ 項(xiàng)目的makefile,

編寫一個(gè)只清楚中間文件,而不清除可執(zhí)行文件的task

搭建VSCode + 嵌入式 ARM編譯調(diào)試環(huán)境

碼字不易,覺得稍微有點(diǎn)用的,可以在git里面 star一下,博客點(diǎn)個(gè)小贊;

讀書的時(shí)候就想了2、3年的事情,現(xiàn)在終于快要看到成功了;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容