kazuk は null に触れてしまった

C# / .NET 系技術ネタ縛りでお送りしております

月別アーカイブ: 2月 2017

.NET Core 1.1 で msbuild はどうなったのか


一度は nuget統合がらみで project.json とかに移行するという形でdiscon言われた msbuild ですが、結局息を吹き返し、Visual Studio 2017 RC で .NET Core App (ASP.NET vNext 改め ASP.NET Core でのWebアプリを含む)のビルドランナーとして復活を果たしました。

この msbuild について、ビルドのカスタム手法について諸々調べてみましたので blog にまとめてみます。

デフォルトの csproj からの targets / props の読み込み

実際にプロジェクトを作って csproj を開いてもらうと解りますが、msbuild の Import による targets の取り込みがありません。過去の知識だけを頼りに調べようとすると一体何が起こってるのやらで即詰みしますね。

いつ増えたんだ!って感じですが、 msbuild に /pp:出力ファイル名 で import によるファイルインクルードの解決結果を出力するオプションがあるのでこれを使って標準ターゲットを取り込んだ XML を生成すると、その冒頭で回答が出てました。

<?xml version=”1.0″ encoding=”utf-8″?>
<!–
==========<snip>===============================================
C:\Users\kazuk\Documents\Visual Studio 2017\Projects\WebApplication4\WebApplication2\WebApplication2.csproj
==========<snip>===============================================
–>
<Project ToolsVersion=”15.0″ DefaultTargets=”Build”>
  <!–
==========<snip>===============================================
  <Import Project=”Sdk.props” Sdk=”Microsoft.NET.Sdk.Web”>
  This import was added implicitly because of the Project element’s Sdk attribute specified “Microsoft.NET.Sdk.Web”.

C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk.Web\Sdk\Sdk.props

==========<snip>===============================================
–>

csproj ファイルの冒頭、Sdk アトリビュートによって、Sdk.props の読み込みが行われていて、Sdk.props は C:\Program Files\dotnet\sdk\… にあるという事でした。

実際の csproj での Project 要素のSdkアトリビュートは以下のようになっています。

<Project ToolsVersion=”15.0″ Sdk=”Microsoft.NET.Sdk.Web”>

この Sdk 属性により関連 props が読み取られます。

この Sdk.props は以下のように終わります。

  <!–

==========<snip>===============================================

  </Import>

C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk.Web\Sdk\Sdk.props

==========<snip>===============================================

==========<snip>===============================================
  </Import>

C:\Users\kazuk\Documents\Visual Studio 2017\Projects\WebApplication4\WebApplication2\WebApplication2.csproj
==========<snip>===============================================
–>

続いて csproj での定義内容が現れ、

  <PropertyGroup>
    <TargetFramework>netcoreapp1.1</TargetFramework>
  </PropertyGroup>
  <PropertyGroup>
    <PackageTargetFallback>$(PackageTargetFallback);portable-net45+win8+wp8+wpa81;</PackageTargetFallback>
  </PropertyGroup>
  <PropertyGroup>
    <UserSecretsId>aspnet-WebApplication2-898cd849-2e88-466a-81b4-e1d20363bffb</UserSecretsId>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include=”Microsoft.ApplicationInsights.AspNetCore” Version=”2.0.0-beta1″ />
    <PackageReference Include=”Microsoft.AspNetCore” Version=”1.1.0″ />
    <PackageReference Include=”Microsoft.AspNetCore.Authentication.Cookies” Version=”1.1.0″ />
    <PackageReference Include=”Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore” Version=”1.1.0″ />
    <PackageReference Include=”Microsoft.AspNetCore.Identity.EntityFrameworkCore” Version=”1.1.0″ />
    <PackageReference Include=”Microsoft.AspNetCore.Mvc” Version=”1.1.1″ />
    <PackageReference Include=”Microsoft.AspNetCore.StaticFiles” Version=”1.1.0″ />
    <PackageReference Include=”Microsoft.EntityFrameworkCore.Design” Version=”1.1.0″ PrivateAssets=”All” />
    <PackageReference Include=”Microsoft.EntityFrameworkCore.SqlServer” Version=”1.1.0″ />
    <PackageReference Include=”Microsoft.EntityFrameworkCore.SqlServer.Design” Version=”1.1.0″ PrivateAssets=”All” />
    <PackageReference Include=”Microsoft.EntityFrameworkCore.Tools” Version=”1.1.0-msbuild3-final” PrivateAssets=”All” />
    <PackageReference Include=”Microsoft.Extensions.Configuration.UserSecrets” Version=”1.1.0″ />
    <PackageReference Include=”Microsoft.Extensions.Logging.Debug” Version=”1.1.0″ />
    <PackageReference Include=”Microsoft.VisualStudio.Web.CodeGeneration.Design” Version=”1.1.0-msbuild3-final” PrivateAssets=”All” />
    <PackageReference Include=”Microsoft.VisualStudio.Web.BrowserLink” Version=”1.1.0″ />
  </ItemGroup>
  <ItemGroup>
    <DotNetCliToolReference Include=”Microsoft.EntityFrameworkCore.Tools.DotNet” Version=”1.0.0-msbuild3-final” />
    <DotNetCliToolReference Include=”Microsoft.Extensions.SecretManager.Tools” Version=”1.0.0-msbuild3-final” />
    <DotNetCliToolReference Include=”Microsoft.VisualStudio.Web.CodeGeneration.Tools” Version=”1.0.0-msbuild3-final” />
  </ItemGroup>

