RFC: ability to define preprocessor flags on MSW without modifying cinder repo

I’d like to bring to attention a proposed addition to the Windows platform that would allow one to modify the C preprocessor symbols that are used when building libcinder, without requiring modifications to the cinder repo:

This is considered advanced usage and leverages some perhaps offbeat features of Visual Studio to accomplish what it does. Nonetheless it is an invaluable feature when working on large projects that need to keep all changes versioned, and so they don’t want to fork and modify cinder’s sources to do that. This is typically available when building with Makefiles or CMake using CFLAGS at the command line, and many open source libraries provide command line flags to allow you to customize their build. As far as I know there is no way to achieve the same with Xcode, so we haven’t attempted this same feature there.

Why would you want to modify proprocessor symbols that cinder uses when building, you ask? Some common cases include the CI_MIN_LOG_LEVEL, as described in this guide, and a few compile time macros that adjust the way that CI_ASSERT() works (see this header).

Setting up your project to use this new feature requires a bit of work.

  • For starters, you need to add cinder.vcxproj to your main project’s solution file. This is a nice thing to do anyway when working on a large project, as it allows you to easily navigate cinder’s codebase to find what you’re after.
  • Next thing to know, is that cinder.vcxproj will search for a file called CinderMswUserDefines.h, which will be added as a “Forced Include File”, i.e. its contents will be preprended to every source file built in libcinder (if you don’t provide a CinderMswUserDefines.h file, a dummy default will be used that is tucked away in cinder’s include/cinder/msw folder). The crafty part to this trick is that a new header include path has been added that first searches in the same directory as your solution file (.sln), which lives outside of the cinder repo in the setup described here. You also need to add this same setting to any vcxproj file that you want to make use of the same preprocessor adjustments. Here’s a screencap of what that looks like:

  • For this file to also be found in your projects, you should add an ‘Additional Include Directories’ to your project for $(SolutionDir), which looks like:

  • For my projects, I also make cinder.lib a dependency on my app’s target, which forces it to be rebuilt whenever necessary.

That’s about it, now when you place anything in your CinderMswUserDefines.h file, it will customize the cinder.lib that your app links to accordingly. Of course, this file could be abused by placing #includes or other devilry in there so use when appropriate. Ultimately for me, this is a feature common when building open source libraries that hasn’t been available when building with Visual Studio, so I find it worthy of consideration. In fact, we’ve already used it on a remotely deployed project to debug where assertion failures were coming from, thereby allowing us to track down problems with file logs.

Here is a stackoverflow post that describes using this same technique.

Happy to hear about suggestions, opinions, ways to improve on this, or anything else you have to offer.


Any concerns or reservations regarding this? It is being used in a production setting so I’d otherwise like to merge this soon.

This has been merged into the master branch, along with docs that should show up on this page after a nightly build has completed.