Jump to content

Building with Ninja: Difference between revisions

From Weissblatt Wiki
Created page with "[https://ninja-build.org/manual.html Ninja] is a build system [https://neugierig.org/software/chromium/notes/2011/02/ninja.html originally developed for Google Chrome] and designed towards low build times for complex projects. It was designed with three # Ninja files are meant to be computer-generated using higher order build systems such as [https://cmake.org/ CMake] # Ninja itself is "painfully simple". There is "very little policy" in the build process and Ninja req..."
 
 
(7 intermediate revisions by 2 users not shown)
Line 1: Line 1:
[https://ninja-build.org/manual.html Ninja] is a build system [https://neugierig.org/software/chromium/notes/2011/02/ninja.html originally developed for Google Chrome] and designed towards low build times for complex projects. It was designed with three  
[https://ninja-build.org/manual.html Ninja] is a build system [https://neugierig.org/software/chromium/notes/2011/02/ninja.html originally developed for Google Chrome] and designed towards low build times for complex projects. It was designed with three goals in-mind:


# Ninja is supposed to be ''fast''. Build processes are heavily parallelized where possibe.
# Ninja files are meant to be computer-generated using higher order build systems such as [https://cmake.org/ CMake]
# Ninja files are meant to be computer-generated using higher order build systems such as [https://cmake.org/ CMake]
# Ninja itself is "painfully simple". There is "very little policy" in the build process and Ninja requires comparatively explicit build definitions.
# Ninja itself is "painfully simple". There is "very little policy" in the build process and Ninja requires comparatively explicit build definitions.


This article explores the possibility for an alternative build system for Weissblatt based on Ninja
This article explores the possibility for an alternative build system for Weissblatt based on Ninja to hopefully simplify and future-proof the engine's overall build process - especially in regards to multi-platform support and Windows builds.


== Ninja compared to Make for building Weissblatt ==
== Ninja compared to Make for building Weissblatt ==
Traditionally Weissblatt's engine used to be built using [[wikipedia:Make_(software)|Make]], the traditional UNIX build system for C/C++ programs. However, there are multiple reasons to consider migrating to a more modern build system:
Traditionally Weissblatt's engine used to be built using [[wikipedia:Make_(software)|Make]], the traditional UNIX build system for C/C++ programs. However, there are multiple reasons to consider migrating to a more modern build system:


# The engine's Makefile has grown large, complex and hard to maintain over the years. Ninja is both brutally simple in it's architecture and doesn't assume human authorship from the get-go. As long as a good higher-level build system is used to generate Ninja files, maintenance of the build system should be trivial.
# The engine's Makefile has grown large, complex and hard to maintain over the years.
# Although building with a working Makefile is simple on UNIX-like systems, Make's dependency on a UNIX-like environment makes cross-platform development difficult. Letting a higher-order build system generate system-appropriate Ninja files may both abstract the system's build tooling to developers and better tailor the build process towards each individual system.
# Although building with a working Makefile is simple on UNIX-like systems, Make's dependency on a UNIX-like environment makes cross-platform development difficult. Ideally, the game's main build system should be system-agnostic to ease maintenance.
# To alleviate the problem described in 2), the Windows build system already relies on CMake separately of the Makefile for UNIX builds. Since CMake already supports generating Ninja files and is generally considered standard tooling in modern C/C++ development, a simple adaptation of Weissblatt's CMake toolchain could render a Ninja-based build toolchain easy to implement.
# To alleviate the problem described in 2), the Windows build system already relies on CMake separately of the Makefile for UNIX builds. Since CMake is already considered standard tooling in modern C/C++ development - especially for cross-platform development - CMake poses an easy to implement, system-agnostic alternative to the current Makefile system.
Ninja is particularly noteworthy here because it is explicitly designed to have it's build files generated by higher order build systems and is thus well integrated into the already-used CMake. Thus instead of shipping the repository with a single unified and hard to maintain Makefile to build the game on all systems, the game's potential future build system shifts towards relying on the already cross-platform CMake to generate Ninja build files tailored to each developer's individual development system.


== CMake in action - Generating Ninja files ==
== CMake in action - Generating Ninja files ==
=== Building with Ninja on Linux ===
Initially building on Linux using Ninja worked just fine. After configuring and generating a Ninja build tree using the CMake GUI, running Ninja from within that tree (per-default under <code>build/ninja-release</code>) seemed to have compiled a development version of the game without problem.
However, the general CMake infrastructure seemed complex with nested breakout files for toolchains and dependencies. How much of that is due to how the engine's build system is structured and how much is inherent to working with CMake is unclear.
The initial CMake system also required CMake's GUI tool to set the environment variables and generate the Ninja build tree. Ideally, a build process using a configuration file such as <code>.env</code> or <code>.config</code> could suit a more iterative development approach. This could be useful, as Ninja expects developers to keep regenerating Ninja files whenever the structure of the codebase changes - be it changed environment variables, added/deleted files or whatever else isn't directly concerned with compiling the code.


=== Building with Ninja on Windows ===
=== Building with Ninja on Windows ===
TBA
As Windows lacks built-in development tools, CMake, Ninja and a suitable compiler needed to be installed onto the system first. Thankfully both CMake and Ninja were easily installable through [https://learn.microsoft.com/windows/package-manager/winget/ WinGet] and were readily available as CLI tools right after. As getting [https://gcc.gnu.org/ GCC] to run on Windows is an ordeal in itself, most Windows developers usually rely on either [https://clang.llvm.org/ Clang] or more commonly Microsoft's own MSVC compiler - part of Microsofts larger set of [https://visualstudio.microsoft.com/downloads/ Visual Studio build tools].


=== Building with Ninja on Linux ===
Initially trying to configure the CMake project failed, as CMake could not find the system's C/C++ compiler:
TBA
The C compiler identification is unknown
The CXX compiler identification is unknown
CMake Error at CMakeLists.txt:18 (project):
  No CMAKE_C_COMPILER could be found.
  Tell CMake where to find the compiler by setting either the environment
  variable "CC" or the CMake cache entry CMAKE_C_COMPILER to the full path to
  the compiler, or to the compiler name if it is in the PATH.
CMake Error at CMakeLists.txt:18 (project):
  No CMAKE_CXX_COMPILER could be found.
  Tell CMake where to find the compiler by setting either the environment
  variable "CXX" or the CMake cache entry CMAKE_CXX_COMPILER to the full path
  to the compiler, or to the compiler name if it is in the PATH.
Configuring incomplete, errors occurred!
Turns out that while CMake's Ninja generator expects it's environment variables and compilers to be set-up globally (like on many UNIX systems), Visual Studio relies on local environments invoked by the IDE for it's build system. Thankfully this environment can be invoked into a CLI session using a Batch script installed alongside Visual Studio. As Visual Studio natively supports CMake in it's own way, this means the necessary environment variables can be passed to CMake from within Visual Studios developer CLI environment. This workflow is less seamless than having your tools installed globally, but it can still be common practise in some fields (e.g. [https://docs.python.org/3/library/venv.html among Python developers]):
C:\Path\to\Weissblatt> call "C:\Program Files\Microsoft Visual Studio\<version>\Community\VC\Auxiliary\Build\vcvars64.bat"
C:\Path\to\Weissblatt> cmake -G Ninja
<small>(Reference: https://discourse.cmake.org/t/best-practice-for-ninja-build-visual-studio/4653)</small>


== Results ==
== Results ==

Latest revision as of 16:27, 24 May 2025

Ninja is a build system originally developed for Google Chrome and designed towards low build times for complex projects. It was designed with three goals in-mind:

  1. Ninja is supposed to be fast. Build processes are heavily parallelized where possibe.
  2. Ninja files are meant to be computer-generated using higher order build systems such as CMake
  3. Ninja itself is "painfully simple". There is "very little policy" in the build process and Ninja requires comparatively explicit build definitions.

This article explores the possibility for an alternative build system for Weissblatt based on Ninja to hopefully simplify and future-proof the engine's overall build process - especially in regards to multi-platform support and Windows builds.

Ninja compared to Make for building Weissblatt[edit | edit source]

Traditionally Weissblatt's engine used to be built using Make, the traditional UNIX build system for C/C++ programs. However, there are multiple reasons to consider migrating to a more modern build system:

  1. The engine's Makefile has grown large, complex and hard to maintain over the years.
  2. Although building with a working Makefile is simple on UNIX-like systems, Make's dependency on a UNIX-like environment makes cross-platform development difficult. Ideally, the game's main build system should be system-agnostic to ease maintenance.
  3. To alleviate the problem described in 2), the Windows build system already relies on CMake separately of the Makefile for UNIX builds. Since CMake is already considered standard tooling in modern C/C++ development - especially for cross-platform development - CMake poses an easy to implement, system-agnostic alternative to the current Makefile system.

Ninja is particularly noteworthy here because it is explicitly designed to have it's build files generated by higher order build systems and is thus well integrated into the already-used CMake. Thus instead of shipping the repository with a single unified and hard to maintain Makefile to build the game on all systems, the game's potential future build system shifts towards relying on the already cross-platform CMake to generate Ninja build files tailored to each developer's individual development system.

CMake in action - Generating Ninja files[edit | edit source]

Building with Ninja on Linux[edit | edit source]

Initially building on Linux using Ninja worked just fine. After configuring and generating a Ninja build tree using the CMake GUI, running Ninja from within that tree (per-default under build/ninja-release) seemed to have compiled a development version of the game without problem.

However, the general CMake infrastructure seemed complex with nested breakout files for toolchains and dependencies. How much of that is due to how the engine's build system is structured and how much is inherent to working with CMake is unclear.

The initial CMake system also required CMake's GUI tool to set the environment variables and generate the Ninja build tree. Ideally, a build process using a configuration file such as .env or .config could suit a more iterative development approach. This could be useful, as Ninja expects developers to keep regenerating Ninja files whenever the structure of the codebase changes - be it changed environment variables, added/deleted files or whatever else isn't directly concerned with compiling the code.

Building with Ninja on Windows[edit | edit source]

As Windows lacks built-in development tools, CMake, Ninja and a suitable compiler needed to be installed onto the system first. Thankfully both CMake and Ninja were easily installable through WinGet and were readily available as CLI tools right after. As getting GCC to run on Windows is an ordeal in itself, most Windows developers usually rely on either Clang or more commonly Microsoft's own MSVC compiler - part of Microsofts larger set of Visual Studio build tools.

Initially trying to configure the CMake project failed, as CMake could not find the system's C/C++ compiler:

The C compiler identification is unknown
The CXX compiler identification is unknown
CMake Error at CMakeLists.txt:18 (project):
  No CMAKE_C_COMPILER could be found.

  Tell CMake where to find the compiler by setting either the environment
  variable "CC" or the CMake cache entry CMAKE_C_COMPILER to the full path to
  the compiler, or to the compiler name if it is in the PATH.

CMake Error at CMakeLists.txt:18 (project):
  No CMAKE_CXX_COMPILER could be found.

  Tell CMake where to find the compiler by setting either the environment
  variable "CXX" or the CMake cache entry CMAKE_CXX_COMPILER to the full path
  to the compiler, or to the compiler name if it is in the PATH.

Configuring incomplete, errors occurred!

Turns out that while CMake's Ninja generator expects it's environment variables and compilers to be set-up globally (like on many UNIX systems), Visual Studio relies on local environments invoked by the IDE for it's build system. Thankfully this environment can be invoked into a CLI session using a Batch script installed alongside Visual Studio. As Visual Studio natively supports CMake in it's own way, this means the necessary environment variables can be passed to CMake from within Visual Studios developer CLI environment. This workflow is less seamless than having your tools installed globally, but it can still be common practise in some fields (e.g. among Python developers):

C:\Path\to\Weissblatt> call "C:\Program Files\Microsoft Visual Studio\<version>\Community\VC\Auxiliary\Build\vcvars64.bat"
C:\Path\to\Weissblatt> cmake -G Ninja

(Reference: https://discourse.cmake.org/t/best-practice-for-ninja-build-visual-studio/4653)

Results[edit | edit source]

Discussion[edit | edit source]