You are an expert Linux build automation specialist for .NET/Avalonia projects.
Follow these instructions exactly and in order to build Linux binaries for XerahS.
Shared Build Guardrails
Before Linux packaging work, follow build-common for shared timeout, lock recovery, no-concurrent-build, -m:1, TFM, and SkiaSharp rules. This Linux skill owns package-linux usage, log monitoring, Linux artifact validation, and Linux-specific XAML precompilation diagnostics.
Build Process
Preparation
Build the pinned submodule revision. Update ImageEditor only when requested, using the operator's Git wrapper. For confirmed stalls or output locks, use build-common; do not terminate unrelated builds.
Phase 2: Run the Build Script
Use the packaging script below. If the host buffers output, capture a log and inspect it while the build runs. Redirection alone does not background a shell command.
bash build/linux/package-linux.sh > build_output.log 2>&1
Verify the exit code and resulting artifacts. Judge stalls from output and process activity, not a fixed timeout.
Phase 3: Handle Common Failures
🔴 Failure: No precompiled XAML found for XerahS.UI.App
Symptom (at runtime, not build time):
Avalonia.Markup.Xaml.XamlLoadException: No precompiled XAML found for XerahS.UI.App,
make sure to specify x:Class and include your XAML file as AvaloniaResource
Root Cause: A C# converter class referenced in an .axaml file uses the wrong namespace.
Avalonia's XAML compiler silently fails to compile the referencing AXAML, which cascades to break the entire app's precompiled XAML.
How to diagnose:
Check any recently added/modified converters under
ShareX.ImageEditor/src/ShareX.ImageEditor/UI/Adapters/Converters/Verify their C#
namespacematches the AXAMLxmlns:convertersimport:In
EditorView.axaml:xmlns:converters="using:ShareX.ImageEditor.Converters"So all converter classes must declare:
namespace ShareX.ImageEditor.Converters;
Fix:
// WRONG — will silently break Avalonia XAML precompilation:
namespace ShareX.ImageEditor.UI.Adapters.Converters;
// CORRECT — matches the xmlns:converters import in EditorView.axaml:
namespace ShareX.ImageEditor.Converters;
After fixing, rebuild from scratch.
🔴 Failure: AVLN9999: The process cannot access the file '...XerahS.Imgur.Plugin.pdb' because it is being used by another process
Root Cause: A previous dotnet publish is still running in the background (e.g. from a backgrounded & command).
Fix: identify the lock holder and use build-common to cancel only the affected task-owned build, then rerun the packaging script.
🔴 Failure: MSB3026: Could not copy '...XerahS.Uploaders.dll' ... being used by another process
Root Cause: Parallel plugin publishing is racing to write shared DLLs.
Fix: This is usually a transient retry (MSBuild will retry automatically). If it becomes fatal:
rm -rf src/desktop/core/XerahS.Uploaders/obj/Release
bash build/linux/package-linux.sh
🔴 Failure: Error: No plugins were published for linux-x64
Root Cause: The plugin csproj discovery glob found no files, or a plugin build failed early.
Check:
find src/desktop/plugins -mindepth 2 -maxdepth 2 -name "*.csproj"
Each plugin project under src/desktop/plugins/ needs a plugin.json in the same directory.
Phase 4: Validation
After the build completes, verify the artifacts:
ls -lh dist/
Expected output:
XerahS-0.16.1-linux-x64.deb ~90-120MB
XerahS-0.16.1-linux-arm64.deb ~90-120MB
XerahS-0.16.1-linux-x64.rpm ~90-120MB (if rpmbuild installed)
XerahS-0.16.1-linux-arm64.rpm ~90-120MB (if rpmbuild installed)
Timestamps should match the current build session.
Important Notes
Why Avalonia XAML Precompilation Fails Silently
- Avalonia compiles
.axamlfiles to IL at build time - If a referenced type (e.g. a converter) cannot be resolved, the AXAML file is silently skipped
- This doesn't fail the build, but crashes the application at startup
- The fix is always: ensure C#
namespacematches thexmlnsimport in the AXAML
Key Build Parameters (from package-linux.sh)
-p:PublishSingleFile=true --self-contained true: Main app ships as one binary-p:OS=Linux -p:DefineConstants=LINUX: Enables Linux-specific code paths-p:EnableWindowsTargeting=true: Required when cross-compiling on Linux due to shared project references- Plugins publish with
--no-self-containedto share the runtime with the main app
Sequential Builds Are Mandatory
NEVER run two builds at the same time. ShareX.ImageEditor targets multiple TFMs and MSBuild parallelism causes them to race on the same ShareX.ImageEditor.dll output path.
- Architectures:
package-linux.shiterateslinux-x64thenlinux-arm64sequentially — never invoke it twice concurrently. - Internal parallelism: If
CS2012/ file lock errors appear onShareX.ImageEditor, pre-build it separately with/m:1to force single-threaded compilation:dotnet build ShareX.ImageEditor/src/ShareX.ImageEditor/ShareX.ImageEditor.csproj \ -c Release -p:UseSharedCompilation=false /m:1 - Between builds: Ensure this checkout's previous build has exited before starting another build sharing its outputs.
Background Build Caution
- Do not background the build script with
&unless you redirect output to a log file - Multiple concurrent builds share
obj/folders and will conflict - Cancel a confirmed stalled task-owned build before retrying; leave other checkouts' processes alone.
stdout Buffering Issue
- If the host buffers output, redirect to a log and inspect progress through the host's file or terminal tools.
Success Criteria
- ✅ Both
linux-x64andlinux-arm64.debpackages created indist/ - ✅ Files are ~90-120 MB in size
- ✅ Timestamps are recent (within build session)
- ✅ No lingering
dotnetorpackage-linux.shprocesses - ✅ App launches without
XamlLoadExceptionat startup
Troubleshooting
| Symptom | Solution |
|---|---|
XamlLoadException: No precompiled XAML found at startup |
Check namespaces of all new converter classes — must match xmlns:converters in .axaml |
AVLN9999: file used by another process |
Identify the task-owned lock holder; recover through build-common and retry |
MSB3026: Could not copy XerahS.Uploaders.dll |
Usually transient; if fatal, delete src/desktop/core/XerahS.Uploaders/obj/Release and retry |
Error: No plugins were published |
Check src/desktop/plugins/ structure and plugin.json presence in each plugin directory |
| ARM64 cross-compile fails | Ensure linux-arm64 .NET SDK cross-compile support is installed; Fedora needs dotnet-sdk-10.0 |
rpmbuild: command not found |
RPM skipped (not fatal); install with sudo dnf install rpm-build if needed |
| Build succeeds but app segfaults | SkiaSharp native library issue; verify the current centrally managed SkiaSharp/native-assets set and published runtimes before changing versions |
Related Files
- Shared guardrails: build-common
- Build script: build/linux/package-linux.sh
- Packaging tool: build/linux/XerahS.Packaging/
- Version config: Directory.Build.props
- Main app project: src/desktop/app/XerahS.App/XerahS.App.csproj
- Converters namespace reference:
ShareX.ImageEditor.Converters(match all new converter classes to this)