用 Visual C 編譯(命令列)

對於從 GCC 或 Clang 到 Visual Studio 的程式設計師,或者通常更熟悉命令列的程式設計師,你可以從命令列以及 IDE 使用 Visual C++編譯器。

如果你希望從 Visual Studio 中的命令列編譯程式碼,首先需要設定命令列環境。這可以通過開啟 Visual Studio Command Prompt / Developer Command Prompt / x86 Native Tools Command Prompt / x64 Native Tools Command Prompt 或類似的 (由你的 Visual Studio 版本提供)或在命令提示符下導航到編譯器的安裝目錄的 VC 子目錄(通常是\Program Files (x86)\Microsoft Visual Studio x\VC,其中 x 是版本號(例如 2010 年的 10.0 或 2015 年的 14.0)並使用此處指定的命令列引數執行 VCVARSALL 批處理檔案。

請注意,與 GCC 不同,Visual Studio 不通過編譯器(cl.exe)為連結器(link.exe)提供前端,而是將連結器作為單獨的程式提供,編譯器在退出時呼叫該程式。cl.exelink.exe 可以單獨使用不同的檔案和選項,或者如果兩個任務一起完成,cl 可以被告知將檔案和選項傳遞給 link。為 cl 指定的任何連結選項都將轉換為 link 的選項,而未由 cl 處理的任何檔案將直接傳遞給 link。由於這主要是使用 Visual Studio 命令列進行編譯的簡單指南,因此目前不會描述 link 的引數。如果你需要一個清單,請看這裡

請注意,cl 的引數區分大小寫,而 link 的引數則不區分大小寫。

[建議在指定絕對路徑名時,以下某些示例使用 Windows shell當前目錄變數%cd%。對於不熟悉此變數的任何人,它會擴充套件到當前工作目錄。從命令列,它將是你執行 cl 時所在的目錄,預設情況下在命令提示符中指定(例如,如果你的命令提示符為 C:\src>,則%cd%C:\src\)。

假設當前資料夾中有一個名為 main.cpp 的原始檔,編譯和連結未經優化的可執行檔案的命令(對初始開發和除錯很有用)是(使用以下任一項):

cl main.cpp
// Generates object file "main.obj".
// Performs linking with "main.obj".
// Generates executable "main.exe".

cl /Od main.cpp
// Same as above.
// "/Od" is the "Optimisation: disabled" option, and is the default when no /O is specified.

假設在同一目錄中有一個額外的原始檔“niam.cpp”,請使用以下命令:

cl main.cpp niam.cpp
// Generates object files "main.obj" and "niam.obj".
// Performs linking with "main.obj" and "niam.obj".
// Generates executable "main.exe".

你也可以使用萬用字元:

cl main.cpp src\*.cpp
// Generates object file "main.obj", plus one object file for each ".cpp" file in folder
//  "%cd%\src".
// Performs linking with "main.obj", and every additional object file generated.
// All object files will be in the current folder.
// Generates executable "main.exe".

要重新命名或重定位可執行檔案,請使用以下方法之一:

cl /o name main.cpp
// Generates executable named "name.exe".

cl /o folder\ main.cpp
// Generates executable named "main.exe", in folder "%cd%\folder".

cl /o folder\name main.cpp
// Generates executable named "name.exe", in folder "%cd%\folder".

cl /Fename main.cpp
// Same as "/o name".

cl /Fefolder\ main.cpp
// Same as "/o folder\".

cl /Fefolder\name main.cpp
// Same as "/o folder\name".

/o/Fe 都將他們的引數(我們稱之為 o-param)傳遞給 link 作為/OUT:o-param,並根據需要將相應的副檔名(通常為 .exe.dll)附加到 name``o-params。雖然/o/Fe 在功能上都是相同的,但後者是 Visual Studio 的首選。/o 被標記為已棄用,似乎主要提供給更熟悉 GCC 或 Clang 的程式設計師。

請注意,雖然/o 與指定的資料夾和/或名稱之間的空格是可選的,但 /Fe 與指定的資料夾和/或名稱之間不能有空格。

同樣,要生成優化的可執行檔案(用於生產),請使用:

cl /O1 main.cpp
// Optimise for executable size.  Produces small programs, at the possible expense of slower
//  execution.

cl /O2 main.cpp
// Optimise for execution speed.  Produces fast programs, at the possible expense of larger
//  file size.

cl /GL main.cpp other.cpp
// Generates special object files used for whole-program optimisation, which allows CL to
//  take every module (translation unit) into consideration during optimisation.
// Passes the option "/LTCG" (Link-Time Code Generation) to LINK, telling it to call CL during
//  the linking phase to perform additional optimisations.  If linking is not performed at this
//  time, the generated object files should be linked with "/LTCG".
// Can be used with other CL optimisation options.

最後,要生成特定於平臺的優化可執行檔案(用於在具有指定體系結構的計算機上進行生產),請為目標平臺選擇適當的命令提示符或 VCVARSALL 引數link 應該從目標檔案中檢測出所需的平臺; 如果沒有,請使用 /MACHINE 選項明確指定目標平臺。

// If compiling for x64, and LINK doesn't automatically detect target platform:
cl main.cpp /link /machine:X64

上述任何一個都將生成一個名稱由/o/Fe 指定的可執行檔案,或者如果兩者都沒有提供,則其名稱與為編譯器指定的第一個原始檔或目標檔案相同。

cl a.cpp b.cpp c.cpp
// Generates "a.exe".

cl d.obj a.cpp q.cpp
// Generates "d.exe".

cl y.lib n.cpp o.obj
// Generates "n.exe".

cl /o yo zp.obj pz.cpp
// Generates "yo.exe".

要編譯檔案而不進行連結,請使用:

cl /c main.cpp
// Generates object file "main.obj".

這告訴 cl 在不呼叫 link 的情況​​下退出,並生成一個目標檔案,該檔案稍後可以與其他檔案連結以生成二進位制檔案。

cl main.obj niam.cpp
// Generates object file "niam.obj".
// Performs linking with "main.obj" and "niam.obj".
// Generates executable "main.exe".

link main.obj niam.obj
// Performs linking with "main.obj" and "niam.obj".
// Generates executable "main.exe".

還有其他有價值的命令列引數,這對使用者來說非常有用:

cl /EHsc main.cpp
// "/EHsc" specifies that only standard C++ ("synchronous") exceptions will be caught,
//  and `extern "C"` functions will not throw exceptions.
// This is recommended when writing portable, platform-independent code.

cl /clr main.cpp
// "/clr" specifies that the code should be compiled to use the common language runtime,
//  the .NET Framework's virtual machine.
// Enables the use of Microsoft's C++/CLI language in addition to standard ("native") C++,
//  and creates an executable that requires .NET to run.

cl /Za main.cpp
// "/Za" specifies that Microsoft extensions should be disabled, and code should be
//  compiled strictly according to ISO C++ specifications.
// This is recommended for guaranteeing portability.

cl /Zi main.cpp
// "/Zi" generates a program database (PDB) file for use when debugging a program, without
//  affecting optimisation specifications, and passes the option "/DEBUG" to LINK.

cl /LD dll.cpp
// "/LD" tells CL to configure LINK to generate a DLL instead of an executable.
// LINK will output a DLL, in addition to an LIB and EXP file for use when linking.
// To use the DLL in other programs, pass its associated LIB to CL or LINK when compiling those
//  programs.

cl main.cpp /link /LINKER_OPTION
// "/link" passes everything following it directly to LINK, without parsing it in any way.
// Replace "/LINKER_OPTION" with any desired LINK option(s).

對於更熟悉* nix 系統和/或 GCC / Clang 的人,cllink 和其他 Visual Studio 命令列工具可以接受用連字元(例如 -c)而不是斜槓(例如/c)指定的引數。此外,Windows 將斜槓或反斜槓識別為有效的路徑分隔符,因此也可以使用* nix 樣式的路徑。這樣可以很容易地將簡單的編譯器命令列從 g++clang++轉換為 cl,反之亦然,只需進行很少的更改。

g++ -o app src/main.cpp
cl  -o app src/main.cpp

當然,在移植使用更復雜的 g++clang++選項的命令列時,你需要在適用的編譯器文件和/或資源站點上查詢等效命令,但這樣可以更輕鬆地開始學習,花費的時間最少。新的編譯器。

如果你的程式碼需要特定的語言功能,則需要特定版本的 MSVC。從 Visual C++ 2015 Update 3 開始,可以通過/std 標誌選擇要編譯的標準版本。可能的值是/std:c++14/std:c++latest(即將推出/std:c++17)。

注意:在此編譯器的舊版本中,可以使用特定的功能標誌,但這主要用於新功能的預覽。