We have a bunch of custom static analysis rules that we wrote here at the company. We have to make them available for use with both FxCop (the stand-alone tool) and Visual Studio (the Team System edition that supports code analysis). In order to support the rules in both scenarios, they must be built against the specific APIs (either the FxCop or the Visual Studio versions). That means when I build the rules, I need to make sure I add references to the right assemblies. To facilitate this, I’ve changed the MSBuild files to pull in the right references depending on what build configuration I’m using.
The main assemblies we needed imported are the FxCopSdk.dll and the Microsoft.Cci.dll. The FxCop versions reside under the FxCop installation folder (something like c:\Program Files\Microsoft FxCop 1.35), and the Visual Studio version resides under the VS installation folder (something like C:\program files\microsoft visual studio 8\team tools\static analysis tools\fxcop\).
First thing I did was to create a new MSBuild project file, named FxCopReferences.proj. The content of this file is listed below:
<Project DefaultTargets="Build"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup> <Reference Condition=" '$(Configuration)' == 'Debug' "
Include="FxCopSdk, Version=1.35.0.0, Culture=neutral,
PublicKeyToken=2725db9ba1c53c87, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> <HintPath>
..\..\..\..\..\..\Program Files\Microsoft FxCop 1.35\FxCopSdk.dll
</HintPath> </Reference> <Reference Condition=" '$(Configuration)' == 'Debug' "
Include="Microsoft.Cci, Version=1.35.0.0, Culture=neutral,
PublicKeyToken=2725db9ba1c53c87, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> <HintPath>
..\..\..\..\..\..\Program Files\Microsoft FxCop 1.35\Microsoft.Cci.DLL
</HintPath> </Reference> <Reference Condition=" '$(Configuration)' == 'Release' "
Include="FxCopSdk, Version=8.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> <HintPath>
..\..\..\..\..\..\Program Files\Microsoft Visual Studio 8\
Team Tools\Static Analysis Tools\FxCop\FxCopSdk.dll
</HintPath> </Reference> <Reference Condition=" '$(Configuration)' == 'Release' "
Include="Microsoft.Cci, Version=8.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> <HintPath>
..\..\..\..\..\..\Program Files\Microsoft Visual Studio 8\
Team Tools\Static Analysis Tools\FxCop\Microsoft.Cci.dll
</HintPath> </Reference> </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> </Project>
The MSBuild project above defines an ItemGroup with Reference elements. The reference elements use the Condition to determine what kind of Build Configuration is being used: if "Debug", build it to FxCop; if "Release", build it to Visual Studio. Eventually I’ll change that to have FxCop and VS build configurations, but for now, I’m just going with that.
Next, I removed the references to the assemblies that I had before from my rule projects, and changed the project file (csproj file), so that it imports the FxCopReferences.proj file. That means I just added the following line to my csproj files:
<Import Project="..\..\StaticAnalysisRules\FxCopReferences.proj" />
That’s it! This approach gives me a quick way to produce versions of our rules assemblies targeting different code analysis runners (FxCop or Visual Studio, that is).