Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Marking the application's assembly as trimmable passes completely wrong input to linker #13999

Closed
vitek-karas opened this issue Oct 6, 2020 · 3 comments
Assignees

Comments

@vitek-karas
Copy link
Member

Create a console app named "TrimApp"
Modify .csproj like this:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>

  <Target Name="ConfigureTrimming"
          BeforeTargets="PrepareForILLink">
    <ItemGroup>
      <ManagedAssemblyToLink Condition="'%(Filename)' == 'TrimApp'">
        <IsTrimmable>true</IsTrimmable>
      </ManagedAssemblyToLink>
    </ItemGroup>
  </Target>

</Project>

Publishing this app with:

dotnet publish -r win-x64 /p:PublishTrimmed=true /p:TrimMode=link

Actually fails:

  TrimApp -> F:\ILLinker\repro\TrimApp\bin\Debug\net5.0\win-x64\TrimApp.dll
ILLink : error IL1020: No files to link were specified. Use one of '-a|-r|-x' options [F:\ILLinker\repro\TrimApp\TrimApp.csproj]

If I add a project reference to a simple classlib, then linker will actually not fail, but will be given command line where the classlib is treated as the "application assembly" - which leads to deleting the actual app's assembly from the output - producing completely broken app (without failing the build).

@eerhardt
Copy link
Member

eerhardt commented Oct 6, 2020

In the runtime tests, we work around this problem with the following:

https://github.com/dotnet/runtime/blob/1beb1c635a2961d96d56d52025ee0fa7322933bb/eng/testing/linker/SupportFiles/Directory.Build.targets#L30

<TrimmerRootAssembly Include="@(IntermediateAssembly)" />

@sbomer
Copy link
Member

sbomer commented Oct 6, 2020

A short-term fix is just to add IntermediateAssembly to TrimmerRootAssembly, but that won't do the right thing for IsTrimmable libraries (it would keep everything in the library). I actually think that TrimmerRootAssembly is a bit broken, and the longer-term fix is to clean up the linker options for rooting assemblies - I filed dotnet/linker#1541 for this.

Long-term, I think the SDK behavior should be:

  • !IsTrimmable assemblies -> root entire assembly (entry point or not)
  • IsTrimmable IntermediateAssembly -> root entry point or public surface (for app or library, respectively)
  • other IsTrimmable -> don't root

@sbomer
Copy link
Member

sbomer commented Nov 18, 2022

I believe this was fixed a while ago by #16094.

@sbomer sbomer closed this as completed Nov 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants