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

Add step to run linker on entire runtime pack during libraries build #40172

Merged
merged 8 commits into from
Aug 4, 2020

Conversation

layomia
Copy link
Contributor

@layomia layomia commented Jul 31, 2020

Contributes to #38033.

The next step following this PR is to suppress individual warnings using baseline xml files. This can be done following dotnet/linker#1386.

cc @mateoatr @vitek-karas @MichalStrehovsky @sbomer

@layomia layomia added this to the 5.0.0 milestone Jul 31, 2020
@layomia layomia requested review from eerhardt and safern July 31, 2020 00:49
@layomia layomia self-assigned this Jul 31, 2020
@ghost
Copy link

ghost commented Jul 31, 2020

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

eng/illink.targets Outdated Show resolved Hide resolved
eng/illink.targets Outdated Show resolved Hide resolved
eng/illink.targets Outdated Show resolved Hide resolved
src/libraries/pretest.proj Outdated Show resolved Hide resolved
@ViktorHofer ViktorHofer requested a review from ericstj July 31, 2020 13:10
eng/illink.targets Outdated Show resolved Hide resolved
eng/Configurations.props Outdated Show resolved Hide resolved
eng/illink.targets Outdated Show resolved Hide resolved
@marek-safar
Copy link
Contributor

Will this obsolete linker run on individual libraries?

@eerhardt
Copy link
Member

eerhardt commented Aug 3, 2020

Will this obsolete linker run on individual libraries?

No, it doesn't. We still run the linker on individual libraries, and that is what ships in the runtimepack. See #39133 (comment). And the reasoning why we still run the linker on the individual libraries is listed in #31712.

@marek-safar
Copy link
Contributor

No, it doesn't. We still run the linker on individual libraries, and that is what ships in the runtimepack.

Does it mean we won't get correct warnings for the scenarios which use linker by default?

@eerhardt
Copy link
Member

eerhardt commented Aug 3, 2020

Does it mean we won't get correct warnings for the scenarios which use linker by default?

I'm not sure I follow this question. Can you elaborate?

The scenarios which use linker by default will use the assemblies that are contained in the runtimepack. This change is to pass those same libraries into the linker, now with warnings enabled.

So we are running the linker in 2 different locations during the dotnet/runtime build. Once when building the individual library, like we have always been - warnings disabled. Once at the end of the build against the whole runtimepack - warnings enabled.

eng/illink.targets Outdated Show resolved Hide resolved
-->
<ILLinkArgs>$(ILLinkArgs) --nowarn IL2006;IL2008;IL2009;IL2012;IL2025;IL2026;IL2035;IL2041</ILLinkArgs>
<ILLinkArgs>$(ILLinkArgs) --nowarn IL2006;IL2008;IL2009;IL2012;IL2025;IL2026;IL2035;IL2050</ILLinkArgs>
Copy link
Member

Choose a reason for hiding this comment

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

Why the change from IL2041 to IL2050? Nothing in this change should have changed what warnings are produced for the individual library build. So I think both 2041 and 2050 can be removed here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I started getting 2050 after syncing with master at the beginning of this PR. Some new code since the initial suppressions check in must have been added which causes these errors:

