-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDirectory.Build.targets
More file actions
94 lines (77 loc) · 6.8 KB
/
Copy pathDirectory.Build.targets
File metadata and controls
94 lines (77 loc) · 6.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
<Project>
<!-- ─────────────────────────────────────────────────────────────
AOT 严格模式:通过 -p:AotStrictMode=true 激活,将 AOT 相关诊断精确清单式升级为错误。
作用域 = 库 + Demo(排除 *.Tests / *.Benchmarks:测试与基准代码不是 AOT 交付物,
其反射/动态代码用法属测试基建,纳入严格模式只会产生噪声)。
声明位置说明:必须在 .targets(而非 .props)中注入——.props 在项目文件之前导入,
读不到项目内定义的属性,导致下文的工程级退出开关永远不生效。
<MudExcludeFromAotStrictMode>true</MudExcludeFromAotStrictMode> 供单个工程退出,
适用于"消费已发布 NuGet 包"的示例工程:其生成代码来自已发布版本的源生成器,
本仓库无法修复,纳入严格模式只会在既有发布包上产生无法消除的 IL1xxx/IL3xxx 错误。
此前该清单分散定义在 3 个 Demo csproj 中,且 MSBuild 项目属性不向被 ProjectReference 的库传播,
导致"库内 IL 告警永远不失败、CI 严格模式名不副实"。上移后库工程同样受检(防回归)。
───────────────────────────────────────────────────────────── -->
<PropertyGroup Condition="'$(AotStrictMode)' == 'true' AND '$(MudExcludeFromAotStrictMode)' != 'true' AND !$(MSBuildProjectName.EndsWith('.Tests')) AND !$(MSBuildProjectName.EndsWith('.Benchmarks'))">
<WarningsAsErrors>$(WarningsAsErrors);IL2026;IL2046;IL2050;IL2057;IL2067;IL2070;IL2072;IL2075;IL2080;IL2091;IL3050;IL3051;AOT004;AOT005;AOT006;AOT007</WarningsAsErrors>
</PropertyGroup>
<!-- ─────────────────────────────────────────────────────────────
[P2-1] Polyfill guard 锚点规则(改 Mud.HttpUtils.Abstractions/Polyfills/*.cs 前必读)
Polyfill 的 `#if !NETx_0_OR_GREATER` guard 必须对齐**该 API 首次 in-box 的 TFM**,
而不是"仓库当前最低 TFM"。仓库最低 TFM(netstandard2.0 / net6.0)与 API 引入版本
并不一致,写错会得到两种相反的故障:
· guard 过宽(如 RequiresDynamicCode 写成 !NET6_0_OR_GREATER)→ net6.0 下跳过定义,
而该 API 在 net6.0 尚不存在 ⇒ net6.0 编译失败;
· guard 过窄(如对 .NET 6 起就 in-box 的属性仍写 !NET7_0_OR_GREATER)→ 新 TFM 下
重复定义同名类型 ⇒ 与 BCL 类型冲突。
现有锚点:RequiresUnreferencedCode / DynamicallyAccessedMembers / DynamicDependency /
UnconditionalSuppressMessage = !NET6_0_OR_GREATER;RequiresDynamicCode = !NET7_0_OR_GREATER;
IsExternalInit = !NET6_0_OR_GREATER(语言特性要求,非 BCL API)。
另:嵌套同类 guard(如 `#if NET7_0_OR_GREATER` 内再写 `#if NET6_0_OR_GREATER`)恒真,属冗余,不要保留。
───────────────────────────────────────────────────────────── -->
<!-- Phase 5.4 / H-4: PublicAPI per-TFM 基线管理
仅对发布库(有 PackageId、非源生成器/分析器、有构建输出、非测试项目)启用。
在 Directory.Build.targets 中声明,因为 PackageId 等属性在项目文件中设置,
需在项目文件之后导入才能读取。
EnablePublicApiBaseline(默认 true):通过 AdditionalFiles 按 TFM 声明
PublicAPI.Shipped.txt / PublicAPI.Unshipped.txt,并引入 Microsoft.CodeAnalysis.PublicApiAnalyzers,
使新增/删除公共符号分别触发 RS0016(未登记)/ RS0017(已登记但被删)。
PublicApiStrictMode(默认关闭,CI 传入 true):将 RS0016/RS0017 升级为 error,
作为第三方分发类库的编译期 API 契约门禁。形如 -p:AotStrictMode 的严格模式子集。
PublicApiGenerateFiles(默认关闭,仅 tools/rebuild-publicapi.ps1 传入 true):
接入 Mono.ApiTools.MSBuildTasks.GeneratePublicApiFiles,在构建后一次性生成/回归基线文件。
基线重建:tools/rebuild-publicapi.ps1(依据本文件下方 GeneratePublicApiBaselines target)。 -->
<PropertyGroup>
<!-- PackAsTool 是 dotnet 全局工具(CLI 可执行程序),非供外部引用的类库,
其公共类型(如 JsonContextGenerator)属于工具内部实现细节,无需维护公共 API 基线。 -->
<EnablePublicApiBaseline Condition="'$(PackageId)' != '' AND '$(IsRoslynComponent)' != 'true' AND '$(IncludeBuildOutput)' != 'false' AND '$(IsTestProject)' != 'true' AND '$(PackAsTool)' != 'true'">true</EnablePublicApiBaseline>
</PropertyGroup>
<!-- H-4:PublicAPI 严格模式 —— RS0016(新增未登记)/ RS0017(已登记被删)升级为 error -->
<PropertyGroup Condition="'$(EnablePublicApiBaseline)' == 'true' AND '$(PublicApiStrictMode)' == 'true'">
<WarningsAsErrors>$(WarningsAsErrors);RS0016;RS0017</WarningsAsErrors>
</PropertyGroup>
<ItemGroup Condition="'$(EnablePublicApiBaseline)' == 'true'">
<PackageReference Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" Version="5.6.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup Condition="'$(EnablePublicApiBaseline)' == 'true' AND '$(TargetFramework)' != ''">
<AdditionalFiles Include="PublicAPI\$(TargetFramework)\PublicAPI.Shipped.txt" />
<AdditionalFiles Include="PublicAPI\$(TargetFramework)\PublicAPI.Unshipped.txt" />
</ItemGroup>
<!-- H-4:基线生成(仅 PublicApiGenerateFiles=true 时生效,正常构建不引用 Mono.ApiTools)
依赖 $(TargetPath)(构建产物)与 @(ReferencePath)(依赖解析路径),故挂在 AfterTargets="Build"。 -->
<ItemGroup Condition="'$(PublicApiGenerateFiles)' == 'true' AND '$(TargetFramework)' != ''">
<PackageReference Include="Mono.ApiTools.MSBuildTasks" Version="0.6.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<Target Name="GeneratePublicApiBaselines" AfterTargets="Build"
Condition="'$(PublicApiGenerateFiles)' == 'true' AND '$(EnablePublicApiBaseline)' == 'true' AND '$(TargetFramework)' != ''">
<GeneratePublicApiFiles
Assembly="$(TargetPath)"
Files="@(AdditionalFiles)"
ReferenceSearchPaths="@(ReferencePath->'%(RootDir)%(Directory)')" />
</Target>
</Project>