Skip to content

Building From Source

Taiizor edited this page Jun 5, 2026 · 2 revisions

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.

Contents

Prerequisites

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.

The three solutions

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 and build

Restore packages for the main solution first:

dotnet restore src/Sucrose.slnx

Build the whole solution for x64 in Release:

dotnet build src/Sucrose.slnx -c Release -p:PlatformTarget=x64

The 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 .7z payload) is not done with dotnet build. For that, run the publish pipeline described in Publish Pipeline.

Building a single project

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=x64

Because 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.

Build output locations

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.

Code-style enforcement

Directory.Build.props sets EnforceCodeStyleInBuild=true, so .editorconfig violations are build errors on your machine. Notable global build characteristics:

  • Nullable is disabled project-wide.
  • ImplicitUsings is enabled.
  • LangVersion is preview.
  • Optimize=false is set globally — even for Release builds (a deliberate, notable build characteristic).
  • CS8632, WFO0003, SYSLIB0014 are suppressed in Directory.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.

No test suite

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.

What CI actually builds

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.yml runs on push/PR to develop and nightly (cron: '0 0 * * *'), on windows-2022, language matrix csharp only.
  • It builds a matrix of only 7 src/Library/ projects: Pipe, Memory, Signal, Manager, Resources, Transmission, XamlAnimatedGif. Mpv.NET is excluded (commented out).
  • It does not build the executables, engines, the Portal, or the full solution.
  • It uses .NET 11.0.x quality preview, 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.

Common build gotchas

  • Building the Bundle first fails. Sucrose.Bundle embeds src/Sucrose/Package/Compressed/net10.0-windows/Sucrose-<Platform>.7z, which only exists after the publish pipeline runs with CompressPackage=true. Run Publish Pipeline before building the Bundle.
  • Style errors are build errors. Because EnforceCodeStyleInBuild=true, an .editorconfig violation will stop your local build even though CI (which only compiles 7 projects) might not catch it.
  • Optimize=false is global, so Release output is not optimized — expected, not a misconfiguration.

See also

Home

Getting Started

Wallpaper Types

Using Sucrose

Settings Reference

Creating Wallpapers

Engine Reference

Automation & Command Line

Architecture & Internals

Data, Files & Diagnostics

Building & Contributing

Help & Support

Clone this wiki locally