-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Let roslyn generate reference assemblies from source projects and remove reference projects #58163
Comments
Tagging subscribers to this area: @Anipik, @safern, @ViktorHofer Issue DetailsPackages produce in NET6 and onwards don't contain reference assemblies anymore. The existing targeting packs Problem statementReference assemblies in dotnet/runtime are currently generated via dedicated reference projects which expose various downsides:
SolutionAs of time of writing, there are 227 libraries under To make this work, the following work needs to be done (in no particular order):
Partial façade assembliesFor the remaining 63 assemblies, It's yet unclear how to generate these type forwards without having a reference assembly available that represents the public API surface area. A possible solution to that could be to check in the type forwards, adding them to the compilation input and making sure that they are kept up-to-date. The problem with that is that Roslyn keeps passed-in type forward attributes in reference assemblies instead of following the type and replacing the attribute with the actual type. We should sync up with the Roslyn team to see if supporting this scenario is feasible. cc @danmoseley @jaredpar @ericstj @stephentoub @eerhardt
|
Contributes to dotnet#58163 This is a POC that demonstrates that most out-of-band reference projects in dotnet/runtime can be deleted. See reasoning in the linked issue. The remaining OOBs are more challenging as they are depend on the PNSE or PartialFacade infrastructure which itself depends on the reference source / reference assembly: System.Management (PNSE) System.Net.Http.WinHttpHandler (PNSE) System.Reflection.Context (PNSE) System.Security.Cryptography.Pkcs (Facade) System.Security.Cryptography.ProtectedData (Facade + PNSE) System.Security.Cryptography.Xml (Facade) System.Security.Permissions (Facade) System.ServiceModel.Syndication (Facade) System.ServiceProcess.ServiceController (Facade + PNSE) System.Speech (PNSE) System.Threading.AccessControl (Facade + PNSE) System.Windows.Extensions (PNSE)
Contributes to #58163 - Remove unused reference assembly projects and move the forwards.cs files into the src folder. - Don't rely on IsPartialFacadeAssembly switch anymore which makes it possible to use the compiler generated xml file and removes the dependency on the reference source project. - Enable package baseline validation for Microsoft.Bcl.Numerics This improves restore and build perf in total as well as per leaf project on the CLI and inside VS.
…105312) * Remove unused reference assembly projects from Bcl folders Contributes to #58163 - Remove unused reference assembly projects and move the forwards.cs files into the src folder. - Don't rely on IsPartialFacadeAssembly switch anymore which makes it possible to use the compiler generated xml file and removes the dependency on the reference source project. - Enable package baseline validation for Microsoft.Bcl.Numerics This improves restore and build perf in total as well as per leaf project on the CLI and inside VS. * Update project references - Update projects that now need to reference the src project as the ref project got deleted. - Remove target that validates that ref projects only reference ref project. That target doesn't make sense anymore with our direction towards removing reference assembly projects.
Packages produced by dotnet/runtime targeting NET6 and upwards don't contain reference assemblies anymore. The existing targeting packs
Microsoft.NETCore.App.Ref
,Microsoft.AspNetCore.App.Ref
andMicrosoft.WindowsDesktop.App.Ref
are the only shipping assets which still contain reference assemblies (by design). That said, reference assemblies are general goodness as leveraging them improves incremental build performance which is why they are emitted by the SDK by default since .NET 5.Problem statement
Reference assemblies in dotnet/runtime are currently generated via dedicated reference projects which expose various downsides:
Microsoft.Extensions.*
don't ship to customers anymore as they aren't part of the generated packages. Their sole purpose today is infrastructure only needs (ApiCompat and GenFacades).Microsoft.NET.Sdk
project), they contribute to the overall restore performance. NuGet creates intermediate files per project and tfm: i.e.project.assets.json
,$(MSBuildProjectName).nuget.g.props
,$(MSBuildProjectName).nuget.g.targets
. Removing reference projects will result in a faster repo per project restore, as less computation (traversing the graph) and less IO operations are necessary.Solution
As of time of writing, there are 227 libraries under
src/libraries
and 63 of those are partial or full façade assemblies. Presumably, the 164 libraries which don't use GenFacade's<IsPartialFacadeAssembly />
feature could leverage Roslyn's RefOut feature to generate reference assemblies as a secondary build output of the source project.To make this work, the following work needs to be done (in no particular order):
src\$(MSBuildProjectName).$(TargetFramework).ref.cs
and exclude that file from being added as a compile source when the<EnableDefaultItems />
or<EnableDefaultCompileItems />
properties are set to true. Update the bot which warns about public API changes to also watch for changes in that location.Partial façade assemblies
For the remaining 63 assemblies,
GenFacades
is used to add type forward attributes to the project's compilation input (via a generatedCompile
item) for public API that is missing from the compilation sources, but which is available in any of the referenced assemblies (ReferencePath
). Missing is defined as an API that is available in the reference assembly but not in the implementation compilation sources.As an example, the
System.AppContext
type is exposed in the System.Runtime.dll reference assembly but its implementation is found in System.Private.CoreLib.dll and not in the System.Runtime.dll implementation assembly. The implementation assembly instead contains a type forward attribute that indicates that the type is exposed in another assembly.It's yet unclear how to generate these type forwards without having a reference assembly available that represents the public API surface area. A possible solution to that could be to check in the type forwards, adding them to the compilation input and making sure that they are kept up to date. The problem with that is that Roslyn keeps passed-in type forward attributes in reference assemblies instead of following the type and replacing the attribute with the actual type. We should sync up with the Roslyn team to see if supporting this scenario is feasible.
PlatformNotSupportedException assemblies (PNSEs)
Some libraries generate
PlatformNotSupportedException
assemblies (via one of these two switches). The PNSE logic takes the reference project's source files as an input and transforms them to throw PNSEs instead of returning null.It's yet unclear which input would be used without a reference project being existent. One option would be to feed in the generated reference source (which only acts as an output) as an input to keep the existing logic as-is. The obvious downside of that is that the PNSE logic would depend on the reference source file being up-to-date, which only other inner builds (which run in parallel) make sure of.
Alternatively the TFM that is responsible for generating the PNSE could leverage the
RefOnly
Roslyn switch to generate the reference assembly only, generate the reference source file from it and then invoke the existing PNSE logic an feed in that just generated reference source file. Ideally we would not depend on the reference source file which is considered as an output, at all and explore if it's possible to use the linker to transform the reference assembly to a PNSE one.Public API differences
There is a list of public APIs that is intentionally different between the reference and the runtime assemblies. The major difference for all libraries is that the following set of attributes is not exposed in the reference assemblies: https://github.com/dotnet/runtime/blob/main/eng/DefaultGenApiDocIds.txt.
In addition to that, libraries exist which differ in other public APIs as well, i.e. for System.Runtime: https://github.com/dotnet/runtime/blob/main/src/libraries/System.Runtime/src/MatchingRefApiCompatBaseline.txt.
To being able to leverage Roslyn to generate the reference assemblies, we would need to make it possible to exclude these APIs from the reference assembly.
cc @danmoseley @jaredpar @ericstj @stephentoub @eerhardt
The text was updated successfully, but these errors were encountered: