はじめに
内々で使っているツールでPublishTrimmed(PublishAotではない)している場所が存在しているが、
.NET SDK 8.0でエラーが出るようになったので原因と回避方法の解説を行う。
PublishTrimmedに関しての解説は下記公式ドキュメントを参照すること。
Microsoft Learn - Trimming options
なお、今回書いた内容はPublishAotでも大体当てはまる(多分もっと制限がきつい)
前提条件
まず、このエラーが出る条件としては、
- .NET SDK 8.0を使用している
- net6.0以降のEXEプロジェクトが存在する(app1とする)
- EXEプロジェクトがnetstandard2.0あるいは2.1のライブラリプロジェクト(lib1とする)をProjectReferenceしている
- アナライザープロジェクトでも該当する
- PackageReferenceの場合は試してないが同じようなことになったらもっと多くの人が気づいてると思うので大丈夫だと思う
現象発生
この状態で、app1を dotnet publish [app1.csprojファイルパス] -r win-x64 --self-contained -c Release -p:PublishTrimmed=true
すると以下のようなエラーが出て失敗する
C:\Program Files\dotnet\sdk\8.0.100\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(90,5): error NETSDK1124: アセンブリをトリミングするには、.NET
Core 3.0 以降が必要です。 [D:\src\gitrepos\dotnet-sandbox\trimlabs2\lib1\lib1.csproj]
原因
dotnet publish
は、依存プロジェクトがある場合はそれを先にビルドするような動作をする。
-p:PublishTrimmed=true
はmsbuildプロパティをビルド全体に適用するオプションとなる(msbuild由来)。
つまり、lib1を"PublishTrimmed=true"プロパティ付きでビルドしようとすると、lib1でもPublishTrimmed=trueが適用されて、上記のNETSDK1124エラーが出る。
これはSDK側のバージョンアップによる動作変更なので、app1.csprojのTargetFrameworkをnet6.0に下げても変わらない
対策
global.jsonで使用する.NET SDKのバージョンダウンを行う
この動作は.NET SDK 8.0からなので、使うSDKのバージョンを7.0以前に下げれば対応は可能。
ただし、 バージョンダウンなのでTargetFrameworkにnet8.0が使えなくなる 事には注意。
具体的にはリポジトリルートに下記の内容で"global.json"というファイルを作成する
{
"sdk": {
"version": "7.0.200"
}
}
"version"要素の仕様を含むglobal.jsonの詳しい仕様は下記公式ドキュメントを参考にすること
Microsoft Learn - global.json overview
csprojの書き換え
net8.0を使いたい場合ではどうするかというと、コマンドラインで指定するのではなく、csprojの中で指定する必要がある。
csprojに下記内容を追加する
<Project Sdk="Microsoft.NET.Sdk">
<!-- 途中省略 -->
<PropertyGroup>
<PublishTrimmed>true</PublishTrimmed>
</PropertyGroup>
<!-- 途中省略 -->
</Project>
ある条件の場合だけ有効にしたい場合は、下記のようにCondition属性を付ける
<PropertyGroup Condition="'$(Runtime)' != ''">
<PublishTrimmed>true</PublishTrimmed>
</PropertyGroup>
終わりに
今回の内容はSDKの動作仕様の変更なので、ソースやプロジェクト等の設定を一切変えてなくても、
VSのアップデートを行うだけで出るようになってしまう場合があるため注意が必要。
アナライザープロジェクトを参照してもこれが出るので、可能ならばその辺りはどうにかして欲しい所。
なお、この問題と類似ケースが下記で議論されている。
Build error NETSDK1124 with NET8 RC2 when multiple TargetFrameworks