dotnet / sdk

Core functionality needed to create .NET Core projects, that is shared between Visual Studio and CLI
https://dot.net/core
MIT License
2.66k stars 1.06k forks source link

Is it possible to get dotnet build to produce a Windows and a Linux executable? #43317

Open sandrock opened 1 week ago

sandrock commented 1 week ago

Is your feature request related to a problem? Please describe.

dotnet build on Windows for an executable project will produce a .dll and a runnable .exe file
dotnet build on GNU+Linux for an executable project will produce a .dll and a runnable ELF file

There does not seem to be a way to do both.

Describe the solution you'd like

In our CI/CD build, we would like to produce both the EXE and ELF file. This would make our package runnable on both OS.
Can we have an option to produce both the EXE and ELF file?
Something like: dotnet build --exe-and-elf

Additional context

I found this post for the same request: SO Is it possible to get dotnet to produce a Windows and a Linux executable?]

baronfel commented 1 week ago

This isn't difficult using MSBuild, it's just not something that the .NET SDK has a first-class treatment for (yet). The solution is

  1. make sure that each platform you want to build for is in your RuntimeIdentifiers property, like so:
<PropertyGroup>
  <RuntimeIdentifiers>win-x64;win-arm64;linux-x64;linux-arm64</RuntimeIdentifiers>
</PropertyGroup>
  1. Create a target in your project to orchestrate calling publish for each RID. This involves a little bit of MSBuild know-how, but isn't too terrible:
  <Target Name="MultiArchPublish">
    <ItemGroup>
      <_rids Include="$(RuntimeIdentifiers)" />
      <_InnerBuild Include="$(MSBuildProjectFullPath)"
        AdditionalProperties="RuntimeIdentifier=%(_rids.Identity)" />
    </ItemGroup>
    <MSBuild
        Projects="@(_InnerBuild)"
        Targets="Publish"
        BuildInParallel="true"
        Properties="_IsPublishing=true" />
  </Target>
  1. Call that target from the command line: dotnet publish -t:MultiArchPublish

Calling this target will publish your app for each RID you've specified. It's important to make sure that your RuntimeIdentifiers are all listed in the project because the .NET SDK uses that to make sure that all of the platform-specific dependencies required to build a platform-specific application are downloaded during restore.

huoyaoyuan commented 1 week ago

Note: it can be difficult to produce complete native executable on different platform, because there are platform-native tools used.