target_compile_features may cause inconsistent C++ standard settings, leading to silent ODR violations
As demonstrated in the following project,
target_compile_features(lib1 PUBLIC cxx_std_14)
is propagated to lib2
, but not to the main executable. This causes lib1
and lib2
to be compiled with -std=c++14
, but the executable with -std=c++11
. If lib2
has a C++ API (which it typically would, if it cared to use target_compile_features
to request a minimum C++ standard), the executable uses this API in C++11 mode, and lib2
itself would use it in C++14 mode. This can affect lib2
's ABI, potentially cause the class layouts to change, and lead to very hard to track ODR violations.
A similar problem can occur with a graph of the form lib1 <- exe -> lib2
, where lib1
would cause the C++ standard level of exe
to be bumped to C++14, but the C++ standard level of lib2
would remain C++11, again potentially causing ABI/ODR issues.
For uses of target_compile_features
to be safe, there probably should exist a way for a C++ library to express in its CMakeLists.txt
a requirement that mixing C++ standard levels is not supported. In scenarios like the above, this could either lead to a diagnostic, or alternatively, a consistent C++ standard level of the entire project can be computed and propagated.