Configuring Build Systems

Describes how to configure Cinema 4D SDK 2027 modules with native CMakeLists.txt files.

Overview

Cinema 4D uses CMake to generate build systems. Each SDK module is configured by a project/CMakeLists.txt file which defines the module's target name, supported platforms, metadata, source directories, and build settings.

Note
The legacy projectdefinition.txt system has been fully deprecated since release 2027.0.0. See Migrating from projectdefinition.txt for details on migrating existing modules to the new CMakeLists.txt format.

In addition to the local CMakeLists.txt files in each module, the SDK root contains a top-level CMakeLists.txt and CMakePresets.json that orchestrate the build process for all modules. You can also edit the top-level CMakePresets.json to some extent, to for example customize module discovery or build settings but this file cannot be fully rewritten, as it contains calls to the necessary CMake functions and includes required for the build process. We recommend leaving the root level CMakeLists.txt untouched and entirely rely on it module auto discovery and configuration.

+ SDK // A Cinema 4D C++ SDK project root.
├── + cmake // Cinema 4D SDK CMake helpers; do not modify.
├── + frameworks // Cinema 4D API frameworks; do not modify.
├── + plugins
│ ├── + my_module // A plugin module, i.e., your code.
│ │ ├── + project
│ │ │ └── CMakeLists.txt // The module configuration.
│ │ ├── + res // Optional module resources.
│ │ └── + source // Module source code.
├── + tools // SDK build tools; do not modify.
├── CMakeLists.txt // SDK root project, this should only be modified with caution.
└── CMakePresets.json // Supported generator presets.
Fig. I: Each SDK module is configured by a CMakeLists.txt in its project directory. A legacy projectdefinition.txt can be converted during CMake configuration.
Note
See example.hello_world for the most basic module implementation, including a minimal and commented CMakeLists.txt configuration.
See example.build for an example of a more complex module build configuration that also handles linking against static and dynamic libraries, code signing, and platform specific compilation steps.

Common Settings

Module configurations use ordinary CMake syntax. Variable names are case-sensitive, lists are separated by whitespace or semicolons, and paths containing spaces must be quoted. CMake variables are referenced as ${VARIABLE}. The following settings define the identity and basic behavior of a module.

Setting Description
target_base_name Required target name. It conventionally matches the module directory name.
target_platforms Required list of supported systems or system-architecture pairs.
source_directories Module-root-relative directories recursively scanned for source and project files. Common values are source and res.
enable_rtti Enables compiler RTTI when ON. SDK modules conventionally use OFF.
enable_exception_handling Enables C++ exceptions when ON. SDK modules conventionally use OFF and the Maxon error system instead.

And these are special JSON settings used in the target_settings variable.

Setting Description
moduleid The unique module identifier in reverse-domain notation. You must use a domain or email you own followed by a qualifier for the module E.g., com.mycompany.example.my_module or com.gmail.alice.my_module.
type The output type for this project. Plugins can effectively only use DLL.
apis Sets the frameworks that the module uses.
c4d Enables Cinema API integration when true. Should always be enabled for plugins.
stylecheck.level Sets the style check level for all code in the module.
omitapidefine Omits the framework API define. This is a specialized framework setting.
frameworkregistration Frameworks which receive generated component registrations. Primarily used by framework modules.
Example
# Set the name of the plugin target and the platforms it supports.
set(target_base_name my_plugin)
set(target_platforms windows macos)
# Set the Cinema 4D integration and other target settings.
set(target_settings [=[
{
"apis": ["cinema.framework", "cinema_hybrid.framework", "core.framework"],
"c4d": true,
"moduleid": "com.mycompany.example.my_command",
"stylecheck.level": 3,
"type": "DLL"
}
]=])
# Set the source directories and disable RTTI and exception handling.
set(source_directories source res)
set(enable_rtti OFF)
set(enable_exception_handling OFF)
# Let the build system process the target variables.
MaxonTargets_ProcessCinemaTargetVars()

Source Files and Platform Selection

source_directories defines the module-root-relative directories scanned by the SDK. Add sources outside those directories with target_sources() after MaxonTargets_ProcessCinemaTargetVars(). Use ordinary CMake conditions to select sources or settings for a system or architecture.

set(source_directories source res)
MaxonTargets_ProcessCinemaTargetVars()
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
target_sources(${target_name} PRIVATE "${CMAKE_CURRENT_LIST_DIR}/../platform/mac_helper.mm")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
target_sources(${target_name} PRIVATE "${CMAKE_CURRENT_LIST_DIR}/../platform/win_helper.cpp")
endif()

Use CMAKE_SYSTEM_NAME for operating-system selection and CMAKE_SYSTEM_PROCESSOR when an architecture-specific implementation is required. Keep shared source files in source_directories and place platform-specific implementations in clearly named subdirectories.

Including Libraries

Use ordinary CMake target commands after MaxonTargets_ProcessCinemaTargetVars(). Prefer imported targets provided by find_package() because they carry their own include directories, link libraries, and platform-specific settings.

Note
See example.build for an example of a more complex module build configuration that also handles linking against static and dynamic libraries, code signing, and platform specific compilation steps.
MaxonTargets_ProcessCinemaTargetVars()
find_package(Foo CONFIG REQUIRED)
target_link_libraries(${target_name} PRIVATE Foo::Foo)

For code built within the module, create normal CMake targets and express the dependency with target_link_libraries(). The plugins/example.build module demonstrates this pattern: it adds its libraries directory with add_subdirectory(), then links its static and dynamic library targets to the plugin. CMake derives the necessary build order from those target dependencies.

Note
See plugins/example.build in the SDK for a complete static and dynamic library workflow, including platform-specific library implementations and placing the dynamic library next to the plugin resources.
MaxonTargets_ProcessCinemaTargetVars()
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../libraries ${CMAKE_BINARY_DIR}/example.build/libraries)
target_link_libraries(${target_name} PRIVATE example.build.static example.build.dynamic)
target_include_directories(${target_name} PRIVATE ${CMAKE_CURRENT_LIST_DIR}/../libraries/include)

Use CMAKE_SYSTEM_NAME and CMAKE_SYSTEM_PROCESSOR when a dependency is only available on selected platforms or architectures. Do not maintain separate legacy platform-variable lists for native CMake targets.

Compilation Settings

Apply include paths, compile definitions, compile options, and link options directly to ${target_name} after the SDK has created it. Target-local settings avoid leaking configuration to other modules. Use generator expressions when a setting is configuration-specific.

MaxonTargets_ProcessCinemaTargetVars()
target_include_directories(${target_name} PRIVATE "${CMAKE_CURRENT_LIST_DIR}/../third_party/include")
target_compile_definitions(${target_name} PRIVATE MYPLUGIN_ENABLE_FEATURE=1)
target_compile_options(${target_name} PRIVATE
$<$<CXX_COMPILER_ID:MSVC>:/wd4242>
$<$<CXX_COMPILER_ID:AppleClang>:-Wno-deprecated-declarations>)
target_link_options(${target_name} PRIVATE
$<$<PLATFORM_ID:Darwin>:-Wl,-dead_strip>)

The SDK target settings configure the API frameworks, source processor, and normal plugin defaults. Use native CMake commands only for module-specific settings that are not part of those core settings.

Target Output

Use set_target_properties() to adjust the output name, prefix, suffix, or output directory of a module-owned target. This is useful for dynamic libraries that must be shipped next to a plugin. The example.build dynamic library sets OUTPUT_NAME and places its runtime output in the module's res directory. The SDK template's legacy output_directory variable is not consumed by the SDK 2027 target implementation.

set_target_properties(example.build.dynamic PROPERTIES
OUTPUT_NAME "example.build"
PREFIX ""
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/../res"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/../res")

Pre- and Post-Build Events

Use add_custom_command() for work which must occur before or after a specific target is built. Attach the command to ${target_name} after MaxonTargets_ProcessCinemaTargetVars() so CMake schedules it as part of that target. The SDK owns source-processor execution; do not add legacy source-processor calls to custom commands.

MaxonTargets_ProcessCinemaTargetVars()
add_custom_command(TARGET ${target_name} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E echo "Packaging $<TARGET_FILE_NAME:${target_name}>"
COMMENT "Packaging module output")

Use PRE_BUILD, PRE_LINK, or POST_BUILD according to when the command's output is needed. For work which is not associated with one binary, create an add_custom_target() and express its relationship with add_dependencies().

Runtime Dependencies

Shared libraries, data files, and other runtime payloads must be copied to the location from which the plugin or application loads them. Attach a post-build command to the module target to copy a module-owned or third-party runtime dependency into the module's res directory.

add_custom_command(TARGET ${target_name} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"$<TARGET_FILE:Foo::Foo>"
"${CMAKE_CURRENT_LIST_DIR}/../res")

The target must already exist. Select platform-specific source paths with normal CMake if() conditions. On macOS, sign nested dynamic libraries before signing the plugin that loads them.

Style Check Settings

Style settings are JSON members in target_settings. They are consumed by the source processor rather than by CMake. The recommended baseline for third-party modules is "stylecheck.level": 3. A level is a preset: 0 disables checks, 1 and 2 progressively enable more groups, and 3 or greater enables the complete default set. Individual options can override that preset.

Key Description
stylecheck.level Selects a numeric style-check preset. Level 3 is the recommended strict preset.
stylecheck Enables or disables style checks.
stylecheck.aswarnings Reports style violations as warnings.
stylecheck.domains Restricts registration identifiers to the listed domain prefixes.
stylecheck.register-qualifiers Registers custom declaration qualifiers with the source processor.
stylecheck.whitespace, stylecheck.no-whitespace, stylecheck.indentation Controls whitespace and indentation checks.
stylecheck.todo, stylecheck.consistent-blocks, stylecheck.newline-for-substatement, stylecheck.case-break Controls comment, block, substatement, and switch-case checks.
stylecheck.typedef-struct, stylecheck.enum-class, stylecheck.enum-registration, stylecheck.class-for-templateparam Controls type and enum declaration checks.
stylecheck.explicit, stylecheck.void-paramlist, stylecheck.virtual, stylecheck.static-within-type Controls constructor, function, virtual declaration, and static-member checks.
stylecheck.supercall, stylecheck.ambiguouscalls, stylecheck.selfcalls Controls component method and call checks.
stylecheck.using, stylecheck.naming, stylecheck.methodmarker Controls namespace directives, naming, and MAXON_METHOD usage.
stylecheck.max-linecount Sets the maximum permitted function length.
Example
set(target_settings [=[
{
"apis": ["cinema.framework", "core.framework"],
"c4d": true,
"moduleid": "com.mycompany.example",
"stylecheck.domains": ["com.mycompany"],
"stylecheck.level": 3,
"type": "DLL"
}
]=])

Boolean style-check members use JSON booleans, stylecheck.level and stylecheck.max-linecount use numbers, and stylecheck.domains and stylecheck.register-qualifiers accept strings or arrays which the source processor reads as lists.

Advanced Source Processor Settings

The shipped SDK source processor also accepts the following advanced target_settings members. Use them only when their generated-code behavior is required.

Key Description
dontuncrustify Array of path fragments excluded from source processing. Despite its legacy name, matching files are skipped by the source processor, not only by formatting.
modules, modulesweak, modulesoptional Module dependencies recorded as strong, weak, or optional dependencies in generated registration data.
frameworkregistrationincludereflection Includes reflection registration for a framework-registration module.
moduleregistration Enables or disables generated module registration. Defaults to true.
encoding Overrides the source encoding used by the processor. Use only for legacy source files.

Settings such as maxon, publicationlevel, obfuscate, excludesplitregistercpps, and frameworkroot occur in the internal Cinema 4D source tree or SDK framework descriptors, but they are not part of the supported third-party SDK configuration contract. In particular, the shipped source processor rejects "maxon": true for modules below the SDK plugins directory.

Migrating from projectdefinition.txt

The SDK can convert legacy modules automatically during CMake configuration. Set MAXON_SDK_MODULES_DIR to the directory containing the modules and explicitly enable MAXON_MIGRATE_LEGACY_PROJECTS, which is disabled by default. The SDK examines every immediate module directory before module discovery. For each module, it generates project/CMakeLists.txt only when that file does not exist and project/projectdefinition.txt does exist. Existing native configurations are never overwritten by this automatic migration.

The migration option is a CMake cache setting. After changing it or MAXON_SDK_MODULES_DIR in the CMake GUI, run Configure again before pressing Generate. Generated CMakeLists.txt files are written into the module source directories, not into the CMake build directory, and are immediately used by module discovery in the same configuration pass.

Warning
Automatic conversion produces a base native CMake configuration, not a guaranteed complete or flawless translation of every legacy projectdefinition.txt setup. Review and adapt every generated CMakeLists.txt, especially custom paths, external dependencies, platform-specific settings.
MAXON_MIGRATE_LEGACY_PROJECTS conversion produces a base native CMake configuration, not a guaranteed complete or flawless translation of every legacy projectdefinition.txt setup. Review and adapt every generated CMakeLists.txt, especially custom paths, external dependencies, platform-specific settings. The feature is meant as a one-time migration tool for legacy projects. You cannot keep using the legacy project definitions after migration; any support requests for migration after the end of the 2027.X.X cycle will be out of scope of support.
Legacy setting Native CMake equivalent
Platform target_platforms.
Type JSON type. App targets require a manual native CMake setup.
APIS JSON apis.
C4D JSON c4d.
ModuleId JSON moduleid.
OmitApiDefine / FrameworkRegistration JSON omitapidefine / frameworkregistration.
stylecheck.* Corresponding JSON members.
ExceptionHandling / RuntimeTypeInfo enable_exception_handling / enable_rtti.
Include.{OS} target_sources() within a matching CMake if() condition.
Exclude.{OS} / ExcludeFromBuild.{OS} Select the source list with CMake conditions instead of adding excluded files.
AdditionalPreprocessorDefinitions target_compile_definitions().
AdditionalIncludeDirectories / HEADER_SEARCH_PATHS / USER_HEADER_SEARCH_PATHS target_include_directories().
AdditionalLibraryDirectories / LibrarySearchPath Prefer imported targets from find_package(); use target_link_directories() only when necessary.
AdditionalDependencies / Libraries / StaticLibraries.Linux target_link_libraries().
Frameworks.OSX find_library() followed by target_link_libraries().
OTHER_LDFLAGS target_link_options().
SystemIncludePaths target_include_directories(SYSTEM ...).
PreBuildEvent / ShellScript.OSX add_custom_command() or add_custom_target(). Remove source-processor invocations.
AdditionalCompileOptions.{OS} / DisableSpecificWarnings.{OS} target_compile_options().
AdditionalLinkOptions target_link_options().
SUBSYSTEMCONSOLE Set the subsystem with a generator-specific target property or linker option when required.
AdditionalSolutionFiles Usually unnecessary; SDK type-viewer handling is automatic.

After conversion, configure and build every supported platform and configuration. Remove projectdefinition.txt only after the native project has been verified.