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

In conflict resolution, treat items from FrameworkList.xml as platform assemblies #1618

Merged

Conversation

dsplaisted
Copy link
Member

Fixes #1336

Tests still to come (though they will probably depend on the .NET 4.7.1 targeting pack, so they'll have to be disabled until it is released).

@ericstj @AlexGhiondea @nguerrera @AndyGerlicher @cdmihai for review

Version assemblyVersion;
if (string.IsNullOrEmpty(assemblyVersionString) || !Version.TryParse(assemblyVersionString, out assemblyVersion))
{
string errorMessage = string.Format(CultureInfo.InvariantCulture, Strings.ErrorParsingFrameworkListInvalidValue,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Messages shown to the user should be formatted with current culture

}

var frameworkList = XDocument.Load(frameworkListPath);
foreach (var file in frameworkList.Elements("File"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some framework lists chain to others. Critically, I believe Mono's are that way and this will need to work when targeting net471 with Mono msbuild.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took a look at this and it turns out that the GetReferenceAssemblyPaths target takes care of this. If there are chained framework lists, it will set TargetFrameworkDirectory to a semicolon-separated list of the chained folders. For example:

C:\Program Files %28x86%29\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\ReferenceAssemblies\Microsoft\Framework\MonoAndroid\v6.0;C:\Program Files %28x86%29\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\ReferenceAssemblies\Microsoft\Framework\MonoAndroid\v5.1;C:\Program Files %28x86%29\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\ReferenceAssemblies\Microsoft\Framework\MonoAndroid\v5.0;C:\Program Files %28x86%29\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\ReferenceAssemblies\Microsoft\Framework\MonoAndroid\v4.4.87;C:\Program Files %28x86%29\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\ReferenceAssemblies\Microsoft\Framework\MonoAndroid\v4.4;C:\Program Files %28x86%29\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\ReferenceAssemblies\Microsoft\Framework\MonoAndroid\v4.3;C:\Program Files %28x86%29\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\ReferenceAssemblies\Microsoft\Framework\MonoAndroid\v4.2;C:\Program Files %28x86%29\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\ReferenceAssemblies\Microsoft\Framework\MonoAndroid\v4.1;C:\Program Files %28x86%29\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\ReferenceAssemblies\Microsoft\Framework\MonoAndroid\v4.0.3;C:\Program Files %28x86%29\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\ReferenceAssemblies\Microsoft\Framework\MonoAndroid\v2.3;C:\Program Files %28x86%29\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\ReferenceAssemblies\Microsoft\Framework\MonoAndroid\v1.0;;;C:\Program Files %28x86%29\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\ReferenceAssemblies\Microsoft\Framework\MonoAndroid\v1.0\Facades\

However, the FrameworkList.xml files for Mono don't list any File entries. So I think we will need to scan the directory for assemblies to treat as platform assemblies if we don't find any File items listed in the FrameworkList.xml.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That could get expensive, if you do need to do that make sure you don't crack the assemblies at that point but instead create lazy items that point to the TargetFrameworkDirectory location.

I don't suppose MSBuild has an API built on top of their framework list / metadata cache?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ericstj Yes, that's the way I would do it. I'm not sure at this point whether we need this to apply to Xamarin/Mono.

The MSBuild API (the RedistList class) isn't public and doesn't have any way to get a list of the framework assemblies, only to check if a given assembly name is part of the framework. We could make an API for this public if we have to, but so far it doesn't look like we do.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yield return new ConflictItem(assemblyName + ".dll",
packageId: null,
assemblyVersion: assemblyVersion,
fileVersion: null);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra whitespace

@dsplaisted
Copy link
Member Author

@Pilchie for approval

Customer scenario

.NET Framework 4.7.1 projects which reference libraries targeting .NET Standard 1.x

Bugs this fixes

#1336

Workarounds, if any

n/a

Risk

Medium

Performance impact

TBD

Root cause analysis

.NET 4.7.1 ships with .NET Standard Facades in box, and as part of the reference assemblies. This requires some additional logic in order for the in-box versions to override the ones coming from NuGet.

How was the bug found?

Internal design

@Pilchie
Copy link
Member

Pilchie commented Oct 3, 2017

What is the state of the testing mentioned above?

Additionally, what can be done to mitigate performance concerns?

@dsplaisted
Copy link
Member Author

@Pilchie The PR includes tests, which are disabled for now because we don't have the .NET 4.7.1 targeting pack on the CI machines. I've run the tests locally and filed #1625 to enable them later.

As for perf, we could make a process-wide cache of the data we are reading, which is what MSBuild does. We could also update MSBuild to provide an API to get the list of assemblies in the framework along with the versions. MSBuild already reads and caches this file so that solution would have very little overhead.

@Pilchie
Copy link
Member

Pilchie commented Oct 3, 2017

I'm going to need some code reviewers to sign off on this before I can approve an escalate.

{
// This is not an error, as we get both the root target framework directory as well as the Facades folder passed in as TargetFrameworkDirectories.
// Only the root will have a RedistList\FrameworkList.xml in it
yield break;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider not using a yield enumerator if this is a hot path where allocations matter.

// Also treat assemblies from FrameworkList.xml as platform assemblies
if (TargetFrameworkDirectories != null && TargetFrameworkDirectories.Any())
{
platformItems = platformItems.Concat(TargetFrameworkDirectories.SelectMany(tfd =>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider not using SelectMany + Concat if this is a hot path where allocations matter.

Copy link
Contributor

@nguerrera nguerrera left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please file a bug to handle the Mono case. (I know you have offline discussions going on that, but it would be good to have a bug tracking what isn't handled in initial commit.)

@dsplaisted
Copy link
Member Author

@nguerrera I've filed #1627

@livarcocc livarcocc added this to the 15.5 milestone Oct 5, 2017
@dsplaisted dsplaisted closed this Oct 8, 2017
@nguerrera
Copy link
Contributor

Why did this get closed?

@dsplaisted
Copy link
Member Author

Why did this get closed?

Good question... I guess I misclicked (or maybe my daughter did :-) )

@dsplaisted
Copy link
Member Author

@MattGertz for approval. Ask mode template is here: #1618 (comment)

@MattGertz
Copy link

We are in Escrow. Please migrate to VSO bug -- thanks!

@livarcocc
Copy link
Contributor

@MattGertz
Copy link

Approved from my side. Escrow technically starts at 5PM tonight, but we likely can't get it in before then due to turnaround on signing, so I've submitted for Escrow in VSO.

@dsplaisted
Copy link
Member Author

@dotnet-bot test OSX10.12 Debug

@dsplaisted
Copy link
Member Author

@dotnet-bot test OSX10.12 Release

@@ -0,0 +1,124 @@
using FluentAssertions;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing copyright header

@dsplaisted dsplaisted merged commit 9e7c61c into dotnet:release/15.5 Oct 12, 2017

compilePlatformItems = TargetFrameworkDirectories.SelectMany(tfd =>
{
return frameworkListReader.GetConflictItems(Path.Combine(tfd.ItemSpec, "RedistList", "FrameworkList.xml"), log);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Return here is confusing, can you eliminate the curly braces?

dsplaisted added a commit to dsplaisted/sdk that referenced this pull request Oct 19, 2017
With dotnet#1618, conflict resolution now depends on TargetFrameworkDirectory property, and the
GetReferenceAssemblyPaths target to set it.  However, the custom FilterCopyLocal target in our
projects was causing GetReferenceAssemblyPaths to run before GetFrameworkPaths, and when
GetFrameworkPaths was subsequently run, it reset the TargetFrameworkDirectory property to
v4.0.30319.

This change adds a dependency to PrepareForBuild so that both targets run in the right
order.
JL03-Yue pushed a commit that referenced this pull request Mar 19, 2024
…df6-aca1-e570af2cc4d4

[release/6.x] Update dependencies from dotnet/roslyn
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants