Voo
Voo

Reputation: 30216

Exclude Project in sln from dotnet build

I have a roslyn analyzer project based on Microsoft's default template. I can easily build the analyzer in Visual Studio or with msbuild.

The problem is that the solution includes a vsix project that relies on the microsoft.vssdk.buildtools which are not supported by dotnet build. This results in an error message when trying to build the solution in the command line with dotnet build: microsoft.vssdk.buildtools\17.4.2119\tools\VSSDK\Microsoft.VsSDK.targets(826,5): error : VSIX deployment is not supported with 'dotnet build'

The vsix is nice to have when developing with Visual Studio, but I do publish my analyzer via NuGet package instead of as vsix so I don't need the vsix on the CLI.

Is there a way to specify in the csproj that I don't want it to be built when it is invoked from dotnet build? I'd like to avoid having a separate sln file or a specific dotnet configuration that excludes the project if possible.

Upvotes: 0

Views: 3673

Answers (1)

Jonathan Dodds
Jonathan Dodds

Reputation: 5068

Two possible approaches include using a solution filter and changing the project to not build under certain conditions.

Use a Solution Filter

dotnet build will accept a solution filter file (.slnf).

To create the solution filter:

  1. Open the solution in Visual Studio
  2. Go to the solution explorer window
  3. Right-click on the VSIX project, choose 'Unload Project'
  4. Right-click on the solution, choose 'Save As Solution Filter'

When building with dotnet the .slnf will need to be used. Using the .sln file or the VSIX project file with dotnet will be an error.

Detecting when Invoked from dotnet build

There isn't a defined property or function in MSBuild that identifies the executable that is running the MSBuild engine.

However there is a MSBuildRuntimeType property.

Prior to MSBuild 15, MSBuildRuntimeType will be undefined. In MSBuild 15 and later MSBuildRuntimeType will have a value of Full, Core, or Mono. From the documentation MSBuildRuntimeType will have a value of Core when dotnet build is used. (Further the error message "VSIX deployment is not supported with 'dotnet build'" is only displayed when '$(MSBuildRuntimeType)' == 'Core'.)

There isn't an 'exit build' task so the project can't detect and then end. We need to detect before the project really starts. But wrapping a project within a project is clunky especially if you want to be able to work with the project and change properties from the Visual Studio IDE.

Targets can be redefined and an Import can have a condition. A file can be imported when MSBuildRuntimeType is Core and the file can redefine the 'Build' target.

Add to the VSIX project file:

    <Import Project="noop.targets" Condition="'$(MSBuildRuntimeType)' == 'Core'" />

The noop.targets may contain the following:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Target Name="Build">
        <Message Text="$(MSBuildProjectName) has been skipped." />
    </Target>
</Project>

Hope this helps or at least provides some ideas.

Upvotes: 3

Related Questions