Skip to content

feat: refactor old build system into a proper Sdk#3085

Open
Kryptos-FR wants to merge 73 commits intostride3d:masterfrom
Kryptos-FR:feature/stride-sdk
Open

feat: refactor old build system into a proper Sdk#3085
Kryptos-FR wants to merge 73 commits intostride3d:masterfrom
Kryptos-FR:feature/stride-sdk

Conversation

@Kryptos-FR
Copy link
Member

@Kryptos-FR Kryptos-FR commented Mar 7, 2026

PR Details

Replaces the legacy build system (sources/targets/ + scattered .props/.targets files) with three MSBuild SDK packages under sources/sdk/. All 112 projects now use <Project Sdk="Stride.Sdk"> (or Stride.Sdk.Editor / Stride.Sdk.Tests).

Motivation

The old build system was a web of 20+ .props and .targets files 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/):

Package Purpose
Stride.Sdk Base SDK — platform detection, target frameworks, graphics API multi-targeting, assembly processor, native dependencies
Stride.Sdk.Editor Composes Stride.Sdk + editor framework properties
Stride.Sdk.Tests Composes Stride.Sdk.Editor + xunit infrastructure, test launchers, asset compilation

Simplified project files — 184 .csproj files 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 system
  • Obsolete build/*.props and build/*.targets files

Solution filters.slnf files replace separate .sln files for Android/iOS builds.

CI updated — all workflows now build the SDK packages first via a shared build-sdk action.

How to review

  • Start with sources/sdk/Stride.Sdk/Sdk/Sdk.props and Sdk.targets to understand what the SDK provides
  • Skim a few .csproj diffs to see the simplification (e.g., Stride.Core.csproj, Stride.Engine.csproj)
  • Detailed guide: build/docs/SDK-GUIDE.md explains the SDK hierarchy, property evaluation order, and development workflow

Related Issue

Build system modernization — no prior issue.

Types of changes

  • Docs change / refactoring / dependency upgrade
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • My change requires a change to the documentation.
  • I have added tests to cover my changes.
  • All new and existing tests passed.
  • I have built and run the editor to try this change out.

- 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.
Move package props to targets
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.
@Kryptos-FR Kryptos-FR marked this pull request as ready for review March 7, 2026 00:07
@Kryptos-FR Kryptos-FR marked this pull request as draft March 7, 2026 00:10
@Kryptos-FR Kryptos-FR changed the title Stride SDK (for building) feat: refactor old build system into a proper Sdk Mar 7, 2026
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.
@Kryptos-FR Kryptos-FR marked this pull request as ready for review March 7, 2026 00:18
@Kryptos-FR Kryptos-FR marked this pull request as draft March 7, 2026 00:25
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.
@Kryptos-FR Kryptos-FR force-pushed the feature/stride-sdk branch from 2279802 to 9d99576 Compare March 7, 2026 13:30
@Kryptos-FR Kryptos-FR force-pushed the feature/stride-sdk branch from 71d4ef1 to e5f9b77 Compare March 7, 2026 14:01
@Kryptos-FR Kryptos-FR marked this pull request as ready for review March 7, 2026 14:02
@Kryptos-FR
Copy link
Member Author

Kryptos-FR commented Mar 7, 2026

Some tests are failing. I'm investigating. I haven't tried yet to run and open the GameStudio with these changes.

@xen2 this likely affects the TeamCity builds, though I tried to make sure that using Stride.build should continue to work.

@Kryptos-FR Kryptos-FR added enhancement New feature or request engineering labels Mar 7, 2026
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.
@Kryptos-FR Kryptos-FR requested a review from xen2 March 7, 2026 16:53
Copy link
Member

@xen2 xen2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Member

@xen2 xen2 Mar 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The build is passing but I don't have an iPhone or macOS desktop to test it out.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Android already doesn't build on master

@@ -1,16 +1,13 @@
<Project>
<Import Project="..\..\targets\Stride.props" />
<Project Sdk="Stride.Sdk.Editor">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

<AllowUnsafeBlocks>true</AllowUnsafeBlocks>

<!-- Enable assembly processor for test projects -->
<StrideAssemblyProcessor Condition="'$(StrideAssemblyProcessor)' == ''">true</StrideAssemblyProcessor>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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. -->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't it same problem? StrideGraphicsApiDependent can't be accessed in .props, only .targets

Copy link
Member Author

@Kryptos-FR Kryptos-FR Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

  1. MSBuild reads <Project Sdk="Stride.Build.Sdk">
  2. MSBuild looks up Stride.Build.Sdk version in global.json
  3. MSBuild resolves the SDK package from NuGet cache
  4. If not found → immediate failure (MSBuild error, not a target failure)
  5. Only then does it import Sdk.props.csprojSdk.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

  1. Documentation — Make it clear in the repo README / contributor guide that dotnet build sources/sdk/Stride.Build.Sdk.slnx must be run once before opening Stride.sln. This is the same pattern as many repos with custom SDKs.

  2. The existing Stride.build approachMSBuild Stride.build /t:Build already runs BuildSdk first, then builds the solution. This is the command-line workflow.

  3. A setup script — A setup.bat/setup.ps1 that builds the SDK could reduce friction for first-time contributors. But this is just syntactic sugar over dotnet build sources/sdk/Stride.Build.Sdk.slnx.

  4. Pre-built SDK in the repo — We could check in the .nupkg files to build/packages/, so the SDK is always available without a build step. The nuget.config already 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.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants