PVS-StudioでのVisual Studio 2017およびRoslyn 2.0のサポート:既製のソリューションの使用はそれほど簡単ではない場合があります

この記事では、PVS-Studio開発者がVisual Studioの新しいバージョンのサポートで直面した問題についてお話したいと思います。 さらに、「既製のソリューション」(この場合はRoslyn)に基づくC#アナライザーのサポートが、状況によっては「自己作成」C ++アナライザーよりも高価になる理由を質問に答えてみます。



Visual Studioの新しいバージョン-2017のリリースにより、Microsoftは「フラッグシップ」IDEに多数の革新を提供します。 これらには以下が含まれます。





Visual Studio 2017をサポートするPVS-Studio 6.14のバージョンは、このIDEのリリースからわずか10日後にリリースされました。 新しいVSをサポートする作業は、昨年の終わりにかなり早く開始されました。 もちろん、Visual Studioのすべての革新がPVS-Studioの作業を損なうことはありませんでしたが、このIDEの最新リリースは、製品のすべてのコンポーネントでのサポートの点で特に時間がかかりました。 最も影響を受けたのは、「従来の」C ++アナライザーではなく(新しいバージョンのVisual C ++をサポートするのに十分高速であることが判明しました)、MSBuildアセンブリシステムおよびC#アナライザーのベースであるRoslynプラットフォームとの対話を担当するコンポーネントです。



また、Visual Studioの新しいバージョンは、C#アナライザーがPVS-Studio(Visual Studio 2015の最初のRoslynリリースと並行してリリースされました)に登場して以来、最初のものとなり、WindowsのC ++アナライザーはMSBuildアセンブリシステムにより密接に統合されました。 したがって、これらのコンポーネントを更新する際に直面する困難のため、新しいVSのサポートは、製品の歴史の中で最もコストがかかりました。



PVS-Studioが使用するマイクロソフトのソリューション



ほとんどの場合、PVS-StudioはC / C ++ / C#言語用の静的アナライザーであり、WindowsおよびLinuxで実行されることをご存じでしょう。 PVS-Studioの構成要素は何ですか? まず第一に、これはもちろん、クロスプラットフォームC ++アナライザーであり、さまざまなアセンブリシステムへの統合のための(主に)クロスプラットフォームユーティリティのセットです。



ただし、Windowsプラットフォームでは、ほとんどのユーザーがMicrosoftのソフトウェア開発にテクノロジースタックを使用しています。 Visual C ++ / C#、Visual Studio、MSBuildなど 彼らのために、Visual Studio環境(IDEプラグイン)からアナライザーを操作するためのツールと、C ++ / C#MSBuildプロジェクトをチェックするためのコマンドラインユーティリティがあります。 「ボンネットの下」で同じユーティリティがVSプラグインを使用します。 このユーティリティは、MSBuild自体が提供するAPIを使用して、プロジェクトの構造を直接分析します。 C#アナライザーは.NET Compiler Platform(Roslyn)に基づいており、これまではWindowsユーザーのみが利用できます。



そのため、Windowsプラットフォームでは、PVS-StudioはMicrosoftのネイティブツールを使用してVisual Studioへの統合、アセンブリシステムの分析、C#コードの分析を行うことがわかります。 Visual Studioの新しいバージョンのリリースに伴い、これらのコンポーネントもすべて更新されました。



Visual Studio 2017のリリースで変更された点



Visual Studio 2017には、MSBuildおよびRoslynのバージョンの更新に加えて、製品に大きな影響を与えた多くの革新的な機能が含まれています。 そのため、Visual Studioの以前のいくつかのリリースで変更せずに使用していたコンポーネントの多くが動作を停止し、それらの一部はVisual Studio 2005(現在サポートしていません)以降動作しています。 これらの変更をより詳細に検討してみましょう。



Visual Studio 2017の新しいインストール順序



ユーザーが作業に必要なコンポーネントのみを選択できるようにする新しいモジュール式インストールシステムは、Windowsレジストリの使用から完全に「無縁」になりました。 理論的には、これにより開発環境の移植性が高まり、同じシステムに複数の異なるエディションのVisual Studioをインストールできるようになりました。 ただし、これはすべて、拡張機能の開発者に大きな影響を与えました。 最もインストールされた環境またはその個々のコンポーネントの存在を以前に判断できるすべてのコードが機能しなくなりました。



図1-Visual Studioの新しいインストーラー







図1-Visual Studioの新しいインストーラー



システムにインストールされているVisual Studioのインスタンスに関する情報を取得するために、開発者はCOMインターフェイス、特にISetupConfigurationを使用するように招待されています。 COMインターフェイスを使用することの利便性は、レジストリからの読み取りに劣ることに、多くの人が同意すると思います。 また、たとえばC#コードの場合、少なくともこれらのインターフェイスのラッパーが既に存在する場合は、InnoSetupに基づいてインストーラーを適合させるために一生懸命に作業する必要がありました。 実際、ここでMicrosoftはWindows固有のテクノロジーを別のテクノロジーに変更しました。 私の意見では、特にVSはまだレジストリの使用を完全に拒否することができなかったため、このような移行からの利益は非常に疑わしいです。 少なくともこのバージョンでは。



かなり主観的な使いやすさに加えて、この移行のより重要な結果は、使用したMSBuild 15ライブラリの操作と以前のバージョンのMSBuildとの下位互換性に間接的に影響したことです。 これは、MSBuildの新しいバージョンでもレジストリの使用が停止されたためです。 次のように、MSBuildに使用したすべてのコンポーネントを更新する必要がありました。 ロズリンはそれらに直接依存しています。 これらの変更の結果については、後ほど詳しく説明します。



C ++ MSBuildインフラストラクチャの変更点



C ++のMSBuildインフラストラクチャとは、主にVisual C ++プロジェクトをビルドするときにコンパイラを直接呼び出す役割を担うレイヤーを意味します。 この層は、MSBuildではPlatformToolsetと呼ばれ、C ++コンパイラが動作する環境の準備を担当します。 PlatformToolsetシステムは、Visual C ++コンパイラの以前のバージョンとの下位互換性も提供します。 これにより、MSBuildの最新バージョンを使用して、以前のバージョンのVisual C ++コンパイラーを使用してプロジェクトをビルドできます。



たとえば、このバージョンのコンパイラがシステムにインストールされている場合、MSBuild 15 / Visual Studio 2017でVisual Studio 2015のC ++コンパイラを使用してプロジェクトをビルドできます。 これは便利かもしれません 最初にプロジェクトを新しいバージョンのコンパイラに移植することなく、プロジェクトですぐに新しいバージョンのIDEの使用を開始できます(常に簡単ではありません)。



PVS-StudioはPlatformToolsetを完全にサポートし、「ネイティブ」MSBuild APIを使用してC ++アナライザーの環境を準備します。これにより、アナライザーはコンパイル方法に最も近いソースコードをチェックできます。



MSBuildとのこのような緊密な統合により、以前のMicrosoftのC ++コンパイラの新しいバージョンを簡単にサポートできました。 より正確には、アセンブリ環境を維持するため、 直接新しいコンパイラ機能(たとえば、この構文を使用する構文およびヘッダーファイル)のサポートは、この記事で説明されている問題には含まれていません。 サポートされているもののリストに新しいPlatformToolsetを追加しただけです。



Visual C ++の新しいバージョンでは、コンパイラー環境の設定順序が大幅に変更され、Visual Studio 2010以降のすべてのバージョンで以前に動作していたコードが再び「壊れ」ます。以前のバージョンのコンパイラーのPlatformToolsetは引き続き動作しますが、新しいツールセットをサポートするために「しかし、別のコードブランチを作成する必要がありました。 奇妙な偶然の一致(おそらく偶然ではない)により、MSBuild開発者は、C ++ツールセットの命名パターンも変更しました:以前のバージョンのv100、v110、v120、v140、および最新バージョンのv141(Visual Studio 2017にはまだバージョンがありますが) 15.0)。



新しいバージョンでは、vcvarsスクリプトの構造が完全に変更されました。これは、コンパイラー環境の展開に関連しています。 これらのスクリプトは、コンパイラに必要な環境変数を設定し、バイナリディレクトリやシステムC ++ライブラリなどへのパスでPATHを補完します。 アナライザーの操作には、特に分析自体を開始する前にソースファイルを前処理するために、同一の環境が必要です。



ある意味で、展開スクリプトの新しいバージョンは「よりきれい」になり、維持および拡張が容易になる可能性が高いと言えます(これらのスクリプトの更新は、Visual C ++の新しいバージョンにclangサポートを含めることによって引き起こされた可能性があります)コンパイラ)、しかし、C ++アナライザーの開発者の観点から、これは私たちの仕事に追加されました。



C#アナライザーPVS-Studio



Visual Studio 2017とともに、Roslyn 2.0およびMSBuild 15がリリースされましたが、PVS-Studio Cでこれらの新しいバージョンをサポートするために、プロジェクトでNugetが使用するパッケージを更新するのは非常に簡単です。 その後、C#7.0のサポート、新しいタイプの.NET Coreプロジェクトなど、新しいバージョンのすべての「利点」がすぐにアナライザで利用可能になります。



実際、使用しているパッケージの更新とC#アナライザーの再構築は非常に簡単でした。 ただし、テストでこのような新しいバージョンを初めて起動すると、「すべてが壊れた」ことが示されました。 さらに実験を行ったところ、C#アナライザーはVisual Studio 2017 \ MSBuild 15がインストールされているシステムでのみ正常に動作することがわかりました。 C#アナライザーの新しいバージョンの「現状のまま」のリリースは、以前のバージョンのC#コンパイラーで作業するすべてのユーザーの分析結果の悪化を伴います。



Roslyn 1.0を使用したC#アナライザーの最初のバージョンを作成したとき、システムにサードパーティのインストールコンポーネントを必要とせずに、アナライザーを可能な限り「独立」にしようとしました。 同時に、ユーザーシステムの主な要件は、チェックされたプロジェクトの収集可能性です。プロジェクトが組み立てられている場合、アナライザーでチェックできます。 明らかに、WindowsでVisual C#プロジェクト(csproj)をビルドするには、少なくともMSBuildとC#コンパイラが必要です。



私たちは、ユーザーにC#アナライザーと共に最新バージョンのMSBuildとVisual C#のインストールを要求するという考えをすぐに放棄しました。 ユーザーが通常プロジェクトをビルドする場合、たとえばVisual Studio 2013(順番にMSBuild 12を使用)でMSBuild 15をインストールする要件は冗長に見えます。 それどころか、「しきい値」を下げてアナライザーの使用を開始しようとしています。



MicrosoftのWebインストーラーは、必要なダウンロードのサイズを非常に要求していることが判明しました-ディストリビューションのサイズは約50メガバイトですが、たとえば、Visual C ++ 2017(C ++アナライザーにも必要)のインストーラーは、ダウンロードするデータ量を約3ギガバイト。 その結果、後で確認したように、これらのコンポーネントの存在は、C#アナライザーが正常に機能するには不十分です。



PVS-StudioとRoslynの相互作用



C#アナライザーの開発を始めたばかりのとき、Roslynプラットフォームと対話する方法は2つありました。



最初のオプションは、.NETアナライザーの開発用に特別に作成された診断APIを使用することでした。 このAPIは、抽象クラスDiagnosticAnalyzerから継承して、「診断」を実装する機会を提供します。 CodeFixProviderクラスを使用すると、このような警告に対する自動修正を実装できます。



このアプローチの間違いない利点は、既存のRoslynインフラストラクチャのフルパワーです。 診断ルールは、Visual Studioコードエディターですぐに使用可能になり、IDEエディターでコードを編集するときとプロジェクトの再構築を開始するときに自動的に適用できます。 このアプローチでは、アナライザーの開発者がプロ​​ジェクトファイルとソースファイルを個別に開く必要はありません。すべてがRoslynに基づく「ネイティブ」コンパイラーの作業の一部として実行されます。 最初にこの方法で行けば、新しいRoslynへの移行に関する問題は、少なくとも現在の形では発生しないでしょう。



2番目のオプションは、PVS-Studio C ++の動作と同様に、完全に自律的なアナライザーを実装することでした。 私たちはそれで止めました、なぜなら C#アナライザーインフラストラクチャを既存のC / C ++ツールに可能な限り近づけることにしました。 将来的には、これにより、現在のC ++診断(もちろん、すべてではなく、C#に関連する部分)と、より高度な分析手法の両方を迅速に適合させることができました。



Roslynは、このアプローチを実装する機会を提供します。VisualC#プロジェクトファイルを独立して開き、ソースコードから構文ツリーを構築し、それらを横断する独自のメカニズムを実装します。 これはすべて、MSBuildおよびRoslyn APIを使用して行われます。 したがって、分析のすべての段階を完全に制御でき、コンパイラまたはIDEの動作に依存しません。



Visual Studioコードエディタとの「無料」統合がいかに魅力的であっても、標準のエラーリスト(このような警告が発行される)よりも多くの機能を提供するため、独自のIDEインターフェイスを使用することを好みます。 Diagnostics APIを使用すると、Roslynベースのコンパイラバージョン、つまり Visual Studio 2015および2017に沿って進み、独立したアナライザーによって以前のすべてのバージョンをサポートできました。



C#アナライザーの作成中に、RoslynがMSBuildと非常に密接に結びついていることが判明しました。 もちろん、ここで私はRoslynのWindowsバージョンについて話していますが、残念ながら、Linuxバージョンをまだ使用する必要はないので、そこにどのように進んでいるかは言えません。



私の意見では、MSBuildプロジェクトを操作するためのRoslynのAPIは、バージョン2.0でも十分に未加工のままです。 C#アナライザーを作成するとき、さまざまな「クランチ」を作成する必要がありました。 Roslynはいくつかのことを間違って行い(誤って=「同じプロジェクトをビルドするときにMSBuildが行っていなかったように」)、最終的にソースファイルをチェックするときに誤検知と分析エラーを引き起こしました。



Visual Studio 2017へのアップグレード時に遭遇した問題につながったのは、まさにMSBuildでのRoslynの関与でした。



ロズリンとMSBuild



アナライザーが機能するためには、ほとんどの場合、Roslynから2つのエンティティを取得する必要があります。テスト対象のコードの構文ツリーと、このツリーのセマンティックモデルです。 ノードを表す構文構造の意味—クラスフィールドタイプ、戻り値、メソッドシグネチャなど。 Roslynを使用して構文ツリーを取得するには、ソースコードを含むファイルがあれば十分です。このファイルのセマンティックモデルを生成するには、それを含むプロジェクトをコンパイルする必要があります。



Roslynをバージョン2.0に更新すると、テストでセマンティックモデルにエラーが発生しました(アナライザーV051のメッセージがこれを示しています)。 このようなエラーは通常、アナライザーの結果に偽陰性/偽陽性の応答として表示されます。 いくつかの良いメッセージが消え、悪いメッセージが表示されます。



セマンティックモデルを取得するために、Roslynはいわゆる .NET MSBuildプロジェクト(この場合はcsprojとvbproj)を開き、そのようなプロジェクトの「コンパイル」を取得できるワークスペースAPI。 このコンテキストでは、Roslynのコンパイルユーティリティクラスのオブジェクトについて説明し、C#コンパイラの準備と呼び出しを抽象化します。 このような「コンパイル」から、セマンティックモデルを直接取得できます。 コンパイルのエラーは、最終的にセマンティックモデルのエラーにつながります。



次に、RoslynがMSBuildと対話してプロジェクトの「コンパイル」を取得する方法を見てみましょう。 以下は、この相互作用を簡略化した形式で示す図です。



図2-RoslynとMSBuildの相互作用のスキーム







図2-RoslynとMSBuildの相互作用のスキーム



この図は、PVS-Studioとビルドツールの2つのセグメントに分かれています。 PVS-Studioセグメントには、アナライザーと一緒に配布されるコンポーネント(使用するAPIを実装するMSBuildおよびRoslynライブラリー)が含まれています。 ビルドツールセグメントには、APIデータが正しく機能するためにシステムに存在する必要があるアセンブリシステムインフラストラクチャが含まれています。



アナライザーが(セマンティックモデルを取得するために)ワークスペースAPIからコンパイルオブジェクトを要求した後、Roslynはプロジェクトのビルドを開始します。MSBuildの用語では、cscタスクの実行を開始します。 アセンブリを開始すると、制御はMSBuildに渡され、MSBuildはそのアセンブリスクリプトに従ってすべての準備手順を実行します。



これは「通常の」アセンブリではないことに注意してください(バイナリファイルの生成にはつながりません)。 デザインモード。 このステップの最終目標は、「実際の」ビルド中にコンパイラーに提供されるすべての情報をRoslynに取得することです。 アセンブリがいくつかの事前アセンブリ手順(たとえば、ソースファイルの一部を自動的に生成するスクリプトの実行)に関連付けられている場合、そのようなアクションはすべて、MSBuildによって通常のアセンブリであるかのように実行されます。



制御を取得すると、MSBuild、またはPVS-Studioの一部であるライブラリが、システムにインストールされているアセンブリツール(ツールセット)の検索を開始します。 適切なツールセットを見つけた後、彼女はビルドスクリプトで説明されている手順をインスタンス化しようとします。 ツールセットは、システムにインストールされているMSBuildのインスタンスに対応しています。 たとえば、MSBuild 14(Visual Studio 2015)はツールセット14.0、MSBuild 12-12.0などをインストールします。



ツールセットには、MSBuildプロジェクトのすべてのサンプルビルドスクリプトが含まれています。 通常、プロジェクトファイル(csprojなど)には、アセンブリ入力ファイル(ソースファイルなど)のリストのみが含まれます。 ツールセットには、これらのファイルで実行する必要があるすべての手順が含まれています。コンパイルとリンクから、アセンブリ結果の公開までです。 MSBuildの仕組みについては説明しません。1つのプロジェクトファイルとプロジェクトパーサー(つまり、PVS-Studioに付属のMSBuildライブラリ)がアセンブリを完了するのに十分でないことを理解することだけが重要です。



[ビルドツール]チャートセグメントに移動します。 アセンブリ手順cscに興味があります。 MSBuildは、このステップが直接実装されているライブラリを見つける必要があり、選択されたツールセットのタスクファイルがこれに使用されます。 タスクファイルは、標準のアセンブリタスクを実装するライブラリへのパスを含むxmlファイルです。 このファイルに従って、cscタスクの実装を含むライブラリが検索され、ロードされます。 このタスクは、コンパイラ自体を呼び出すためのすべてを準備します(通常、これは別個のコマンドラインユーティリティcsc.exeです)。 思い出すように、「偽の」ビルドがあるため、すべての準備ができたときにコンパイラは呼び出されません。 Roslynは、セマンティックモデルを取得するために必要なすべての情報を既に持っています-他のプロジェクトおよびライブラリへのすべてのリンクが公開されています(結局、これらの依存関係で宣言された型は、テスト対象のコードで使用でき、すべての事前アセンブリ手順が実行され、すべての依存関係が復元\コピーなどされます)



幸いなことに、これらのステップの一部で何かが「間違った」場合、Roslynにはコンパイル前に知られている情報に基づいてセマンティックモデルを準備するための予備のメカニズムがあります。 MSBuild Execution APIへの移行まで。 通常、これはプロジェクトファイルの評価からの情報です(別のMSBuild評価APIを使用して行われます)。 多くの場合、この情報では完全なセマンティックモデルを構築するには不十分です。 ここで最も顕著な例は、新しい.NET Coreプロジェクト形式です。この形式では、プロジェクトファイル自体にはまったく何も含まれません。依存関係はもちろん、ソースファイルのリストも含まれません。 しかし、「通常の」csprojファイルでも、コンパイルに失敗すると依存関係と条件付きコンパイルシンボル(define'ov)へのリンクが失われますが、それらの値はプロジェクトファイル自体に直接書き込まれます。



何が悪かった



私が望むように、C#プロジェクトをチェックするときにPVS-Studioの「内部」で何が起こっているかが多かれ少なかれ明らかになったので、RoslynとMSBuildのアップグレード後に何が起こったのか見てみましょう。 上記の図から、PVS-Studioの観点から見たビルドツールの一部は「外部環境」にあり、したがって、当社によって制御されていないことがはっきりとわかります。 前に説明したように、MSBuild全体をディストリビューションに含めるという考えを捨てたため、ユーザーのシステムにインストールされるものに依存する必要があります。 2010バージョンのVisual Studio以降、Visual C#のすべてのバージョンでの作業をサポートしているため、多くのオプションがあります。 同時に、RoslynはVisual Studio-2015の以前のバージョンからのみC#コンパイラの基礎として使用されるようになりました。



MSBuild 15がアナライザーを起動するシステムにインストールされていない状況を考慮し、Visual Studio 2015(MSBuild 14)でプロジェクトを検証するためにアナライザーを実行します。 そしてここで、Roslynで最初の「カント」にすぐに遭遇します-MSBuildプロジェクトを開くと、正しいツールセットを示していません。 ツールセットが指定されていない場合、MSBuildは、MSBuildが使用するライブラリのバージョンに応じて、デフォルトでツールセットの使用を開始します。 そしてなぜなら Roslyn 2.0はMSBuild 15に依存してコンパイルされるため、このライブラリはこのバージョンのツールセットを選択します。



このツールセットがシステムに存在しないという事実により、MSBuildはこのツールセットを正しくインストールしません。4番目のバージョンのツールセットを指す存在しない不正なパスの「ミッシュマッシュ」を作成します。 なぜ4番目なのか? そのようなツールセットとMSBuildの4番目のバージョンは、.NET Framework 4の一部としてシステムで常に利用できるため(MSBuildの後続のバージョンでは、フレームワークから解放されました)。 この結果、誤ったターゲットファイル、誤ったcscタスク、および最終的にはコンパイルおよびセマンティックモデルのエラーが選択されます。



古いバージョンのRoslynでこのようなエラーが発生しなかったのはなぜですか? まず、アナライザーの使用統計から判断すると、ほとんどのユーザーはVisual Studio 2015を使用しています。 (Roslyn 1.0の)正しいバージョンのMSBuildが既にインストールされています。



第二に、MSBuildの新しいバージョンは、前述したように、レジストリを使用してその構成、特にインストールされているツールセットに関する情報を保存することを停止しました。 また、MSBuildの以前のバージョンがすべてツールセットをレジストリに保存していた場合、MSBuild 15はMSBuild.exeの隣の構成ファイルに保存するようになりました。 また、新しいMSBuildは「登録アドレス」を変更しました-以前のバージョンはc:\ Program Files(x86)\ MSBuild \%VersionNumber%に一様にインストールされ、新しいバージョンはデフォルトでVisual Studioインストールディレクトリに展開されます(以前のバージョンと比較して変更されました) )



この事実は、以前のバージョンで誤って選択されたツールセットを「隠した」場合があります-セマンティックモデルはそれで正しく生成されました。 さらに、必要な新しいツールセットがシステムにある場合でも、使用するライブラリが見つからない場合があります。これは、レジストリではなくapp.configファイルに登録され、MSBuild.exeプロセスからライブラリが読み込まれないためです。およびPVS-Studio_Cmd.exeから。 同時に、新しいMSBuildにはこのケース用の予備のメカニズムがあります。 前述のISetupConfigurationを実装するCOMサーバーがシステムにインストールされている場合、MSBuildはVisual Studioインストールディレクトリでツールセットを見つけようとします。 ただし、スタンドアロンのMSBuildインストーラーは、もちろんこのCOMインターフェイスを登録しません-Visual Studioインストーラーのみがこれを行います。



そして最後に、第三に、おそらく、主な理由は、残念なことに、サポートされている構成のさまざまなオプションでのアナライザーのテストが不十分であったため、問題を早期に特定できなかったためです。 アナライザーの毎日のテスト用のすべてのマシンにVisual Studio 2015 \ MSBuild 14がインストールされていたので、クライアントから報告される前にこの問題を特定して修正することができました。



Roslynが機能しない理由を理解したため、プロジェクトを開くときに正しいツールセットを示すことを試みることにしました。 別の質問、どのツールセットを「正しい」と見なすべきですか? 同じMSBuild APIを使用して、C ++アナライザー用のC ++プロジェクトを開いたときに尋ねました。 なぜなら 記事全体をこの問題に当てることができますが、ここでは詳しく説明しません。 残念ながら、Roslynは使用するツールセットを選択する機会を提供していないため、独自のコードを変更する必要がありました(既製のNugetパッケージを取得できないため、さらに不便です)。 その後、テストベースの一部のプロジェクトで問題がなくなりました。 ただし、さらに多くのプロジェクトには新しい問題があります。 今何が悪かったのですか?



上記の図で説明されているすべてのプロセスは、オペレーティングシステムの同じプロセス(PVS-Studio_Cmd.exe)内で行われることに注意してください。 適切なツールセットを選択すると、dllモジュールのロード中に競合が発生することが判明しました。 テストバージョンではRoslyn 2.0を使用していますが、その一部は、たとえばバージョン2.0のMicrosoft.CodeAnalysis.dllライブラリです。 このライブラリは、プロジェクト分析の開始時にすでにPVS-Studio_Cmd.exeプロセスメモリ(C#アナライザー)にロードされていました。 2015 Visual Studioのプロジェクトをチェックしていることを思い出させてください。そのため、開くときにツールセット14.0を指定します。 次に、MSBuildは正しいタスクファイルを見つけてコンパイルを開始します。 なぜなら このツールセットのC#コンパイラ(Visual Studio 2015を使用していることを思い出します)はRoslynバージョン1.3を使用し、それに応じてMSBuildはMicrosoft.CodeAnalysis.dllバージョン1.3をプロセスメモリにロードしようとします。 そして、このステップで落ちます、なぜなら 上位バージョンの同じモジュールがプロセスメモリに既にロードされています。



この状況で何ができるでしょうか? 別のプロセスまたはAppDomainでセマンティックモデルを取得しようとしていますか? しかし、モデルを取得するには、Roslyn(つまり、競合を引き起こすすべてのライブラリ)が必要であり、あるプロセスドメインから別のドメインにモデルを転送するのは簡単な作業ではありません。 このオブジェクトには、プロジェクト、コンパイル、および派生元のワークスペースへのリンクが含まれています。



より適切なオプションは、C ++アナライザーとC#アナライザーに共通のパーサーソリューションとは別のバックエンドプロセスにC#アナライザーを分離し、それぞれRoslyn 1.0および2.0を使用して、このようなバックエンドの2つのバージョンを作成することです。 しかし、このソリューションには重大な欠点もあります。





最後の項目をさらに詳しく見てみましょう。 Visual Studio 2015の存在中に、3つの更新プログラムがリリースされました。それぞれの更新プログラムでは、Roslynコンパイラバージョンも1.0から1.3に更新されました。 たとえば、2.1に更新する場合、バックエンドを割り当てる場合、マイナースタジオの更新ごとにアナライザーの個別のバージョンを作成する必要があります。そうしないと、バージョンの競合でエラーを繰り返す可能性が、最新バージョンではないVisual Studioを使用しているユーザーに残ります。



また、たとえば、バージョン12.0(Visual Studio 2013)など、Roslynを使用しないツールセットで作業しようとすると、コンパイルが失敗したことにも注意してください。 理由は異なっていましたが、深く掘り下げることはしませんでした。 そして、既知の問題はそのような解決策を拒否するのに十分でした。



アナライザーと古いC#プロジェクトとの後方互換性の問題をどのように解決したか



エラーの原因を理解したため、アナライザーでツールセットバージョン15.0を「提供」する必要が生じました。 その可用性は、Roslynコンポーネントのバージョンの競合の問題から私たちを救い、Visual Studioのすべての以前のバージョンのプロジェクトをチェックすることを可能にします(コンパイラの最新バージョンは、C#言語のすべての以前のバージョンと下位互換性があります)。 「本格的な」MSBuild 15をインストーラーに取り込まないことを決めた理由は、すでに上記で説明しました。





しかし、プロジェクトのコンパイル時にRoslynが遭遇した問題を調査していると、そのようなコンパイルに必要なほとんどすべてのRoslynおよびMSBuildライブラリが既にディストリビューションに含まれていることがわかりました(必要ありません)。 実際、本格的なツールセットには、このツールセットが記述されたいくつかの小道具とターゲットファイルのみが必要でした。 そして、これらはMSBuildプロジェクト形式の通常のxmlファイルであり、合計数メガバイトの重さです。これらのファイルを配布キットに含めても問題ありません。



, , «» MSBuild «» toolset . MSBuild : Running without any defined toolsets. Most functionality limited. Likely will not be able to build or evaluate a project. (eg reference to Microsoft.*.dll without a toolset definition or Visual Studio instance installed) . , MSBuild , - , MSBuild.exe. , , « ».



MSBuild 15 toolset? , toolset app.config MSBuild.exe. , (PVS-Studio_Cmd.exe) MSBUILD_EXE_PATH . ! MSBuild Release Candidate 4. , master MSBuild GitHub'. , master' toolset' — appconfig' toolset , MSBuild.exe. 0 MSBuild.exe, MSBUILD_EXE_PATH PVS-Studio_Cmd.exe.



MSBuild . , toolset' , MSBuild — . , WebApplication, Portable, .NET Core . Visual Studio, MSBuild. «» MSBuild , , . « » toolset. ( MSBuildExtensionsPath) toolset' , PVS-Studio_Cmd.exe . , WebApplication Visual Studio 2015, , , , , extension' toolset' 14.0, . MSBuild props\targets , .



C# Visual Studio, - MSBuild. - MSBuild, toolset', PVS-Studio.



PVS-Studio , Lightweight Solution Load



Visual Studio 2017, , , — «lightweight solution load».



 3 - lightweight solution load







3 — lightweight solution load



IDE , . «lightweight solution load» ( ) Visual Studio. ( ) : ( ), . .



:





, , . , , Visual Studio 2017 «lightweight solution load», .



« », RC Visual Studio « » Microsoft , , . — , , PVS-Studio.



? , , Visual Studio 2 — Visual Studio, 2- — Visual Studio SDK ( Visual Studio ). - Visual Studio SDK RC Visual Studio 2017. .. SDK ( , – ), . , PVS-Studio, . , , .



おわりに



Visual Studio 2017 «» PVS-Studio . — MSBuild\Visual Studio, C# PVS-Studio ( ).



C#, , Roslyn . — 4 . , , C++ , C#. . , «», Roslyn / Visual Studio. C#, Roslyn, - ( MSBuild Visual Studio), . Roslyn MSBuild standalone .



, «» C++ - , , Clang. , C++ . , , , « », .







, : Paul Eremeev. Support of Visual Studio 2017 and Roslyn 2.0 in PVS-Studio: sometimes it's not that easy to use ready-made solutions as it may seem



記事を読んで質問がありますか?
多くの場合、記事には同じ質問が寄せられます。 ここで回答を収集しました: PVS-Studioバージョン2015に関する記事の読者からの質問への回答 。 リストをご覧ください。



All Articles