csproj の Project 要素内が展開された続きが以下です。

  <!–
==========<snip>===============================================
  <Import Project=”Sdk.targets” Sdk=”Microsoft.NET.Sdk.Web”>
  This import was added implicitly because of the Project element’s Sdk attribute specified “Microsoft.NET.Sdk.Web”.

C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk.Web\Sdk\Sdk.targets
==========<snip>===============================================
–>
  <!–
***********************************************************************************************
Sdk.targets

WARNING:  DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
          created a backup copy.  Incorrect changes to this file will make it
          impossible to load or build your projects from the command-line or the IDE.

Copyright (c) .NET Foundation. All rights reserved.
***********************************************************************************************
–>

csproj の Project 要素の末尾に Sdk.targets が暗黙に展開されるようになっています、これが Sdk アトリビュートの仕組みという事ですね。 Project 要素に Sdk アトリビュートを付けると先頭に props 、末尾にtargets が挿入される、そういう仕組みです。

SDK として配布展開される props / targets の参照方法としては非常にシンプルで良いと思います。

csproj.user はどうなった

プリプロセス結果から Import Project を拾ってみた結果は以下です。

長いですけど、結果的に csproj.user の読み込みは無くなってます。

途中赤字にしてるのがプロジェクト配下の props / targets の読み込みでビルドのカスタム化という点で言えば有望株です。

<Import Project=”Sdk.props” Sdk=”Microsoft.NET.Sdk.Web”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk.Web\Sdk\Sdk.props

<Import Project=”$(MSBuildSdksPath)\Microsoft.NET.Sdk\Sdk\Sdk.props” Condition=”Exists(‘$(MSBuildSdksPath)\Microsoft.NET.Sdk\Sdk\Sdk.props’)”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk\Sdk\Sdk.props

<Import Project=”$(MSBuildThisFileDirectory)..\build\Microsoft.NET.Sdk.props”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Sdk.props

<Import Project=”Microsoft.NET.Sdk.DefaultItems.props”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Sdk.DefaultItems.props

<Import Project=”$(MSBuildThisFileDirectory)Microsoft.NET.Sdk.CSharp.props” Condition=”‘$(MSBuildProjectExtension)’ == ‘.csproj'”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Sdk.CSharp.props

<Import Project=”$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\15.0\Microsoft.Common.props

<Import Project=”$(MSBuildProjectExtensionsPath)$(MSBuildProjectFile).*.props” Condition=”‘$(ImportProjectExtensionProps)’ == ‘true’ and exists(‘$(MSBuildProjectExtensionsPath)’)”>
C:\Users\kazuk\Documents\Visual Studio 2017\Projects\WebApplication4\WebApplication2\obj\WebApplication2.csproj.nuget.g.props

<Import Project=”$(NuGetPackageRoot)microsoft.diasymreader.native\1.4.0\build\Microsoft.DiaSymReader.Native.props” Condition=”Exists(‘$(NuGetPackageRoot)microsoft.diasymreader.native\1.4.0\build\Microsoft.DiaSymReader.Native.props’)”>
C:\Users\kazuk\.nuget\packages\microsoft.diasymreader.native\1.4.0\build\Microsoft.DiaSymReader.Native.props

<Import Project=”$(MSBuildSdksPath)\Microsoft.NET.Sdk.Web.ProjectSystem\Sdk\Sdk.props” Condition=”Exists(‘$(MSBuildSdksPath)\Microsoft.NET.Sdk.Web.ProjectSystem\Sdk\Sdk.props’)”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk.Web.ProjectSystem\Sdk\Sdk.props

<Import Project=”$(MSBuildThisFileDirectory)..\build\netstandard1.0\Microsoft.NET.Sdk.Web.ProjectSystem.props” Condition=”Exists(‘$(MSBuildThisFileDirectory)..\build\netstandard1.0\Microsoft.NET.Sdk.Web.ProjectSystem.props’)”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk.Web.ProjectSystem\build\netstandard1.0\Microsoft.NET.Sdk.Web.ProjectSystem.props

<Import Project=”$(MSBuildSdksPath)\Microsoft.NET.Sdk.Publish\Sdk\Sdk.props” Condition=”Exists(‘$(MSBuildSdksPath)\Microsoft.NET.Sdk.Publish\Sdk\Sdk.props’)”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk.Publish\Sdk\Sdk.props

<Import Project=”$(MSBuildThisFileDirectory)..\build\netstandard1.0\Microsoft.NET.Sdk.Publish.props” Condition=”Exists(‘$(MSBuildThisFileDirectory)..\build\netstandard1.0\Microsoft.NET.Sdk.Publish.props’)”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk.Publish\build\netstandard1.0\Microsoft.NET.Sdk.Publish.props

<Import Project=”Sdk.targets” Sdk=”Microsoft.NET.Sdk.Web”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk.Web\Sdk\Sdk.targets

<Import Project=”$(MSBuildSdksPath)\Microsoft.NET.Sdk\Sdk\Sdk.targets” Condition=”Exists(‘$(MSBuildSdksPath)\Microsoft.NET.Sdk\Sdk\Sdk.targets’)”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk\Sdk\Sdk.targets

<Import Project=”$(MSBuildThisFileDirectory)..\build\Microsoft.NET.Sdk.BeforeCommon.targets” Condition=”‘$(IsCrossTargetingBuild)’ != ‘true'”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Sdk.BeforeCommon.targets

<Import Project=”$(MSBuildThisFileDirectory)Microsoft.NET.DefaultOutputPaths.targets”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.DefaultOutputPaths.targets

<Import Project=”$(MSBuildThisFileDirectory)Microsoft.NET.TargetFrameworkInference.targets” Condition=”‘$(TargetFramework)’ != ””>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.TargetFrameworkInference.targets

<Import Project=”$(MSBuildThisFileDirectory)Microsoft.NET.RuntimeIdentifierInference.targets”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.RuntimeIdentifierInference.targets

<Import Project=”$(LanguageTargets)”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Microsoft.CSharp.targets

<Import Project=”$(CSharpTargetsPath)”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Microsoft.CSharp.CurrentVersion.targets

<Import Project=”$(CSharpCoreTargetsPath)”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Roslyn\Microsoft.CSharp.Core.targets

<Import Project=”Microsoft.Common.targets”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Microsoft.Common.targets

<Import Project=”$(CommonTargetsPath)”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Microsoft.Common.CurrentVersion.targets

<Import Project=”$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.targets\ImportAfter\*” Condition=”‘$(ImportByWildcardAfterMicrosoftCommonTargets)’ == ‘true’ and exists(‘$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.targets\ImportAfter’)”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\15.0\Microsoft.Common.targets\ImportAfter\Microsoft.NuGet.ImportAfter.targets

<Import Project=”$(NuGetRestoreTargets)” Condition=”Exists(‘$(NuGetRestoreTargets)’)”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\NuGet.targets

<Import Project=”$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.targets\ImportAfter\*” Condition=”‘$(ImportByWildcardAfterMicrosoftCommonTargets)’ == ‘true’ and exists(‘$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.targets\ImportAfter’)”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\15.0\Microsoft.Common.targets\ImportAfter\Microsoft.TestPlatform.ImportAfter.targets

<Import Project=”$(VSTestTargets)” Condition=”Exists(‘$(VSTestTargets)’)”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Microsoft.TestPlatform.targets

<Import Project=”$(MSBuildProjectExtensionsPath)$(MSBuildProjectFile).*.targets” Condition=”‘$(ImportProjectExtensionTargets)’ == ‘true’ and exists(‘$(MSBuildProjectExtensionsPath)’)”>
C:\Users\kazuk\Documents\Visual Studio 2017\Projects\WebApplication4\WebApplication2\obj\WebApplication2.csproj.nuget.g.targets

<Import Project=”$(NuGetPackageRoot)microsoft.extensions.configuration.usersecrets\1.1.0\build\netstandard1.0\Microsoft.Extensions.Configuration.UserSecrets.targets” Condition=”Exists(‘$(NuGetPackageRoot)microsoft.extensions.configuration.usersecrets\1.1.0\build\netstandard1.0\Microsoft.Extensions.Configuration.UserSecrets.targets’)”>
C:\Users\kazuk\.nuget\packages\microsoft.extensions.configuration.usersecrets\1.1.0\build\netstandard1.0\Microsoft.Extensions.Configuration.UserSecrets.targets

<Import Project=”$(MSBuildThisFileDirectory)..\build\Microsoft.NET.Sdk.targets” Condition=”‘$(IsCrossTargetingBuild)’ != ‘true'”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Sdk.targets

<Import Project=”Microsoft.NET.Sdk.Common.targets”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Sdk.Common.targets

<Import Project=”$(MSBuildThisFileDirectory)Microsoft.PackageDependencyResolution.targets” Condition=”Exists(‘$(MSBuildThisFileDirectory)Microsoft.PackageDependencyResolution.targets’)”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk\build\Microsoft.PackageDependencyResolution.targets

<Import Project=”Microsoft.NET.Sdk.DefaultItems.targets”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Sdk.DefaultItems.targets

<Import Project=”$(MSBuildThisFileDirectory)Microsoft.NET.DisableStandardFrameworkResolution.targets” Condition=”‘$(DisableStandardFrameworkResolution)’ == ‘true'”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.DisableStandardFrameworkResolution.targets

<Import Project=”$(MSBuildThisFileDirectory)Microsoft.NET.GenerateAssemblyInfo.targets”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.GenerateAssemblyInfo.targets

<Import Project=”$(MSBuildThisFileDirectory)Microsoft.NET.Publish.targets”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Publish.targets

<Import Project=”$(MSBuildThisFileDirectory)Microsoft.NET.PreserveCompilationContext.targets”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.PreserveCompilationContext.targets

<Import Project=”$(MSBuildThisFileDirectory)Microsoft.NET.Sdk.CSharp.targets” Condition=”‘$(Language)’ == ‘C#'”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Sdk.CSharp.targets

<Import Project=”$(NuGetBuildTasksPackTargets)” Condition=”Exists(‘$(NuGetBuildTasksPackTargets)’)”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\NuGet.Build.Tasks.Pack\build\NuGet.Build.Tasks.Pack.targets

<Import Project=”$(MSBuildSdksPath)\Microsoft.NET.Sdk.Web.ProjectSystem\Sdk\Sdk.targets” Condition=”Exists(‘$(MSBuildSdksPath)\Microsoft.NET.Sdk.Web.ProjectSystem\Sdk\Sdk.targets’)”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk.Web.ProjectSystem\Sdk\Sdk.targets

<Import Project=”$(MSBuildThisFileDirectory)..\build\netstandard1.0\Microsoft.NET.Sdk.Web.ProjectSystem.targets” Condition=”Exists(‘$(MSBuildThisFileDirectory)..\build\netstandard1.0\Microsoft.NET.Sdk.Web.ProjectSystem.targets’)”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk.Web.ProjectSystem\build\netstandard1.0\Microsoft.NET.Sdk.Web.ProjectSystem.targets

<Import Project=”$(MSBuildSdksPath)\Microsoft.NET.Sdk.Publish\Sdk\Sdk.targets” Condition=”Exists(‘$(MSBuildSdksPath)\Microsoft.NET.Sdk.Publish\Sdk\Sdk.targets’)”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk.Publish\Sdk\Sdk.targets

<Import Project=”$(MSBuildThisFileDirectory)..\build\netstandard1.0\Microsoft.NET.Sdk.Publish.targets” Condition=”Exists(‘$(MSBuildThisFileDirectory)..\build\netstandard1.0\Microsoft.NET.Sdk.Publish.targets’)”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk.Publish\build\netstandard1.0\Microsoft.NET.Sdk.Publish.targets

<Import Project=”$(WebPublishProfileFile)” Condition=”Exists(‘$(WebPublishProfileFile)’)”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk.Publish\build\netstandard1.0\PublishProfiles\DefaultProfile.pubxml

<Import Project=”$(_ComputeTargetsDir)Microsoft.NET.Sdk.Publish.ComputeFiles.targets” Condition=”Exists(‘$(_ComputeTargetsDir)Microsoft.NET.Sdk.Publish.ComputeFiles.targets’)”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk.Publish\build\netstandard1.0\ComputeTargets\Microsoft.NET.Sdk.Publish.ComputeFiles.targets

<Import Project=”$(_CopyTargetsDir)Microsoft.NET.Sdk.Publish.CopyFiles.targets” Condition=”Exists(‘$(_CopyTargetsDir)Microsoft.NET.Sdk.Publish.CopyFiles.targets’)”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk.Publish\build\netstandard1.0\CopyTargets\Microsoft.NET.Sdk.Publish.CopyFiles.targets

<Import Project=”$(_TransformTargetsDir)Microsoft.NET.Sdk.Publish.TransformFiles.targets” Condition=”Exists(‘$(_TransformTargetsDir)Microsoft.NET.Sdk.Publish.TransformFiles.targets’)”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk.Publish\build\netstandard1.0\TransformTargets\Microsoft.NET.Sdk.Publish.TransformFiles.targets

<Import Project=”$(_PublishTargetsDir)Microsoft.NET.Sdk.Publish.$(PublishProtocol).targets” Condition=”Exists(‘$(_PublishTargetsDir)Microsoft.NET.Sdk.Publish.$(PublishProtocol).targets’)”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk.Publish\build\netstandard1.0\PublishTargets\Microsoft.NET.Sdk.Publish.FileSystem.targets

<Import Project=”$(_DotNetCLIToolTargetsDir)Microsoft.NET.Sdk.DotNetCLITool.targets” Condition=”Exists(‘$(_DotNetCLIToolTargetsDir)Microsoft.NET.Sdk.DotNetCLITool.targets’)”>
C:\Program Files\dotnet\sdk\1.0.0-rc3-004530\Sdks\Microsoft.NET.Sdk.Publish\build\netstandard1.0\DotNetCLIToolTargets\Microsoft.NET.Sdk.DotNetCLITool.targets

さて、有望株と言える二つに注目しましょう。

$(MSBuildProjectExtensionsPath)$(MSBuildProjectFile).*.props と $(MSBuildProjectExtensionsPath)$(MSBuildProjectFile).*.targets を読み込んでいます。

dotnet build /v:diag

での出力から、MSBuildProjectExtensionsPath は Project の obj 配下となります。

MSBuildProjectExtensionsPath = C:\Users\kazuk\Documents\Visual Studio 2017\Projects\WebApplication4\WebApplication2\obj\

よりによって obj かよ!って事でこれは残念。NuGet から展開された props / targets を実行するのに使ってるみたいです。

ですが、それの近くに Condition がマッチせずに Import されなかった

<Import Project=”$(DirectoryBuildPropsPath)” Condition=”‘$(ImportDirectoryBuildProps)’ == ‘true’ and exists(‘$(DirectoryBuildPropsPath)’)”>

<Import Project=”$(DirectoryBuildTargetsPath)” Condition=”‘$(ImportDirectoryBuildTargets)’ == ‘true’ and exists(‘$(DirectoryBuildTargetsPath)’)” />

な Import があります。

DirectoryBuildPropsPath はプロジェクトディレクトリの Directory.Build.props、DirectoryBuildTargetsPathはプロジェクトディレクトリの Directory.Build.targets があれば読み込むようになっています。

やってみた

Directory.build.targets をプロジェクト配下に作成します。

<?xml version=”1.0″ encoding=”utf-8″ ?>
<Project>
  <Target Name=”mySampleTarget” AfterTargets=”Build” >
    <Message Text=”mySampleTarget running” Importance=”High”/>
  </Target>
</Project>

dotnet build でビルド実行した結果、定義したターゲットが実行されました。

C:\Users\kazuk\Documents\Visual Studio 2017\Projects\WebApplication4\WebApplication2> dotnet build
Microsoft (R) Build Engine version 15.1.523.56541
Copyright (C) Microsoft Corporation. All rights reserved.   WebApplication2 -> C:\Users\kazuk\Documents\Visual Studio 2017\Projects\WebApplication4\WebApplication2\bin\Debug\netcoreapp1.1\WebApplication2.dll   mySampleTarget running C:\Users\kazuk\Documents\Visual Studio 2017\Projects\WebApplication4\WebApplication2>

Visual Studio でビルドしてもいけるよね?

いけるみたいです。上記でのメッセージはビルドの出力ウインドウに出ました。

まとめ

遠回りはした気もしないでもないが、 Directory.build.props / Directory.build.targets をプロジェクトディレクトリに置くだけで msbuild でのビルドプロセスはカスタマイズできます。

その昔のビルドカスタマイズポイントだった csproj.user とかはどうやら無くなってます。

なんかカスタマイズとかしたのに読まれてなくない?とか一体どこのファイルがコレやってるのとかその辺を調べるのには /pp でプリプロセス結果吐かせると便利ですね。(このファイル、Import の解決した結果を完全に吐いてくれるので別環境でビルドするには便利かもしれません。)

あとは /v:diag してログ眺めれば不思議な事なんてない(震え声

広告