用 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)。

注意:在此编译器的旧版本中,可以使用特定的功能标志,但这主要用于新功能的预览。