feat: refactor old build system into a proper Sdk#3085
feat: refactor old build system into a proper Sdk#3085Kryptos-FR wants to merge 73 commits intostride3d:masterfrom
Conversation
- Add stride-build-properties-inventory.md documenting 100+ MSBuild properties - Catalog all custom items, targets, and conditional patterns - Document import chains and file structure - Update roadmap to mark Phase 1 as complete - Add cross-references between documentation files The inventory provides a complete specification for implementing Stride.Sdk in Phase 2.
To be removed
Looks like we don't need Stride.Sdk.Runtime after all
Add CLAUDE.md with build instructions, architecture overview, and coding guidelines for working with the Stride codebase. Add .claude/ folder with skill commands: - /build - Build solution or specific project via MSBuild - /build-sdk - Build SDK packages with NuGet cache management - /test - Run tests by category - /find-component - Find ECS components - /analyze-asset - Analyze Stride asset files - /explain-rendering - Explain rendering features - /sdk-status - Check SDK work progress - /msbuild-debug - Debug MSBuild issues
Create comprehensive SDK-WORK-GUIDE.md based on analysis of build system documentation from feature/build-analysis-and-improvements branch. The guide covers: - SDK development workflow and NuGet cache management - Package structure and MSBuild SDK conventions - Migration strategy from current 17-file build system - Current challenges (Graphics API targeting, platform detection) - Testing strategy and troubleshooting Update CLAUDE.md: - Add Build System section explaining multi-targeting complexity - Document key build properties (StridePlatform, StrideGraphicsApi) - Add SDK build commands with cache clearing instructions - Reference new SDK-WORK-GUIDE.md Update /build-sdk command: - Add context about SDK work goals and current status - Reference SDK-WORK-GUIDE.md for details This provides foundation for ongoing SDK-style build system rework that aims to consolidate ~3500 lines of MSBuild across 17 files into a clean, versioned Stride.Sdk package.
Add front matter with name and description to all 8 skill commands: - build, test, find-component - build-sdk, sdk-status - analyze-asset, explain-rendering - msbuild-debug This enables lazy loading of skill commands, preventing them from consuming context tokens until they are actually invoked. The front matter includes the command name and a brief description for display in skill listings.
Create SUMMARY.md capturing current session's work: - Claude Code configuration setup (CLAUDE.md, 8 skills) - SDK work documentation (SDK-WORK-GUIDE.md) - Critical SDK workflow with NuGet cache management - Build system context (17 files, 3500 lines, 30 configs) - Current SDK status and next steps Add /summarize-session skill command for automation: - Triggers at ~60% context usage (120k tokens) - Provides template and best practices for session handoffs - Ensures comprehensive context preservation - Includes examples of effective summaries This enables smooth context handoff when approaching token limits, maintaining continuity across sessions without losing critical information about workflows, gotchas, and progress.
- Add comprehensive MSBuild SDK evaluation order section to CLAUDE.md - Create SDK-PROPERTY-EVALUATION-ANALYSIS.md (400+ line detailed analysis) - Update SDK-WORK-GUIDE.md with evaluation timing and property phase analysis - Add explanatory header comments to Sdk.props and Sdk.targets - Document critical bug fix in Stride.Frameworks.targets - Update notes.txt with bug discovery and historical context - Create /analyze-csproj-migration and /compare-csproj-versions commands - Update /build-sdk and /sdk-status commands with evaluation reminders - Update SUMMARY.md with session handoff information Discovered critical evaluation order bug in sources/targets/Stride.Core.props:58 that has been silently failing for years. The old system checks StrideRuntime in the .props phase where user properties from .csproj are not yet visible, causing multi-targeting to only work via command-line properties. The new SDK correctly implements this check in Stride.Frameworks.targets (after .csproj loads), fixing this long-standing bug.
Add platform detection, code analysis, and assembly processor infrastructure to Stride.Sdk, enabling Stride.Core to build with SDK-style project format. New SDK files: - Stride.Platform.props: Platform detection (Windows/Linux/macOS) and output paths - Stride.Platform.targets: Platform defines (STRIDE_PLATFORM_DESKTOP, STRIDE_RUNTIME_CORECLR) - Stride.AssemblyProcessor.targets: Stub with defaults (full implementation deferred) - Stride.CodeAnalysis.targets: Code analysis ruleset integration Updated SDK files: - Sdk.props: Import Stride.Platform.props - Sdk.targets: Import new platform, assembly processor, and code analysis targets - Stride.Sdk.csproj: Package new files and Stride.ruleset - Stride.Frameworks.targets: Fix multi-targeting logic (remove StrideExplicitWindowsRuntime requirement) Updated project: - Stride.Core.csproj: Remove unused properties (StrideBuildTags, RestorePackages) Verified working: - Multi-targeting produces net10.0 and net10.0-windows outputs - Platform detection sets StridePlatform=Windows correctly - StridePlatforms property enables framework expansion - Code analysis uses Stride.ruleset from SDK package - Build succeeds with no errors Scope: Desktop platforms only (Windows/Linux/macOS) Deferred: Mobile/UWP platforms, full Assembly Processor implementation
Document completion of Stride.Core SDK migration for desktop platforms: - All 4 new SDK files created and working - Multi-targeting verified (net10.0 and net10.0-windows) - Platform detection and code analysis integration working - Critical NuGet cache clearing requirement documented Added comprehensive next steps: - High priority: Assembly Processor full implementation - Medium-term: Mobile/UWP support, additional project migrations - Long-term: Complete SDK migration for all projects Key learnings documented: - NuGet cache must be manually cleared after SDK changes - Property evaluation order critical for correctness - StridePlatforms semicolon pattern required for multi-targeting Next session should focus on Assembly Processor implementation.
…tion) Compacted SUMMARY.md from ~595 to 188 lines following new guidelines: - Latest session: Full detail on Assembly Processor implementation - Previous session: Condensed to key points only - Removed older session verbose details - Updated critical information and next steps Implementation status: - 3 files modified (~200 lines added) - Assembly Processor integration complete - Path fix applied, ready for testing
- Package Assembly Processor binaries with SDK in tools/AssemblyProcessor/ - Add TEMP property for cross-platform compatibility - Implement full Assembly Processor targets file (184 lines): * Path detection (SDK package vs source build) * Hash-based temp directory for file locking avoidance * PrepareForRunDependsOn integration * Explicit NuGet package references (add-reference) * Dev mode support (StrideAssemblyProcessorDev) * .usrdoc file handling for public APIs * Validation warnings if processor not found Tested with Stride.Core - builds successfully with processor execution verified. Implementation follows sources/core/Stride.Core/build/Stride.Core.targets pattern.
Final update to SUMMARY.md documenting successful completion: - Assembly Processor implementation verified working (commit 35eb779) - All success criteria met (SDK builds, packages binaries, Stride.Core builds) - Documented key discoveries (packaging gotchas, build tool requirements) - Ready for next phase: unit tests and additional project migrations Also updated summarize-session.md command with improved guidelines.
Migrated three core projects from old build system to SDK-style: - Stride.Core.IO: Removed unused StridePlatformDependent, StrideBuildTags - Stride.Core.MicroThreading: Removed unused StrideBuildTags - Stride.Core.Serialization: Clean migration with serialization support All projects build successfully with multi-targeting (net10.0, net10.0-windows). Note: Serialization unit tests currently failing with NullReferenceException in generated serializers - investigation needed for Assembly Processor.
Created comprehensive SDK for Stride test projects:
**Stride.Sdk.Tests features:**
- Composes Stride.Sdk + test-specific configuration
- Automatic xunit package references (Microsoft.NET.Test.Sdk, xunit, etc.)
- Test-specific output paths (bin/Tests/{ProjectName}/{Platform}/)
- Graphics API configuration for test projects
- IsTestProject=true for dotnet test discovery
- Shader code generation support
- Platform target metadata for test runners
**Stride.Core.Tests migration:**
- Migrated from old Stride.UnitTests.props/targets to Stride.Sdk.Tests
- Reduced from 30 lines to 29 lines (cleaner, SDK-based)
- Disabled xunit launcher (not needed for dotnet test)
- OutputType=Library instead of WinExe for standard test library
**Benefits:**
- Consistent SDK-based build system for both runtime and test projects
- Easier to maintain and extend
- Follows MSBuild SDK best practices
- Test projects can now use simple `<Project Sdk="Stride.Sdk.Tests">`
Note: All projects now use SDK-style, providing consistent build behavior
for investigating serialization test issues.
Migrate 10 more projects to SDK-style: - Runtime: Mathematics, Reflection, Design, Translation, Yaml, Tasks - Tests: Mathematics.Tests, Design.Tests, Yaml.Tests, CompilerServices.Tests Fix xunit launcher in Stride.Sdk.Tests: embed launcher .cs files in SDK package instead of using relative path to source tree (broke from NuGet). Re-enable xunit launcher for all test projects (was incorrectly disabled). Update roadmap to reflect completed phases 1-3.
Roslyn analyzer project - uses Stride.Sdk for versioning consistency. Removed unused StrideSkipAutoPack, empty Folder items, duplicate Using.
SDK changes: - Add Stride.Graphics.props (default graphics API per platform) - Add Stride.Graphics.targets (API defines, UI framework, multi-API lists) - Wire into Sdk.props and Sdk.targets Engine projects migrated to Sdk="Stride.Sdk": - Stride, Stride.Shaders, Stride.Rendering, Stride.Particles - Stride.Engine, Stride.Audio, Stride.UI, Stride.Navigation - Stride.Physics, Stride.SpriteStudio.Runtime, Stride.Voxels Removed unused properties: StrideBuildTags, StridePlatformDependent, ProductVersion, SchemaVersion, RestorePackages. Added explicit AllowUnsafeBlocks (was inherited from old Stride.props). Replaced $(StrideAssemblyProcessorDefaultOptions) with literal values.
…ls, presentation Migrated remaining engine projects (13), shader projects (3), build engine projects (2), asset projects (4), tool projects (17), and presentation projects (7) to Stride.Sdk format. Removed unused properties (StrideBuildTags, ProductVersion, SchemaVersion, RestorePackages, ProjectTypeGuids, ProjectGuid, ParadoxBuildTags). Replaced $(StrideAssemblyProcessorDefaultOptions) with literal values. Skipped: PublicApiCheck, PackageInstall, VisualStudio.PackageInstall (already SDK-style with Microsoft.NET.Sdk), editor projects (deferred), and test projects (use Stride.Sdk.Tests).
…m base SDK Introduces Stride.Sdk.Editor MSBuild SDK package that owns StrideEditorTargetFramework and StrideXplatEditorTargetFramework properties. This prevents engine/runtime projects from accidentally using editor-specific frameworks and prepares for future WPF to Avalonia migration by isolating editor build concerns. SDK hierarchy: Stride.Sdk -> Stride.Sdk.Editor -> Stride.Sdk.Tests - Created Stride.Sdk.Editor package (csproj, Sdk.props/targets, Stride.Editor.Frameworks.props) - Removed editor framework properties from Stride.Sdk/Stride.Frameworks.props - Updated Stride.Sdk.Tests to compose Stride.Sdk.Editor instead of Stride.Sdk - Updated 38 editor/tool/presentation .csproj files: Sdk="Stride.Sdk" -> Sdk="Stride.Sdk.Editor" - Added Stride.Sdk.Editor to global.json and Stride.Sdk.slnx
Runtime projects use Stride.Sdk directly with StrideRuntime=true. The Stride.Sdk.Runtime package was never referenced by any project.
Phases 1-5 complete, Phase 6 in progress. Added Stride.Sdk.Editor package, removed Stride.Sdk.Runtime. ~67% of projects migrated.
Two issues fixed: 1. Assembly processor target never executed during builds because PrepareForRunDependsOn was set in Stride.AssemblyProcessor.targets (imported before Microsoft.NET.Sdk) but then overwritten by Microsoft.NET.Sdk Sdk.targets. Changed to BeforeTargets= "CopyFilesToOutputDirectory" matching the old build system. 2. Multiple MSBuildThisFileDirectory-relative paths in Sdk.targets resolved to the NuGet package cache instead of the source tree, breaking CompilerServices analyzer, localization, and packaging paths. Replaced with $(StrideRoot) which is set by sources/Directory.Build.props.
- Remove StridePackageBuild guard from GeneratePackageOnBuild to match old build system behavior (all projects auto-pack unless StrideSkipAutoPack) - Fix PackageOutputPath to bin\packages\ (was build\packages\) - Add StrideSkipAutoPack to StorageTool (PackAsTool conflicts with custom _WalkEachTargetPerFramework override) - Move Stride.GraphicsApi.PackageReference.targets into Stride.Graphics/build/ (was in deleted sources/targets/, needed for NuGet package consumers) - Restore nuget-icon.png to SDK package (was in deleted sources/targets/)
The .sln→.slnf rename (commit 984ea11) was not reflected in Stride.build. Update all Runtime/Android/iOS build targets to reference .slnf files, and include file extensions in solution path properties so RestoreInternal no longer appends .sln.
Create .github/actions/build-sdk composite action that builds Stride.Sdk.slnx into the local NuGet cache. All 10 CI workflow files now call this action before their main build step, since every project requires Sdk="Stride.Sdk" to be resolvable.
Shared projects (.shproj) are included implicitly via projitems imports and don't need to be listed in solution filters. Stride.Refactor.shproj had no Project entry in Stride.sln, causing MSB5028 during CI builds.
All build targets (Build, BuildRuntime, BuildWindows, etc.) now depend on BuildSdk which builds sources/sdk/Stride.Sdk.slnx. This ensures the Stride.Sdk MSBuild SDK packages are in the local NuGet cache before any project using Sdk="Stride.Sdk" is evaluated.
These 9 files were legacy solution-level build property files from before the SDK migration. All properties they defined are now handled by the Stride.Sdk MSBuild SDK packages: - StrideCommonPreSettingsName → Stride.Platform.props - StridePlatforms (OS defaults) → Stride.Platform.props - StrideGraphicsApis (platform defaults) → Stride.Platform.props - StridePlatformFullName → Stride.Platform.props - StrideAssemblyProcessorBasePath → Stride.AssemblyProcessor.targets - StridePackageStride*/StrideCoreAssemblyPath/StrideAssemblyProcessorGlobal /StrideEditorTargetFrameworks → dead code, no longer referenced
Stride's graphics API inner build system overrides _ComputeTargetFrameworkItems to create multiple entries per TFM (one per graphics API). The .NET SDK's ValidateExecutableReferences task calls .Single() filtered by TFM, which crashes with "Sequence contains more than one element" when multiple graphics-API variants share the same TFM.
…nstants The DefineConstants block was evaluated before the iOS/Android StridePlatformDefines were set, so STRIDE_PLATFORM_IOS, STRIDE_PLATFORM_ANDROID, and STRIDE_PLATFORM_MONO_MOBILE were never added to the compiler defines. Move all platform define blocks before the DefineConstants application.
2279802 to
9d99576
Compare
71d4ef1 to
e5f9b77
Compare
|
@xen2 this likely affects the TeamCity builds, though I tried to make sure that using Stride.build should continue to work. |
Set StrideAssemblyProcessor=true in Stride.Sdk.Tests/Sdk/Sdk.props so all test projects automatically get assembly processing (serialization, module initializers, parameter keys). Remove redundant per-project settings from 11 test .csproj files.
These are local development configuration files that should not be tracked. Added to .git/info/exclude to keep them locally.
Temporary design documents, will be removed completely later. Added to .git/info/exclude to keep them locally.
xen2
left a comment
There was a problem hiding this comment.
Thanks for working on it!
It was a much needed rewrite of our build system 🏗️
I might need to do another pass on the details, but here is what I found so far.
Note: I didn't try to build/run anything yet.
| ..\sources\engine\Stride.Shared\Refactor\Stride.Refactor.projitems*{fb06c76a-6bb7-40be-9afa-fec13b045fb5}*SharedItemsImports = 4 | ||
| EndGlobalSection | ||
| GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
| Debug|iPhone = Debug|iPhone |
There was a problem hiding this comment.
FYI, I remember Xamarin.iOS had issues if the Platform was not "iPhone" (and "iPhoneSimulator" to use the simulator), which is why we couldn't reuse Stride.Runtime.sln.
I suspect this is not a problem anymore with net10-android/ios and all the recent improvements/unification, so let's keep it deleted and see what happens when we try to make iOS/Android supported again.
There was a problem hiding this comment.
The build is passing but I don't have an iPhone or macOS desktop to test it out.
There was a problem hiding this comment.
Yes sorry if it wasn't clear, this was just a FYI so nothing to do.
However the Android build seems broken: https://github.com/stride3d/stride/actions/runs/22866630705/job/66335122196?pr=3085
There was a problem hiding this comment.
Android already doesn't build on master
| @@ -1,16 +1,13 @@ | |||
| <Project> | |||
| <Import Project="..\..\targets\Stride.props" /> | |||
| <Project Sdk="Stride.Sdk.Editor"> | |||
There was a problem hiding this comment.
I assume we don't want a Stride.Sdk.Editor.Tests since it's too different from our other typical unit tests projects, being a test for our VS SDK package?
There was a problem hiding this comment.
The Stride.Sdk.Tests is kind of already a Stride.Sdk.Editor.Tests. Stride.Sdk.Tests imports Stride.Sdk.Editor which imports Stride.Sdk.
I'll look into why it is not used for this project. I suspect it is because it wasn't importing the tests .props and .targets before.
sources/core/Stride.Core.MicroThreading/Stride.Core.MicroThreading.csproj.backup
Outdated
Show resolved
Hide resolved
| <AllowUnsafeBlocks>true</AllowUnsafeBlocks> | ||
|
|
||
| <!-- Enable assembly processor for test projects --> | ||
| <StrideAssemblyProcessor Condition="'$(StrideAssemblyProcessor)' == ''">true</StrideAssemblyProcessor> |
There was a problem hiding this comment.
From what I understood, Sdk.props is inserted before our project properties.
So I think it doesn't need to check if this user property is already defined? (or it should be moved to Targets file).
Same goes for everything checking existing properties from .csproj in .props file (except TargetFramework and all the properties derived from it, since this it is passed as a global parameter in inner builds)
There was a problem hiding this comment.
I'll review that. I had back and forth for these stuff. I think it is checked in both .props and .targets especially because of inner builds.
| <!-- Original: NuGet.Build.Tasks.Pack.targets | ||
| Standard NuGet uses _ProjectsWithTFM (one per TFM). We override | ||
| to use @(_InnerBuildProjects) which includes TFM x API combos. | ||
| This ensures all graphics API variants get included in the package. --> |
There was a problem hiding this comment.
Maybe we can add a small comment that once NuGet/Home#10556 is fixed, we could remove some of those targets.
| <OutputPath Condition="'$(OutputPath)' == ''">$(_StrideTestOutputDir)</OutputPath> | ||
|
|
||
| <!-- Set intermediate output path --> | ||
| <IntermediateOutputPath Condition="'$(StrideGraphicsApiDependent)' != 'true'">$(BaseIntermediateOutputPath)$(StridePlatform)\$(Configuration)\</IntermediateOutputPath> |
There was a problem hiding this comment.
Isn't it same problem? StrideGraphicsApiDependent can't be accessed in .props, only .targets
There was a problem hiding this comment.
I think it is again because of inner builds. I'll review again the analysis the AI made. And if so, add some notes in the SDK-guide document.
| into the local NuGet cache. Required before any project using Sdk="Stride.Sdk" can build. | ||
| --> | ||
| <Target Name="BuildSdk"> | ||
| <PropertyGroup> |
There was a problem hiding this comment.
What would the workflow be if we want to build Stride.sln with Visual Studio?
Do we need to open Stride.Sdk.slnx first, build it, then open Stride.sln?
If yes, would there be a way to auto build it if not present (or at least put an error message about what to do), i.e. in Directory.build.targets?
There was a problem hiding this comment.
For now we do need to buid it first. I think it is hard to have it automatic since the restore phase does need the Sdk to be present. It's a chicken-egg problem.
There was a problem hiding this comment.
I asked AI and it confirms it.
The reviewer is right that this is a friction point, but I agree with you that it's essentially unsolvable at the SDK level. Here's why:
Why auto-building the SDK from Directory.Build.targets won't work
MSBuild SDK resolution happens before any targets or props execute. The sequence is:
- MSBuild reads
<Project Sdk="Stride.Build.Sdk"> - MSBuild looks up
Stride.Build.Sdkversion inglobal.json - MSBuild resolves the SDK package from NuGet cache
- If not found → immediate failure (MSBuild error, not a target failure)
- Only then does it import
Sdk.props→.csproj→Sdk.targets
Directory.Build.targets runs at step 5. The failure happens at step 3/4. There's no hook to intercept "SDK not found" — it's a hard MSBuild infrastructure error, not something a target can catch.
What about a better error message?
Unfortunately, MSBuild already gives a clear error when an SDK isn't found:
error MSB4236: The SDK 'Stride.Build.Sdk' specified could not be found.
We can't customize that message — it comes from MSBuild internals before any project code runs.
What about Visual Studio specifically?
VS does NuGet restore on solution open, but SDK resolution is a prerequisite for restore itself. The SDK must exist in the NuGet cache before VS can even parse the project files. There's no VS extensibility point to intercept this either.
Practical options for the reviewer's concern
-
Documentation — Make it clear in the repo README / contributor guide that
dotnet build sources/sdk/Stride.Build.Sdk.slnxmust be run once before openingStride.sln. This is the same pattern as many repos with custom SDKs. -
The existing
Stride.build approach—MSBuild Stride.build /t:Buildalready runsBuildSdkfirst, then builds the solution. This is the command-line workflow. -
A setup script — A
setup.bat/setup.ps1that builds the SDK could reduce friction for first-time contributors. But this is just syntactic sugar overdotnet build sources/sdk/Stride.Build.Sdk.slnx. -
Pre-built SDK in the repo — We could check in the
.nupkgfiles tobuild/packages/, so the SDK is always available without a build step. Thenuget.configalready points there. This would make "clone and open in VS" work immediately. The downside is committing binary packages (~small, since these are mostly .props/.targets files).
Option 4 is the only one that truly solves the "open Stride.sln in VS without a prior step" problem. The packages are tiny (mostly XML files + assembly processor binaries that are already in deps/), so the repo size impact would be minimal.
There was a problem hiding this comment.
Option 4 could be good to have.
We'll have to make sure people don't forget to rebuild them on change. (from top of my head, I can think of 2 options: some warning top of props/targets file in the SDK, or to automatize it, a check for any modified date of props/targets files in SDK folder later than nupkg itself => issue a warning/error).
Also, if doing so, please make sure to add .nupkg to .gitattributes for git LFS (BEFORE doing any git add).
There was a problem hiding this comment.
What about another option 5:
Simply keep props/targets in Sdk-like format, but add them as proper Import in the file? (with relative path)
(a bit like we were doing before, except now we can properly put them as first and last line of csproj)
Even if it doesn't look as nice as Sdk, I think it would fit better the intent: import a local target which is in the same repo
But I wonder if there would be any disadvantage? Are all the features going to work fine? Is tooling OK with that?
…e user-facing SDK Renames all three internal MSBuild SDK packages: - Stride.Sdk -> Stride.Build.Sdk - Stride.Sdk.Editor -> Stride.Build.Sdk.Editor - Stride.Sdk.Tests -> Stride.Build.Sdk.Tests Updates 126 consuming .csproj files, global.json, nuget.config, build scripts, GitHub actions, and documentation. Adds README.md to all SDK packages to eliminate NuGet warnings. Removes notes.txt.
PR Details
Replaces the legacy build system (
sources/targets/+ scattered.props/.targetsfiles) with three MSBuild SDK packages undersources/sdk/. All 112 projects now use<Project Sdk="Stride.Sdk">(orStride.Sdk.Editor/Stride.Sdk.Tests).Motivation
The old build system was a web of 20+
.propsand.targetsfiles imported via relative paths in every.csproj. This made project files verbose, fragile to move, and hard to reason about. The new SDK approach follows .NET conventions: build logic lives in versioned SDK packages, and project files only declare what makes them unique.What changed
New SDK packages (
sources/sdk/):Stride.SdkStride.Sdk.EditorStride.Sdk+ editor framework propertiesStride.Sdk.TestsStride.Sdk.Editor+ xunit infrastructure, test launchers, asset compilationSimplified project files — 184
.csprojfiles modified with a net reduction of ~2,100 lines. A typical project went from 30+ lines of imports and boilerplate to a clean SDK-style file.Deleted legacy files:
sources/targets/(20 files, ~1,500 lines) — the old build systembuild/*.propsandbuild/*.targetsfilesSolution filters —
.slnffiles replace separate.slnfiles for Android/iOS builds.CI updated — all workflows now build the SDK packages first via a shared
build-sdkaction.How to review
sources/sdk/Stride.Sdk/Sdk/Sdk.propsandSdk.targetsto understand what the SDK provides.csprojdiffs to see the simplification (e.g.,Stride.Core.csproj,Stride.Engine.csproj)build/docs/SDK-GUIDE.mdexplains the SDK hierarchy, property evaluation order, and development workflowRelated Issue
Build system modernization — no prior issue.
Types of changes
Checklist