Building C++ plugins in R2025.2
The problem, as explained in my blog article here, is that before R2025.2 plugins for macOS could only be built by using Xcode 13, but Macs capable of running Cinema R2025 can't use Xcode 13 without a problematic hack. The reason Xcode 13 was needed at all was that it was necessary to use the 'legacy' build system which was not supported in Xcode versions after 13.
The solution was to no longer require the legacy build system, which meant moving to a build system generator other than the project tool which has been in use for some years. Maxon has done this with C4D R2025.2, which uses CMake instead of the project tool.
The SDK documentation gives an excellent tutorial on building the SDK example plugins but doesn't say much about how to build your own plugins. There are one or two hints but no detailed explanation. This page aims to rectify that omission.
Building the SDK examples
There's no need to repeat here what is said in the SDK docs; we can just follow that and the example plugins will build without problems. When you've done so, you end up with a directory structure which might look something like this, which is what it is on my hard drive:
Adding my own plugins
Let's say I want to build my plugin 'ArrowMaker' using this new system. How do I go about that?
The first thing is to add the source code and resources for the plugin. But where? The logical place is alongside the other plugins, so we have:
You'll see that as well as the seven folders containing the source for the various plugins there is also a 'project' folder. This contains the file 'projectdefinition.txt' which essentially just says that this project is a solution and gives the list of plugins to build in that solution. This file is no longer required if using CMake (it's there in case you want to use the old project tool, which it is said will not be used after R2025.x). So we can forget about that.
Inside the 'ArrowMaker' folder, as well as the source code and resource files, there is a folder named 'project'. This contains another, different, file called 'projectdefinition.txt' and this is definitely required in the new build system. The format is explained in the SDK docs, which state that in many cases it may not be necessary to change it from previous versions. In my case, it wasn't necessary to change that file at all.
Now, what would happen if we ran CMake at this point following the original tutorial in the SDK? The first issue is that CMake would overwrite the build system it created for the SDK examples with the build system for ArrowMaker. Adding another plugin would overwrite the ArrowMaker solution, and so on. That's a problem (to me, anyway) because if I ever wanted to go back and revisit the ArrowMaker solution, perhaps to fix a bug and rebuild it, I would have to go through the process of generating the build system all over again. It seems to me, therefore, that rather than using the same location every time we want to generate a build system for a plugin, we could use a separate folder for each build system. I did this and called the folder '_build_ArrowMaker' and got this:
Each '_build_xxx' folder contains its own build system and solution file, so I can now load any solution and work on it in the future without having to generate the build system all over again.
Of course, this is pretty wasteful in terms of disk space because it duplicates a lot of CMake files generated from the frameworks, but hard drive space is cheap and with a 4Tb drive I'm not likely to run out of disk space any time soon.
However, there is a bigger problem. The plugins folder containing the source code for all the plugins now has seven plugins in it in their own folders. Left to its own devices, CMake will trawl through all those plugins and include them in the solution, as shown here in Visual Studio:
This means that when I build ArrowMaker, the SDK examples will be built all over again. That's a complete waste of time when all I want to build is ArrowMaker.
This is the default behaviour but the fix is simple, and it's to use a 'custom_paths.txt' file. Note that the SDK docs say that an example of such a file is included in the archive, but that's incorrect. What there is, rather confusingly, is a file named 'sdk_modules.txt' which, as far as I can tell, is not used by CMake at all. At least, searching through the various CMake script and other files, I can't find any mention of this file. It may be intended as a template for a custom_paths.txt file, though the syntax doesn't quite match.
All you have to remember about custom_paths.txt is that if it is not present, or if it doesn't define any plugins (or 'modules') to load, the default behaviour above is executed. Therefore, to build only ArrowMaker and nothing else, I need to specify that plugin, and only that plugin, in custom_paths.txt. I used the 'sdk_modules.txt' file as a template. All I did was comment out the SDK example modules, because I didn't want them, and added a module statement for ArrowMaker. The final result looks like this:
# The Cinema 4D SDK can load module paths from a text file. By default this is not necessary,
# as modules are loaded by default from the MAXON_SDK_MODULES_DIR. Module files are case insensitive.
# Lines that start with the hashtag character are interpreted as comments; inline comments are not
# supported.
# A module path is defined by just placing a path onto a new line. Paths can be both relative and
# absolute, where by default relative paths are interpreted in relation to the MAXON_SDK_ROOT_DIR.
# d:/documents/code/my_plugin
# plugins/example.assets
# ../../foo/bar
# Finally, the root directory in relation to which relative paths are set can be overwritten using
# the root keyword. A root keyword will apply until it is overwritten by a new root keyword. Roots
# must be absolute paths.
# root = d:/downloads/sdk
# Loading the modules of the Cinema 4D SDK could look like this, where we load all modules relative
# to the current root dir (which is still the default root dir).
#plugins/example.assets
#plugins/example.image
#plugins/example.main
#plugins/example.migration_2024
#plugins/example.nodes
MODULE plugins/ArrowMaker
This is then saved as 'custom_paths.txt'. Where to save it? The SDK docs imply that it goes into the root directory for the build - in my case, that would be the folder '/C4D Plugins/C4D_2025_2'. But if I do that, then when I add another plugin to build, I'll have to edit that file and if I then wanted to generate the build system for ArrowMaker again for some reason, I'd have to change it back. Since it can go anywhere, the logical place seemed to me to be the project folder of the ArrowMaker folder, alongside the project definition file. This seems to work fine.
So now, I have each plugin completely self-contained, with its own build system, custom paths file, solution file and so on. That makes it really easy to reconfigure or regenerate the build system for any plugin without interfering with those of other plugins, or to reload and recompile the plugin at any time by loading its own solution file. The only small remaining issue is that the solution file for any plugin is always named 'c4d-sdk.sln' and there seems to be no easy way to change that.
This has all been done on Windows but it should be identical on macOS.
I hope this has been helpful. The use of CMake rather than Maxon's proprietary build system is a genuine step forward and at last lets us build plugins for Mac on the same machine which runs C4D R2025.
Page last updated April 11th 2025