# Visual Studio 專案建置
###### tags: `NTOU CSE C++ Programming` `Visual Studio`
> 教學文件和作業說明文件: https://hackmd.io/@kogiokka/ntou-cse-cpp-nav
> 範例程式和範例專案:[Google Drive](
https://drive.google.com/drive/folders/100YvcqccLgY_27mJnubRSuPALrMAghJQ?usp=sharing)
目前 Visual Studio 的最新版本是 2022。如果沒有特別需求,直接到[微軟官網](https://visualstudio.microsoft.com/zh-hant/downloads/)下載最新版本。你會得到一個 Visual Studio 安裝程式。開啟安裝程式之後會進入一個頁面要你選擇工作負載。勾選「**使用 C++ 的桌面開發**」並安裝。

如果希望下載較舊的版本(2019 或 2017)請到 [Visual Studio Subscription 網站](https://my.visualstudio.com/Downloads/Featured) 登入海大的微軟O365帳號。帳號是`<學號>@o365.ntou.edu.tw`,密碼是教學務系統密碼。
> 海洋大學微軟O365雲端服務說明:https://software.ntou.edu.tw/?q=node/536
不同版本的 Visual Studio 在建立新專案的部分稍有不同。本文皆下來會以 2019 為例。
## 建立空白專案
在**開始視窗**點選**建立新的專案→空白專案**,或是在主視窗的選單點擊**檔案→新增→專案→空白專案**。

建立專案時**勾選**下方的「**將解決方案和專案置於相同目錄中**」核取方塊。這樣可以避免產生兩個相同名稱的資料夾,簡化我們專案的檔案結構。

> Visual Studio 2017
>
> 請使用**檔案→新增→專案→已安裝→Visual C++→空白專案**來建立新專案,**不要**使用起始頁的新增專案功能。起始頁的新增專案功能在方案檔和專案檔共用目錄的設定下會把方案檔放錯地方。(測試的版本:15.9.45)
>
> 在建立專案時**取消勾選**位於右下角的「**為方案建立目錄**」核取方塊,將解決方案和專案置於相同目錄中。
>
> 
## 範例一、為現有原始碼檔案建立專案
依照前述方式建立一個空白專案。
### 將原始碼檔案加入專案
我們在電腦上整理文件或是相簿時會把相關的檔案放在一起,才能方便瀏覽、剪貼、壓縮和分享。寫一個軟體專案時也應該遵循這樣的原則,將同一個專案的程式碼和專案資源全部放在一個資料夾下。這個資料夾我們稱為**專案目錄**或**專案根目錄**,就是專案的最上層資料夾。所有與此專案相關的檔案都會放在這個資料夾內。所以請在加入現有檔案時記得,**先到檔案總管把原始碼檔案剪貼/複製進專案目錄,再到 Visual Studio 加入這些在專案的資料夾內的檔案**。
首先我們可以先在檔案總管中開啟專案根目錄:在 Visual Studio 的**方案總管**的專案名稱上點擊**右鍵→在檔案總管中開啟資料夾**。

開啟專案根目錄之後,我們把現有的程式碼放進專案的資料夾內,再告訴 Visual Studio 我們用到哪些檔案。複製原始碼檔案到專案根目錄:

在**方案總管**的專案名稱上點擊**右鍵→加入→現有項目**,並選取剛剛複製進去的檔案。Visual Studio 會自動幫你分類來源檔案和標頭檔。

如此一來就設定完成了!按畫面上方有綠色鍵頭的「本機 Windows 偵錯工具」,或按`F5`編譯並執行。
## 範例二、建立和使用靜態函式庫
依照前述方式建立一個空白專案`Project1`,作為我們應用程式的主體。這個專案會是解決方案中的**啟始專案**,是程式執行的進入點(`main`函式所在的地方)。
### 建立專案
> 微軟官方文件的範例:
> [Walkthrough: Create and use a static library](https://docs.microsoft.com/en-us/cpp/build/walkthrough-creating-and-using-a-static-library-cpp)
在方案總管的**解決方案'Project1'點擊右鍵→加入→新增專案→靜態程式庫**:


按下一步進入「設定新的專案」的畫面。更改**位置**欄位的路徑,設成`Project1`的路徑,**把靜態函式庫專案`StaticLib1`建立在啟始專案`Project1`的資料夾內**。

> Visual Studio 2017
>
> **解決方案'Project1'右鍵→加入→新增專案→靜態程式庫→已安裝→Visual C++→Windows Desktop→靜態程式庫**。一樣要記得更改**位置**的路徑到`Poject1`。
>
> 
>
接著依照上一題範例加入現有檔案的方法,把`main.cpp`加入`Project1`,把`f1.h`、`f1.cpp`、`f2.h`和`f2.cpp`加入`StaticLib1`。完成後整個專案的目錄結構會長這樣:
```
PROJECT1
│ main.cpp <-- main.cpp
│ Project1.sln <-- 方案檔
│ Project1.vcxproj <-- 啟始專案(Project1)的專案檔
│ Project1.vcxproj.filters
│ Project1.vcxproj.user
│
└─StaticLib1
f1.cpp <-- f1.cpp
f1.h <-- f1.h
f2.cpp <-- f2.cpp
f2.h <-- f2.h
framework.h
pch.cpp
pch.h
StaticLib1.cpp
StaticLib1.vcxproj <-- 靜態函式庫專案(StaticLib1)的專案檔
StaticLib1.vcxproj.filters
StaticLib1.vcxproj.user
```
### 修改範例程式
開啟`f1.cpp`和`f2.cpp`,在兩個檔案的最頂端引入`pch.h`檔。
```cxx=
// f1.cpp
#include "pch.h"
#include "f1.h"G
int g1 = 999;
// ......
```
```cxx=
// f2.cpp
#include "pch.h"
#include "f2.h"
void f2()
{
// ......
```
### 設定專案屬性
#### 調整`include`路徑
現在`main.cpp`中引入`f1`和`f2`的路徑如下:
```cxx=
// In main.cpp
#include "f1.h"
#include "f2.h"
// ......
```
C/C++在引入檔案時依循的是**相對路徑**,以這個範例而言就是相對於`main.cpp`的位置。原本`main.cpp`引入的兩個標頭檔的路徑是`"f1.h"`、`"f2.h"`,代表兩者與`main.cpp`位處同一個資料夾(可以表示為`"./f1.h"`、`"./f2.h"`)。現在`f1.h`和`f2.h`被放到`StaticLib1`的專案目錄內,如果`main.cpp`還使用上述的相對路徑,就會找不到檔案。
##### 方法一、修改原始碼
```cxx=
// In main.cpp
#include "StaticLib1/f1.h"
#include "StaticLib1/f2.h"
// ......
```
這麼做的缺點是當你在`Project1`使用到任何位於`StaticLib1`的標頭檔時,就必須加一個`StaticLib1/`前綴。
##### 方法二、修改專案的 Include 目錄
將`StaticLib1`資料夾加入`Project1`的`include`路徑中。在方案總管中的`Project1`上點擊**右鍵→屬性**進到專案的屬性頁。依序進入**組態屬性→C/C++→一般**,點選「**其他 Include 目錄**」後在最右邊的下拉選單選擇「**<編輯...>**」。

在編輯頁面的上方空白區域點兩下來編輯,輸入`$(ProjectDir)StaticLib1`後按Enter,在評估值的欄位檢查路徑是否正確。
> $(ProjectDir)是 MSBuild 的一個巨集。會被替換為專案目錄的路徑,結尾有目錄分隔符(反斜線「\」)。
>
> 更多關於 MSBuild 的巨集請見:
> [Common macros for MSBuild commands and properties](https://docs.microsoft.com/en-us/cpp/build/reference/common-macros-for-build-commands-and-properties)

#### 連結靜態函式庫
建立`Project1`到`StaticLib1`的相依性:
##### 方法一、將 `.lib` 加入專案
在方案總管的`Project1`點擊**右鍵→加入→現有項目**,在 Visual Studio 產生的建置目錄(`Debug`或`x64`資料夾)內找到並點選`StaticLib1.lib`檔案。
為了免去每次更改`StaticLib1`時都要手動建置的困擾,我們可以設定`Project1`的相依性。在方案總管的`解決方案'Project1'`上點擊**右鍵→屬性→通用屬性→專案相依性**。勾選`StaticLib1`的核取方塊,讓`Project1`相依於`StaticLib1`:

##### 方法二、設定專案參考
在方案總管的`Project1`之下的「**參考**」欄位點擊**右鍵→加入參考→專案**。勾選`StaticLib1`的核取方塊。


#### 編譯並執行
恭喜你走到這一步,請大膽地按下畫面上方的綠色播放鍵!
## 範例三、建立和使用動態函式庫
> 微軟官方文件的範例:
> [Walkthrough: Create and use your own Dynamic Link Library (C++)](https://docs.microsoft.com/en-us/cpp/build/walkthrough-creating-and-using-a-dynamic-link-library-cpp)
暫略。