ILLink : error IL2050: System.Runtime.InteropServices.Marshal.CreateBindCtx(UInt32,IBindCtx&): P/invoke method 'System.Runtime.InteropServices.Marshal.CreateBindCtx(UInt32,IBindCtx&)' declares a parameter with COM marshalling. Correctness of COM interop cannot be guaranteed after trimming. Interfaces and interface members might be removed. [D:\repos\dotnet_runtime_2\src\coreclr\src\System.Private.CoreLib\System.Private.CoreLib.csproj]
ILLink : error IL2050: System.Runtime.InteropServices.Marshal.CreateBindCtx(UInt32,IBindCtx&): P/invoke method 'System.Runtime.InteropServices.Marshal.CreateBindCtx(UInt32,IBindCtx&)' declares a parameter with COM marshalling. Correctness of COM interop cannot be guaranteed after trimming. Interfaces and interface members might be removed. [D:\repos\dotnet_runtime_2\src\coreclr\src\System.Private.CoreLib\System.Private.CoreLib.csproj]
ILLink : error IL2050: System.Runtime.InteropServices.Marshal.MkParseDisplayName(IBindCtx,String,UInt32&,IMoniker&): P/invoke method 'System.Runtime.InteropServices.Marshal.MkParseDisplayName(IBindCtx,String,UInt32&,IMoniker&)' declares a parameter with COM marshalling. Correctness of COM interop cannot be guaranteed after trimming. Interfaces and interface members might be removed. [D:\repos\dotnet_runtime_2\src\coreclr\src\System.Private.CoreLib\System.Private.CoreLib.csproj]
ILLink : error IL2050: System.Runtime.InteropServices.Marshal.MkParseDisplayName(IBindCtx,String,UInt32&,IMoniker&): P/invoke method 'System.Runtime.InteropServices.Marshal.MkParseDisplayName(IBindCtx,String,UInt32&,IMoniker&)' declares a parameter with COM marshalling. Correctness of COM interop cannot be guaranteed after trimming. Interfaces and interface members might be removed. [D:\repos\dotnet_runtime_2\src\coreclr\src\System.Private.CoreLib\System.Private.CoreLib.csproj]
ILLink : error IL2050: System.Runtime.InteropServices.Marshal.BindMoniker(IMoniker,UInt32,Guid&,Object&): P/invoke method 'System.Runtime.InteropServices.Marshal.BindMoniker(IMoniker,UInt32,Guid&,Object&)' declares a parameter with COM marshalling. Correctness of COM interop cannot be guaranteed after trimming. Interfaces and interface members might be removed. [D:\repos\dotnet_runtime_2\src\coreclr\src\System.Private.CoreLib\System.Private.CoreLib.csproj]
ILLink : error IL2050: System.Runtime.InteropServices.Marshal.BindMoniker(IMoniker,UInt32,Guid&,Object&): P/invoke method 'System.Runtime.InteropServices.Marshal.BindMoniker(IMoniker,UInt32,Guid&,Object&)' declares a parameter with COM marshalling. Correctness of COM interop cannot be guaranteed after trimming. Interfaces and interface members might be removed. [D:\repos\dotnet_runtime_2\src\coreclr\src\System.Private.CoreLib\System.Private.CoreLib.csproj]
ILLink : error IL2050: Microsoft.VisualBasic.CompilerServices.UnsafeNativeMethods.VarNumFromParseNum(Byte[],Byte[],Int32): P/invoke method 'Microsoft.VisualBasic.CompilerServices.UnsafeNativeMethods.VarNumFromParseNum(Byte[],Byte[],Int32)' declares a parameter with COM marshalling. Correctness of COM interop cannot be guaranteed after trimming. Interfaces and interface members might be removed. [D:\repos\dotnet_runtime_2\src\libraries\Microsoft.VisualBasic.Core\src\Microsoft.VisualBasic.Core.vbproj]
ILLink : error IL2050: Microsoft.VisualBasic.CompilerServices.UnsafeNativeMethods.VarNumFromParseNum(Byte[],Byte[],Int32): P/invoke method 'Microsoft.VisualBasic.CompilerServices.UnsafeNativeMethods.VarNumFromParseNum(Byte[],Byte[],Int32)' declares a parameter with COM marshalling. Correctness of COM interop cannot be guaranteed after trimming. Interfaces and interface members might be removed. [D:\repos\dotnet_runtime_2\src\libraries\Microsoft.VisualBasic.Core\src\Microsoft.VisualBasic.Core.vbproj]
ILLink : error IL2050: Microsoft.VisualBasic.CompilerServices.UnsafeNativeMethods.VariantChangeType(Object&,Object&,Int16,Int16): P/invoke method 'Microsoft.VisualBasic.CompilerServices.UnsafeNativeMethods.VariantChangeType(Object&,Object&,Int16,Int16)' declares a parameter with COM marshalling. Correctness of COM interop cannot be guaranteed after trimming. Interfaces and interface members might be removed. [D:\repos\dotnet_runtime_2\src\libraries\Microsoft.VisualBasic.Core\src\Microsoft.VisualBasic.Core.vbproj]
ILLink : error IL2050: Microsoft.VisualBasic.CompilerServices.UnsafeNativeMethods.VariantChangeType(Object&,Object&,Int16,Int16): P/invoke method 'Microsoft.VisualBasic.CompilerServices.UnsafeNativeMethods.VariantChangeType(Object&,Object&,Int16,Int16)' declares a parameter with COM marshalling. Correctness of COM interop cannot be guaranteed after trimming. Interfaces and interface members might be removed. [D:\repos\dotnet_runtime_2\src\libraries\Microsoft.VisualBasic.Core\src\Microsoft.VisualBasic.Core.vbproj]
    0 Warning(s)
    10 Error(s)

