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

Satellite assemblies from PackageReference all copy to root bin folder #1360

Closed
AArnott opened this issue Jun 20, 2017 · 30 comments
Closed

Satellite assemblies from PackageReference all copy to root bin folder #1360

AArnott opened this issue Jun 20, 2017 · 30 comments
Assignees

Comments

@AArnott
Copy link
Contributor

AArnott commented Jun 20, 2017

From @AArnott on June 20, 2017 15:19

Details about Problem

NuGet product used (NuGet.exe | VS UI | Package Manager Console | dotnet.exe): 4.3.0

VS version (if appropriate): 15.3.26616.2.d15rel

OS version (i.e. win10 v1607 (14393.321)): Win10 15063.rs2_release.170317-1834

Worked before? If so, with which NuGet version: Yes, this worked in 15.1 or 15.2 I believe.

Detailed repro steps so we can see the same problem

Create a new .NET Core library, then replace the project file content with this:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net46</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.VisualStudio.Composition" Version="15.0.71" />
  </ItemGroup>
</Project>

Restore, and build.

Expected

The project's bin folder has just a few DLLs, and a bunch of culture folders, each with a few *.resources.dll assemblies.

Actual

The bin folder that contains the project output no sub-folders. Instead, "all" the satellite assemblies are copied into that one root bin folder, causing each one to overwrite another so that only one culture wins. And at runtime, the satellite assemblies cannot be found.

Copied from original issue: NuGet/Home#5458

@AArnott
Copy link
Contributor Author

AArnott commented Jun 20, 2017

From @rohit21agrawal on June 20, 2017 18:36

shouldn't this go to msbuild?

@AArnott
Copy link
Contributor Author

AArnott commented Jun 20, 2017

I expected NuGet owned the .targets that copy files from nuget packages into the user's bin folder based on PackageReference.

@AArnott
Copy link
Contributor Author

AArnott commented Jun 20, 2017

From @rohit21agrawal on June 20, 2017 18:57

NuGet doesn't decide where the DLLs would be copied to on disk. It only creates an assets file which is a dependency graph, then NuGetBuildTasks convert these to References. Finally, SDK targets decide what to do with these references. So I would lean towards this being something that SDK isn't handling well.

@AArnott
Copy link
Contributor Author

AArnott commented Jun 20, 2017

Very well. It only seems to repro for .NET SDK projects so I'll move to dotnet/sdk

@nguerrera
Copy link
Contributor

This is the same as #1006 and #1132, fixed by #1224, but that fix is only in v2.0 of the SDK, which requires the v2.0 .NET Core SDK to be installed as it does not ship with Visual Studio 15.3 (only v1.1 does).

I'll be documenting a work-around here shortly for projects that must work on v1.1 too.

cc @jaredpar

@nguerrera
Copy link
Contributor

nguerrera commented Jun 21, 2017

Here is a workaround when using v2.0 is not possible:

  <!-- Work around bug in Microsoft.NET.Sdk < v2.0 where satellites were deployed on top of each other in root. -->
  <!-- https://github.com/dotnet/sdk/issues/1360 -->
  <Target Name="WorkaroundIncorrectSatelliteDeployment" AfterTargets="ResolveLockFileCopyLocalProjectDeps">
    <ItemGroup>
      <ReferenceCopyLocalPaths Remove="@(ResourceCopyLocalItems)" />
      <ReferenceCopyLocalPaths Include="@(ResourceCopyLocalItems)" Condition="'@(ResourceCopyLocalItems)' != ''">
        <DestinationSubDirectory>$([System.IO.Directory]::GetParent(%(ResourceCopyLocalItems.FullPath)).get_Name())\</DestinationSubDirectory>
      </ReferenceCopyLocalPaths>
    </ItemGroup>
  </Target>

@nguerrera
Copy link
Contributor

Closing as duplicate since this is already fixed in latest bits.

@nguerrera
Copy link
Contributor

nguerrera commented Jun 21, 2017

Worked before? If so, with which NuGet version: Yes, this worked in 15.1 or 15.2 I believe.

This is not in fact a regression. 15.0, 15.1, 15.2 would have exhibited the same behavior for Microsoft.NET.Sdk-using project targeting net4x (where we copy-local of nuget dependencies is on by default).

@AArnott
Copy link
Contributor Author

AArnott commented Jun 21, 2017

Thanks, @nguerrera

@AArnott
Copy link
Contributor Author

AArnott commented Jun 21, 2017

@onovotny do you want to include this workaround in https://github.com/onovotny/MSBuildSdkExtras?

@clairernovotny
Copy link

clairernovotny commented Jun 21, 2017

@nguerrera I assume that workaround should be disabled with the 2.0 SDK so we don't interfere?

