Search code examples
c#.netlinuxmonodocfx

using the docfx.console nuget package on linux


At the moment I have a visual studio project and I use the docfx.console nuget package to build the documentation, and everything works fine and as expected... on windows. The point is now I want to make a docker image based on mcr.microsoft.com/dotnet/core/sdk:3.1 which is based on a linux image. And compiling in this docker image running the command:

dotnet publish -c Release -o out

Gives the following error

 > [build 9/9] RUN dotnet publish -c Release -o out:
#22 1.080 Microsoft (R) Build Engine version 16.0.450+ga8dc7f1d34 for .NET Core
#22 1.080 Copyright (C) Microsoft Corporation. All rights reserved.
#22 1.080
#22 2.852   Restore completed in 215.94 ms for /app/Documentation/Documentation.csproj.
#22 6.299   Documentation -> /app/Documentation/bin/Release/netcoreapp2.1/Documentation.dll
#22 6.402   /bin/sh: 2: /tmp/tmpbd72ebbe5e6b49c1b3244f1f50c8b57a.exec.cmd: /root/.nuget/packages/docfx.console/2.48.1/build/../tools/docfx.exe: Exec format error
#22 6.407 /root/.nuget/packages/docfx.console/2.48.1/build/docfx.console.targets(57,5): error MSB3073: The command ""/root/.nuget/packages/docfx.console/2.48.1/build/../tools/docfx.exe" "/app/Documentation/docfx.json" -o "" -l "log.txt" --logLevel "Verbose"" exited with code 2. [/app/Documentation/Documentation.csproj]

I already did some prodding around and I believe I have the issue mostly solved. Running file on console.exe shows that this is a PE32 executable (console) Intel 80386 Mono/.Net assembly, for MS Windows. And these kind of files should not be executed on linux using sh but with mono. And indeed running:

mono docfx.exe "/app/Documentation/docfx.json" -o "" -l "log.txt" --logLevel "Verbose"

builds the documentation just fine as expected. At this point of course I have a bunch of workarounds to get the documentation building correctly, just remove docfx.console form the csproj and build it manualy from the command line using a docker command.

But the question is, can I also use the nuget package on linux by changing how the docfx.exe command is run by the nuget package? Or is this only possible by actually fixing this in docfx.console?

p.s. in case it matters, the version of docfx.console that I am using is the most recent one available at the time of writing, namely 2.48.1


Solution

  • But the question is, can I also use the nuget package on linux by changing how the docfx.exe command is run by the nuget package? Or is this only possible by actually fixing this in docfx.console?

    Create script docfx that runs docfx.exe using Mono, e.g., like this (assuming docfx.exe is located in /opt/docfx/docfx.exe):

    echo '#!/bin/bash\nmono /opt/docfx/docfx.exe $@' > /usr/bin/docfx && chmod +x /usr/bin/docfx
    

    Then, pass MSBuild parameter BuildDocToolPath with path to that script, e.g., like this:

    dotnet publish -c Release -o out -p:BuildDocToolPath=/usr/bin/docfx
    

    docfx.console will than use this path to execute DocFX. I think the property BuildDocToolPath isn't documented anywhere, but you can see it in source code.