I have a cross-platform solution with multiple projects targetting iOS, Android, Mac, Windows, and Linux using Avalonia. I am using Windows Application Packaging Project to package and deploy the Windows app. The main project has reference to various library projects, all of which target NET8.0.
When try to publish the Windows packaging project, unless I add <RuntimeIdentifiers>win-x64;</RuntimeIdentifiers>
to every project (including the library projects), I will get an error like this
Severity Code Description Project File Line Suppression State
Error Assets file 'C:\Projects\Samples\AvaloniaPackagingSample\AvaloniaPackagingSample.Desktop\obj\wappublish\win-x64\project.assets.json' not found. Run a NuGet package restore to generate this file. AvaloniaPackagingSample.Desktop.Package C:\Program Files\dotnet\sdk\8.0.101\Sdks\Microsoft.NET.Sdk\targets\Microsoft.PackageDependencyResolution.targets 267
Instead of manually adding that build property to all projects, I have configured Directory.Build.props
to apply that to all of the projects
<Project>
<Target Name="ConfirmDirectoryBuildPropsImport" AfterTargets="PrepareForBuild">
<Message Text="Directory.Build.props has been imported successfully" Importance="high" />
</Target>
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Version>$(Version)</Version>
<AssemblyVersion>$(Version)</AssemblyVersion>
<RuntimeIdentifiers>win-x64;</RuntimeIdentifiers>
</PropertyGroup>
</Project>
The problem is that I have other targets besides the Windows and when I leave the runtime identifier Android/iOS build/publish would fail. So, I need a way to conditionally add <RuntimeIdentifiers>win-x64;</RuntimeIdentifiers>
.
The idea is pretty simple - whenever I build the Windows app, indicate somehow that the runtime identifiers should be added, otherwise, skip them. I've tried adding a new variable called IsDesktop
and add a conditional section to the Directory.build.props
<Project>
<Target Name="ConfirmDirectoryBuildPropsImport" AfterTargets="PrepareForBuild">
<Message Text="Directory.Build.props has been imported successfully" Importance="high" />
</Target>
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Version>$(Version)</Version>
<AssemblyVersion>$(Version)</AssemblyVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(IsDesktop)' == 'true'">
<DefineConstants>$(DefineConstants);MY_CUSTOM_DESKTOP_CONSTANT</DefineConstants>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
</PropertyGroup>
</Project>
And then, I execute the msbuild command against the packaging project
msbuild $packagingProjectPath `
/nologo /nr:false `
/p:ProjectName="$PackagingProjectPath" `
/p:AppxBundlePlatforms="x64" `
/p:Platform="x64" `
/p:Configuration="Release" `
/p:AppxPackageDir=$OutputPath `
/p:AppxBundle=Always `
/p:PackageCertificateThumbprint=$PackageCertificateThumbprint `
/p:PackageCertificateKeyFile=$PackageCertificateKeyFile `
/p:PackageCertificatePassword=$PackageCertificatePassword `
/p:Version="$($EnvironmentSpecificVersion.VersionText)" `
/p:IsDesktop=true `
/v:detailed
However, the runtime identifiers are not getting added and the build fails.
2 observations
- Notice how I've added this piece in
Directory.Build.props
<Message Text="Directory.Build.props has been imported successfully" Importance="high" />
- when msbuild is executed this message does get printed, which means thatDirectory.Build.props
is being picked up - I also see
MY_CUSTOM_DESKTOP_CONSTANT
printed out in the build log, which means that the conditional section does get activated
But anyhow, my build still fails due to the same error I was seeing before adding the runtime identifier: ...project.assets.json' doesn't have a target for 'net8.0/win-x64'
What am I doing wrong? Perhaps, there's a different strategy for having conditional sections inside Directory.Build.props
?