ビルド プロセスを拡張して柔軟性を高めるために、MSBuild API を直接使用する作業を開始しました。
プロジェクトを構築するプロセス全体を自動化することに成功しましたが、いくつかの「落とし穴」がないわけではありません。MSBuild API に関するドキュメントと使用例が極端に不足していたため、長時間のデバッグ セッションに耐えることを余儀なくされました。
ここで概説する詳細が、MSBuild API との直接統合を検討している他のユーザーに役立つことを願っています。
C# コードのコンパイルは非常に簡単でしたが、MSBuild API を使用して従来の VC++ プロジェクトのいくつかをコンパイルしようとすると、プロセスが本当に行き詰まりました。
これは、私のコンパイラ ラッパーのコード サンプルです。
globalProperties["Configuration"] = CommonLibrary.BuildMode.Release.ToString();
//add the compiler variables from the specific project to the properties dictionary
if (compilerVariables != null)
{
foreach(var kvp in compilerVariables)
{
globalProperties.Add(kvp.Key, kvp.Value);
}
}
//set up a build request to be sent to MSBuild
var request = new BuildRequestData(project.SolutionFile.FullName, globalProperties, null, new string[] { "Rebuild" }, null);
//configure settings for MSBuild specifically
var buildParams = new BuildParameters();
buildParams.EnableNodeReuse = true;
buildParams.Loggers = new List<Microsoft.Build.Framework.ILogger>()
{
buildLogger,
fileLogger
};
//instantiate the BuildManager, kick off the build, and get the results
BuildManager buildManager = new BuildManager();
project.BuildResult = buildManager.Build(buildParams, request);
このプロセスのもう 1 つの側面には、リンカに必要な INCLUDE (およびその他のパス) を取得するために VC++ が使用する .props ファイルが含まれます。この .props ファイルは C:\Users\%BUILDACCOUNT%\AppData\Local\Microsoft\MSBuild\v4.0\Microsoft.Cpp.%TargetPlatform%.user.props にあります。
次に興味深い部分です。
このコードを C# プロジェクト/ソリューションに対して実行すると、すべて正常に動作します。これは、.props ファイルが C# のコンパイルに関与しないためです (インクルード パスは .csproj レベルとして格納されます)。
ただし、VC++ プロジェクトを含むソリューションに対して実行すると、このメソッドは完全に面目を失います。その理由は、props ファイル内 (上記の場所) にあると思われる INCLUDE パスを解決できないためです。
もう 1 つの興味深い情報は、引数をコマンド ラインから直接 MSBuild にレプリケートでき、ビルドが正常に成功することです。これには本当に戸惑いました...そのため、詳細な診断をオンにして、テストケースを再度実行しました。
ログからの興味深い情報 (ログはトリミングされています):
- コマンドラインからのビルド
ユーザードメイン = [編集済]
USERNAME = MyUserName
LOCALAPPDATA = C:\Users\MyUserName\AppData\Local
- API からの構築
ユーザードメイン = [編集済]
ユーザー名 = BUILDMACHINE$
LOCALAPPDATA = C:\Windows\system32\config\systemprofile\AppData\Local
ご覧のとおり、CLI からビルドしたときの現在の ID は、自分の ID に正しく設定されているようです。ただし、API からビルドすると、現在の ID がローカル システムに設定されます。これにより、API ビルド用に INCLUDE パスが正しく設定されません。これは、その情報を含む props ファイルが予期される場所 (C:\Windows\system32\config\systemprofile\AppData\Local) で利用できないためです。
これまでのところ機能しているように見える私の回避策は、実際にすべての小道具ファイルを AppData の場所から API が予期しているディレクトリに移動することです。非常にわかりやすい。
その他の注意事項:
- このコードは、(ローカル システムではなく) "MyUserName" として実行されているアプリケーション プール内の IIS でホストされています。
- Windows Server 2008 を実行している 2 台の異なるマシンでこの問題を再現できました。
私が何か間違ったことをしているのですか、それとも MSBuild API が何か間違っているのですか? MSBuild API によって認識される props ファイルを取得するための公式の手段についての情報は、非常に役立ちます。
ありがとう。