-
Notifications
You must be signed in to change notification settings - Fork 0
MS_MSBuildDefineConstants
- 戻る(MSBuild)
Linux 上の .NET Core 環境で dotnet コマンドのビルドで
条件付きコンパイルシンボル(DefineConstants)に設定した値が効かず、
#if-#endif が適切に動作しない。
- 以下の Condition が Linux 環境と異なるっぽい。
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">- 単純に Condition を削除したら動作した。
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DefineConstants>TRACE;NETCORE</DefineConstants>
</PropertyGroup>↓ ↓ ↓
<PropertyGroup>
<DefineConstants>TRACE;NETCORE</DefineConstants>
</PropertyGroup>補足(原因の特定): 原文の「Linux 環境と異なるっぽい」という
見立ては正しく、$(Platform)の既定値が一致していないことが原因である。【Visual Studio でビルド】 Platform = "AnyCPU" ← .sln のソリューション構成から渡される → Condition が成立する 【dotnet build(.csproj 単体)】 Platform = "AnyCPU" の場合もあるが、 SDK スタイルでは PlatformTarget と混同されやすく、 ソリューションを介さないと空や別の値になることがある → Condition が成立せず、DefineConstants が設定されないLinux 固有の問題ではなく、
「IDE 経由かどうか」「.sln 経由かどうか」の差である
(Windows でもdotnet build Foo.csprojで再現し得る)。確認方法: 実際に渡っているプロパティを出力させる。
dotnet build -v:diag 2>&1 | grep -E "^\s+Platform = |^\s+DefineConstants = " # あるいは、プロパティを直接評価する dotnet msbuild Foo.csproj -getProperty:Platform -getProperty:DefineConstants
-getProperty(.NET 8 SDK 以降)は、
ビルドせずにプロパティの評価結果だけを見られるため、
この種の調査に有用である。
補足(推奨する書き方): 原文の対処
(Condition を外す)は確実だが、
「Debug の時だけ」という意図が失われる。
意図を保ったまま安全にする書き方を挙げておく。①
Configurationだけで判定する(Platformに依存しない)<PropertyGroup Condition="'$(Configuration)'=='Debug'"> <DefineConstants>$(DefineConstants);MY_DEBUG_ONLY</DefineConstants> </PropertyGroup>② SDK が用意する定数を使う(自分で定義しない)
SDK スタイルでは、次の定数が自動で定義される。
定数 条件 DEBUGConfiguration=DebugTRACE既定で常に( <DefineTrace>)NET8_0,NET8_0_OR_GREATERターゲット フレームワーク NETCOREAPP,NETSTANDARD,NETFRAMEWORKプラットフォーム系 WINDOWS,LINUX,MACOSOS 固有 TFM 使用時 #if NET8_0_OR_GREATER // .NET 8 以降 #elif NETFRAMEWORK // .NET Framework #endif原文が定義している
NETCOREは、
標準のNETCOREAPPで代替できる
(ターゲット フレームワークのバージョン)。
自前の定数を定義しないのが、この種の事故を防ぐ最善策である。③ 追記形式にする(既存の定数を潰さない)
<!-- 悪い:TRACE / DEBUG を上書きして消してしまう --> <DefineConstants>NETCORE</DefineConstants> <!-- 良い:既存に足す --> <DefineConstants>$(DefineConstants);NETCORE</DefineConstants>原文の例(
TRACE;NETCORE)はTRACEを手で書き足しているが、
$(DefineConstants)を展開する形にしておく方が安全である。
補足(インクリメンタル ビルドの罠): 原文が参照している
MSBuild Issue #3350 は、
**「DefineConstantsを変更しても再コンパイルされない」**という
別の問題である。DefineConstants を書き換える → ソース ファイルは変わっていない → MSBuild が「最新」と判断し、CoreCompile を省略する → 変更が反映されないこの現象は現在は修正されているが、
疑わしい場合はクリーンしてから確認する。dotnet clean && dotnet build # あるいは rm -rf obj bin && dotnet build「設定を変えたのに効かない」時に、
設定の問題なのかキャッシュの問題なのかを切り分けるため、
まずクリーン ビルドで確認するのが定石である。
- DefineConstants should be considered for CoreCompile incrementality · Issue #3350 · Microsoft/msbuild
https://github.com/dotnet/msbuild/issues/3350 - c# - How to use custom preprocessor directives in .Net Core - Stack Overflow
https://stackoverflow.com/questions/43743808/how-to-use-custom-preprocessor-directives-in-net-core
- 一般的な MSBuild プロジェクト プロパティ
https://learn.microsoft.com/ja-jp/visualstudio/msbuild/common-msbuild-project-properties - SDK スタイル プロジェクトで定義済みのプリプロセッサ シンボル
https://learn.microsoft.com/ja-jp/dotnet/csharp/language-reference/preprocessor-directives#conditional-compilation - 複数ターゲットの条件付きコンパイル
https://learn.microsoft.com/ja-jp/dotnet/standard/frameworks#preprocessor-symbols
Tags: 移行, テスト, デバッグ, デプロイ, .NET開発, .NET Core
このWikiは「Open棟梁Project」,「OSSコンソーシアム 開発基盤部会」によって運営されています。