Skip to content

CMake build system for the core and apps (macOS, iOS, tvOS, Emscripten, Linux, Windows) - #8586

Open
danoli3 wants to merge 7 commits into
openframeworks:masterfrom
danoli3:cmake-build-system
Open

danoli3 wants to merge 7 commits into
openframeworks:masterfrom
danoli3:cmake-build-system

Conversation

@danoli3

@danoli3 danoli3 commented Oct 13, 2026

Copy link
Copy Markdown
Member

A CMake build for the openFrameworks core and apps on every desktop, web and Apple platform, built the same way as Android's: a core project, and an app template that links it. Next, the Project Generator can write CMakeLists.txt projects.

Draft: Windows (Visual Studio, MSYS2) is written but not yet built; a Windows test run is next.

Usage

Copy scripts/templates/cmake/CMakeLists.txt into a project:

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
  • Sources come from src/, addons from addons.make, or of_add_app(myApp ADDONS ofxGui ofxOsc).
  • The app goes into bin/, named <app> (Release) or <app>_debug (Debug).
  • The core is linked from libs/openFrameworksCompiled/lib/<platform>. If it isn't there for the configuration being built, it's built first and written there for the next app. -DOF_BUILD_CORE=ON always rebuilds it.

Per-platform commands, options and the PG integration are in libs/openFrameworksCompiled/project/CMake/README.md.

What it mirrors

platform/<family>.cmake holds each platform's settings, taken from its makefile config or IDE project:

  • core exclusions, defines and flags
  • frameworks, system and pkg-config libraries
  • third-party libraries from libs/*/lib/<platform>
  • the app output
Platform Output Core (same file as the existing builds)
macOS bin/<app>.app: Info.plist from the project or template, icon lib/macos/openFrameworks.a (Xcode's)
iOS / tvOS bin/<app>.app: xcframeworks, bin/data and mediaAssets in the bundle lib/ios/<sdk>/openFrameworksiOS.a, lib/tvos/<sdk>/openFrameworkstvOS.a
Emscripten bin/em/<app>/index.html with bin/data preloaded, plus app.js and style.css lib/emscripten/libopenFrameworks.a
Linux bin/<app> lib/<platform>/libopenFrameworks.a (make's)
Visual Studio bin/<app>.exe lib/vs/<arch>/openframeworksLib.lib (the VS project's)
MSYS2 bin/<app>.exe lib/msys2/libopenFrameworks.a (make's)

Addons are read the same way as the makefiles:

  • sources, include paths and libraries from the addon's folders
  • addon_config.mk sections, = / +=, % wildcards, ADDON_DEPENDENCIES and ADDON_*_EXCLUDE

of_target_addon_files() takes explicit lists instead, so the Project Generator can write out the addons it has already resolved.

Tested

Platform Core Apps built and run
macOS 26, AppleClang 21: Ninja and Xcode, Release and Debug ✅ emptyExample, graphicsExample, guiExample (ofxGui)
Emscripten 6.0.11, headless Chrome ✅ graphicsExample, guiExample, 0 errors
Linux aarch64, Ubuntu 24.04, GCC 13 (Docker, Xvfb) ✅ emptyExample, graphicsExample, guiExample
iOS 26 simulator, Xcode generator ✅ graphicsExample
tvOS 26 simulator, Xcode generator ✅ emptyExample, ofBoxExample
Visual Studio, MSYS2 not yet test run pending

Known: opencvExample on macOS fails to link, with undefined kleidicv:: symbols. The make build fails identically: apothecary's macOS OpenCV xcframework is missing KleidiCV.

Differences from the makefiles

  • Third-party include paths: only libs/*/include roots are added, as in the Xcode and VS projects. The makefiles also add every subfolder, and on iOS that lets glm/include/glm/simd shadow the SDK's <simd/…> headers. Addons keep the makefiles' recursive includes.
  • Opt-in renderers: Dawn and MetalANGLE are left out unless OF_USE_DAWN / OF_USE_ANGLE are set.
  • Core file: the macOS core is Xcode's lib/macos/openFrameworks.a rather than make's lib/osx/libopenFrameworks.a.

