Skip to content

修复 AOT 编译时产生的 Trimming 警告 #2007

Open
@Delsin-Yu

Description

@Delsin-Yu

Feature 特性

正确标记裁剪不兼容的 API 或为其补充给 ILC 的类型使用信息以消除编译期(发布期)产生的 ILC 警告

简要描述原因

虽然 FreeSql 声明自己支持 AOT,但是在发布期产生的 ILXXXX 警告通常代表 ILC 无法确保给定的 API 在经过裁剪后能够正常运作;所以在源码中对这些依赖动态特性的API进行标注是很重要的,因为这些额外的 Attribute 能够帮助 ILC 决定要保留哪些类型或类型的成员(以使得原本经过裁剪导致错误的API变得可用),以及用户是否使用了根本无法在AOT环境调用的API(以确保AOT发布失败来避免用户获得本就不可用的应用程序)

可以查看 准备 .NET 库以进行剪裁 文档以获取更多和裁剪 / 正确支持AOT相关的信息

使用场景

对 .Net 应用程序进行 AOT 编译时

亟待解决的 IL 错误汇总

我编写了一个极小的 C# AOT Minimal API 应用程序以检查常见 API 的使用情况,此项目在发布时会产生若干 IL 警告

using System.Text.Json.Serialization;
using FreeSql;
using FreeSql.DataAnnotations;
using Microsoft.AspNetCore.Mvc;
using DataType = FreeSql.DataType;

var builder = WebApplication.CreateSlimBuilder(args);

builder.Services.ConfigureHttpJsonOptions(option =>
    option.SerializerOptions.TypeInfoResolver = ApplicationJsonContext.Default);
builder.Services.AddSingleton<IFreeSql>(_ => new FreeSqlBuilder()
    // .UseAdoConnectionPool(true)
    .UseConnectionString(DataType.Sqlite, "data source=application_data.db")
    // .UseMonitorCommand(cmd => Console.WriteLine($"SqlCommand:\n{cmd.CommandText}"))
    .UseAutoSyncStructure(true)
    .Build()
);

var app = builder.Build();

app.MapGet("/add", async ([FromHeader(Name = nameof(name))] string name, [FromHeader(Name = nameof(score))] int score, IFreeSql sql) =>
{
    await sql.InsertOrUpdate<LeaderBoardItem>().SetSource(new LeaderBoardItem(name, score)).ExecuteAffrowsAsync();
    return Results.Ok();
});
app.MapGet("/check", (IFreeSql sql) => sql.Select<LeaderBoardItem>().ToListAsync());

app.Run();

[JsonSerializable(typeof(List<LeaderBoardItem>))]
internal partial class ApplicationJsonContext : JsonSerializerContext;

internal record LeaderBoardItem(
    [property: Column(IsPrimary = true)] string Name,
    int Score
);
警告类型 数量 描述 示例 潜在风险
动态代码生成 (IL3050) ~50 使用需要运行时生成代码的 API Expression.Lambda() AOT 编译时无法生成代码
类型反射缺少注释 (IL2070/IL2075) ~45 没有适当 DynamicallyAccessedMembers 注解的反射 GetType().GetMethods() 修剪可能会删除被反射访问的成员
动态类型创建 (IL3050) ~35 运行时创建泛型类型 MakeGenericType() AOT 环境无法生成动态类型
表达式构建 (IL2026) ~10 使用字符串创建属性表达式 Expression.Property(expr, "Name") 修剪可能移除表达式引用的成员
单文件部署 (IL3000/IL3002) 3 使用不支持单文件发布的 API Assembly.Location 在单文件应用中会抛出异常

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions