對於多文件的C項目,大部分人會選擇使用'cmake'來管理編譯過程,對於精力充沛的朋友來說,也可以學習一下使用這個強大的工具。
但我覺得如果只想在VS Code里寫幾行代碼應對當前需求,沒必要再去學習一個完全陌生的東西,也沒必要把配置過程復雜化。
所以我接下來講的配置多文件編譯的過程並不涉及'cmake'。
目錄模式
我將這種配置方式稱為“目錄模式”,跟Eclipse類似,每個目錄作為一個項目。

在上一篇中我們講了如何進行單文件的編譯和調試,其中使用了VS Code提供的變量,以定位到當前文件。
同樣地,我們只需要再使用VS Code提供的變量,定位到當前目錄,再利用Linux Shell的通配符,即可匹配到當前目錄下所有要編譯的源文件。
gcc本身是支持多文件編譯的,只需要把文件名作為參數即可。
配置好的tasks.json文件大致如下:
{ "version": "2.0.0", "tasks": [ { "type": "shell", "label": "build(gcc)", "command": "gcc", "args": [ "-g", "-o", "/tmp/buildtempc", "*.c" // 匹配所有源文件 ], "options": { "cwd": "${fileDirname}" // 定位到當前目錄 }, "group": { "kind": "build", "isDefault": true } } ] }
配置好的launch.json文件大致如下:
{ "version": "0.2.0", "configurations": [ { "name": "debug(gdb)", "type": "cppdbg", "request": "launch", "program": "/tmp/buildtempc", "args": [], "stopAtEntry": false, "cwd": "${fileDirname}", // 定位到當前目錄 "environment": [], "externalConsole": false, "MIMode": "gdb", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true } ], "preLaunchTask": "build(gcc)", } ] }
注意:匹配源文件時一定要寫成'*.c',而不能寫成'*'。因為頭文件不是編譯單元,頭文件在編譯源文件時被處理。
在我的配置文件里,我將可執行文件放在了'/tmp'目錄下,以使工作目錄看起來簡潔一些。
'.vscode'目錄下的配置文件對工作空間下的所有目錄和文件都是有效的,現在我們只需要新建一個目錄,並在里面寫好頭文件和源文件,就可以編譯和調試了。

目錄模式有一些缺陷:
✿ 頭文件和源文件放在一起會比較亂 ✿ 項目變多的時候,工作空間會比較亂 ✿ ‘C/C++’擴展會掃描工作空間內的所有文件,如果項目變多會降低擴展性能,也會使擴展功能混亂 |
授之以魚不如授之以漁。
我強烈建議不要直接復制我的配置文件,而是要理解每個配置選項的意義和目的,從而寫出符合個人喜好的配置。
項目模式
對於目錄模式來說,如果工作空間的項目變多,就會出現麻煩。所以在項目模式里,每個項目獨占一個工作空間,類似VS的解決方案。
因為一個項目獨占一個工作空間,所以我們沒必要把所有文件都擠在一起,還可以再細分。比如我喜歡分為“頭文件”、“源文件”、“資源文件”。
“資源文件”目錄用於調試程序的相對位置讀寫,或者存放一些與編譯無關的其他文件。每一個類別建立一個目錄。

'C/C++'擴展會掃描工作空間下的所有文件,所以在寫#include時不需要指定文件夾,代碼提示也能正常工作。
但是gcc在編譯時只會查找源文件所在目錄下的頭文件,所以需要額外參數指定頭文件目錄。
另外,也需要指定需要編譯的源文件目錄。
而資源文件與編譯過程無關,需要修改調試的配置文件。
配置好的tasks.json文件大致如下:
{ "version": "2.0.0", "tasks": [ { "type": "shell", "label": "build(gcc)", "command": "gcc", "args": [ "-g", "-o", "/tmp/buildtempc", "-iquote", // 指定頭文件目錄 "Headers", // 頭文件目錄 "Sources/*.c" // 源文件目錄下的所有源文件 ], "options": { "cwd": "${workspaceFolder}" // 定位到工作空間 }, "group": { "kind": "build", "isDefault": true } } ] }
配置好的launch.json文件大致如下:
{ "version": "0.2.0", "configurations": [ { "name": "debug(gdb)", "type": "cppdbg", "request": "launch", "program": "/tmp/buildtempc", "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}/Resources", // 定位到資源文件目錄 "environment": [], "externalConsole": false, "MIMode": "gdb", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true } ], "preLaunchTask": "build(gcc)", } ] }
這樣,就可以跟VS一樣在項目中寫代碼了。

當然,這種配置方法的缺點也顯而易見。新建一個項目的成本太大了,每新建一個項目就得再寫一次配置文件,並新建三個目錄。
不過,在Linux下,這些重復的工作當然是交給計算機來做。我們只需要保存一份'.vscode'模板就好,比如我保存在變量CODE_PATH表示的目錄下。每個項目的配置文件都是一樣的,直接拷貝就好。
Bash腳本如下:
#!/bin/bash # Filename: project-c # Create a C project, and open it in vscode. echo -n "project name: " read name name=$(date +%Y%m%d)-"$name" // 生成項目名 mkdir "$CODE_PATH"/"$name" // 新建項目目錄 cd "$CODE_PATH"/"$name" cp -r "$CODE_PATH"/.vscode . // 拷貝配置文件 mkdir Headers Sources Resources // 新建分類目錄 code . // 使用VS Code打開項目 cd - &> /dev/null
在腳本中,我給項目名稱加上了時間戳,方便查找與避免重名。啟動VS Code的命令是code。

不管你是轉行也好,初學也罷,進階也可
——【值得關注】我的C/C++編程學習進階俱樂部 ——
涉及到:C語言、C++、windows編程、網絡編程、QT界面開發、Linux編程、游戲編程、黑客等等......