dotnet / sdk

Core functionality needed to create .NET Core projects, that is shared between Visual Studio and CLI
https://dot.net/core
MIT License
2.75k stars 1.07k forks source link

Transitive Project References without respect for ReferenceOutputAssembly #1764

Open KirillOsenkov opened 7 years ago

KirillOsenkov commented 7 years ago

\kirillo7\public\Bugs\SDK1764 contains two .binlog files that describe the problem.

We have a project Xamarin.Designer.Forms.Preview.csproj that includes this project reference:

    <ProjectReference Include="..\XamarinFormsPreviewer.Android\XamarinFormsPreviewer.Android.csproj">
      <Project>{2E28F5F9-4847-4644-B14D-6D3FEAAAFF67}</Project>
      <Name>XamarinFormsPreviewer.Android</Name>
      <ReferenceOutputAssembly>False</ReferenceOutputAssembly>
      <Private>False</Private>
    </ProjectReference>

We have another project, Xamarin.VisualStudio.Forms.Previewer.csproj which inherits that project reference transitively via the IncludeTransitiveProjectReferences target. Bringing this reference is undesired because it causes a C# compiler conflict (the type Foo is declared in both bar.dll and XamarinFormsPreviewer.Android.dll).

The bug is that the ReferenceOutputAssembly metadata is not preserved when adding that reference transitively.

We've tried different ways to turn that reference off:

Add an explicit <ProjectReference Include="..\XamarinFormsPreviewer.Android\XamarinFormsPreviewer.Android.csproj to the consuming project, and set the ReferenceOutputAssembly metadata to false on it. It didn't help because the target runs after evaluation and it adds another copy of the ProjectReference item which "wins" over the one we add. It could be because it uses different slashes (the one added transitively uses / for some reason, and the one we add uses \) but it could be a red herring and they don't unify even if slashes are identical.

However it works if you turn off the entire target: <Target Name="IncludeTransitiveProjectReference"></Target>

Good thing that Jared added this: https://github.com/dotnet/sdk/blob/8c5d7a7c5bfd3b3eba5cb5bde4339dda470bd39a/src/Tasks/Microsoft.NET.Build.Tasks/build/Microsoft.PackageDependencyResolution.targets#L482-L483

as an escape hatch.

However it'd be good if it preserved the metadata in the first place.

KirillOsenkov commented 7 years ago

cc @nguerrera @alanmcgovern

tgeng commented 5 years ago

We are having this same issue with a VSIX extension project that has some template projects (which does not generate dll as outputp). Basically we have three projects with dependencies like the following.

unit test -> VSIX project -> template project

The VSIX project builds fine but the unit test project does not build because it wants a dll file from the template project.

hknielsen commented 7 months ago

We are getting the same issue. Project:

a.csproj -> b.csproj(Private=false) -> c.csproj

When calling publish on a.csproj, c.csproj is still getting published, looking at the IncludeTransitiveProjectReferences Target it does not bubble up the Private metadata so the Publish can respect it.

hknielsen commented 7 months ago

Friendly ping to @rainersigwald as this issue seem pretty old. Wonder if theres some other solution we are missing here? :)