Documentation Index
Fetch the complete documentation index at: https://mintlify.com/MicrosoftDocs/cpp-docs/llms.txt
Use this file to discover all available pages before exploring further.
The MSVC toolchain can be used entirely from the command line without opening the Visual Studio IDE. This is useful for build servers, CI pipelines, scripted builds, and developers who prefer terminal-based workflows. The key requirement is that the correct environment variables — PATH, INCLUDE, LIB, LIBPATH, and others — must be set before invoking any MSVC tool. Visual Studio installs several batch files and Start menu shortcuts that configure this environment automatically.
If you have Visual Studio installed with a C++ workload, all command-line tools are already available. If you only need the build tools without the IDE, download the free Build Tools for Visual Studio package from the Visual Studio Downloads page and install the Desktop development with C++ workload.
Setting Up the Environment
The MSVC tools depend on dozens of environment variables. Rather than setting these manually, use one of the provided command files or Start menu shortcuts.
Developer Command Prompt Shortcuts
The Start menu includes pre-configured shortcuts that open a Command Prompt with the correct environment:
| Shortcut | Environment |
|---|
| Developer Command Prompt | x86 tools → x86 output |
| x86 Native Tools Command Prompt | x86 tools → x86 output |
| x64 Native Tools Command Prompt | x64 tools → x64 output |
| x86_x64 Cross Tools Command Prompt | x86 tools → x64 output |
| x64_x86 Cross Tools Command Prompt | x64 tools → x86 output |
For Visual Studio 2022, shortcuts are in Start → Programs → Visual Studio 2022 → Visual Studio Tools.
Using vcvarsall.bat
For scripted environments, call vcvarsall.bat from an existing Command Prompt window:
# Typical location for Visual Studio 2022
call "C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Auxiliary\Build\vcvarsall.bat" x64
Syntax:
vcvarsall.bat [architecture] [platform_type] [winsdk_version] [-vcvars_ver=vcversion] [spectre_mode]
architecture | Host | Target |
|---|
x86 | x86 or x64 | x86 (32-bit) |
x64 or amd64 | x64 | x64 (64-bit) |
x86_x64 | x86 or x64 | x64 |
x86_arm | x86 or x64 | ARM |
x86_arm64 | x86 or x64 | ARM64 |
amd64_arm64 or x64_arm64 | x64 | ARM64 |
amd64_x86 or x64_x86 | x64 | x86 |
Common examples:
# 64-bit native build (most common on modern machines)
call vcvarsall.bat x64
# Cross-compile for ARM64 from an x64 host
call vcvarsall.bat x64_arm64
# Target UWP with a specific Windows SDK version
call vcvarsall.bat amd64_arm uwp 10.0.19041.0
# Use the VS 2019 toolset even if VS 2022 is installed
call vcvarsall.bat x64 -vcvars_ver=14.29
Using VsDevCmd.bat
VsDevCmd.bat is the primary command file located in the Common7\Tools directory. With no arguments it sets up x86 native tools:
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsDevCmd.bat"
Do not mix command files from different Visual Studio versions in the same Command Prompt window. Also avoid setting MSVC environment variables in the global Windows environment — use a fresh command window each time.
Compiling with cl.exe
Once the environment is configured, cl.exe is on your PATH.
Basic Usage
# Compile and link a single file into an executable
cl /EHsc hello.cpp
# Compile only (no link) — produces hello.obj
cl /c /EHsc hello.cpp
# Specify the output executable name
cl /EHsc /Fe:myapp.exe main.cpp utils.cpp
# Compile with C++20 and full optimizations
cl /std:c++20 /O2 /EHsc /W4 main.cpp
# Define preprocessor macros
cl /DNDEBUG /DMY_VERSION=2 /EHsc main.cpp
Common cl.exe Options
# Specify include directories
cl /I "C:\libs\boost\include" /I ".\include" /EHsc main.cpp
# Generate a PDB file for debugging
cl /Zi /EHsc main.cpp
link /DEBUG main.obj
# Compile to a named object file
cl /c /Fo:obj\main.obj /EHsc main.cpp
# Use dynamic CRT (recommended for most DLLs and applications)
cl /MD /EHsc main.cpp
# Use static CRT (for self-contained executables)
cl /MT /EHsc main.cpp
Compiling Multiple Files
# Compile a list of source files together
cl /EHsc /std:c++17 /W4 /O2 /MD ^
src\main.cpp ^
src\engine.cpp ^
src\utils.cpp ^
/Fe:myapp.exe ^
/I include
# Separate compilation and linking
cl /c /EHsc /std:c++17 /W4 /O2 /MD src\main.cpp src\engine.cpp
link /OUT:myapp.exe main.obj engine.obj msvcrt.lib kernel32.lib
Using a Response File
For long command lines, put options in a response file:
# options.rsp
/EHsc /std:c++17 /W4 /O2 /MD
/I include
/I "C:\libs\boost\include"
src\main.cpp src\engine.cpp
/Fe:myapp.exe
Linking with link.exe
When cl.exe compiles and links in a single step it invokes link.exe automatically. You can call link.exe directly for finer control:
# Link object files into a console executable
link /OUT:myapp.exe /SUBSYSTEM:CONSOLE main.obj engine.obj kernel32.lib
# Create a DLL with an import library
link /DLL /OUT:mylib.dll /IMPLIB:mylib.lib mylib.obj kernel32.lib
# Generate a map file for symbol analysis
link /OUT:myapp.exe /MAP:myapp.map main.obj engine.obj
# Enable link-time code generation (whole-program optimization)
link /LTCG /OPT:REF /OPT:ICF /OUT:myapp.exe main.obj engine.obj
# Create a debug build with full PDB
link /DEBUG /PDB:myapp.pdb /OUT:myapp.exe main.obj engine.obj
Building with MSBuild
MSBuild can drive .vcxproj builds from the command line:
# Build the Release|x64 configuration of a project
msbuild MyApp.vcxproj /p:Configuration=Release /p:Platform=x64
# Build the entire solution
msbuild MySolution.sln /p:Configuration=Release /p:Platform=x64
# Parallel build with 8 worker processes
msbuild MySolution.sln /p:Configuration=Release /p:Platform=x64 /m:8
# Clean only
msbuild MySolution.sln /t:Clean /p:Configuration=Release /p:Platform=x64
# Binary log for later analysis with MSBuild Structured Log Viewer
msbuild MySolution.sln /p:Configuration=Release /p:Platform=x64 /bl:build.binlog
# Override a property (e.g., change output directory)
msbuild MyApp.vcxproj /p:Configuration=Release /p:Platform=x64 ^
/p:OutDir=C:\CI\Output\
Building with nmake
nmake.exe is the MSVC equivalent of Unix make. It reads a Makefile that describes targets and their build rules:
# Makefile for a simple C++ project
CC = cl
CFLAGS = /EHsc /std:c++17 /W4 /O2 /MD
INCLUDES = /I include
LDFLAGS = /OUT:myapp.exe
OBJS = main.obj engine.obj utils.obj
myapp.exe: $(OBJS)
link $(LDFLAGS) $(OBJS) kernel32.lib msvcrt.lib
.cpp.obj:
$(CC) $(CFLAGS) $(INCLUDES) /c $<
clean:
del *.obj myapp.exe
# Run the default target
nmake
# Run a specific target
nmake clean
# Use a non-default makefile name
nmake /f MyMakefile
# Suppress output banner
nmake /nologo
Building CMake Projects from the Command Line
# Set up environment
call vcvarsall.bat x64
# Configure with a preset
cmake --preset windows-release
# Build
cmake --build --preset windows-release-build
# Or without presets
cmake -S . -B build\release -G Ninja -DCMAKE_BUILD_TYPE=Release
cmake --build build\release
Practical CI Example
A complete CI build script using the command line:
@echo off
setlocal
:: Set up MSVC x64 environment
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
if errorlevel 1 goto :error
:: Build release configuration
msbuild MySolution.sln ^
/p:Configuration=Release ^
/p:Platform=x64 ^
/m:%NUMBER_OF_PROCESSORS% ^
/bl:build.binlog ^
/nologo
if errorlevel 1 goto :error
echo Build succeeded.
exit /b 0
:error
echo Build FAILED with error %errorlevel%.
exit /b %errorlevel%
In CI environments, prefer msbuild.exe or cmake --build over the Visual Studio IDE. Both tools are available without a GUI and can run in Docker containers or headless cloud agents.
Environment Variables Reference
| Variable | Purpose |
|---|
PATH | Directories containing compiler, linker, and tool executables |
INCLUDE | Semicolon-separated list of directories searched for #include files |
LIB | Semicolon-separated list of directories searched for .lib files |
LIBPATH | Additional library paths searched by the linker |
TMP | Temporary file directory used by the compiler |
CL | Default compiler options applied to every cl.exe invocation |
LINK | Default linker options applied to every link.exe invocation |