View on GitHub

FOnline Engine

Flexible cross-platform isometric game engine

BuildTools Pipeline

This document explains the staged CMake pipeline under BuildTools/cmake/. It is a source-grounded companion to BuildWorkflow.md: use BuildWorkflow.md for how to approach builds as a user, and this file for where the reusable build machinery lives.

Ownership model

FOnline is normally configured from an embedding game project. The engine supplies CMake stages and helpers; the game project supplies values such as product names, main config, enabled targets, output paths, packages, scripts, and platform choices.

Source paths inspected

Important consequences:

Stage files

The staged pipeline lives in BuildTools/cmake/stages/. Canonical stage order is defined by BuildTools/Init.cmake: Init, ProjectOptions, ThirdParty, EngineSources, Codegen, CoreLibs, Applications, ScriptsAndBaking, Packages, Finalize.

Init.cmake

Establishes baseline configuration. It declares and checks core project options such as:

It also establishes build hash and common generation context. Start here when a build option is missing or validated too early/late.

ProjectOptions.cmake

Normalizes and validates project-level option combinations. Examples from the current stage include checks around code coverage, build mode combinations, and scripting/tool compatibility such as FO_BUILD_ASCOMPILER requiring AngelScript support.

Start here when a combination of options should be rejected or derived before source lists and targets are created.

ThirdParty.cmake

Adds bundled engine third-party libraries. The stage comment notes that it installs a find_package() interceptor before third-party AddSubdirectory() calls so vendored libraries cannot silently reach into the host system.

Start here when a bundled dependency is added, removed, or needs build isolation rules.

EngineSources.cmake

Builds source lists and generated resource files used by later stages. It appends source lists for engine layers such as Essentials, Common, Frontend, Client, Server, Tools, Scripting, and tests. It also prepares app icon/resource data such as the generated Windows .rc file.

Start here when a new hand-authored source file must become part of a core engine library.

Codegen.cmake

Constructs the code-generation command and output set. It passes project and engine metadata to BuildTools/codegen.py, including main config, build hash, generated output path, project names, embedded data capacity, metadata source files, and added common headers.

It creates codegen targets such as normal and forced code generation. Start here when generated C++/script API metadata changes.

Related doc: GeneratedApiAndMetadata.md.

CoreLibs.cmake

Creates core static libraries from the source lists prepared by EngineSources.cmake. Current responsibilities include libraries such as Essentials, Common, frontend/headless app layers, scripting integration libraries, client/server libraries, baker libraries, and testing support depending on enabled options.

Start here when source grouping, library dependencies, or runtime layer boundaries change.

ScriptsAndBaking.cmake

Creates custom targets for script compilation and resource baking. Current responsibilities include:

Related docs: BakingPipeline.md and Scripting.md.

Applications.cmake

Creates executable and shared-library applications from Source/Applications/*.cpp. It uses helpers such as AddExecutableApplication and AddSharedApplication and project variables such as FO_DEV_NAME, output paths, platform flags, and enabled build modes.

Examples of entry points wired here include client, client runtime library, client headless variants, server variants, mapper/editor/tool apps, baker, AngelScript compiler, and testing app depending on options.

See Applications.md.

Packages.cmake

Creates package targets from FO_PACKAGES and calls BuildTools/package.py with project context such as main config, build hash, developer name, nice name, input/output paths, platform/architecture/config data, and binary-output postfix.

Start here when platform package layout, package target naming, or package script arguments change.

Finalize.cmake

Performs final solution/project organization and late reporting. Current responsibilities include target folder grouping, optional ReSharper settings copy, third-party dummy grouping, and verbose cache-variable reporting when FO_VERBOSE_BUILD is enabled.

Start here for final target organization or post-generation diagnostics, not for source ownership or build feature validation.

Helper files

Reusable helpers live in BuildTools/cmake/helpers/:

When a stage needs reusable behavior, prefer adding a helper here instead of copy-pasting logic between stages.

Stage hooks

Stage comments reference the hook convention:

AddStageHook(<StageName> Pre|Post <macro-name>)

Use hooks when an embedding project or a later refactor needs to extend stage behavior without editing the middle of a stage body. Keep hook behavior documented near the owning stage or in the project docs if it is game-specific.

Change routing

Validation checklist

For BuildTools changes:

  1. Configure from a real embedding project root.
  2. Use the narrowest preset that exercises the changed stage.
  3. For source-list changes, verify the affected target builds.
  4. For codegen changes, verify generated files and script API consumers.
  5. For baking changes, run normal and forced bake paths when relevant.
  6. For package changes, run the affected package target and inspect output layout.
  7. Run documentation link checks if docs changed.
  8. Run git diff --check before reporting completion.