Building F# projects on NixOS

Posted in category nixos on 2017-01-30
Tags: F#, mono, nixos

Table of Contents

Building F# projects on NixOS with mono

Building F# on NixOS might result in Microsoft.FSharp.Targets target file not found. In order to cope with this, locate appropriate version of the Microsoft.FSharp.Targets file first:

echo $(dirname $(which fsharpc))/../lib/mono/4.5/Microsoft.FSharp.Targets

You might want to modify the version of mono currently used on your system.

Then just change all of your F# *.fsproj files from having this:

<Choose>
  <When Condition="'$(VisualStudioVersion)' == '11.0'">
    <PropertyGroup Condition="Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\           ⟫⟫⟫
      F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')">
      <FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\       ⟫⟫⟫
        v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>
    </PropertyGroup>
  </When>
  <Otherwise>
    <PropertyGroup Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\      ⟫⟫⟫
      v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets')">
      <FSharpTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\                   ⟫⟫⟫
        v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath>
    </PropertyGroup>
  </Otherwise>
</Choose>
<Import Project="$(FSharpTargetsPath)" />

Please note that ⟫⟫⟫ is there to denote the wrapped line and should never appear in your real code.

To having this:

<Choose>
  <When Condition="'$(VisualStudioVersion)' == '11.0'">
    <PropertyGroup Condition="Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\           ⟫⟫⟫
      F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')">
      <FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\       ⟫⟫⟫
        v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>
    </PropertyGroup>
  </When>
  <Otherwise>
    <PropertyGroup Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\      ⟫⟫⟫
      v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets')">
      <FSharpTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\                   ⟫⟫⟫
        v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath>
    </PropertyGroup>
    <PropertyGroup Condition="Exists('/run/current-system/sw/bin/../lib/mono/4.5/             ⟫⟫⟫
      Microsoft.FSharp.Targets')">
      <FSharpTargetsPath>/run/current-system/sw/bin/../lib/mono/4.5/                          ⟫⟫⟫
        Microsoft.FSharp.Targets</FSharpTargetsPath>
    </PropertyGroup>
  </Otherwise>
</Choose>
<Import Project="$(FSharpTargetsPath)" />

Notice how /run/current-system/sw/bin/../lib/mono/4.5/Microsoft.FSharp.Targets was added to test the path for FSharpTargetsPath variable.

Troubleshooting XBuild errors

In case you see errors like following:

Make sure to remove ~/.config/xbuild as it is the local cache for XBuild that remembers paths to F# libraries which prone to change in case you run nix-collect-garbage -d.