C#
AzureFunctions
VSTS

sln ファイルと csproj ファイル の関係と特定の プロジェクトだけビルドする方法

More than 1 year has passed since last update.

Azure Functions のプロジェクトを VSTS でビルド/テストをして、デプロイする環境を作った。その過程で、いろいろ気になることを調べてみた。

Solution と Project

最初に初めてC# を触った時に、一番頭が混乱したことが、sln ファイルとか、csproj ファイルが自動的に出来上がることだった。テンプレートでできるので、「作れる」のだが、意味がわからないのは相当気持ち悪かった。整理のために、今まで理解したことを書いておく。

Project が exe を生成する単位。ソースだけではなく、設定ファイルや、データ、イメージも含まれる。拡張子は、様々なバリエーションがあって、csproj だったり、sfproj だったりする。

solutionandproject.jpeg

Solution と Project の実態

テキストファイルである。ただし、あまり手で編集することを想定されていない(が、たまにある)sln が、基本的にはプロジェクトへの参照とグローバルのコンフィグレーション、projファイルが、実際のプロジェクトの実態になっている。

それぞれがどんな内容になるのかは、最小限のMSプロジェクトを公開してくれている人がいるので、それがわかりやすい

ビルドの用語

MS 独特の用語が説明もなく出てくるので最初は戸惑うかもしれない。

Build Configuration

Build Configuration は、環境ごとのコンフィグで、Release Debug が、最初からデフォルトである。環境ごとにコンフィグレーションを作ることができる。これらは、Configuration Manager から操作される(C# では)

Build Platform

ビルドプラットフォームは、x64 x86 Any CPUから選べる。ビルドするときのその名の通りのプラットフォーム

特定のプロジェクトのみビルドする

VSTS や、Visual Studio でビルドに使われているのは、msbuild というツールだ。一つのソリューション(sln) に複数のプロジェクトが含まれている場合、特定のプロジェクトのみビルドしたいという場合があるが、いくつかの方法がある。

1. msbuild のオプションを指定する

大抵ツールで隠蔽されているが、中身では、単純にmsbuildが動いている。/t オプションで必要となるプロジェクトのみターゲットを指定する

msbuild functions.sln /t:"Telemetry:Clean;Build";"Telemetry_Test:Clean;Build"

1.2. '.' は '_' に

尚、この際、VSTS もしくは他のツールでも、衝撃のポイントがあった。Telemetry.Test というプロジェクト名がテストプロジェクトでこれは普通のプラクティスだろう。その際、/t を使うときに、. を使うとヒットしない。代わりに _ を使う必要があった。だから上記のように、実際のプロジェクトは、Telemetry.Test でも、Telemetry_Test と記述している。

ちなみに、WebApp や AzureFunctions デプロイの際には、msbuild で zip に固められる。そしてそれを、msdeploy

VSTS で標準でついてくる Azure App Service Deploy でも、 VSTS のログを見ると、msdeploy を使っている。

"C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" -verb:sync -source:package='d:\a\1\a\WebApp.zip' -dest:auto,ComputerName='https://japanfunctions.scm.azurewebsites.net:443/msdeploy.axd?site=JapanFunctions',UserName='********',Password='********',AuthType='Basic' -setParam:name='IIS Web Application Name',value='JapanFunctions' -enableRule:DoNotDeleteRule -userAgent:VSTS_0de2e4a9-d53c-4227-a23d-f0b322cc38f2_build_36_225

2. ターゲットを sln ではなく、xxproj ファイルにする

上記のものは、functions.sln がターゲットになっているが、ソリューションではなく、個別のプロジェクトを指定してビルドをしてもよい。結果として、

bin
  Debug               <- bulid configuration
    net461
Obj
  Debug               <- build configuration
    net461

といった構造がプロジェクトごとに作られて、DLL 等が格納される。

3. sln ファイルの該当プロジェクトをコメントアウトする

ビルドすると見当たらないものが見つかるようなプロジェクトはコメントアウトしても上記と同じ結果が得られるが、お勧めはしない。バッドノウハウだ。

Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Telemetry", "Telemetry\Telemetry.csproj", "{7556824E-51EE-40F8-8A83-BCAE8975E7A6}"
EndProject
# Project("{E6C563F2-BDC2-4A24-ACBF-01715157DCBB}") = "ASAApplication", "ASAApplication\ASAApplication.asaproj", "{8741C1EE-B4E6-4620-80F4-FFFBF4B89019}"
# EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Telemetry.Test", "Telemetry.Test\Telemetry.Test.csproj", "{BAA6AC78-59C2-4472-ABE4-4064C38DDD07}"
EndProject
# Project("{00D1A9C2-B5F0-4AF3-8072-F6C62B433612}") = "ASASQL", "ASASQL\ASASQL.sqlproj", "{C018046A-28D0-4B9F-AF1B-2A0CC6B8FD6F}"
# EndProject

テンプレートのオプションを解析してみる

ついでなので、VSTS のテンプレートについてくる、Azure Functions をデプロイするときのビルドのオプションをみてみよう。

/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:DesktopBuildPackageLocation="$(build.artifactstagingdirectory)\WebApp.zip" /p:DeployIisAppPath="Default Web Site" /t:"Telemetry:Clean;Build";"Telemetry_Test:Clean;Build"

/p

プロパティの書き換え。例えば次のような感じ。/p = /property プロパティの区切りは ;

/property:WarningLevel=2;OutDir=bin\Debug

DeployOnBuild

ビルドの際に、パッケージ化/デプロイされるようにする指定

WebPublishMethod

デプロイメントパッケージの場合は Package を指定。ほかには file system などがある。

PackageAsSingleFile

アウトプットを、1つのzip にまとめ上げる指定

SkipInvalidConfigrations

不正なコンフィグを無視する指定

DesktopBuildPackageLocation

zip ファイルの場所を指定している

DeployIisAppPath

おそらく、デプロイ先の IIS のパス指定。

NOTE: ここはまだよくわかっていないので継続調査

How to package a web project for deployment from the command line

/t

先ほど解説したターゲットプロジェクトの指定

まとめ

簡単だが、ビルド周りに関する基礎知識をまとめてみた。実は、Azure Functions の push 型デプロイは完成しているのだが、それはまた次回以降で。

Resource