Driving Unreal with CMake
The Unreal Build Tool (UBT) can be driven from the command line, but once you start scripting your builds, tests, and other tools, you’ll rapidly be building an ad-hoc build system.
I already have a build system.
Unfortunately, it’s CMake.
“I love cmake. It’s a brilliant tool… The whole process was a joy.”
“CMake’s only good quality is that it’s better than the alternatives.”
“I’d rather get shot than go back to cmake or Auto tools.”
Jokes aside, I quite like CMake. To be clear, I’m suggesting using CMake to drive UBT, not bypass it.
CMake lets you describe tasks and their dependencies, then works out what needs to run and in what order. You could run a code generator, build your game and its dependencies, and test them with just:
cmake --workflow --preset debug-game
I use CMake to drive almost everything in my workflow:
- Building Unreal through UBT
- Compiling libraries
- Testing
- Formatters
- Static analysers
- Generators (code, images, meshes, materials)
CMake has a scripting language. It’s not great. If you’re new, a good LLM can take the sting out of getting started.
For this use case, add_custom_target and add_dependencies will cover most of what you need to define commands and their dependencies. I suggest wrapping those in workflow presets so they can be invoked with a single command.
A lot of your workflow can be reduced to a variation of:
cmake --workflow --preset foo
This can be useful for LLMs. Uniform commands are easy for them to learn, and running the build and tests means they’re much less likely to present broken work to you.
Conclusion
CMake gives me a uniform interface for invoking my Unreal game’s tooling, e.g., UBT, compilers, tests, and generators.