Repository navigation
AssetCompiler: the package is build-only, a plain PackageReference or #:package is enough - #3570
Kryptos-FR wants to merge 1 commit into
Conversation
… #:package is enough Games referenced Stride.AssetCompiler with IncludeAssets="build;buildTransitive"; without it the package's lib/ assembly and its dependencies were copied next to the game, whose serializer factory then loaded Stride.AssetCompiler.dll at start-up and failed on Stride.NuGetResolver. A .NET 10 file-based app can't write IncludeAssets at all. - Stride.AssetCompiler packs no lib/ (IncludeBuildOutput=false) and every dependency is private except buildTransitive, so its nuspec dependencies exclude Runtime,Compile,Build,Native,Analyzers. Consumers get what IncludeAssets="build;buildTransitive" gave them; the old form keeps working. - Stride.NuGetResolver: for a package with no lib/, the restore also takes the dependencies its nuspec keeps out of consumers' runtime as direct dependencies, so the compiler running from the package's tools/ still resolves its own closure. - Stride.Editor.Wpf references the compiler project for build order only (nothing loads it in-process). - The new-game template and the packaging-test consumer use the plain reference; the packaging test checks the compiler and Mono.Options stay out of the consumer's output. Docs updated.
|
Note It should be easy to backport to 4.4 if needed. Should I update all game samples to remove |
| <ProjectReference Include="..\..\assets\Stride.AssetCompiler\Stride.AssetCompiler.csproj" /> | ||
| <!-- Build order only: a Game Studio run from the source tree builds games with the compiler built here. | ||
| Nothing in the editor loads the compiler in-process, and its package has no lib/ assembly to load. --> | ||
| <ProjectReference Include="..\..\assets\Stride.AssetCompiler\Stride.AssetCompiler.csproj" ReferenceOutputAssembly="false" Private="false" /> |
There was a problem hiding this comment.
With ReferenceOutputAssembly="false", NuGet drops this dependency from the nuspec. It was the only path from Stride.GameStudio to Stride.AssetCompiler.
The CLI installs only Stride.GameStudio, then looks for the Stride.AssetCompiler package. On a clean cache, stride upgrade fails with "couldn't locate its Asset Compiler", and stride new keeps the old version.
We need to keep the dependency in the nuspec somehow.
| var pathResolver = new VersionFolderPathResolver(packagesPath); | ||
| var nuspecPath = pathResolver.GetManifestFilePath(packageName, versionRange.MinVersion); | ||
| if (!File.Exists(nuspecPath) || Directory.Exists(Path.Combine(pathResolver.GetInstallPath(packageName, versionRange.MinVersion), "lib"))) | ||
| return []; |
There was a problem hiding this comment.
This reads the nuspec before the restore, and only from the user-level packages folder. If the game restores somewhere else (globalPackagesFolder in nuget.config, RestorePackagesPath, a fallback folder), nothing is found. The first build then fails with "'Stride.Core' was not present", and the second build works.
Suggestion: if the nuspec is missing, restore first, read the nuspec from the restored package, then restore again.
PR Details
Every game references
Stride.AssetCompilerwithIncludeAssets="build;buildTransitive". Without that attribute the game builds, but crashes at start-up:Cause: the package ships the compiler assembly under
lib/too, and its 11 dependencies flow normally. A plain reference copiesStride.AssetCompiler.dlland the asset pipeline (Assimp,NuGet.*, …) next to the game. The game's serializer factory then loadsStride.AssetCompiler.dll, whose resolver module initializer needsStride.NuGetResolver.dll, which is only undertools/.So every consumer has to know the package is build-only. A .NET 10 file-based app can't express it at all:
#:packagehas noIncludeAssets, so a single-file Stride game needs aDirectory.Build.targetsnext to it just for that.This PR makes the package build-only by itself.
Changes
Stride.AssetCompiler.csproj:lib/(IncludeBuildOutput=false).buildTransitive, so the nuspec dependencies getexclude="Runtime,Compile,Build,Native,Analyzers".IncludeAssets="build;buildTransitive"gave them:build/andbuildTransitive/targets, and nothing in references or the output folder. Restore still downloads the whole dependency tree, which the compiler needs.IncludeAssets="build;buildTransitive"behave the same.Stride.NuGetResolver(RestoreHelper):tools/folder and resolves its own dependencies by restoring its package. Since the nuspec now keeps them out of runtime, that restore would no longer give the compiler its own assemblies (it fails with'Stride.Core' was not present).lib/, the restore also adds the dependencies its nuspec excludes from runtime as direct dependencies, read from the nuspec in the global packages folder.lib/(Game Studio, …) are unaffected.Stride.Editor.Wpf: references the compiler project for build order only (ReferenceOutputAssembly=false). No editor code uses it, and the package no longer has alib/assembly to load.MyTemplate.Game.csproj): plain reference.IncludeAssets.IncludeAssets="build;buildTransitive", which stays harmless.Consumer.Gamefixture uses the plain reference; the plugin fixture keeps theIncludeAssetsform, so both stay covered.Stride.AssetCompiler.dllandMono.Options.dll(a dependency only the compiler has) stay out of the consumer's output.docs/asset-system/compiler.mdandregistration.mddescribe the plain reference. The stride-docs pages are updated in docs: The asset compiler package is Stride.AssetCompiler, build-only by itself from 4.5 stride-docs#575.Before / after
Single-file game below, built with
dotnet build game.cs:Stride.*@4.4.0(published)Stride.AssetCompiler.dll,NuGet.*, Assimp, the asset pipelineCould not load file or assembly 'Stride.NuGetResolver'Stride.*@4.5.0-dev(this branch)CONTENT OK HelloFont (OfflineRasterizedSpriteFont, size 40), exit 0Reproduce with a file-based app
Four files in an empty folder outside the repo. Replace
4.5.0-devwith the version of your local build (bin/packages/Stride.AssetCompiler.<version>.nupkg); use4.4.0and dropnuget.configto see the crash.The asset package file must be named
game.cs.sdpkg: the project name of a file-based app isgame.cs, and agame.sdpkgis ignored.game.csgame.cs.sdpkgAssets/HelloFont.sdfntnuget.config(only for a local build; point it at your checkout'sbin/packages)Then (PowerShell):
Related Issue
No GitHub issue; reported on Discord. A plain reference to
Stride.AssetCompiler, which is the only possible form in a .NET 10 file-based app (#:package), makes the game fail at start-up withCould not load file or assembly 'Stride.NuGetResolver'.Types of changes
Checklist