1. 程式人生 > >快速在VSCode中建立多檔案多目錄C++專案

快速在VSCode中建立多檔案多目錄C++專案

對於輕量級的VSCode編輯器,我想像使用那些IDE一樣,通過簡單的幾步就能構建出自己的專案檔案樹,類似於下面的結構。所以特地寫了一個指令碼,用於自動建立一個基本的專案。

.
├── Headers
│   └── test.hpp
├── makefile
├── Output
│   └── bin
└── Sources
    ├── main.cpp
    └── test.cpp

下面直接提供指令碼:

### new.sh

# 輸入一個檔名 $projectname
read projectname

# 新增字首
filename="VSC_CPP_"$projectname
# 原始檔目錄 Src="$filename/Sources" # 標頭檔案目錄 Inc="$filename/Headers" # 建立專案樹 mkdir -p $Src $Inc $filename/Output/bin # 建立makefile檔案 touch $filename/makefile # 建立 main.cpp檔案 touch $Src/main.cpp # 檔名小寫轉換 #declare -l lfilename=$projectname lfilename="${projectname,,}" # 原始檔 cpp_file=$Src"/"${lfilename}".cpp"
# 標頭檔案 hpp_file=$Inc"/"${lfilename}".hpp" # 建立一對專案檔案 touch $cpp_file $hpp_file # 向main.cpp中寫入內容 echo "#include <iostream> " >> $Src/main.cpp echo "#include \"$lfilename.hpp\"" >> $Src/main.cpp echo "" >> $Src/main.cpp echo "using namespace std;" >> $Src/main.cpp echo "" >>
$Src/main.cpp echo "int main()" >> $Src/main.cpp echo "{" >> $Src/main.cpp echo " cout << \"Hello VSC\" << endl;" >> $Src/main.cpp echo " return 0;" >> $Src/main.cpp echo "}" >> $Src/main.cpp # 向*.hpp中寫入內容 echo "#pragma once" >> $Inc/$lfilename.hpp echo "#include <iostream>" >> $Inc/$lfilename.hpp echo "using namespace std;" >> $Inc/$lfilename.hpp echo "" >> $Inc/$lfilename.hpp echo "class $projectname" >> $Inc/$lfilename.hpp echo "{" >> $Inc/$lfilename.hpp echo "public:" >> $Inc/$lfilename.hpp echo " $projectname();" >> $Inc/$lfilename.hpp echo " $projectname($projectname &&) = default;" >> $Inc/$lfilename.hpp echo " $projectname(const $projectname &) = default;" >> $Inc/$lfilename.hpp echo " $projectname &operator=($projectname &&) = default;" >> $Inc/$lfilename.hpp echo " $projectname &operator=(const $projectname &) = default;" >> $Inc/$lfilename.hpp echo " ~$projectname();" >> $Inc/$lfilename.hpp echo "" >> $Inc/$lfilename.hpp echo "protected:" >> $Inc/$lfilename.hpp echo "" >> $Inc/$lfilename.hpp echo "private:" >> $Inc/$lfilename.hpp echo "" >> $Inc/$lfilename.hpp echo "};" >> $Inc/$lfilename.hpp # 向*.cpp中寫入內容 echo "#include \"$lfilename.hpp\"" >> $Src/$lfilename.cpp echo "" >> $Src/$lfilename.cpp echo "$projectname::$projectname()" >> $Src/$lfilename.cpp echo "{" >> $Src/$lfilename.cpp echo "}" >> $Src/$lfilename.cpp echo "" >> $Src/$lfilename.cpp echo "$projectname::~$projectname()" >> $Src/$lfilename.cpp echo "{" >> $Src/$lfilename.cpp echo "}" >> $Src/$lfilename.cpp # 匯入makefile # cat "./makefile" >> $filename/makefile echo "# 描述: C++ 專案 makefile檔案" >> $filename/makefile echo "# 版本: v3.0" >> $filename/makefile echo "# 修改記錄: 1.先測試普通的cpp檔案的編譯執行" >> $filename/makefile echo "# 2.使用變數來改進我們的makefile檔案" >> $filename/makefile echo "# 3.新加了一個原始檔" >> $filename/makefile echo "# 4.使用偽目標,加上clean規則" >> $filename/makefile echo "# 5.使用wildcard函式,自動掃描當前目錄下的原始檔" >> $filename/makefile echo "# 6.加入了自動規則依賴" >> $filename/makefile echo "# 7.改變依賴關係的生成模式" >> $filename/makefile echo "# 8.提供多目錄檔案編譯" >> $filename/makefile echo "" >> $filename/makefile echo "# 標頭檔案存放目錄" >> $filename/makefile echo "INC_DIR=./Headers" >> $filename/makefile echo "" >> $filename/makefile echo "# 可執行檔案存放目錄" >> $filename/makefile echo "BIN_DIR=./Output/bin" >> $filename/makefile echo "" >> $filename/makefile echo "# 原始檔存放目錄" >> $filename/makefile echo "SRC_DIR=./Sources" >> $filename/makefile echo "" >> $filename/makefile echo "# 其它中間檔案存放目錄" >> $filename/makefile echo "OBJ_DIR=./Output" >> $filename/makefile echo "" >> $filename/makefile echo "# 原始檔列表" >> $filename/makefile echo "SRC := \${wildcard \${SRC_DIR}/*.cpp}" >> $filename/makefile echo "" >> $filename/makefile echo "# obj檔案列表" >> $filename/makefile echo "OBJ := \${patsubst %.cpp, \$(OBJ_DIR)/%.o, \${notdir \${SRC}}}" >> $filename/makefile echo "" >> $filename/makefile echo "# 定義編譯命令變數" >> $filename/makefile echo "CC := g++" >> $filename/makefile echo "rm := rm -rf" >> $filename/makefile echo "" >> $filename/makefile echo "# 定義可執行檔案變數" >> $filename/makefile echo "executable := main" >> $filename/makefile echo "BIN_TARGET=\${BIN_DIR}/\${executable}" >> $filename/makefile echo "" >> $filename/makefile echo "# 終極目標規則:生成可執行檔案" >> $filename/makefile echo "\${BIN_TARGET}:\${OBJ}" >> $filename/makefile echo " \${CC} \${OBJ} -o \[email protected]" >> $filename/makefile echo "" >> $filename/makefile echo "# 子目標規則:生成連結檔案" >> $filename/makefile echo "\${OBJ_DIR}/%.o:\${SRC_DIR}/%.cpp" >> $filename/makefile echo " \${CC} -o \[email protected] -c $< -I\${INC_DIR}" >> $filename/makefile echo "" >> $filename/makefile echo "#clean規則" >> $filename/makefile echo "#.PHONY: clean" >> $filename/makefile echo "#clean:" >> $filename/makefile echo "#清除編譯生成的所有檔案" >> $filename/makefile echo "## \$(RM) \$(BIN_TARGET) \$(OBJ_DIR)/*.o" >> $filename/makefile echo "#清除編譯生成的所有檔案,不包括可執行檔案" >> $filename/makefile echo "# \$(RM) \$(OBJ_DIR)/*.o" >> $filename/makefile

現在對指令碼進行簡單的介紹:

  • 首先我們需要從外部讀入一個專案名稱,用於建立資料夾和內部的標頭檔案以及原始檔。需要注意的時,這個檔名需要是英文,並且最好是遵守駝峰命名法,因為專案檔案中的類名與這個名稱一致。指令碼中對專案名加字首是為了好與其他型別的專案進行區別。
$ bash new.sh
# 在終端中輸入Test作為這個專案名
Test
  • 建立專案樹。建立Headers資料夾用於存放標頭檔案,建立Sources資料夾用於存放原始檔,建立Output檔案用於存放可執行檔案以及中間檔案,可執行檔案存放在Output的子資料夾bin中。

  • 建立檔案。main.cpp, test.cpp, test.hpp, makefile。其中test.hpp和test.cpp是根據讀入的專案名建立的兩個檔案,檔名都經過了小寫轉換。

  • 向檔案中寫入基本的內容。這裡是通過echo的重定向操作實現寫入。以下是具體的寫入內容。

// main.cpp
#include <iostream> 
#include "test.hpp"

using namespace std;

int main()
{
    cout << "Hello VSC" << endl;
    return 0;
}

// test.hpp
#pragma once
#include <iostream>
using namespace std;

class Test
{
public:
    Test();
    Test(Test &&) = default;
    Test(const Test &) = default;
    Test &operator=(Test &&) = default;
    Test &operator=(const Test &) = default;
    ~Test();

protected:

private:

};
// test.cpp
#include "test.hpp"

Test::Test()
{
}

Test::~Test()
{
}

# makefile
# 描述: C++ 專案 makefile檔案
# 版本: v3.0
# 修改記錄:  1.先測試普通的cpp檔案的編譯執行
#		    2.使用變數來改進我們的makefile檔案
#			3.新加了一個原始檔
#			4.使用偽目標,加上clean規則
#			5.使用wildcard函式,自動掃描當前目錄下的原始檔
#			6.加入了自動規則依賴
#			7.改變依賴關係的生成模式
#			8.提供多目錄檔案編譯

# 標頭檔案存放目錄
INC_DIR=./Headers

# 可執行檔案存放目錄
BIN_DIR=./Output/bin

# 原始檔存放目錄
SRC_DIR=./Sources

# 其它中間檔案存放目錄
OBJ_DIR=./Output

# 原始檔列表
SRC	:= ${wildcard ${SRC_DIR}/*.cpp}

# obj檔案列表
OBJ	:= ${patsubst %.cpp, $(OBJ_DIR)/%.o, ${notdir ${SRC}}}

# 定義編譯命令變數
CC	:= g++
rm	:= rm -rf

# 定義可執行檔案變數
executable	:= main
BIN_TARGET=${BIN_DIR}/${executable}

# 終極目標規則:生成可執行檔案
${BIN_TARGET}:${OBJ}
	${CC} ${OBJ} -o [email protected]

# 子目標規則:生成連結檔案
${OBJ_DIR}/%.o:${SRC_DIR}/%.cpp
	${CC} -o [email protected] -c $< -I${INC_DIR}

#clean規則
#.PHONY: clean
#clean:
#清除編譯生成的所有檔案
##	$(RM) $(BIN_TARGET) $(OBJ_DIR)/*.o
#清除編譯生成的所有檔案,不包括可執行檔案
#	$(RM) $(OBJ_DIR)/*.o

這樣一個基本的專案就建立完成了。那麼應該在VS Code怎麼使用呢?
在這裡預設大家對在Linux環境下VS Code開發C++有一定的瞭解了。如果不瞭解的話,可以參考本人的相關部落格。

首先,我們需要對coder-runner外掛的配置檔案進行部分的改動。

image_1cp6m8e541uiq16jl18951j6h16khp.png-234.4kB

在User Settings 中搜索 code-runner.executorMap對C++專案檔案的執行命令進行更改。
更改如下:
"cpp": "cd $dir && cd .. && make && cd ./Output/bin && ./main && cd ../../"
解釋一下,$dir是我們在VS Code 中當前開啟的檔案目錄,一般是標頭檔案和原始檔(如果是makefile檔案,那麼執行這個外掛是沒有用的),首先會開啟這個目錄,然後回退到有makefile檔案的檔案目錄中,然後 進行make,我們使用VS Code 並不僅僅是為了生成可執行檔案,還需要看到執行結果,所以還需要瀏覽到可執行檔案所在的資料夾中,執行可執行檔案,在makefile中預設可執行檔名是main,執行完到這裡後,我是讓終端的當前目錄回到最初的目錄。

最後執行產生的專案檔案樹:

.
├── Headers
│   └── test.hpp
├── makefile
├── Output
│   ├── bin
│   │   └── main
│   ├── main.o
│   └── test.o
└── Sources
    ├── main.cpp
    └── test.cpp