2041 doesn't show up anymore following the sync hence removed.

Copy link
Member

Choose a reason for hiding this comment

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

Looks like that came in last week with dotnet/linker#1382.

cc @MichalStrehovsky

Copy link
Member

Choose a reason for hiding this comment

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

Yes, we now detect COM usage and mark it as unsafe. Apps that end up referencing these methods after trimming will always warn.

@marek-safar
Copy link
Contributor

So we are running the linker in 2 different locations during the dotnet/runtime build. Once when building the individual library, like we have always been - warnings disabled. Once at the end of the build against the whole runtimepack - warnings enabled.

Running linker against the whole runtime pack will produce different output than running linker when building individual libraries? Why are we doing the first run which is now redundant and only slows down the build?

<ILLinkArgs>$(ILLinkArgs) --nowarn IL2006;IL2009;IL2025;IL2026;IL2035;IL2050</ILLinkArgs>
</PropertyGroup>

<!-- Retrieve CoreLib's targetpath via GetTargetPath as it isn't binplaced yet. -->
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure I understand this. Why can't we use $(MicrosoftNetCoreAppRuntimePackNativeDir) instead?

Copy link
Contributor Author

@layomia layomia Aug 4, 2020

Choose a reason for hiding this comment

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

$(MicrosoftNetCoreAppRuntimePackNativeDir) does not have S.P.CoreLib present when the new target is running. @safern's thought on it was that the directory gets populated in pretest.proj as a preparation for being able to run tests.

fwiw, wasm.targets takes a similar approach -

<!-- Retrieve CoreLib's targetpath via GetTargetPath as it isn't binplaced yet. -->
<MSBuild Projects="$(CoreLibProject)"
Targets="GetTargetPath">
<Output TaskParameter="TargetOutputs" ItemName="WasmPInvokeAssembly" />
</MSBuild>
.

Copy link
Member

Choose a reason for hiding this comment

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

