-
-
Notifications
You must be signed in to change notification settings - Fork 60
Building From Source
This page is the developer's guide to compiling Sucrose locally. It covers the required SDK and toolchain, the three solutions, the exact dotnet restore/dotnet build commands, single-project builds, where build output lands, the absence of a test suite, and what Continuous Integration actually compiles (much less than you might expect). If your goal is to produce shippable installers rather than just compile, read Publish Pipeline and Bundle Installer Internals afterward.
- Prerequisites
- The three solutions
- Restore and build
- Building a single project
- Build output locations
- Code-style enforcement
- No test suite
- What CI actually builds
- Common build gotchas
- See also
| Requirement | Detail |
|---|---|
| SDK | A .NET 11 preview SDK. global.json pins "version": "11.0.0" with "allowPrerelease": true and "rollForward": "latestMajor". CI uses dotnet-version: 11.0.x, dotnet-quality: preview. |
| Target framework (app) |
net10.0-windows (set via TargetFrameworks in Directory.Build.props). The .NET 11 SDK builds the .NET 10 target. |
| Target framework (installer) |
net48 (.NET Framework 4.8) — only the Sucrose.Bundle installer project uses this; you also need the .NET Framework 4.8 targeting pack to build it. |
| OS | Windows (WPF, Windows-only). |
| NuGet source | nuget.org only (NuGet.Config). Packages are centrally pinned in Directory.Packages.props (transitive pinning enabled). |
| Code style |
EnforceCodeStyleInBuild=true — .editorconfig violations fail the build (see Code Conventions). |
The .NET 11 SDK pin is deliberate: rollForward: latestMajor + allowPrerelease: true means the build picks the newest installed major-version SDK, falling forward to a preview if that is what is installed. Install a current .NET 11 preview SDK and the repo will use it.
Sucrose is split across three .slnx (the new XML-based solution format) files:
| Solution | Contains | Platforms |
|---|---|---|
src/Sucrose.slnx |
The main app — all live engines, services, and class libraries | x86, x64, ARM64 |
src/Sucrose.Bundle.slnx |
Only the Sucrose.Bundle installer/packager project (plus solution-items: build props/targets, packages, global.json, NuGet.Config) |
ARM64, x64, x86 |
src/Sucrose.Localizer.slnx |
The Sucrose.Localizer translation tool |
— |
Most development happens against src/Sucrose.slnx. The Bundle and Localizer have their own solutions because they target a different framework (net48 for the Bundle) or are standalone utilities.
Restore packages for the main solution first:
dotnet restore src/Sucrose.slnxBuild the whole solution for x64 in Release:
dotnet build src/Sucrose.slnx -c Release -p:PlatformTarget=x64The supported platforms are x86, x64, and ARM64; pass the one you want via -p:PlatformTarget=. The chosen platform also defines a matching preprocessor symbol (X86/X64/ARM64) used in shared code — see Preprocessor Symbols.
Note: full publish (with the trimmed private runtime and the compressed
.7zpayload) is not done withdotnet build. For that, run the publish pipeline described in Publish Pipeline.
You can compile any individual project directly. For example, to build only the Portal UI:
dotnet build src/Portal/Sucrose.Portal/Sucrose.Portal.csproj -c Release -p:PlatformTarget=x64Because the codebase uses Shared Item Projects (.shproj + .projitems imported with Label="Shared") rather than NuGet packages or class-library references for most cross-cutting code, building a single executable also compiles all the shared source it imports — there is no separate "build the shared library first" step. Class libraries under src/Library/ are the exception: they are real .csproj projects consumed by <ProjectReference> and produce their own .dll. See Repository Layout for the physical-to-logical folder mapping.
| Path | Contents |
|---|---|
src/Sucrose/ |
Build output root — BaseOutputPath is ..\..\Sucrose in Directory.Build.props. |
src/Sucrose/Object/<Project>/ |
Per-project intermediate (obj) output. |
src/Sucrose/<Layer>/<arch>/ |
Per-executable output, e.g. src/Sucrose/Launcher/x64; engines nest under src/Sucrose/Live/<EngineName>/<arch>. |
src/Sucrose/Package |
Publish packages produced by the publish pipeline. |
src/Sucrose/Bundle/<arch> |
The compiled installer .exe (when building Sucrose.Bundle). |
Each executable sets a per-platform OutputPath under $(BaseOutputPath) (e.g. $(BaseOutputPath)\Launcher\x64). Release builds also set AppHostDotnetRoot/AppHostRelativeDotNet to ..\Sucrose.Runtime so the published apps probe the trimmed private runtime folder rather than a machine-wide install.
Directory.Build.props sets EnforceCodeStyleInBuild=true, so .editorconfig violations are build errors on your machine. Notable global build characteristics:
-
Nullableis disabled project-wide. -
ImplicitUsingsis enabled. -
LangVersionispreview. -
Optimize=falseis set globally — even for Release builds (a deliberate, notable build characteristic). -
CS8632,WFO0003,SYSLIB0014are suppressed inDirectory.Build.props.
For the full style ruleset (4-space indent, CRLF, block-scoped namespaces, explicit types over var, expression-bodied accessors, the namespace-alias convention, etc.), see Code Conventions.
There are no test projects in any of the three solutions, so there are no test commands to run. Verification is manual: build locally, run the app, and exercise the affected paths. This makes local building before opening a PR especially important — see Contributing.
This is a frequent source of confusion. No CI job builds the full solution. The only workflow that compiles C# is CodeQL:
-
.github/workflows/codeql-analysis.ymlruns on push/PR todevelopand nightly (cron: '0 0 * * *'), onwindows-2022, language matrixcsharponly. - It builds a matrix of only 7
src/Library/projects:Pipe,Memory,Signal,Manager,Resources,Transmission,XamlAnimatedGif.Mpv.NETis excluded (commented out). - It does not build the executables, engines, the Portal, or the full solution.
- It uses .NET
11.0.xqualitypreview, restores and builds with-p:UseSharedCompilation=false, and suppresses these warnings:CS0067, CS0108, CS0109, CS0114, CS0169, CS0414, CS0618, CS0649, CS8632, CA1416, NU5104, NETSDK1138, SYSLIB0003.
The practical consequence: a change that breaks an engine, the Portal, or a shared project will still pass CI. Reviewers and contributors must build locally. Full-app builds happen only locally or via the publish pipeline. The other workflows (congratulations.yml, nuxt-deploy.yml) do not build the app.
-
Building the Bundle first fails.
Sucrose.Bundleembedssrc/Sucrose/Package/Compressed/net10.0-windows/Sucrose-<Platform>.7z, which only exists after the publish pipeline runs withCompressPackage=true. Run Publish Pipeline before building the Bundle. -
Style errors are build errors. Because
EnforceCodeStyleInBuild=true, an.editorconfigviolation will stop your local build even though CI (which only compiles 7 projects) might not catch it. -
Optimize=falseis global, so Release output is not optimized — expected, not a misconfiguration.
Getting Started
- Installation
- System Requirements
- Quick Start
- Portal Interface Tour
- Updating Sucrose
- Uninstalling Sucrose
Wallpaper Types
Using Sucrose
- Managing Library
- Using Store
- Customizing Wallpaper
- Multi-Monitor
- Wallpaper Cycling
- Choosing Engines
- Performance Rules
- Theme, Tray & Startup
- Discord Rich Presence
Settings Reference
- Settings Overview
- Settings: General
- Settings: Personal
- Settings: Performance
- Settings: Wallpaper
- Settings: System
- Settings: Other
- Settings: All Keys
Creating Wallpapers
- Create Overview
- Create: Step By Step
- Create: Package Format
- Create: Customization Controls
- Create: JS Bridge
- Create: Audio API
- Create: System API
- Create: Property Listener & Filters
- Create: Web Architecture
- Create: Compatibility
- Create: Example Wallpapers
- Create: Sharing & Publishing
Engine Reference
- Engines Overview
- Engine: MpvPlayer
- Engine: VlcPlayer
- Engine: WebView
- Engine: CefSharp
- Engine: Nebula
- Engine: Vexana
- Engine: Xavier
- Engine: Aurora
- Engine Comparison
Automation & Command Line
Architecture & Internals
- Architecture Overview
- Lifecycle
- Commandog Dispatcher
- Single-Instance Mutexes
- IPC
- Backgroundog Service
- Crash Reporting
- Update Internals
- Property Service
- Undo Internals
Data, Files & Diagnostics
Building & Contributing
- Building From Source
- Repository Layout
- Shared Item Projects
- Code Conventions
- Preprocessor Symbols
- Publish Pipeline
- Bundle Installer Internals
- Extending Sucrose
- Contributing
- Translating with Localizer
- Localization Coverage
- Security Policy
- Privacy & Telemetry
Help & Support