Would a check like this work to only apply to SDK's lower than 2.0? https://github.com/paulcbetts/refit/blob/master/Refit/targets/refit.targets#L15-L27

@AArnott
Copy link
Contributor Author

AArnott commented Jun 21, 2017

@onovotny The myapps link you shared doesn't work for me.

@clairernovotny
Copy link

arg....clipboard :(

@clairernovotny
Copy link

Let's try this again -- https://github.com/onovotny/MSBuildSdkExtras/blob/master/src/build/netstandard1.0/MSBuild.Sdk.Extras.targets#L4-L33

Trying to understand how this workaround and that one relate and if that one is needed anymore (or fixed in 2.0 as well?)

@AArnott
Copy link
Contributor Author

AArnott commented Jun 21, 2017

The one you link to is sort of this one's counterpart. That workaround helps NuGet to properly pack satellite assemblies, while this workaround helps MSBuild unpack them.

@clairernovotny
Copy link

Any idea if that pack issue is fixed in the 2.0 SDK? looking to start phasing out the workarounds if running on 2.0.

@AArnott
Copy link
Contributor Author

AArnott commented Jun 21, 2017

The pack bug was fixed in 15.3, I think. So IMO it's too early to remove workarounds since most folks aren't on 15.3 yet. But as the .NET Core SDK 2.0 does not ship even with 15.3 (it's a separate install), I think we must assume most folks are on 1.1 of the SDK for (sniff) a long while yet.

@clairernovotny
Copy link

@AArnott I think I can detect that though based on checking $(BundledNETCoreAppTargetFrameworkVersion). It's a new property in the 2.0 SDK and has the version of .NET Core in it. It's not quite the same as the SDK version, as the SDK could be higher, but that may work for now?

https://github.com/paulcbetts/refit/blob/master/Refit/targets/refit.targets#L15-L27

@nguerrera
Copy link
Contributor

nguerrera commented Jun 21, 2017

You could use $(UsingMicrosoftNETSdk) as we only started setting that to true in 2.0. Also, the workaround shouldn't cause any harm, only redundant work, if it runs on a fixed SDK.

@clairernovotny
Copy link

@nguerrera is there an actual SDK version number we can check in addition to that prop or is $(BundledNETCoreAppTargetFrameworkVersion) the right way?

@nguerrera
Copy link
Contributor

There's nothing else other than only the boolean I just mentioned. Using BundledNETCoreAppTargetFrameworkVersion should be fine.

@clairernovotny
Copy link

ok...thanks. I thought there's an open issue to actually put the SDK version in as a property. Would seem to be useful if the SDK can version higher than the .NET Core version itself.

clairernovotny pushed a commit to novotnyllc/MSBuildSdkExtras that referenced this issue Jun 21, 2017
@clairernovotny
Copy link

@AArnott quick code review here? novotnyllc/MSBuildSdkExtras@d1b5527

It's also on the MyGet feed https://www.myget.org/F/msbuildsdkextras/api/v3/index.json, if you wanted to try it out quickly.

@clairernovotny
Copy link

@nguerrera that code yields an error:

C:\Users\oren\.nuget\packages\msbuild.sdk.extras\1.0.4-beta.44\build\netstandard1.0\MSBuild.Sdk.Extras.targets(45,9): er
ror MSB4186: Invalid static method invocation syntax: "[System.IO.Directory]::GetParent().get_Name()". System.IO.Directo
ry.GetParent Static method invocation should be of the form: $([FullTypeName]::Method()), e.g. $([System.IO.Path]::Combi
ne(`a`, `b`)).  [C:\dev\Humanizer\src\Humanizer\Humanizer.csproj]
C:\dev\Humanizer\src\Humanizer [dev ≡ +1 ~2 -0 !]>

@nguerrera
Copy link
Contributor

Yep. Fixing it. There's a missing condition on there actually being ResourceCopyLocalItems.

@nguerrera
Copy link
Contributor

#1360 (comment) is edited to include the fix. Sorry about that.

@nguerrera
Copy link
Contributor

Edited one more time. Should be good now. Sorry again.

@jaredpar
Copy link
Member

@nguerrera verified this works. Our build correctness leg is no longer flagging double writes and I manually verified the output directory contains the proper resource layout. Thanks!

@clairernovotny
Copy link

clairernovotny commented Jun 21, 2017

The MSBuild.Sdk.Extras package 1.0.4 contains this workaround too now. The existing workarounds for issues are now only included in when run on with 1.x SDK's, since I believe they've all been fixed in 2.0.
https://github.com/onovotny/MSBuildSdkExtras/blob/master/src/build/netstandard1.0/NetCoreSdk1Workarounds.targets

@AArnott
Copy link
Contributor Author

AArnott commented Jun 21, 2017

Thanks, @onovotny!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants