Skip to content

Commit

Permalink
Cleanup GenFacades logic and don't bind against non-shipping contract…
Browse files Browse the repository at this point in the history
… assemblies (dotnet#78703)

* Clean-up the ApiCompat and GenAPI logic

* Fix System.DirectoryServices.AccountManagement build

System.DirectoryServices.AccountManagement now builds against
src/System.DirectoryServices instead of ref/System.DirectoryServices
(because the package doesn't contain the ref assembly).

Because of that, the compiler now gets confused because of the
System.DirectoryServices.Interop namespace and the global Interop class.
This happens even though the DirectoryServices.Interop namespace doesn't include any
public types.

That results in the following erros:
src\libraries\System.DirectoryServices.AccountManagement\src\System\DirectoryServices\AccountManagement\AD\SidList.cs(50,26): error CS0246: The type or namespace name 'SID_AND_ATTRIBUTES' could not be found (are you missing a using directive or an assembly reference?)
src\libraries\System.DirectoryServices.AccountManagement\src\System\DirectoryServices\AccountManagement\interopt.cs(439,20): error CS0246: The type or namespace name 'UNICODE_INTPTR_STRING' could not be found (are you missing a using directive or an assembly reference?)

This commit fixes that by removing the System.DirectoryServices.Interop
namespace and moving the types into the parent namespace.

* Suppress nullable warnings in Serialization.Schema

Now that Schema compiles against the source assembly of System.CodeDom,
it receives nullability errors. I'm suppressing them manually for now
but am filing an issue to correctly fix those.

Related: dotnet#78036

* Move SkipUseReferenceAssembly target up
  • Loading branch information
ViktorHofer committed Nov 22, 2022
1 parent a8e2b6e commit c8503d3
Show file tree
Hide file tree
Showing 39 changed files with 147 additions and 134 deletions.
4 changes: 2 additions & 2 deletions eng/Version.Details.xml
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,9 @@
<Uri>https://github.com/dotnet/arcade</Uri>
<Sha>80b6be47e1425ea90c5febffac119250043a0c92</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.GenFacades" Version="8.0.0-beta.22554.2">
<Dependency Name="Microsoft.DotNet.GenFacades" Version="8.0.0-beta.22572.2">
<Uri>https://github.com/dotnet/arcade</Uri>
<Sha>80b6be47e1425ea90c5febffac119250043a0c92</Sha>
<Sha>fc4ba340496ca0e45d51914f8f1606c60e3c75c6</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.XUnitExtensions" Version="8.0.0-beta.22554.2">
<Uri>https://github.com/dotnet/arcade</Uri>
Expand Down
2 changes: 1 addition & 1 deletion eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
<MicrosoftDotNetBuildTasksFeedVersion>8.0.0-beta.22554.2</MicrosoftDotNetBuildTasksFeedVersion>
<MicrosoftDotNetCodeAnalysisVersion>8.0.0-beta.22554.2</MicrosoftDotNetCodeAnalysisVersion>
<MicrosoftDotNetGenAPIVersion>8.0.0-beta.22554.2</MicrosoftDotNetGenAPIVersion>
<MicrosoftDotNetGenFacadesVersion>8.0.0-beta.22554.2</MicrosoftDotNetGenFacadesVersion>
<MicrosoftDotNetGenFacadesVersion>8.0.0-beta.22572.2</MicrosoftDotNetGenFacadesVersion>
<MicrosoftDotNetXUnitExtensionsVersion>8.0.0-beta.22554.2</MicrosoftDotNetXUnitExtensionsVersion>
<MicrosoftDotNetXUnitConsoleRunnerVersion>2.5.1-beta.22554.2</MicrosoftDotNetXUnitConsoleRunnerVersion>
<MicrosoftDotNetBuildTasksArchivesVersion>8.0.0-beta.22554.2</MicrosoftDotNetBuildTasksArchivesVersion>
Expand Down
20 changes: 20 additions & 0 deletions eng/references.targets
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,26 @@
</ItemGroup>
</Target>

<!-- Allows building against source assemblies when the 'SkipUseReferenceAssembly' attribute is present on ProjectReference items. -->
<Target Name="HandleReferenceAssemblyAttributeForProjectReferences"
AfterTargets="ResolveProjectReferences"
BeforeTargets="FindReferenceAssembliesForReferences"
Condition="'@(ProjectReference)' != '' and '@(_ResolvedProjectReferencePaths)' != ''">
<!-- If we have a ProjectReference to CoreLib, we need to compile against implementation assemblies. -->
<PropertyGroup Condition="@(_ResolvedProjectReferencePaths->AnyHaveMetadataValue('MSBuildSourceProjectFile', '$(CoreLibProject)'))">
<CompileUsingReferenceAssemblies Condition="'$(CompileUsingReferenceAssemblies)' == ''">false</CompileUsingReferenceAssemblies>
</PropertyGroup>
<!-- Clear the ReferenceAssembly attribute on resolved P2Ps that set SkipUseReferenceAssembly to true. -->
<ItemGroup>
<_resolvedP2PFiltered Include="@(ProjectReference)"
ProjectReferenceItemSpec="$([System.IO.Path]::GetFullPath('%(ProjectReference.Identity)'))"
SkipUseReferenceAssembly="%(ProjectReference.SkipUseReferenceAssembly)" />
<_ResolvedProjectReferencePaths Condition="'%(_resolvedP2PFiltered.ProjectReferenceItemSpec)' == '%(_resolvedP2PFiltered.MSBuildSourceProjectFile)' and
'%(_resolvedP2PFiltered.SkipUseReferenceAssembly)' == 'true'"
ReferenceAssembly="" />
</ItemGroup>
</Target>

<ItemDefinitionGroup>
<TargetPathWithTargetPlatformMoniker>
<IsReferenceAssemblyProject>$(IsReferenceAssemblyProject)</IsReferenceAssemblyProject>
Expand Down
14 changes: 0 additions & 14 deletions eng/resolveContract.props

This file was deleted.

128 changes: 73 additions & 55 deletions eng/resolveContract.targets
Original file line number Diff line number Diff line change
@@ -1,20 +1,72 @@
<Project>
<!--
##### Contract project settings #####
- Allows referencing contract projects for passing matching reference assemblies to tooling like ApiCompat.
- Allows building against contract assemblies when referencing source projects.
-->

<PropertyGroup>
<ContractProject Condition="'$(ContractProject)' == ''">$(LibrariesProjectRoot)$(MSBuildProjectName)\ref\$(MSBuildProjectName).csproj</ContractProject>
<HasMatchingContract Condition="'$(HasMatchingContract)' == '' and Exists('$(ContractProject)')">true</HasMatchingContract>
<!-- Don't build against reference assemblies when projects are packable and the tfm is not the latest .NETCoreApp as
such reference assemblies don't ship to customers and only exist for tooling scenarios. -->
<AnnotateTargetPathWithContract Condition="'$(AnnotateTargetPathWithContract)' == '' and
'$(HasMatchingContract)' == 'true' and
(
'$(IsPackable)' != 'true' or
(
'$(TargetFrameworkIdentifier)' == '.NETCoreApp' and
'$(TargetFrameworkVersion)' == 'v$(NetCoreAppCurrentVersion)'
)
)">true</AnnotateTargetPathWithContract>
</PropertyGroup>

<ItemGroup Condition="'$(HasMatchingContract)' == 'true' and '$(ContractProject)' != ''">
<ProjectReference Include="$(ContractProject)" ReferenceOutputAssembly="false" OutputItemType="ResolvedMatchingContract" />
<!-- We aren't referencing the contract, but make sure it's considered as an input to Compile so that if it changes we rebuild and rerun API compat -->
<ProjectReference Include="$(ContractProject)" ReferenceOutputAssembly="false" OutputItemType="CustomAdditionalCompileInputs" />
</ItemGroup>

<!-- Allow P2Ps that target a source project to build against the corresponding ref project. -->
<Target Name="AnnotateTargetPathWithTargetPlatformMonikerWithReferenceAssembly"
Condition="'$(AnnotateTargetPathWithContract)' == 'true'"
DependsOnTargets="ResolveProjectReferences"
AfterTargets="GetTargetPathWithTargetPlatformMoniker">
<ItemGroup>
<TargetPathWithTargetPlatformMoniker ReferenceAssembly="@(ResolvedMatchingContract)" />
</ItemGroup>
</Target>

<!-- ##### APICompat settings ##### -->

<PropertyGroup>
<ApiCompatContractItemName>ResolvedMatchingContract</ApiCompatContractItemName>
<ApiCompatStrictMode Condition="'$(ApiCompatStrictMode)' == ''">true</ApiCompatStrictMode>

<!-- Optional rules -->
<ApiCompatEnableRuleAttributesMustMatch>true</ApiCompatEnableRuleAttributesMustMatch>
<ApiCompatEnableRuleCannotChangeParameterName>true</ApiCompatEnableRuleCannotChangeParameterName>

<_ApiCompatCaptureGroupPattern>.+%5C$([System.IO.Path]::DirectorySeparatorChar)(.+)%5C$([System.IO.Path]::DirectorySeparatorChar)(.+)</_ApiCompatCaptureGroupPattern>
<_ApiCompatRuntimePrefixPattern>(.+)/(net%5Cd.%5Cd)-(.+)/(.+)</_ApiCompatRuntimePrefixPattern>
<_ApiCompatLibReplacementString>lib/$1/$2</_ApiCompatLibReplacementString>
<!-- CoreLib source projects have different output paths. -->
<_ApiCompatLibReplacementString Condition="'$(MSBuildProjectName)' == 'System.Private.CoreLib'">lib/$(NetCoreAppCurrent)/$2</_ApiCompatLibReplacementString>
</PropertyGroup>

<GenAPIExcludeAttributesList>$(RepositoryEngineeringDir)DefaultGenApiDocIds.txt</GenAPIExcludeAttributesList>
<GenAPIHeaderFile>$(RepositoryEngineeringDir)LicenseHeader.txt</GenAPIHeaderFile>
<GenAPITargetPath>$([MSBuild]::NormalizePath('$(MSBuildProjectDirectory)', '..', 'ref', '$(AssemblyName).cs'))</GenAPITargetPath>
<GenAPILangVersion Condition="'$(LangVersion)' != ''">$(LangVersion)</GenAPILangVersion>
<ProjectForGenAPIDocIdGeneration Condition="'$(IsSourceProject)' == 'true' and '$(ProjectForGenAPIDocIdGeneration)' == ''">$(CoreLibProject)</ProjectForGenAPIDocIdGeneration>
<PropertyGroup Condition="'$(IsCrossTargetingBuild)' != 'true'">
<!-- Disable API compat if the project doesn't have a reference assembly. -->
<ApiCompatValidateAssemblies Condition="'$(HasMatchingContract)' != 'true'">false</ApiCompatValidateAssemblies>
<!-- TODO: Move into Microsoft.DotNet.GenFacadesNotSupported.targets. -->
<!-- Not supported sources are created from the ref assembly, we currently don't produce finalizers in dummy assemblies, so we disable ApiCompat to not fail. -->
<ApiCompatValidateAssemblies Condition="'$(GeneratePlatformNotSupportedAssemblyMessage)' != ''">false</ApiCompatValidateAssemblies>
</PropertyGroup>

<ItemGroup>
<ApiCompatExcludeAttributesFile Include="$(RepositoryEngineeringDir)DefaultGenApiDocIds.txt" />
<ApiCompatExcludeAttributesFile Include="$(RepositoryEngineeringDir)ApiCompatExcludeAttributes.txt" />
</ItemGroup>

<ItemGroup>
<!-- Transform the API Compat assemblies passed in to log-able strings. -->
<ApiCompatLeftAssembliesTransformationPattern Include="$(_ApiCompatCaptureGroupPattern)" ReplacementString="ref/$1/$2" />
Expand All @@ -30,64 +82,30 @@
Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', '$(NetCoreAppCurrent)'))" />
</ItemGroup>

<PropertyGroup Condition="'$(IsSourceProject)' == 'true'">
<ContractProject Condition="'$(ContractProject)' == ''">$(LibrariesProjectRoot)$(MSBuildProjectName)\ref\$(MSBuildProjectName).csproj</ContractProject>
<HasMatchingContract Condition="'$(HasMatchingContract)' == '' and Exists('$(ContractProject)')">true</HasMatchingContract>
</PropertyGroup>

<PropertyGroup Condition="'$(IsSourceProject)' == 'true' and '$(IsCrossTargetingBuild)' != 'true'">
<!-- Disable API compat if the project doesn't have reference assembly -->
<ApiCompatValidateAssemblies Condition="'$(HasMatchingContract)' != 'true'">false</ApiCompatValidateAssemblies>
<!-- TODO: Move into Microsoft.DotNet.GenFacadesNotSupported.targets. -->
<!-- Not supported sources are created from the ref assembly, we currently don't produce finalizers in dummy assemblies, so we disable ApiCompat to not fail. -->
<ApiCompatValidateAssemblies Condition="'$(GeneratePlatformNotSupportedAssemblyMessage)' != ''">false</ApiCompatValidateAssemblies>
</PropertyGroup>

<!-- Use the apicompat task package instead of the in-built SDK functionality to consume newer features. -->
<ItemGroup Condition="'$(EnablePackageValidation)' == 'true' or
'$(ApiCompatValidateAssemblies)' == 'true'">
<PackageReference Include="Microsoft.DotNet.ApiCompat.Task" Version="$(MicrosoftDotNetApiCompatTaskVersion)" PrivateAssets="all" IsImplicitlyDefined="true" />
</ItemGroup>

<ItemGroup Condition="'$(HasMatchingContract)' == 'true' and '$(ContractProject)' != '' and '@(ResolvedMatchingContract)' == ''">
<ProjectReference Include="$(ContractProject)" ReferenceOutputAssembly="false" OutputItemType="ResolvedMatchingContract" />
<!-- We aren't referencing the contract, but make sure it's considered as an input to Compile so that if it changes we rebuild and rerun API compat -->
<ProjectReference Include="$(ContractProject)" ReferenceOutputAssembly="false" OutputItemType="CustomAdditionalCompileInputs" />
</ItemGroup>
<!-- intentionally empty since we no longer need a target -->
<Target Name="ResolveMatchingContract" />
<!-- ##### GenAPI settings ##### -->

<!-- Allow P2Ps that target a source project to build against the corresponding ref project. -->
<Target Name="AnnotateTargetPathWithTargetPlatformMonikerWithReferenceAssembly"
Condition="'$(HasMatchingContract)' == 'true'"
DependsOnTargets="ResolveProjectReferences"
AfterTargets="GetTargetPathWithTargetPlatformMoniker">
<ItemGroup>
<!-- Allow to point to a different reference project than what GenFacades uses to generate the type forwards. -->
<TargetPathWithTargetPlatformMoniker ReferenceAssembly="@(ResolvedMatchingContractOverride)" />
<TargetPathWithTargetPlatformMoniker ReferenceAssembly="@(ResolvedMatchingContract)"
Condition="'@(ResolvedMatchingContractOverride)' == ''" />
</ItemGroup>
</Target>
<PropertyGroup>
<GenAPIExcludeAttributesList>$(RepositoryEngineeringDir)DefaultGenApiDocIds.txt</GenAPIExcludeAttributesList>
<GenAPIHeaderFile>$(RepositoryEngineeringDir)LicenseHeader.txt</GenAPIHeaderFile>
<GenAPITargetPath>$([MSBuild]::NormalizePath('$(MSBuildProjectDirectory)', '..', 'ref', '$(AssemblyName).cs'))</GenAPITargetPath>
<GenAPILangVersion Condition="'$(LangVersion)' != ''">$(LangVersion)</GenAPILangVersion>
<ProjectForGenAPIDocIdGeneration Condition="'$(ProjectForGenAPIDocIdGeneration)' == ''">$(CoreLibProject)</ProjectForGenAPIDocIdGeneration>
</PropertyGroup>

<Target Name="HandleReferenceAssemblyAttributeForProjectReferences"
AfterTargets="ResolveProjectReferences"
BeforeTargets="FindReferenceAssembliesForReferences"
Condition="'@(ProjectReference)' != '' and '@(_ResolvedProjectReferencePaths)' != ''">
<!-- If we have a ProjectReference to CoreLib, we need to compile against implementation assemblies. -->
<PropertyGroup Condition="@(_ResolvedProjectReferencePaths->AnyHaveMetadataValue('MSBuildSourceProjectFile', '$(CoreLibProject)'))">
<CompileUsingReferenceAssemblies Condition="'$(CompileUsingReferenceAssemblies)' == ''">false</CompileUsingReferenceAssemblies>
</PropertyGroup>
<!-- Clear the ReferenceAssembly attribute on resolved P2Ps that set SkipUseReferenceAssembly to true. -->
<ItemGroup>
<_resolvedP2PFiltered Include="@(ProjectReference)"
ProjectReferenceItemSpec="$([System.IO.Path]::GetFullPath('%(ProjectReference.Identity)'))"
SkipUseReferenceAssembly="%(ProjectReference.SkipUseReferenceAssembly)" />
<_ResolvedProjectReferencePaths Condition="'%(_resolvedP2PFiltered.ProjectReferenceItemSpec)' == '%(_resolvedP2PFiltered.MSBuildSourceProjectFile)' and
'%(_resolvedP2PFiltered.SkipUseReferenceAssembly)' == 'true'"
ReferenceAssembly="" />
</ItemGroup>
</Target>
<ItemGroup>
<!-- GenAPI is currently only invoked on demand and not used as part of the build as it isn't source build compatible. -->
<PackageReference Include="Microsoft.DotNet.GenAPI"
Version="$(MicrosoftDotNetGenApiVersion)"
PrivateAssets="all"
IsImplicitlyDefined="true"
Condition="'$(DotNetBuildFromSource)' != 'true'" />
</ItemGroup>

<!-- Generate a .txt file with all public types of the project referenced by ProjectForGenAPIDocIdGeneration (e.g. System.Private.CoreLib or System.Private.Uri implementation assembly).
This file is then later on passed to GenAPI as the list of types which should be "split out" with the conditional compilation logic. -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -348,8 +348,7 @@

<!-- Import refererence assembly and ApiCompat logic -->
<PropertyGroup>
<IsSourceProject>true</IsSourceProject>
<ApiCompatValidateAssemblies>true</ApiCompatValidateAssemblies>
</PropertyGroup>
<Import Project="$(RepositoryEngineeringDir)resolveContract.props" />
<Import Project="$(RepositoryEngineeringDir)resolveContract.targets" />
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -608,8 +608,7 @@

<!-- Import refererence assembly and ApiCompat logic -->
<PropertyGroup>
<IsSourceProject>true</IsSourceProject>
<ApiCompatValidateAssemblies>true</ApiCompatValidateAssemblies>
</PropertyGroup>
<Import Project="$(RepositoryEngineeringDir)resolveContract.props" />
<Import Project="$(RepositoryEngineeringDir)resolveContract.targets" />
</Project>
2 changes: 1 addition & 1 deletion src/libraries/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@

<Import Project="NetCoreAppLibrary.props" />
<Import Project="$(RepositoryEngineeringDir)referenceAssemblies.props" Condition="'$(IsReferenceAssemblyProject)' == 'true'" />
<Import Project="$(RepositoryEngineeringDir)resolveContract.props" />

<PropertyGroup>
<!-- Default any assembly not specifying a key to use the Open Key -->
Expand All @@ -84,6 +83,7 @@

<!-- Language configuration -->
<PropertyGroup>
<ApiCompatValidateAssemblies Condition="'$(IsSourceProject)' == 'true'">true</ApiCompatValidateAssemblies>
<GenFacadesIgnoreBuildAndRevisionMismatch>true</GenFacadesIgnoreBuildAndRevisionMismatch>
<!-- Disable analyzers for tests and unsupported projects -->
<RunAnalyzers Condition="'$(IsTestProject)' != 'true' and '$(IsSourceProject)' != 'true' and '$(IsGeneratorProject)' != 'true'">false</RunAnalyzers>
Expand Down
11 changes: 8 additions & 3 deletions src/libraries/Directory.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@

<Import Project="$(RepositoryEngineeringDir)codeOptimization.targets" />
<Import Project="$(RepositoryEngineeringDir)references.targets" />
<Import Project="$(RepositoryEngineeringDir)resolveContract.targets" />
<Import Project="$(RepositoryEngineeringDir)resolveContract.targets" Condition="'$(IsSourceProject)' == 'true'" />
<Import Project="$(RepositoryEngineeringDir)testing\tests.targets" Condition="'$(EnableTestSupport)' == 'true'" />
<Import Project="$(RepositoryEngineeringDir)testing\linker\trimmingTests.targets" Condition="'$(IsPublishedAppTestProject)' == 'true'" />
<Import Project="$(RepositoryEngineeringDir)testing\runtimeConfiguration.targets" />
Expand All @@ -141,11 +141,16 @@
<PackageReference Include="Microsoft.DotNet.Build.Tasks.TargetFramework" Version="$(MicrosoftDotNetBuildTasksTargetFrameworkVersion)" PrivateAssets="all" IsImplicitlyDefined="true" />
</ItemGroup>

<ItemGroup Condition="'$(IsSourceProject)' == 'true' or '$(IsReferenceAssemblyProject)' == 'true' or '$(IsPartialFacadeAssembly)' == 'true'">
<PackageReference Include="Microsoft.DotNet.GenAPI" Condition="'$(DotNetBuildFromSource)' != 'true'" Version="$(MicrosoftDotNetGenApiVersion)" PrivateAssets="all" IsImplicitlyDefined="true" />
<!-- Reference the GenFacades package when the assembly is a partial facade or a PNSE throwing. -->
<ItemGroup Condition="'$(IsPartialFacadeAssembly)' == 'true' or
'$(GeneratePlatformNotSupportedAssembly)' == 'true' or
'$(GeneratePlatformNotSupportedAssemblyMessage)' != ''">
<PackageReference Include="Microsoft.DotNet.GenFacades" Version="$(MicrosoftDotNetGenFacadesVersion)" PrivateAssets="all" IsImplicitlyDefined="true" />
</ItemGroup>

<!-- GenFacades target that is intentionally empty since we no longer need it. -->
<Target Name="ResolveMatchingContract" />

<!--
Do not clean binplace assets in the ref targeting pack to avoid incremental build failures
when the SDK tries to resolve the assets from the FrameworkList.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<argument>ILLink</argument>
<argument>IL2050</argument>
<property name="Scope">member</property>
<property name="Target">M:System.DirectoryServices.Interop.UnsafeNativeMethods.ADsOpenObject(System.String,System.String,System.String,System.Int32,System.Guid@,System.Object@)</property>
<property name="Target">M:System.DirectoryServices.UnsafeNativeMethods.ADsOpenObject(System.String,System.String,System.String,System.Int32,System.Guid@,System.Object@)</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace System.DirectoryServices.Interop
namespace System.DirectoryServices
{
internal enum AdsOptions
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace System.DirectoryServices.Interop
namespace System.DirectoryServices
{
internal enum AdsPropertyOperation
{
Expand Down
Loading

0 comments on commit c8503d3

Please sign in to comment.