Skip to content

/flags/dotnet-cli/dotnet-build-configuration-release

dotnet build -c Release: build the Release configuration instead of Debug

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · 10.0.401updated
tool
.NET CLI
command
dotnet build
flag
-c, --configuration NAME
default
Debug (Release for dotnet publish and dotnet pack since the .NET 8 SDK)

dotnet build -c Release (long form --configuration Release) compiles the project with the Release configuration: optimisations on, the DEBUG symbol not defined, output in bin/Release/<tfm>/. Without the flag, dotnet build, dotnet run and dotnet test use Debug. The option is shared by every build-related command (run, test, publish, pack, clean), and since the .NET 8 SDK publish and pack already default to Release.

Debug versus Release

bash
dotnet new console -o app > /dev/null && cd app
cat > Program.cs <<'EOF'
#if DEBUG
Console.WriteLine("Debug build");
#else
Console.WriteLine("Release build");
#endif
EOF
dotnet build -v q -nologo > /dev/null
dotnet build -c Release -v q -nologo > /dev/null
ls bin
echo "--- dotnet run"
dotnet run
echo "--- dotnet run -c Release"
dotnet run -c Release

Output

Debug
Release
--- dotnet run
Debug build
--- dotnet run -c Release
Release build

Each configuration gets its own folder under bin (and obj), so both builds exist side by side. Code inside #if DEBUG is compiled only into the Debug build.

What changes with the configuration

SettingDebugRelease
Optimize (JIT-friendly IL)falsetrue
DEBUG constantdefinednot defined
RELEASE constantnot defineddefined (SDK-style projects)
Output folderbin/Debug/<tfm>/bin/Release/<tfm>/
Debug.Assert / Debug.WriteLineactiveremoved by the compiler
PDB symbolsportable PDBportable PDB (still generated)

Configuration-specific settings

xml
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
  <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
  <DebugType>none</DebugType>
</PropertyGroup>

Conditions on $(Configuration) apply settings only to one configuration. Typical uses are stricter warnings in Release CI builds or removing symbols from the shipped files.

Pitfalls

  • dotnet test after dotnet build -c Release --no-build must use the same configuration, otherwise it looks in bin/Debug and finds nothing: dotnet test -c Release --no-build.
  • Benchmarks and performance measurements in Debug are meaningless; BenchmarkDotNet refuses to run non-optimised builds.
  • -c release (lowercase) works on Windows but creates a separate bin/release folder on case-sensitive file systems, and conditions comparing to 'Release' do not match. Use the exact spelling.
  • In a folder with several projects or solutions, add the file name, otherwise the build fails with MSB1011.

Publishing a deployable app, including self-contained builds, is covered in dotnet publish --self-contained.

FAQ

Does dotnet publish use Release by default?

Since the .NET 8 SDK, yes for projects targeting .NET 8 or later: dotnet publish and dotnet pack default to Release. dotnet build, dotnet run and dotnet test still default to Debug.

Where does dotnet build -c Release put the output?

In bin/Release/<target framework>/, for example bin/Release/net10.0/. Debug builds go to bin/Debug/<target framework>/. Use -o to choose another folder.

Can I use other configuration names?

Yes. -c accepts any name, such as Staging; MSBuild sets the Configuration property and the DEBUG and RELEASE symbols only for the two standard names, so define your own symbols for custom configurations.

Sources