runtime icon indicating copy to clipboard operation
runtime copied to clipboard

Publishing hosted Blazor WASM project breaks if not self-contained

Open yugabe opened this issue 3 years ago • 3 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

Describe the bug

Up until and including .NET 7 Preview 7, I could publish a hosted Blazor WASM project by providing both the runtime identifier and the SelfContained false flag to MSBuild (providing it via command line --runtime and either --self-contained false or --no-self-contained switches didn't work either).

Since .NET 7 RC 1, the following exception occurs:

C:\Program Files\dotnet\sdk\7.0.100-rc.1.22431.12\Sdks\Microsoft.NET.ILLink.Tasks\build\Microsoft.NET.ILLink.targets(196,5): error NETSDK1102: Optimizing assemblies for size is not supported for the selected publish configuration. Please ensure that you are publishing a self-contained app. [*.Client.csproj]

Related previous issue: dotnet/aspnetcore#43068

In the pevious .NET release, providing the MSBuild flag /p:SelfContained=false (or modifying the project file) worked and produced a non-SCD build.

Weirdly, the build DOES work if publishing via Visual Studio UI or when putting the <SelfContained>false</SelfContained> property in Server.csproj.

Expected Behavior

Publishing via command line should work (for building via CI scenarios using the dotnet CLI).

The issue is probably related to how there needs to be two different builds for the Client project in this case: one self-contained and trimmed for the browser, and one possibly framework-dependent for the Server environment. The self-contained flag in the Blazor WASM project should only apply when building for the browser, otherwise it should be inferred.

Steps To Reproduce

dotnet new blazorwasm -ho -o BlazorWasmHosted
dotnet publish ./BlazorWasmHosted --runtime linux-x64 --no-self-contained

Exceptions (if any)

C:\Program Files\dotnet\sdk\7.0.100-rc.1.22431.12\Sdks\Microsoft.NET.ILLink.Tasks\build\Microsoft.NET.ILLink.targets(196,5): error NETSDK1102: Optimizing assemblies for size is not supported for the selected publish configuration. Please ensure that you are publishing a self-contained app. [*.Client.csproj]

.NET Version

7.0.100-rc.1.22431.12

Anything else?

Following the discussion in dotnet/aspnetcore#43068, the documentation was modified to explicitly reflect that the MSBuild parameter was to be set (https://github.com/dotnet/AspNetCore.Docs/issues/26619). Now that might need to be updated once more.

yugabe avatar Sep 15 '22 12:09 yugabe

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

Tagging subscribers to 'arch-wasm': @lewing See info in area-owners.md if you want to be subscribed.

Issue Details

Is there an existing issue for this?

  • [X] I have searched the existing issues

Describe the bug

Up until and including .NET 7 Preview 7, I could publish a hosted Blazor WASM project by providing both the runtime identifier and the SelfContained false flag to MSBuild (providing it via command line --runtime and either --self-contained false or --no-self-contained switches didn't work either).

Since .NET 7 RC 1, the following exception occurs:

C:\Program Files\dotnet\sdk\7.0.100-rc.1.22431.12\Sdks\Microsoft.NET.ILLink.Tasks\build\Microsoft.NET.ILLink.targets(196,5): error NETSDK1102: Optimizing assemblies for size is not supported for the selected publish configuration. Please ensure that you are publishing a self-contained app. [*.Client.csproj]

Related previous issue: dotnet/aspnetcore#43068

In the pevious .NET release, providing the MSBuild flag /p:SelfContained=false (or modifying the project file) worked and produced a non-SCD build.

Weirdly, the build DOES work if publishing via Visual Studio UI or when putting the <SelfContained>false</SelfContained> property in Server.csproj.

Expected Behavior

Publishing via command line should work (for building via CI scenarios using the dotnet CLI).

The issue is probably related to how there needs to be two different builds for the Client project in this case: one self-contained and trimmed for the browser, and one possibly framework-dependent for the Server environment. The self-contained flag in the Blazor WASM project should only apply when building for the browser, otherwise it should be inferred.

Steps To Reproduce

dotnet new blazorwasm -ho -o BlazorWasmHosted
dotnet publish ./BlazorWasmHosted --runtime linux-x64 --no-self-contained

Exceptions (if any)

C:\Program Files\dotnet\sdk\7.0.100-rc.1.22431.12\Sdks\Microsoft.NET.ILLink.Tasks\build\Microsoft.NET.ILLink.targets(196,5): error NETSDK1102: Optimizing assemblies for size is not supported for the selected publish configuration. Please ensure that you are publishing a self-contained app. [*.Client.csproj]

.NET Version

7.0.100-rc.1.22431.12

Anything else?

Following the discussion in dotnet/aspnetcore#43068, the documentation was modified to explicitly reflect that the MSBuild parameter was to be set (https://github.com/dotnet/AspNetCore.Docs/issues/26619). Now that might need to be updated once more.

Author: yugabe
Assignees: -
Labels:

arch-wasm

Milestone: -

msftbot[bot] avatar Sep 19 '22 16:09 msftbot[bot]

@lewing can you please look into this? We don't recall any work that we did in this area to cause this, so maybe something has changed in your area or even in the SDK?

mkArtakMSFT avatar Sep 19 '22 17:09 mkArtakMSFT

this isn't related to the wasm part of the build

lewing avatar Sep 23 '22 17:09 lewing

@lewing Even though the error message comes from the WASM client project? It's true that the Server project is the one getting built and published, but indirectly it both builds and publishes the (WASM) Client too, and the error message originates from there.

yugabe avatar Sep 23 '22 20:09 yugabe

@yugabe yes, it has nothing to do with the wasm runtime. The error is coming from the illink targets and the surrounding build logic comes from the sdk and the blazor team's code in the sdk. This doesn't look like it has anything to do with the wasm runtime directly.

cc @sbomer @vitek-karas @mkArtakMSFT @javiercn

lewing avatar Sep 24 '22 04:09 lewing

Tagging subscribers to this area: @vitek-karas, @agocke See info in area-owners.md if you want to be subscribed.

Issue Details

Is there an existing issue for this?

  • [X] I have searched the existing issues

Describe the bug

Up until and including .NET 7 Preview 7, I could publish a hosted Blazor WASM project by providing both the runtime identifier and the SelfContained false flag to MSBuild (providing it via command line --runtime and either --self-contained false or --no-self-contained switches didn't work either).

Since .NET 7 RC 1, the following exception occurs:

C:\Program Files\dotnet\sdk\7.0.100-rc.1.22431.12\Sdks\Microsoft.NET.ILLink.Tasks\build\Microsoft.NET.ILLink.targets(196,5): error NETSDK1102: Optimizing assemblies for size is not supported for the selected publish configuration. Please ensure that you are publishing a self-contained app. [*.Client.csproj]

Related previous issue: dotnet/aspnetcore#43068

In the pevious .NET release, providing the MSBuild flag /p:SelfContained=false (or modifying the project file) worked and produced a non-SCD build.

Weirdly, the build DOES work if publishing via Visual Studio UI or when putting the <SelfContained>false</SelfContained> property in Server.csproj.

Expected Behavior

Publishing via command line should work (for building via CI scenarios using the dotnet CLI).

The issue is probably related to how there needs to be two different builds for the Client project in this case: one self-contained and trimmed for the browser, and one possibly framework-dependent for the Server environment. The self-contained flag in the Blazor WASM project should only apply when building for the browser, otherwise it should be inferred.

Steps To Reproduce

dotnet new blazorwasm -ho -o BlazorWasmHosted
dotnet publish ./BlazorWasmHosted --runtime linux-x64 --no-self-contained

Exceptions (if any)

C:\Program Files\dotnet\sdk\7.0.100-rc.1.22431.12\Sdks\Microsoft.NET.ILLink.Tasks\build\Microsoft.NET.ILLink.targets(196,5): error NETSDK1102: Optimizing assemblies for size is not supported for the selected publish configuration. Please ensure that you are publishing a self-contained app. [*.Client.csproj]

.NET Version

7.0.100-rc.1.22431.12

Anything else?

Following the discussion in dotnet/aspnetcore#43068, the documentation was modified to explicitly reflect that the MSBuild parameter was to be set (https://github.com/dotnet/AspNetCore.Docs/issues/26619). Now that might need to be updated once more.

Author: yugabe
Assignees: -
Labels:

area-HostModel

Milestone: -

msftbot[bot] avatar Sep 24 '22 04:09 msftbot[bot]

Tagging subscribers to 'linkable-framework': @eerhardt, @vitek-karas, @LakshanF, @sbomer, @joperezr See info in area-owners.md if you want to be subscribed.

Issue Details

Is there an existing issue for this?

  • [X] I have searched the existing issues

Describe the bug

Up until and including .NET 7 Preview 7, I could publish a hosted Blazor WASM project by providing both the runtime identifier and the SelfContained false flag to MSBuild (providing it via command line --runtime and either --self-contained false or --no-self-contained switches didn't work either).

Since .NET 7 RC 1, the following exception occurs:

C:\Program Files\dotnet\sdk\7.0.100-rc.1.22431.12\Sdks\Microsoft.NET.ILLink.Tasks\build\Microsoft.NET.ILLink.targets(196,5): error NETSDK1102: Optimizing assemblies for size is not supported for the selected publish configuration. Please ensure that you are publishing a self-contained app. [*.Client.csproj]

Related previous issue: dotnet/aspnetcore#43068

In the pevious .NET release, providing the MSBuild flag /p:SelfContained=false (or modifying the project file) worked and produced a non-SCD build.

Weirdly, the build DOES work if publishing via Visual Studio UI or when putting the <SelfContained>false</SelfContained> property in Server.csproj.

Expected Behavior

Publishing via command line should work (for building via CI scenarios using the dotnet CLI).

The issue is probably related to how there needs to be two different builds for the Client project in this case: one self-contained and trimmed for the browser, and one possibly framework-dependent for the Server environment. The self-contained flag in the Blazor WASM project should only apply when building for the browser, otherwise it should be inferred.

Steps To Reproduce

dotnet new blazorwasm -ho -o BlazorWasmHosted
dotnet publish ./BlazorWasmHosted --runtime linux-x64 --no-self-contained

Exceptions (if any)

C:\Program Files\dotnet\sdk\7.0.100-rc.1.22431.12\Sdks\Microsoft.NET.ILLink.Tasks\build\Microsoft.NET.ILLink.targets(196,5): error NETSDK1102: Optimizing assemblies for size is not supported for the selected publish configuration. Please ensure that you are publishing a self-contained app. [*.Client.csproj]

.NET Version

7.0.100-rc.1.22431.12

Anything else?

Following the discussion in dotnet/aspnetcore#43068, the documentation was modified to explicitly reflect that the MSBuild parameter was to be set (https://github.com/dotnet/AspNetCore.Docs/issues/26619). Now that might need to be updated once more.

Author: yugabe
Assignees: -
Labels:

area-HostModel, linkable-framework

Milestone: -

msftbot[bot] avatar Sep 24 '22 08:09 msftbot[bot]

Sorry for bumping, but I just wanted to confirm this regression still stands as of .NET 7 RC2. So, not able to publish a hosted Blazor app that is framework dependent.

What's weird is that the build succeeds in Visual Studio when using a folder publish profile. The profile contains nothing that seems to indicate a difference in how the build works, but I'll include it here for reference.

<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project>
  <PropertyGroup>
    <DeleteExistingFiles>false</DeleteExistingFiles>
    <ExcludeApp_Data>false</ExcludeApp_Data>
    <LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
    <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
    <LastUsedPlatform>Any CPU</LastUsedPlatform>
    <PublishProvider>FileSystem</PublishProvider>
    <PublishUrl>bin\Release\net7.0\publish\</PublishUrl>
    <WebPublishMethod>FileSystem</WebPublishMethod>
    <_TargetId>Folder</_TargetId>
    <SiteUrlToLaunchAfterPublish />
    <TargetFramework>net7.0</TargetFramework>
    <RuntimeIdentifier>win-x64</RuntimeIdentifier>
    <ProjectGuid>09041cbc-0fbc-4abb-8fc4-280cf26eafeb</ProjectGuid>
    <SelfContained>false</SelfContained>
  </PropertyGroup>
</Project>

The error message is different now in the CLI than it originally was in RC1. The message when running dotnet publish ./BlazorWasmHosted --runtime linux-x64 --no-self-contained became:

C:\Program Files\dotnet\packs\Microsoft.NET.Runtime.WebAssembly.Sdk\7.0.0-rc.2.22472.3\Sdk\WasmApp.targets(208,5): erro
r : $(MicrosoftNetCoreAppRuntimePackDir)='', and cannot find %(ResolvedRuntimePack.PackageDirectory)=. One of these nee
d to be set to a valid path [{...}\BlazorWasmHosted\Client\BlazorWasmHosted.Client.csproj]

yugabe avatar Oct 20 '22 10:10 yugabe

The original error is happening because the SelfContained=false MSBuild property is flowing into the Client project. This value can't be set for the Client project, because it is a WASM app. It HAS to be SelfContained.

One workaround I discovered is to modify the Client.csproj with:

  <PropertyGroup>
    <StaticWebAssetsAdditionalPublishPropertiesToRemove>$(StaticWebAssetsAdditionalPublishPropertiesToRemove);SelfContained</StaticWebAssetsAdditionalPublishPropertiesToRemove>
  </PropertyGroup>

And then when you publish the app, don't publish the .sln file (because if you do, the SelfContained property will be set for the Client project - since it is a "Global" property). Instead publish the Server.csproj. Modifying your command above:

dotnet publish ./BlazorWasmHosted/Server --runtime linux-x64 --no-self-contained

That allowed this scenario to work for me.

eerhardt avatar Oct 20 '22 14:10 eerhardt

Thank you for the workaround, @eerhardt.

It seems reasonable to take this information and supply a fix at the SDK level? I guess, from what you said, that when building a Blazor application specifically for the browser(-wasm) target, it should always be self-contained, so the build shouldn't just break, it should ignore the switch altogether.

Although you are right in that I was publishing the solution directly in my example, it was an oversight on my part -- as in my production CI pipeline I build the Server project directly, and it produces a different result.

That said, is this issue correctly categorized here, or should it go the github.com/dotnet/aspnetcore repo?

yugabe avatar Oct 20 '22 14:10 yugabe

I'm not an expert on Blazor so take all this with a grain of salt but,

If SelfContained=false is being passed to a project with mandatory trimming, I'd expect the trimming targets to error about that. Maybe something else could fix things up at a higher level, but the input being provided to trimming is legitimately nonsensical and indicates some kind of configuration bug upstream, and I'd generally like an error about that.

agocke avatar Oct 20 '22 17:10 agocke

@agocke This I know to be a bit different (accidentally). In a Blazor WASM hosted app (with prerendering), the client bits needs to be built twice: once for running in the browser and once for running on the server.

When building for the browser (the resulting assemblies will be served as static files from the server's wwwroot), the app obviously needs to be self-contained as there is no .NET runtime available in the browser. It is trimmed fully by default from .NET 7 onwards too.

When being built for the server, it's just another assembly to be built for the target runtime (linux-x64 in my case), so it should be handled as any other library project.

The issue I reckon is that somehow these two methods to build the client app need to be configured differently, and the logic that decides how that should be done is possibly flawed. So, the SelfContained flag should always be ignored/should default to true when building the Client for the browser, and should be ambient/configurable when not. The problem is also that both can and do happen in the same build cycle when doing a full build of a Blazor Hosted WASM Server app.

yugabe avatar Oct 20 '22 17:10 yugabe

  <PropertyGroup>
    <StaticWebAssetsAdditionalPublishPropertiesToRemove>$(StaticWebAssetsAdditionalPublishPropertiesToRemove);SelfContained</StaticWebAssetsAdditionalPublishPropertiesToRemove>
  </PropertyGroup>

We could potentially do this in our targets.

The issue is more or less what @yugabe mentioned. There is an invocation for the client project to get the dlls from referenced projects and there is a separate invocation we do to get the files that need to go into the wwwroot folder. I believe we already do work to ensure that on blazor webassembly the rid is always wasm here and we remove other properties here so I think we could add SelfContained there too.

javiercn avatar Oct 20 '22 18:10 javiercn