Open dotMorten opened 3 years ago
NuGet dependencies are including unrelated packages
You referenced the Project Reunion package which includes related packages:
<dependencies>
<dependency id="Microsoft.ProjectReunion.Foundation" version="0.8.0-preview" />
<dependency id="Microsoft.ProjectReunion.DWrite" version="0.8.0-preview" />
<dependency id="Microsoft.ProjectReunion.WinUI" version="0.8.0-preview" />
<dependency id="Microsoft.ProjectReunion.InteractiveExperiences" version="0.8.0-preview" />
</dependencies>
WinUI target throws
error : This version of WinUI does not support AnyCPU. Either set Platform or PlatformTarget to one of the following: x86, x64, or arm64
Dynamic dependencies and other components do not support AnyCPU
. Not sure why the sample ships with that though (bug?).
The error above is extremely confusing as I am not interested in or explicitly referencing the WinUI extension.
Well, you added that dependency (see above). But if you add the Foundation
package by itself, the WinUI targets do still get evaluated, which I agree is very confusing.
Dynamic dependencies and other components do not support AnyCPU. Not sure why the sample ships with that though (bug?).
.NET will deploy all the architecture runtimes when compiling for AnyCPU and dynamically load the correct one, so yes that should work just fine. That's why when you compile for AnyCPU you get a \runtimes\win10-[arch]\
for each supported architecture, but when compiling for a specific runtime identifier, that folder gets dropped and the dependencies gets placed in the root folder instead. Why should reunion work any different?
.NET will deploy all the architecture runtimes when compiling for AnyCPU and dynamically load the correct one, so yes that should work just fine. That's why when you compile for AnyCPU you get a
\runtimes\win10-[arch]\
for each supported architecture, but when compiling for a specific runtime identifier, that folder gets dropped and the dependencies gets placed in the root folder instead. Why should reunion work any different?
Not sure what behavior you're referring to but compiling the WPF app here as AnyCPU
will result in a single ILONLY image.
When you build for any cpu in a .NET 3.1+ project, if a nuget dependency includes runtimes for several different architectures (and/or platforms) they are deployed to a subfolder for each, and .NET automatically knows where to find them based on current platform and architecture at runtime. For instance your output folder might have this:
Sure when you go to publish, you pick a specific architecture, but a standard new .NET Core project defaults to AnyCPU when you hit F5 after creating it - so this is just as much about simplifying the developer experience.
Thanks for pointing this out Morten, @AdamBraden is investigating the AnyCPU topic.
Yes we need to fix the nuget packages to correctly place the native dependencies of our components.
Build/F5 of AnyCPU results in a lot of binaries being deployed, but apparently that's the way it is for .NET.
Duplicate of #922 ?
FYI: When using an Any CPU app head, then I still have to add this.
<Target Name="BinPlaceBootstrapDll" />
Dupe of #1217 ?
@DrusTheAxe No this is different. The other one is about being able to build architecture agnostic class libs and is a regression that holds up control libraries like ours and the toolkit. This one is about following the pattern of the other .net libs where when building for anycpu, all runtimes are deployed and at runtime the right native libs are loaded and will run. That creates a much better and simpler first run experience for .net developers (typically picking platform and architecture doesn't come into play until publish time).
Just adding some of the things that I found and am working around in maui. The Windows App SDK does already support AnyCPU since this is the default mode for .NET "Core", however there are targets that do not allow it and artificially restrict it.
There is a target WindowsAppSDKSelfContainedVerifyConfiguration
that just throws an error. I work around this in my targets by replacing it with a dummy target:
<Target Name="WindowsAppSDKSelfContainedVerifyConfiguration">
</Target>
There is a GetExtractMicrosoftWindowsAppSDKMsixFilesInputs
target that is supposed to extract things, but this fails if the Platform is not set. I work around this by injecting a target that runs right after it to replace the values of NativePlatform
:
<Target Name="_MAUIAfter_GetExtractMicrosoftWindowsAppSDKMsixFilesInputs"
AfterTargets="GetExtractMicrosoftWindowsAppSDKMsixFilesInputs"
Condition="'$(NativePlatform)' == 'AnyCPU'">
<PropertyGroup>
<NativePlatform>Invalid</NativePlatform>
<NativePlatform Condition="'$(Platform)' == 'x86'">x86</NativePlatform>
<NativePlatform Condition="'$(Platform)' == 'Win32'">x86</NativePlatform>
<NativePlatform Condition="'$(Platform)' == 'x64'">x64</NativePlatform>
<NativePlatform Condition="'$(Platform)' == 'arm'">arm</NativePlatform>
<NativePlatform Condition="'$(Platform)' == 'arm64'">arm64</NativePlatform>
</PropertyGroup>
<PropertyGroup Condition="'$(Platform)' == 'AnyCPU' or '$(Platform)' == 'Any CPU'">
<NativePlatform>neutral</NativePlatform>
<NativePlatform Condition="'$(RuntimeIdentifier)' == 'win10-x86' or '$(RuntimeIdentifier)' == 'win-x86'">x86</NativePlatform>
<NativePlatform Condition="'$(RuntimeIdentifier)' == 'win10-x64' or '$(RuntimeIdentifier)' == 'win-x64'">x64</NativePlatform>
<NativePlatform Condition="'$(RuntimeIdentifier)' == 'win10-arm' or '$(RuntimeIdentifier)' == 'win-arm'">arm</NativePlatform>
<NativePlatform Condition="'$(RuntimeIdentifier)' == 'win10-arm64' or '$(RuntimeIdentifier)' == 'win-arm64'">arm64</NativePlatform>
</PropertyGroup>
<ItemGroup>
<MicrosoftWindowsAppSDKMsix Include="$([MSBuild]::NormalizeDirectory('$(MicrosoftWindowsAppSDKPackageDir)','tools\Msix\win10-$(NativePlatform)'))Microsoft.WindowsAppRuntime.?.?.Msix"/>
<MicrosoftWindowsAppSDKMsix Include="$([MSBuild]::NormalizeDirectory('$(MicrosoftWindowsAppSDKPackageDir)','tools\Msix\win10-$(NativePlatform)'))Microsoft.WindowsAppRuntime.?.?-*.Msix"/>
</ItemGroup>
</Target>
There is also a _GetProjectArchitecture
that almost works with Any CPU, except that since .NET added/removed the support for the full RID graph, the conditions are no longer correct. I have also created a replacement target that will fix the values:
<Target Name="_GetProjectArchitecture" Returns="@(ProjectArchitecture)">
<PropertyGroup>
<_ProjectArchitectureOutput>Invalid</_ProjectArchitectureOutput>
<_ProjectArchitectureOutput Condition="'$(Platform)' == 'x86'">x86</_ProjectArchitectureOutput>
<_ProjectArchitectureOutput Condition="'$(Platform)' == 'Win32'">x86</_ProjectArchitectureOutput>
<_ProjectArchitectureOutput Condition="'$(Platform)' == 'x64'">x64</_ProjectArchitectureOutput>
<_ProjectArchitectureOutput Condition="'$(Platform)' == 'arm'">arm</_ProjectArchitectureOutput>
<_ProjectArchitectureOutput Condition="'$(Platform)' == 'arm64'">arm64</_ProjectArchitectureOutput>
</PropertyGroup>
<PropertyGroup Condition="'$(Platform)' == 'AnyCPU' or '$(Platform)' == 'Any CPU'">
<_ProjectArchitectureOutput>neutral</_ProjectArchitectureOutput>
<_ProjectArchitectureOutput Condition="'$(RuntimeIdentifier)' == 'win10-x86' or '$(RuntimeIdentifier)' == 'win-x86'">x86</_ProjectArchitectureOutput>
<_ProjectArchitectureOutput Condition="'$(RuntimeIdentifier)' == 'win10-x64' or '$(RuntimeIdentifier)' == 'win-x64'">x64</_ProjectArchitectureOutput>
<_ProjectArchitectureOutput Condition="'$(RuntimeIdentifier)' == 'win10-arm' or '$(RuntimeIdentifier)' == 'win-arm'">arm</_ProjectArchitectureOutput>
<_ProjectArchitectureOutput Condition="'$(RuntimeIdentifier)' == 'win10-arm64' or '$(RuntimeIdentifier)' == 'win-arm64'">arm64</_ProjectArchitectureOutput>
</PropertyGroup>
<Error Condition="'$(UseAppHost)' == 'true' and '$(_ProjectArchitectureOutput)' == 'neutral' and '$(AllowNeutralPackageWithAppHost)' != 'true'"
Text="Packaged .NET applications with an app host exe cannot be ProcessorArchitecture neutral. Please specify a RuntimeIdentifier or a Platform other than AnyCPU." />
<ItemGroup>
<ProjectArchitecture Include="$(_ProjectArchitectureOutput)" />
</ItemGroup>
</Target>
This is maybe the same/similar issue to https://github.com/microsoft/WindowsAppSDK/issues/2684
@Scottj1s FYI
@mattleibow thanks for reporting. The _GetProjectArchitecture target is fixed in WinAppSDK 1.6, available very soon. I'm really not sure why the WindowsAppSDKSelfContainedVerifyConfiguration target was added, given the more fine-grained check in _GetProjectArchitecture (which prevents packaging for Any CPU, not merely building it). I'll see if there's any resistance to just removing it. Your mods to GetExtractMicrosoftWindowsAppSDKMsixFilesInputs are appreciated - will include these.
At least in the 1.6-experimental1 release, the _GetProjectArchitecture target still does not support the new runtime identifiers.
At least in the 1.6-experimental1 release, the _GetProjectArchitecture target still does not support the new runtime identifiers.
1.6 Experimental 2 includes the changes suggested by @mattleibow
Describe the bug I'm trying to use MRTCore in a WPF application. I reference ProjectReunion package, and compile and I'm presented with this error:
I'm in no way interested in using WinUI here, but the current nuget dependency forces me to get WinUI included, including all the types etc. IMHO this is backwards, and instead
Microsoft.ProjectReunion.WinUI
you be referencingMicrosoft.ProjectReunion
. The error above is extremely confusing as I am not interested in or explicitly referencing the WinUI extension.Sure I can avoid using AnyCPU, but that's not so much the point (and I just followed the sample app config which has AnyCPU as well: https://github.com/microsoft/Project-Reunion-Samples/blob/main/MrtCore/winforms_unpackaged_app/winforms_unpackaged_app.csproj). Also why can't you do AnyCPU? Other .NET3+ apps can handle deploying multiple architecture runtimes in an AnyCPU app.
Steps to reproduce the bug Create a WPF Application and add reunion:
Compile for AnyCPU
I get the app packages the same runtime dependencies, but it creates confusing unrelated errors, and exposes a set of APIs that I never intended to reference. I'm only interested in MRTCore which is packaged with the "base" reunion package, yet I'm getting DWrite, InteractiveExperiences and WinUI throw in as well.
Expected behavior WinUI, DWrite and InteractiveExperiences package is not included. Intellisense doesn't autocomplete those APIs either.
Version Info
NuGet package version: 0.8.0-preview
Additional context