Skip to content

CMake guide for FontForge

Fredrick Brennan edited this page Mar 26, 2022 · 24 revisions

This page gives an overview of how to use the CMake build system (in the context of FontForge), and some notes on transitioning from the old build system.

Quickstart

The simplest use case is:

git clone https://github.com/fontforge/fontforge && cd fontforge && mkdir build && cd build
cmake -GNinja ..
ninja

While using Ninja is strongly recommended, you can generate Makefiles instead:

cmake ..
make -j4

Note: On Windows, the above commands should be run in MSYS2; ffbuild.sh can help with dependency management (from fontforge/fontforgebuilds).

Unlike autotools, this build system requires out of source builds. In this case, I chose the build folder, but you could have named it anything, even placing it outside of the repo altogether. We suggest that you use the build folder though, as the .gitignore has been configured to ignore it.

Usually sensible defaults, as follow, prevail in absence of specified arguments.

  • Building with the GUI enabled (GDK3 by default)
  • Building with all dependencies enabled

Also note that CMake caches variables between invocations, so it is not necessary to specify all options again if you want to rerun CMake with a different option. Conversely, because of the caching, sometimes you may need to clear out the build folder for a fully clean build.

Configuration

There are a number of configuration options that influence the build. These are specified by passing -D to cmake, e.g. cmake -DENABLE_LIBSPIRO=no. CMake is lenient in what it accepts as true/false for Boolean options. To inspect all available build options, look at the top-level CMakeLists.txt - all configurable items use the build_option macro.

For BOOL options that default to true, if it requires a dependency, the build will fail if that dependency is not found. AUTO options are tri-state Boolean values. They are often used for dependencies where it is not a hard-failure if they are not found.

Other common build issues are as follows.

  • libuninameslist is a build dependency, generally available only from its FontForge repository. If you do not have root access on the system, you can build it in a separate directory and then link against it in place.
  • Many systems still default to Python 2.7 and hardwire sphinx-build to use it. Building requires significant overrides of Python defaults. It is not possible to override sphinx-build and thus impossible to build documentation. The following build command hardcodes a non-installed location of libuninameslist, overrides Python defaults to use 3, and disables building of documentation.
env PYTHON=python3 cmake -DENABLE_DOCS=off -DCMAKE_PREFIX_PATH=/path/to/libuninameslist/.libs -DLibuninameslist_INCLUDE_DIRS=/path/to/libuninameslist -DFONTFORGE_INSTALL_PREFIX=/usr/local -DPYTHON_INCLUDE_DIR=$(python3 -c "from distutils.sysconfig import get_python_inc; print(get_python_inc())") -DPYTHON_LIBRARY=$(python3 -c "import distutils.sysconfig as sysconfig; print(sysconfig.get_config_var('LIBDIR'))") .. ; env PYTHON=python3 make ;
Click to expand
CMake build option Type autotools equivalent Notes
CMAKE_INSTALL_PREFIX PATH --prefix This is a standard CMake variable, see here for more details.
CMAKE_INSTALL_DIR PATH --bindir/--mandir/--docdir etc These control the directories where various files get installed. See GNUInstallDirs for more information.
CMAKE_BUILD_TYPE ENUM default RelWithDebInfo N/A This is a standard CMake variable, see here for more details. Defaults to RelWithDebInfo which is release mode (-O2) with debugging symbols. For development, use Debug which disables optimisation.
BUILD_SHARED_LIBS BOOL default on --enable-shared This is a standard CMake variable, see here for more info. While static building is supported, it is not recommended if building the Python hooks, as the code will be duplicated in each Python module generated.
ENABLE_GUI BOOL default on --enable-programs / --with-x / --enable-gdk Defaults to building with the GDK3 backend
ENABLE_X11 BOOL default off --with-x Builds with the X11 backend instead of GDK3. Will be forced to false if ENABLE_GUI is false
ENABLE_NATIVE_SCRIPTING BOOL default on --enable-native-scripting Builds with native scripting support
ENABLE_PYTHON_SCRIPTING BOOL default on --enable-python-scripting Builds with Python3 scripting support
ENABLE_PYTHON_EXTENSION AUTO --enable-python-extension Builds the Python hooks for use with system Python. Can only be enabled if ENABLE_PYTHON_SCRIPTING is true
ENABLE_LIBSPIRO BOOL default on --with-libspiro Builds with libspiro support
ENABLE_LIBUNINAMESLIST BOOL default on --with-libuninameslist Builds with libuninameslist support
ENABLE_LIBGIF AUTO --with-giflib Builds with gif support
ENABLE_LIBJPEG AUTO --with-libjpeg Builds with jpeg support
ENABLE_LIBPNG AUTO --with-libpng Builds with png support
ENABLE_LIBREADLINE AUTO --with-libreadline Builds with readline support
ENABLE_LIBTIFF AUTO --with-libtiff Builds with tiff support
ENABLE_WOFF2 AUTO --enable-woff2 Builds with woff2 support
ENABLE_DOCS AUTO N/A Enables building and installing the documentation. Requires the sphinx-build command to be present, installable via the sphinx Python package.
ENABLE_CODE_COVERAGE BOOL default off --enable-code-coverage Enables build flags that generates code coverage data. Should be done in conjunction with setting CMAKE_BUILD_TYPE to Debug
ENABLE_DEBUG_RAW_POINTS BOOL default off --enable-debug-raw-points Add a raw mode to the points window of the debugger
ENABLE_FONTFORGE_EXTRAS BOOL default off --enable-fontforge-extras Builds programs from the contrib directory
ENABLE_MAINTAINER_TOOLS BOOL default off --enable-maintainer-tools Builds a bunch of maintainer tools
ENABLE_TILE_PATH BOOL default off --enable-tile-path Enable a 'tile path' command (a variant of 'expand stroke')
ENABLE_WRITE_PFM BOOL default off --enable-write-pfm Add the ability to save a PFM file without creating the associated font file
ENABLE_SANITIZER ENUM default none N/A Enables one of the sanitizers (e.g. ASan/UBSan, see also here). Must be one of none, address, leak, thread, undefined or memory).
ENABLE_FREETYPE_DEBUGGER PATH default unset --enable-freetype-debugger / --with-freetype-source Enables the freetype debugger. Set this to the path to the FreeType sources. The build system checks the version of the sources against the version that it will build/link against, and will fail if there is a mismatch
SPHINX_USE_VENV BOOL defualt off N/A If ENABLE_DOCS is not false, creates a venv and installs the sphinx package into it, to be used to build the documentation.
REAL_TYPE ENUM default double --enable-real Sets the floating point type used, can be either double or float. Should probably just be removed and hard-coded to double.
THEME ENUM default tango --enable-theme-2012 Sets the theme to install, either tango or 2012

CMake provides more built-in options that can influence other characteristics of the build. Refer to the CMake documentation for further details.

Command details

There are a set of targets provided, which perform various actions. These are invoked via e.g. make target or ninja target.

Click to expand
Target autotools equivalent Notes
all all The default target, builds (almost) everything
dist dist Generates the dist tarball. This is driven by CPack. This creates a built-in target, package_sources, but it's recommended to call dist instead, as it sets up all required dependencies before building the tarball
check check Runs the test suite. This is driven by CTest. This creates a built-in target, test, but it's recommended to call check instead, as it sets up all required dependencies before running the test suite.
test_dependencies N/A Downloads additional fonts for the test suite
potfiles N/A Regenerates FontForge.pot
N/A distcheck No equivalent. As CMake enforces an out of source build, it's expected that everything in the repo is distributable.
install install Installs the relevant files to the given prefix. Set the environment variable DESTDIR to install to another location.
uninstall uninstall Uninstalls installed files
macbundle N/A Generates the Mac bundle. Output will be in ${CMAKE_BUILD_DIR}/osx/FontForge.app
N/A - run Packaging/debian/setup-metadata.sh from an extracted dist archive deb-src* No direct integration in the build system; use the provided bash scripts instead.
N/A - run Packaging/redhat/generate-spec.sh rpm-src* Generates a spec file to be used with the dist source archive and rpmbuild.

Support details

CMake has been tested on Linux (Ubuntu), Windows and MacOS. The minimum supported CMake version is 3.5. If you experience any issues with the build system, please report them on the issue tracker.

The supported CMake generators are Ninja and Makefiles (Unix Makefiles and MSYS Makefiles).

For CMake less than 3.9, skipped tests are marked as passed, as otherwise skipped tests fail the suite.

Notes for developers

For developing on FontForge, it's strongly recommended to use ccache and the Debug build type:

cmake  -GNinja .. -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_BUILD_TYPE=Debug -DENABLE_MAINTAINER_TOOLS=1 

To compile for profiling (gprof) try adding the flags

-DCMAKE_C_FLAGS=-pg -DCMAKE_EXE_LINKER_FLAGS=-pg -DCMAKE_SHARED_LINKER_FLAGS=-pg

Influencing the detection of libraries

There are a number of methods to influence what libraries CMake will detect. How this is done varies from dependency to dependency, but in general:

  • Set PKG_CONFIG_PATH to influence packages detected by pkg-config
  • Set CMAKE_FIND_ROOT_PATH
  • Set package specific hints. E.g. here for Python

Needed packages for various distributions

Feel free to update; if you have no wiki access please open a documentation issue.

Ubuntu as of 21.04

Required

  • libgdk-pixbuf-2.0-dev
  • libgtk-3-dev
  • libpython3-dev
  • libspiro-dev

Optional

  • ninja-build
  • ccache