Search code examples
blazorncrunch

How to configure NCrunch so that it can build a Blazor project


When NCrunch (version 4.2.0.7) tries to build a Blazor project (version 3.0.0-preview9), it produces the following error:

packages\microsoft.aspnetcore.blazor.build\3.0.0-preview9.19465.2\targets\Blazor.MonoRuntime.targets (441, 5): The command "dotnet "C:\Users\Rodolfo.nuget\packages\microsoft.aspnetcore.blazor.mono\3.0.0-preview9.19462.2\build\netstandard1.0../../tools/illink/illink.dll" -l none --disable-opt unreachablebodies --verbose --strip-security true --exclude-feature com --exclude-feature sre -v false -c link -u link -b true -d (... lots of files here...) exited with code -532462766.

How can I get NCrunch to build Blazor projects?

Disclaimer: I'm writing this question after not finding a single answer online, including SO. I have already found the solution and intend to answer the question myself in order to - hopefully - help someone else.


Solution

  • UPDATE (2023-09-04): the Custom Build variables mentioned in the original post have changed.

    1. Since Blazor General Availability, a variable IsWasmProject=false is required.
    2. Since Visual Studio 17.7, a variable SelfContained=true is required (see https://stackoverflow.com/a/77036175/257372 for details)

    Original post TL;DR

    1. Go to the NCrunch Configuration for the Blazor project.
    2. Add a Custom build property named BlazorLinkOnBuild (as of 3.2.0-preview3, renamed to BlazorWebAssemblyEnableLinking) with a value of false.

    NCrunch configuration for a project NCrunch custom build property dialog


    Full explanation ... in case the details change.

    In line 441 of the .targets file mentioned in the error message you will find the Exec command that causes the error:

    <Exec Command="dotnet &quot;$(MonoLinkerPath)&quot; $(_BlazorLinkerAdditionalOptions) @(_BlazorFolderLookupPaths, ' ') -o &quot;$(BlazorIntermediateLinkerOutputPath)&quot; @(_BlazorAssemblyDescriptorFiles, ' ') @(_BlazorAssembliesToLink, ' ')"  />
    

    This command is wrapped in the following target:

    <Target
      Name="_LinkBlazorApplication"
      Condition="$(_BlazorShouldLinkApplicationAssemblies) != ''"
      Inputs="$(BlazorBuildLinkerInputsCache);
              @(IntermediateAssembly);
              @(_BlazorDependencyInput);
              @(BlazorLinkerDescriptor)"
      Outputs="$(BlazorIntermediateLinkerResultFilePath)"
    >
    

    Which means the Exec will only be executed if the _BlazorShouldLinkApplicationAssemblies property is not empty. Searching the .targets file for where this internal property is set, you will find this PropertyGroup (line 152):

    <PropertyGroup Label="Build properties">
      <_BlazorShouldLinkApplicationAssemblies Condition="$(BlazorLinkOnBuild) == 'false'"></_BlazorShouldLinkApplicationAssemblies>
      <_BlazorShouldLinkApplicationAssemblies Condition="$(BlazorLinkOnBuild) == 'true'">true</_BlazorShouldLinkApplicationAssemblies>
      <_BlazorBuiltInBclLinkerDescriptor>$(MSBuildThisFileDirectory)BuiltInBclLinkerDescriptor.xml</_BlazorBuiltInBclLinkerDescriptor>
    </PropertyGroup>
    

    This is why setting the BlazorLinkOnBuild (as of 3.2.0-preview3, renamed to BlazorWebAssemblyEnableLinking) to false allows NCrunch to build the project.