Android keeps its own CMake; moving it onto this system is a follow-up.

libs/openFrameworksCompiled/project/CMake builds the openFrameworks core
and apps on macOS, iOS, tvOS, Emscripten, Linux (linux64, linuxaarch64,
linuxarmv7l, linuxarmv6l), Visual Studio and MSYS2, mirroring the
makefiles and IDE projects: the same sources, defines, flags and
third-party libraries per platform, apps built into bin/, and the core in
libs/openFrameworksCompiled/lib/<platform> with the names the existing
builds use. Android keeps its own CMake for now.

- openFrameworks.cmake: entry point for apps and the core project
- CMakeLists.txt: the core library project
- OFCore.cmake: core sources, third-party libs, the openFrameworks and
  openFrameworks::deps targets; apps link the prebuilt core, or build it
  first if it isn't there (OF_BUILD_CORE=ON forces that)
- OFAddons.cmake: addons from their folders and addon_config.mk like the
  makefiles, or from explicit lists (of_target_addon_files, for the
  Project Generator)
- OFApp.cmake: of_add_app()
- platform/*.cmake: per platform excludes, defines, flags, libraries and
  app output (.app bundles with Info.plist and icon, bin/em/<app> for
  Emscripten, xcframeworks and bin/data in the bundle on iOS / tvOS)

scripts/templates/cmake/CMakeLists.txt is the app template; generated
CMakeLists.txt in examples are ignored like the Makefiles.
PROJECT_EMSCRIPTEN_WASM (32 / 64), PROJECT_EMSCRIPTEN_TOTAL_MEMORY,
PROJECT_EMSCRIPTEN_EMBIND_AOT and PROJECT_EMSCRIPTEN_TEMPLATE, as in a
project's config.make, so the Project Generator writes the same setting
for both. wasm64 builds the core into lib/emscripten/WASM64 like the
makefiles; EMSCRIPTEN_MEMORY64 still selects 64.
Same names as the makefiles' config.make (openframeworks#8592): APP_VERSION sets
CFBundleShortVersionString (default: project(... VERSION), else 1.0) and
APP_BUILD sets CFBundleVersion (default 1), also as Xcode's
MARKETING_VERSION / CURRENT_PROJECT_VERSION.

Based on openframeworks#3394.

Co-authored-by: Vincent Donnefort <vdonnefort@gmail.com>
@danoli3

danoli3 commented Oct 16, 2026

Copy link
Copy Markdown
Member Author

Added APP_VERSION / APP_BUILD for the macOS / iOS / tvOS Info.plist. These are the same names as the makefiles' config.make option in #8592, which brings back #3394.

  • Setting them: set(APP_VERSION 2.3.4) / set(APP_BUILD 42) before of_add_app(), or -DAPP_VERSION=… -DAPP_BUILD=….
  • Defaults: the version falls back to project(… VERSION x.y), then 1.0; the build defaults to 1.
  • Tested on macOS with emptyExample: defaults gave 1.0 / 1, -D gave 2.3.4 / 42, and project(VERSION 5.6.7) gave 5.6.7. plutil -lint passes.

@danoli3
danoli3 marked this pull request as ready for review October 18, 2026 04:20
scripts/ci/cmake/build.sh builds the core (Release and Debug) with the CMake
project, then emptyExample (Release and Debug), graphicsExample, guiExample
and allAddonsExample. Each example's CMakeLists.txt comes from
projectGenerator -t cmake when --pg is given (linux64 and VS use the nightly
PG), otherwise from scripts/templates/cmake/CMakeLists.txt. A failed step
fails the job with an ::error annotation, and each app must end up in bin/.
Link the core archive with --whole-archive. Keep wasm32 and wasm64 libraries in separate folders, default embind AOT off, and drop MAIN_MODULE so audio worklets link.
The vcxproj sets CharacterSet to Unicode. Without UNICODE and _UNICODE, Win32 calls stay on the ANSI entry points and the wide paths in ofFileUtils and ofSystemUtils do not compile.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant