2

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

Maarten Derickx
  • 1,502
  • 1
  • 16
  • 27
  • One way to fix it is apparently by registering .exe as non-native binaries as described on https://www.mono-project.com/archived/guiderunning_mono_applications/ – Maarten Derickx Feb 04 '20 at 15:18
  • But this does not working nicely with docker, since loading kernel modules should be loaded on the host, and not in the container. And one does not always have acces to the host. – Maarten Derickx Feb 04 '20 at 15:29
  • There's a dockerhub container that runs it on linux https://hub.docker.com/r/tsgkadot/docker-docfx/dockerfile. I had it working in GitLab CI but had to switch to microsoft's .net image instead for CI – R10t-- Feb 27 '20 at 01:17

1 Answers1

1

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.

Jan Joneš
  • 777
  • 6
  • 13