Building Natron from Source

Natron has two parallel build systems. Both are checked in and both are kept working; which one you use depends on your platform and taste.

  • qmake — the traditional build. The entry point is Project.pro at the repository root, which is a TEMPLATE = subdirs project pulling in every module and bundled library. Shared configuration lives in global.pri and libs.pri; platform dependency locations are in config-macports.pri and config-homebrew.pri.

  • CMake — a newer, increasingly preferred build. The entry point is CMakeLists.txt at the root, with one CMakeLists.txt per module. It requires CMake ≥ 3.16.

Note

C++17 is required for every build, not just the CMake one: Global/Macros.h fails compilation with #error "Natron 2.6+ requires C++17" if the standard is older. Configure your toolchain accordingly regardless of which build system you use.

Note

If you touch the source layout — add a file, add a module, rename something — you must update both build systems (the relevant *.pro/*.pri and the relevant CMakeLists.txt). A change that only updates one will break the build on the other platforms.

Platform-specific, step-by-step instructions (including how to obtain the third-party dependencies) live at the repository root in INSTALL_LINUX.md, INSTALL_MACOS.md, INSTALL_WINDOWS.md and INSTALL_FREEBSD.md. This chapter explains the structure of the build so those instructions make sense.

Modules and their build order

Project.pro declares the module dependency graph explicitly. Reading it is the fastest way to understand how the pieces fit together:

glog.depends     = gflags
ceres.depends    = glog gflags
libmv.depends    = gflags ceres
openMVG.depends  = ceres
Engine.depends   = libmv openMVG HostSupport libtess ceres
Renderer.depends = Engine
Gui.depends      = Engine qhttpserver
Tests.depends    = Gui Engine
App.depends      = Gui Engine

So the build order is: the bundled libraries first (gflags, glog, ceres, libmv, openMVG, qhttpserver, hoedown, libtess), then HostSupport, then Engine, then the front-ends (Renderer, Gui), then App, Tests and PythonBin.

Third-party dependencies

Some dependencies are bundled in libs/ and built from source as part of the project: ceres, openMVG and libmv (the tracker), Eigen3 (headers), gflags and glog, hoedown (Markdown → HTML for node docs), libtess (polygon tessellation for roto), qhttpserver (the internal documentation web server), SequenceParsing (image sequence detection) and google-breakpad (crash reporting). With CMake, -DNATRON_SYSTEM_LIBS=ON uses system copies of some of these instead.

Other dependencies must be present on the system: Qt (5 or 6), Boost (notably boost::serialization), Python 3 plus Shiboken/PySide, cairo (roto/paint rasterization), OpenColorIO, and OpenGL. The reader and writer plug-ins pull in OpenImageIO and FFmpeg, but those live in the separate openfx-io repository, not here.

Qt 5 and Qt 6

The CMake build already exposes a Qt version switch:

option(NATRON_QT6 "use Qt6" OFF)
  • With -DNATRON_QT6=OFF (default) it builds against Qt 5.15, Shiboken2 and PySide2.

  • With -DNATRON_QT6=ON it builds against Qt 6.3+, Shiboken6 and PySide6, and additionally requires the OpenGLWidgets component (QOpenGLWidget moved into its own module in Qt 6).

The qmake build does not yet have an equivalent switch and targets Qt 5. Completing and stabilizing Qt 6 support is an active work item; see Qt 6 Migration Plan.

Two compile definitions set in the CMake build are worth knowing about because they affect how you must write code:

  • QT_NO_CAST_FROM_ASCII — you cannot implicitly build a QString from a const char*. Natron treats all strings as UTF-8, so wrap literals in QString::fromUtf8("…") (or the tr() machinery for translatable text).

  • QT_NO_DEBUG_OUTPUT (release builds) — qDebug() output is compiled out of release builds.

Build type, sanitizers and debugging

  • CMake defaults to RelWithDebInfo when no build type is given; a Debug build additionally defines DEBUG.

  • DEBUG builds enable floating-point exception trapping at startup (see Global/FloatingPointExceptions.h and the main() functions) so that a stray NaN or division by zero aborts immediately instead of silently propagating through the image pipeline.

  • The qmake build supports CONFIG+=addresssanitizer for an AddressSanitizer build (see the messages at the bottom of Project.pro), and CONFIG+=enable-breakpad to build with the Breakpad crash reporter.

Code style and the pre-commit hook

Natron enforces a consistent C++ style with astyle. The exact invocation is pinned in .git-hooks/pre-commit:

astyle -p -H -f -j -z2 -c -k3 -U -A8

The hook runs on every staged .c/.cpp/.h file under Global/, Engine/, Gui/, Readers/ and Writers/ and rejects the commit if the file is not already formatted. Install it once per clone:

cd Natron
mkdir -p .git/hooks
ln -s ../../.git-hooks/pre-commit .git/hooks/pre-commit

If the hook complains, re-format and re-stage the offending file:

astyle -p -H -f -j -z2 -c -k3 -U -A8 -n path/to/File.cpp
git add path/to/File.cpp

A .clang-format file is also provided for editor integration, but astyle is the authoritative formatter used by the hook.

Verifying a build

The Tests module builds a Google Test / Google Mock suite (Curve_Test, Lut_Test, Image_Test, Hash64_Test, KnobFile_Test, Tracker_Test, FileSystemModel_Test, OSGLContext_Test). With CMake, tests are registered with CTest (enable_testing()) and built unless you pass -DNATRON_BUILD_TESTS=OFF. Run them after building to confirm your toolchain and your change are sane before opening a pull request.