[question] Enforcing a minimum C++ standard for consumers of a package while remaining compiler and platform independent
See original GitHub issueI have a library that uses some C++17 language features and I am in the process of trying to package it up using Conan so it can be easily consumed by any build system. Because some of the header files in my library use C++17 features, the consumer of the library is also required compile their code with at least a minimum standard of C++17 otherwise compilation will fail.
In the package_info
section of my conanfile I can tell it to use the proper compiler flag:
self.cpp_info.cxxflags = ["-std=c++17"]
But this has two issues:
-
This compiler flag is not recognized by all compilers. For example this works with gcc, but if I try to use MSVC I will get an error
warning D9002: ignoring unknown option '-std=c++17'
and the code will fail to compile. -
This locks the consumer of the package into using C++17 when a newer standard would work. What happens when the consumer decides they want to use my library but they want to compile their code using C++20?
With a pure CMake project that doesn’t use Conan this is handled quite elegantly by just adding:
target_compile_features(<target> PUBLIC cxx_std_17)
This will automatically pass the minimum standard requirement to the consumer of the target AND should they decide to compile their code with a newer standard (like C++20) CMake will account for that and the entire library will be compiled with the newer standard instead.
While the pure CMake solution is nice, I can’t rely on it and still have my library be consumable by users who decide to use a different build system other than CMake. How can I solve this problem with Conan?
- I’ve read the CONTRIBUTING guide.
Issue Analytics
- State:
- Created 3 years ago
- Reactions:1
- Comments:16 (3 by maintainers)
Hi! To be honest, we don’t have a canonical solution, but it is something we’ve been thinking about and we need to come up with a plan for Conan 2.0. Probably a good reading is around issue https://github.com/conan-io/conan/issues/6157 and other issues linked to it.
To summarize a little bit: the way to handle C++ standard in Conan should be using
compiler.cppstd
setting, but we don’t have a mechanism to enforce a setting value for the consumer of a library. If your recipe usestools.check_min_cppstd
(or a custom implementation) it can raise an error if the provided profile doesn’t define a value (high enough) forcompiler.cppstd
, but Conan won’t assign that value based on some attribute declared in the recipes that are part of the full-graph.Nevertheless, C++ standard is a bit tricky, stable implementations are binary compatible, you only need it in the consumer if the headers of your libraries expose some new C++ feature. With this in mind, it depends on the API of your library if you should use
tools.check_min_cppstd
in theconfigure()
method (it is evaluated always) or only in thebuild()
method (that C++ standard is only required if you are going to build the library). And then, depending on the ABI compatibility of your library, you might want to removecompiler.cppstd
from the package-id computation: if all the binaries are compatible, maybe you just want to generate one of them and use it regardless of the value ofcompiler.cppstd
.Thinking about future features in Conan: a way to declare API and ABI compatibility based on the C++ standard might be added in the future, but probably not before Conan 2.0.
And of course, we need to have in mind, that using
compiler.cppstd
will pass the corresponding flags to the build system, but if it is theCMakeLists.txt
the one that defines the C++ standard to use (typicalset_target_properties(<target> PROPERTIES CXX_STANDARD 11
)), Conan won’t know anything about it.I’m so sorry, I don’t have a closed answer for this, we are working hard to improve C++ ecosystem but there are lots of things to do 😄
Thanks!
I’m okay with it if I have to redundantly define the C++ standard in the conanfile in order to have the Conan target embed that information into it, but it doesn’t look like there is any way to embed that information into a Conan target at all so any targets generated by Conan cannot automatically pass the C++ standard to the consuming project.
For now I will probably just start using
cmake_paths
as my preferred generator since that pulls in the actual CMake target and passes along the C++ standard information to the consumer. I’ll make note in the README file that other generators (cmake
andcmake_find_package
) will not capture the C++17 requirement when consuming the package so usingcmake_paths
is preferred otherwise you will need to manually specify that you are using C++17 in the consuming project.I will take a look at the toolchain stuff though and see if that provides any more useful options.