Archive for February, 2012

C++11 Detection with CMake

February 15th, 2012 7 comments

Currently when developing C++, I usually target three different compilers: MSVC, GCC and Clang. While all three offer a pretty good support ISO-C++98, things get a little more difficult with the new C++11, as they all implement different subsets of the new features.

While CMake has its disadvantages, I know of no other tool that works as well in situations like this. Unfortunately, CMake does not offer C++11-detection out-of-the-box as of this writing (version 2.8.6). A little search around the web lead to a post on CMake’s mailing list by Rolf Eike Beer. I found that script to work quite well for simple feature detection and modified it a little to better match my needs.

You can download my script from here.

Also, here’s a quick outline on how it works: Most of this is Rolf Eike Beer’s work, I just made a few minor modifications. Most of the code comes from the CXX11_CHECK_FEATURE macro. In particular, you can add your own feature tests simply by adding another call to that macro. It takes as arguments

  • FEATURE_NAME – A single-word string identifier for the feature
  • FEATURE_NUMBER – The number of the proposal paper where the feature was initially specified. This is optional and may just be set to the empty string.
  • RESULT_VAR – The name of the CMake variable that will be set to indicate whether the feature is present. It is a good idea to chose a name like HAS_CXX11_FOO, so that you can later set a preprocessor constant of the same name to inform your code of the availability of a feature.

For example, the check for the auto keyword calls


With this, the macro searches for a file c++11-test-auto-N2546.cpp and tries to compile it. Only if the file compiles succesfully and returns 0 upon execution, the feature is marked as supported (when cross-compiling it suffices that the test file compiles, as CMake has no means of executing it).

As an optional, second step, if a file c++11-test-auto-N2546_fail_compile.cpp is found, that file must not compile for the feature to be marked as supported. This is useful for checking things like static_assert(false), but is not needed in most cases. There was actually a small bug in the original code that messed up handling of the fail case, but that has been corrected (it did not dereference the RESULT_VAR before assigning).

If all tests pass, the specified RESULT_VAR is set in CMake and also added to the CXX11_FEATURE_LIST list variable.
That way you can easily add them as preprocessor definitions by calling something like

foreach(flag ${CXX11_FEATURE_LIST})
set_property(TARGET your_target

in your CMakeLists.txt.

I added a small number of simple test scripts, which I hope are bug-free. I tested them on Clang, GCC and MSVC 10, so they should at least give correct results there. Currently I test for auto, nullptr, lambdas, static_assert, Rvalue references, decltype, the cstdint-header, long long, variadic templates, constexpr, sizeof() of non-static class members and __func__. If you happen to have some more tests, I’d be glad to hear from you.

Categories: IT, Programming