My naive thinking is that there should be somewhere in the build (that doesn't rely on tests) that we can hook in where the entire runtimepack is built. But I'm not seeing where that place is. Maybe @safern @ViktorHofer @joperezr or @ericstj might know.

But for now, what you have works so let's go with that.

Copy link
Member

Choose a reason for hiding this comment

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

SPC and the runtime gets binplaced into libraries runtime pack and testhost as part of runtime.depproj.

Runtime.depproj is built as part of pretest.proj which is the last step of the libs subset. Which happens after libs.src that is the subset that builds src.proj. That is why wasm.targets also follows that approach.

FWIW we could introduce a common target to get SPC target path instead of duplicating the logic to call MSBuild on it with GetTargetPath target.

Copy link
Member

Choose a reason for hiding this comment

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

FWIW we could introduce a common target to get SPC target path instead of duplicating the logic to call MSBuild on it with GetTargetPath target.

It feels to me that the correct fix here would be to fully populate the runtimepack earlier, and not make it dependent on testing.

Copy link
Member

Choose a reason for hiding this comment

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

It feels to me that the correct fix here would be to fully populate the runtimepack earlier, and not make it dependent on testing.

I agree with @eerhardt, we have talked about this couple times already. I believe we should binplace the runtime artifacts incrementally after they are built (CoreLib, coreclr.dll, etc). For CI we just need a target that re-binplaces the runtime artifacts (to preserve the existing behavior which allows to build coreclr and libraries in parallel).

The reason why having the runtime binplace at pretest is handy, is for inner loop development. For example if I update code in SPC after a vertical build, in order to run tests against the new SPC, I don't have to do a full libraries vertical, I can just do: build libs.pretest -rc

I don't understand why binplacing the runtime artifacts in pretest is handy for inner loop development instead of binplacing the runtime assets at the time they are (re-)built, which doesn't require a libraries rebuild.

Copy link
Member

Choose a reason for hiding this comment

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

I don't understand why binplacing the runtime artifacts in pretest is handy for inner loop development instead of binplacing the runtime assets at the time they are (re-)built, which doesn't require a libraries rebuild.

We've also talked about this a couple of times. If you build for example System.Runtime which has a P2P to SPC, and don't specify RuntimeConfiguration as an argument you would potentially be binplacing a Debug build of SPC when probably you built the runtime for release, this could cause a mismatch in between the native bits and the managed bits of coreclr which is not recommended:
#38885 (comment)

So we should be careful on how we do that.

Copy link
Member

@safern safern Aug 4, 2020

Choose a reason for hiding this comment

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

Btw, I agree we should change this if possible, I'm just saying we should be really careful how and where we put this binplacing to happen.

Also, I wouldn't like removing the build.pretest binplacing the runtime as it is handy for CI as well as I explained above... if we remove that, then provide another hook to binplace the runtime as an individual step.

Copy link
Member

Choose a reason for hiding this comment

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

We've also talked about this a couple of times. If you build for example System.Runtime which has a P2P to SPC, and don't specify RuntimeConfiguration as an argument you would potentially be binplacing a Debug build of SPC when probably you built the runtime for release, this could cause a mismatch in between the native bits and the managed bits of coreclr which is not recommended:
#38885 (comment)
Btw, I agree we should change this if possible, I'm just saying we should be really careful how and where we put this binplacing to happen.

I think we all agree that we should change when we binplace the runtime artifacts and I agree that it should be done with the highest diligence. We should do this as part of #38034.

Also, I wouldn't like removing the build.pretest binplacing the runtime as it is handy for CI as well as I explained above... if we remove that, then provide another hook to binplace the runtime as an individual step.

That's what I meant with:

For CI we just need a target that re-binplaces the runtime artifacts (to preserve the existing behavior which allows to build coreclr and libraries in parallel).

Copy link
Member

Choose a reason for hiding this comment

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

That's what I meant with:

I somehow missed that part 🤦

We should do this as part of #38034.

Sounds good.

@eerhardt
Copy link
Member

eerhardt commented Aug 4, 2020

Running linker against the whole runtime pack will produce different output than running linker when building individual libraries?

Yes, it will produce different warnings. Please read the discussion here #39133 (comment).

Why are we doing the first run which is now redundant and only slows down the build?

It is not redundant. Please see read the discussion in #31712 for why we are doing the first run.

Copy link
Member

@eerhardt eerhardt left a comment

Choose a reason for hiding this comment

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

:shipit:

@layomia layomia merged commit d7506e7 into dotnet:master Aug 4, 2020
@layomia layomia deleted the link_runtimepack branch August 4, 2020 18:43
@ViktorHofer
Copy link
Member

Curious, how much time does this additional step take?

@@ -49,6 +49,9 @@
Properties="$(TraversalGlobalProperties)" />
</Target>

<Import Condition="'$(BuildTargetFramework)' == '$(NetCoreAppCurrent)'"
Copy link
Member

Choose a reason for hiding this comment

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

nit: "$(BuildNetCoreAppVertical) == true"

Copy link
Contributor Author

@layomia layomia Aug 7, 2020

Choose a reason for hiding this comment

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

The BuildNetCoreAppVertical property does not appear to be set at this point in the build.

Copy link
Member

@ViktorHofer ViktorHofer left a comment

Choose a reason for hiding this comment

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

Curious, what are planning to do with the trimmed assemblies in LibrariesTrimmedArtifactsPath?

@eerhardt
Copy link
Member

eerhardt commented Aug 4, 2020

Curious, what are planning to do with the trimmed assemblies in LibrariesTrimmedArtifactsPath?

For now, we throw them away - they aren't used. We are only running the linker to get the warnings/analysis.

@layomia
Copy link
Contributor Author

layomia commented Aug 5, 2020

@ViktorHofer, thanks for the feedback. I'll address them shortly in a follow up PR.

@layomia
Copy link
Contributor Author

layomia commented Aug 7, 2020

Curious, how much time does this additional step take?

A local run took 13.366s.

layomia added a commit to layomia/dotnet_runtime that referenced this pull request Aug 7, 2020
layomia added a commit that referenced this pull request Aug 7, 2020
Jacksondr5 pushed a commit to Jacksondr5/runtime that referenced this pull request Aug 10, 2020
…otnet#40172)

* Add step to run linker on entire runtime pack during libraries build

* Address feedback

* Only run for NetCoreAppCurrent

* Include appropriate S.P.CoreLib

* Address review feedback

* Add common property group for shared linker args; remove unneeded changes from PR

* Rename illink-sharedframeworks.targets to illink-sharedframework.targets

* Address review feedback
Jacksondr5 pushed a commit to Jacksondr5/runtime that referenced this pull request Aug 10, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 8, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants