The dotnet
compiler produces two copies of the same executable and my google skills are not good enough to figure out why.
E.g. in a simple Console project:
dotnet publish --configuration Release
produces bin/Release/net8.0/FizzBuzz and bin/Release/net8.0/publish/FizzBuzz, which are identical.
I want to build one optimized executable and one cross-platform executable. How do I do that?
EDIT: Thanks to @winscripter, I figured out the following:
dotnet publish -c .
will produce:
bin/net8.0/
├── FizzBuzz (executable)
├── FizzBuzz.deps.json (not sure)
├── FizzBuzz.dll (cross-platform IL code)
├── FizzBuzz.pdb (debug symbols)
├── FizzBuzz.runtimeconfig.json (required for non stand-alone)
└── publish/ (a copy of the above files)
FizzBuzz.dll
and FizzBuzz.runtimeconfig.json
are needed for the FizzBuzz
executable, which can be executed directly with ./bin/net8.0/publish/FizzBuzz
.
FizzBuzz.dll
can be run cross-platform with dotnet bin/net8.0/publish/FizzBuzz.dll
. Only FizzBuzz.runtimeconfig.json
is required for that to work.
The rest of the generated files are not needed for running the program.
I'm pretty sure that, without specifying the runtime
option for dotnet
, the default optimized build is for my platform, e.i. linux.
ldd
reports linux specific dependencies:
ldd bin/net8.0/publish/FizzBuzz
linux-vdso.so.1 (0x00007ffd260e0000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fe955acd000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fe955ac8000)
libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fe955800000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fe95571e000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fe955a9b000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe955539000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe955b05000)
I know that there are different build targets (OS specific, dotnet SDK specific etc) but I'm confused by the many options.
If you link to https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-publish, please provide a description of the cons of the options, since I don't get them.
My FizzBuzz.csproj file:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<AssemblyName>FizzBuzz</AssemblyName>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<!-- I added ErrorOnDuplicatePublishOutputFiles -->
<ErrorOnDuplicatePublishOutputFiles>true</ErrorOnDuplicatePublishOutputFiles>
</PropertyGroup>
</Project>
I added <ErrorOnDuplicatePublishOutputFiles>
to see if that would change anything. It did not.
dotnet --version
8.0.301
uname -a
Linux kali 6.8.11-amd64 #1 SMP PREEMPT_DYNAMIC Kali 6.8.11-1kali2 (2024-05-30) x86_64 GNU/Linux
With regards why there are two copies of an executable, see this answer:
dotnet publish
builds the project before copying binaries to the output directory. The files you see in bin\Release\netcoreapp2.0\win-x64 directory are the result of dotnet build command. You could check it by running following command:dotnet build --configuration Release --runtime win-x64
With regards how to publish an executable to run on multiple systems at once: I don't think this is possible. When you use the dotnet publish
command, it generates an executable that is OS specific (so one will run on one operating system only.) So, you would need to publish multiple executables in order to make the application cross platform, for example, dotnet publish --runtime win-x64
for Windows 64-Bit or dotnet publish --runtime linux-x64
for Linux 64-Bit. Or, use dotnet build
to generate a dll file that contains IL code which can run on multiple systems at once, but it may require to be executed with the dotnet
command.