MSBuild Project Files
Overview
The Krypton Toolkit build system uses MSBuild project files (.proj) to orchestrate multi-project builds, NuGet package creation, and distribution archive generation. Project files are located under Scripts/Build/, Scripts/VS2022/, and Scripts/Current/; GitHub Actions use Scripts/Build/.
Each script .proj imports the repo root Directory.Build.props, which defines KryptonBuildOutputRoot and KryptonPackageOutputRoot. Those resolve to legacy Bin\ and Bin\Packages\ by default, or to artifacts\bin\ and artifacts\packages\ when MSBuild is invoked with /p:UseArtifactsOutput=true (as in CI). Clean, Push, and archive targets use $(ReleaseSourcePath), $(ReleasePackagesPath), and equivalent Canary/Nightly properties so they stay aligned with component OutputPath and PackageOutputPath.
Parallel builds
- Command line: Local
.cmdscripts, GitHub Actions, and ModernBuild pass/m(all logical CPUs) when invoking MSBuild. - Orchestration:
nightly.projsetsBuildInParallel="true"on its Build<MSBuild>task. Other orchestration.projfiles use the task default (true). - Ordering: Project references between
Krypton.*libraries still apply; only independent work runs in parallel.
See Build System Overview and Build Scripts.
Project File Structure
All .proj files follow a similar structure:
- Import global properties
- Define configuration-specific properties
- Define targets for Clean, Restore, Build
- Define targets for package creation
- Define targets for archive creation
Core Project Files
build.proj - Stable/Release Builds
Purpose: Builds stable production releases
Key properties (from Scripts/Build/build.proj):
<Import Project="..\..\Directory.Build.props" />
<Configuration>Release</Configuration>
<ReleaseSourcePath>$(KryptonBuildOutputRoot)Release\</ReleaseSourcePath>
<ReleasePackagesPath>$(KryptonPackageOutputRoot)Release\</ReleasePackagesPath>
<ReleaseBuildPath>$(ReleaseSourcePath)Zips\</ReleaseBuildPath>
<ReleaseZipName>Krypton-Release</ReleaseZipName>
Available Targets:
Clean
Cleans all Krypton component projects for the Release configuration.
msbuild /m build.proj /t:Clean
Restore
Restores NuGet packages for all Krypton components.
msbuild /m build.proj /t:Restore
Build (Default)
Builds all Krypton components. Depends on Restore.
msbuild /m build.proj /t:Build
CleanPackages
Deletes existing NuGet packages from $(ReleasePackagesPath) (legacy: Bin/Packages/Release/; artifacts: artifacts/packages/Release/).
msbuild /m build.proj /t:CleanPackages
PackLite
Creates NuGet packages for "lite" target frameworks (net48, net481, net8.0+).
- Cleans projects and NuGet assets
- Restores with
TFMs=lite - Packs with
TFMs=lite
msbuild /m build.proj /t:PackLite
PackAll
Creates NuGet packages for all target frameworks (net472-net10.0-windows).
- Cleans projects and NuGet assets
- Restores with
TFMs=all - Packs with
TFMs=all
msbuild /m build.proj /t:PackAll
Pack
Master packaging target. Depends on CleanPackages, PackLite, and PackAll. Generates both Lite and full packages.
msbuild /m build.proj /t:Pack
Push
Publishes NuGet packages to NuGet.org using nuget.exe.
msbuild /m build.proj /t:Push
Note: Requires NUGET_API_KEY environment variable or configured API key.
CreateReleaseZip
Creates ZIP archive of Release binaries.
- Uses 7-Zip if available
- Falls back to PowerShell
Compress-Archive - Output:
$(ReleaseBuildPath)Krypton-Release_<yyyyMMdd>.zip(underBin/Release/Zips/orartifacts/bin/Release/Zips/)
msbuild /m build.proj /t:CreateReleaseZip
CreateReleaseTar
Creates TAR.GZ archive of Release binaries.
- Tries 7-Zip (recommended)
- Falls back to Windows 10/11 tar command
- Falls back to Git Bash tar
- Output: same
Zipsfolder as ZIP, e.g..../Release/Zips/Krypton-Release_<yyyyMMdd>.tar.gz
msbuild /m build.proj /t:CreateReleaseTar
CreateAllReleaseArchives
Creates both ZIP and TAR.GZ archives.
msbuild /m build.proj /t:CreateAllReleaseArchives
canary.proj - Beta Pre-Release Builds
Purpose: Builds beta pre-release packages for early adopters
Key properties:
<Configuration>Canary</Configuration>
<CanarySourcePath>$(KryptonBuildOutputRoot)Canary\</CanarySourcePath>
<CanaryPackagesPath>$(KryptonPackageOutputRoot)Canary\</CanaryPackagesPath>
<CanaryBuildPath>$(CanarySourcePath)Zips\</CanaryBuildPath>
<CanaryZipName>Krypton-Canary</CanaryZipName>
Available Targets:
Clean- Clean Canary configurationRestore- Restore packagesBuild- Build Canary configurationCleanPackages- Delete packages from$(CanaryPackagesPath)PackAll- Create Canary packages (all TFMs, no Lite variant)Pack- Master packaging target (CleanPackages + PackAll)Push- Publish Canary packagesCreateCanaryZip- Create Canary ZIP archiveCreateCanaryTar- Create Canary TAR.GZ archiveCreateAllCanaryArchives- Create both archives
Key Differences from Stable:
- No
PackLitetarget (Canary always packs all TFMs) - Packages get
-betasuffix in NuGet - Outputs under
$(KryptonBuildOutputRoot)Canary\and$(KryptonPackageOutputRoot)Canary\(legacyBin/...orartifacts/...)
nightly.proj - Alpha Nightly Builds
Purpose: Builds bleeding-edge alpha releases for developers and testers
Key properties:
<Configuration>Nightly</Configuration>
<NightlySourcePath>$(KryptonBuildOutputRoot)Nightly\</NightlySourcePath>
<NightlyPackagesPath>$(KryptonPackageOutputRoot)Nightly\</NightlyPackagesPath>
<NightlyBuildPath>$(NightlySourcePath)Zips\</NightlyBuildPath>
<NightlyZipName>Krypton-Nightly</NightlyZipName>
Available Targets:
Clean- Clean Nightly configurationRestore- Restore packagesBuild- Build Nightly configurationRebuild- Clean + BuildCleanPackages- Delete packages from$(NightlyPackagesPath)PackAll- Create Nightly packages (all TFMs)Pack- Master packaging targetPush- Publish Nightly packagesCreateNightlyZip- Create Nightly ZIP archiveCreateNightlyTar- Create Nightly TAR.GZ archiveCreateAllArchives- Create both archives
Key Differences:
- Includes
Rebuildtarget - Packages get
-alphasuffix in NuGet - Outputs under
$(KryptonBuildOutputRoot)Nightly\and$(KryptonPackageOutputRoot)Nightly\
Build target (explicit cross-project parallelism):
<MSBuild Projects="@(Projects)"
Properties="Configuration=$(Configuration);TFMs=all"
BuildInParallel="true" />
canarylongtermstable.proj - Canary LTS (V105-LTS)
Purpose: Orchestrates Canary-configuration builds for the Canary LTS GitHub Actions workflow (.github/workflows/canary-lts-release.yml) on branch V105-LTS.
Usage: Same targets as canary.proj (Build, Pack, archives, and so on). CI invokes:
msbuild /m "Scripts/Build/canarylongtermstable.proj" /t:Build /p:Configuration=Canary /p:Platform="Any CPU" /p:UseArtifactsOutput=true
Note: The main canary branch release job in release.yml uses canary.proj; scheduled/manual Canary LTS publishing uses this file.
debug.proj - Debug Builds
Purpose: Local development debug builds
Key Properties:
<Configuration>Debug</Configuration>
Available Targets:
Clean- Clean Debug configurationRestore- Restore packagesBuild- Build Debug configuration
Key Differences:
- No packaging or archive targets
- Simplified for local development
installer.proj - Installer Builds
Purpose: Builds packages for demo installers
Key Properties:
<Configuration>Installer</Configuration>
Available Targets:
Clean- Clean Installer configurationRestore- Restore packagesBuild- Build Installer configurationCleanPackages- Delete packages from the Installer folder under$(KryptonPackageOutputRoot)PackAll- Create Installer packagesPack- Master packaging targetPush- Publish Installer packagesCreateNightlyZip- Create Installer ZIP (reuses Nightly zip logic)
Special Notes:
- WiX installers require build numbers ≤ 256
- Version uses month number for Build component
Project File Patterns
Project Selection Pattern
All .proj files under Scripts/Build/ use this pattern to select Krypton projects (two levels up to the repo root):
<ItemGroup>
<Projects Include="..\..\Source\Krypton Components\Krypton.*\*.csproj" />
</ItemGroup>
This selects:
Krypton.Toolkit\Krypton.Toolkit 2022.csprojKrypton.Ribbon\Krypton.Ribbon 2022.csprojKrypton.Navigator\Krypton.Navigator 2022.csprojKrypton.Workspace\Krypton.Workspace 2022.csprojKrypton.Docking\Krypton.Docking 2022.csproj
NuGet Asset Cleanup Pattern
Before packing, intermediate NuGet files are deleted:
<ItemGroup>
<NugetAssets Include="..\..\Source\Krypton Components\Krypton.*\obj\*.json" />
<NugetAssets Include="..\..\Source\Krypton Components\Krypton.*\obj\*.cache" />
<NugetAssets Include="..\..\Source\Krypton Components\Krypton.*\obj\*.g.targets" />
<NugetAssets Include="..\..\Source\Krypton Components\Krypton.*\obj\*.g.props" />
</ItemGroup>
<Delete Files="@(NugetAssets)" />
This ensures clean package generation.
MSBuild Invocation Pattern
Projects are built with configuration and TFM control. The nightly Build target enables cross-project parallelism explicitly:
<MSBuild Projects="@(Projects)"
Properties="Configuration=$(Configuration);TFMs=all"
BuildInParallel="true" />
Other orchestration .proj files omit BuildInParallel and use the MSBuild task default (true). Combine with /m on the msbuild.exe command line for multi-CPU compilation within the graph.
Key properties passed:
Configuration- Debug, Release, Canary, Nightly, InstallerTFMs-lite,all, or empty
Archive Generation
ZIP Archives
Uses multiple fallback methods:
- 7-Zip (preferred): Fast, best compression
- PowerShell Compress-Archive: Built-in Windows
Example (stable release; sources use $(ReleaseSourcePath) so archives follow the same root as binaries):
<!-- 7-Zip method -->
<Exec Command="7z.exe a -tzip "$(ReleaseBuildPath)\$(ReleaseZipName)_$(StringDate).zip" "$(ReleaseSourcePath)*" -x!*.json -x!*.pdb"
Condition="Exists('C:\Program Files\7-Zip\7z.exe')" />
<!-- PowerShell fallback -->
<Exec Command="powershell.exe -Command "Get-ChildItem '$(ReleaseSourcePath)*' -Recurse | Where-Object {$_.Extension -notin '.json','.pdb'} | Compress-Archive -DestinationPath '$(ReleaseBuildPath)\$(ReleaseZipName)_$(StringDate).zip' -Force""
Condition="!Exists('C:\Program Files\7-Zip\7z.exe')" />
TAR.GZ Archives
Uses multiple fallback methods:
- 7-Zip: Creates tar then compresses to tar.gz
- Windows tar: Native tar in Windows 10/11
- Git Bash tar: Uses Git's bundled tar
Custom Target Execution
Execute Specific Target
msbuild /m build.proj /t:TargetName
Execute Multiple Targets
msbuild /m build.proj /t:Clean;Build
Override Configuration
msbuild /m build.proj /t:Build /p:Configuration=Debug
Override TFMs
msbuild /m build.proj /t:Build /p:TFMs=lite
Artifacts output layout (CI / optional local)
msbuild /m Scripts\Build\build.proj /t:Build /p:UseArtifactsOutput=true
Verbose Output
msbuild /m build.proj /t:Build /v:detailed
Save to Log File
msbuild /m build.proj /t:Build /fl /flp:logfile=build.log
Binary Log
msbuild /m build.proj /t:Build /bl:build.binlog
Best Practices
1. Clean Before Major Builds
msbuild /m build.proj /t:Clean;Build
2. Use Rebuild for Complete Rebuild
msbuild /m nightly.proj /t:Rebuild
3. Test Packaging Locally Before Push
msbuild /m build.proj /t:Pack
REM Verify packages under artifacts/packages/Release/ or Bin/Packages/Release/ (depends on UseArtifactsOutput)
msbuild /m build.proj /t:Push
4. Use Binary Logs for Troubleshooting
msbuild /m build.proj /t:Build /bl:build.binlog
# View with MSBuild Structured Log Viewer
5. Parallel builds
Scripts and CI already pass /m. To cap CPU use:
msbuild /m:4 build.proj /t:Build
msbuild /m:1 build.proj /t:Build
Related Documentation
- Build Scripts - Command-line build scripts
- Directory.Build Configuration - Property inheritance
- NuGet Packaging - Package configuration
- Version Management - Versioning details