Helion-Engine / Helion

A modern fast paced Doom FPS engine
GNU General Public License v3.0
86 stars 9 forks source link

Build process improvements #571

Closed lemming104 closed 3 months ago

lemming104 commented 3 months ago

Feedback on this change is welcome; I'm trying to make things nicer here. :) If you are open to further pull requests, there is a bunch of minor quality-of-life stuff I would like to do for Helion.

I noticed that there was a lot of stuff in the .csproj files that was unnecessary, obsolete, or counter to best practices. This actually had the effect of breaking some useful dotnet commands (mainly variations of dotnet publish, also some runtime-specific dotnet build variants), and just generally makes things harder to read and maintain.

This proposed change enables some cool stuff, like being able to publish compressed, single-file, self-contained executables, which results in nice tidy output directories. For example:

cd Client
dotnet publish -c Release -r win-x64 --self-contained=true -p:PublishSingleFile=true -p:EnableCompressionInSingleFile=true

Produces this output in Client\bin\Release\net8.0\win-x64\publish: image

This is complete, fully self-contained, and should run on a (win-x64) machine that doesn't have the .NET framework installed.

I have verified the following:

  1. The tests still run and pass.
  2. Windows x86 and x64 "publish" builds (as above) work as expected and produce an output that runs and plays Doom. I can also use a command line like the one I cited above to build for Linux, but I do not have a Linux install where I can test the output.
  3. The default "unspecified runtime" build (i.e. just dotnet build) still produces a working, debuggable build on my Windows machine.

I have not verified:

  1. Whether this works on Linux. This should be tested before merging this change.

Some details of this change:

  1. Add a global.json to control what version(s) of the .NET SDK are allowed to build these projects. If someone attempts to run any dotnet command from this directory using a runtime other than 8.x.y, they will immediately receive an error informing them that they should install a compatible version of the runtime. I recommend this, because although the .NET 9 preview can probably build projects that target the net8.0 target framework, but you're kind of at Microsoft's mercy--I've maintained large repositories where releases of the SDK have broken random behaviors that simply are not fun to track down. It really is better to lock this down, and I'd actually recommend locking it down further to patch revisions of a specific minor version.

  2. Add a nuget.config file that enables package retrieval from public Nuget (nuget.org). For some reason, it seems like VS installs do something weird with the global Nuget config, and running dotnet restore or dotnet build from the command line results in complaints about packages that cannot be found. It is generally better to bypass whatever hackery people have going on in their global nuget.config and just tell the build process to use the public server.

  3. Get rid of the custom Powershell and Bash scripts for building the assets files. You do not need these. There is a "ZipDirectory" task available in MSBuild, and I have modified the projects to use this instead.

  4. Take common properties (nullability settings, target framework, version stamping) of all three projects, pull that out into a Directory.Build.Props file. Such files recursively apply to projects in any subdirectories.

  5. General cleanup in the .csproj files. They're currently trying to copy a zdbsp.dll file that is already contained in a PackageReference, there are a bunch of individual file includes when you can just do patterned directory globbing (e.g. <None Include="somedirectory/*")

nstlaurent commented 3 months ago

This looks great. I'm open to anything that makes things better and this is very helpful.

Linux is still a pain point and I have some work to do to get that correctly publishing. Right now it's a more manual process because I haven't taken the time to get everything committed. It requires changes similar to how fluidsynth.dll exists in the Unamanged directories for Windows but with libfluidsynth. For whatever reason NFluidSynth was incapable of finding libfluidsynth in the current directory on Linux so I need to properly fork it and add it to nuget for that change. Now with this change I will work on that soon so both Windows and Linux publishing are pain free.