Publishing to Linux Weirdness

Hi, I have an odd inconsistency when publishing a Monogame 3.8 OpenGL project to Linux. I’m building on Windows 10. If I publish from the Build menu in Visual Studio 2019, then the main executable is marked as the correct type of file, I allow it the appropriate permission to run, and it runs. Great! These are the publishing settings and the file type as it appears in Ubuntu.

image

image

The problem I have is that if I publish via the command line using the following settings then the file appears in Ubuntu as a “shared library”, and I can’t run it, even if I make the file executable.

dotnet publish -c Release -r linux-x64 -f netcoreapp3.1 /p:PublishReadyToRun=false /p:TieredCompilation=false --self-contained

image

Anyone got any idea what’s going on here?

I’ve had a similar issue just, although for me it wouldn’t work directly from Visual Studio 2019 either. I had the same issue with Visual Studio 2022 and .NET 5 as well.

It seems at some point one of the Visual Studio updates has changed the program format when building .NET apps for Linux. Using a hex viewer the program field e_type at 0x10 was 0x02 for executable file, but now the field contains 0x03 for shared library (Executable and Linkable Format - Wikipedia).

From what I’ve read this should still run as a valid program, but it seems some Linux distributions do not recognise this format as a program. I was running Ubuntu version 20, but upgrading to version 21 fixed this.

Also downloading older build tools (such as 16.7.10 from Visual Studio 2019 build numbers and release dates | Microsoft Docs), installing to a VM and republishing so that it uses the previous program format worked for me.

Thanks, that’s really interesting stuff. I wonder if manually changing the e_type value in the binary from 0x03 back to 0x02 would fix the issue. Did you try that?

I did try that yesterday but it didn’t work as there are more changes in the file than just that value. I believe the field can be used to indicate whether the program memory addresses are static or dynamic, so it shouldn’t be used by itself to determine if the file is a program or not.

Not sure how many other Linux distributions are affected by this so for now I’ll probably use the older build tools for better compatibility.

Ahh ok, I won’t go down the route of hacking the file then if it’s not going to work. I’ll just have to stick with building via Visual Studio for now, maybe track down the older build tools at a later date.

Thanks anyway. It’s been a frustrating one because folks just keep saying make the file executable, and that’s not the issue! :slight_smile: