# Propagate C++ standard to export

**URL:** https://discourse.cmake.org/t/propagate-c-standard-to-export/11785
**Category:** Usage
**Created:** [September 27, 2024, 11:00am UTC](https://discourse.cmake.org/t/propagate-c-standard-to-export/11785 "2024-09-27T11:00:23Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![KUGA2](https://discourse.cmake.org/user_avatar/discourse.cmake.org/kuga2/32/4968_2.png) [@KUGA2](https://discourse.cmake.org/u/KUGA2)
#### Post date: [September 27, 2024, 11:00am UTC](https://discourse.cmake.org/t/propagate-c-standard-to-export/11785/1 "2024-09-27T11:00:23Z")

</div>

Hi,

I have a project that uses std::string\_view in the interfaces. Therefore I need to propagate the standard to the export so that users using find\_package() will automatically set their standard right.

How to do this?  
As my project has hundreds of exported target, how can I set this for all exported targets?

Thanks!

---

<div class="post-metadata">

### Author: ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)
#### Post date: [September 27, 2024, 12:46pm UTC](https://discourse.cmake.org/t/propagate-c-standard-to-export/11785/2 "2024-09-27T12:46:14Z")

</div>

Use an `INTERFACE` target `my_config_target` with only set some include, defines, properties, …

and use `target_link_libraies(xxx PUBLIC my_config_target)` on all other targets.

For an example see [cpp\_vcpkg\_project/CMakeLists.txt at main · aminya/cpp\_vcpkg\_project (github.com)](https://github.com/aminya/cpp_vcpkg_project/blob/main/CMakeLists.txt#L82)

---

<div class="post-metadata">

### Author: ![jwm](https://discourse.cmake.org/user_avatar/discourse.cmake.org/jwm/32/654_2.png) [@jwm](https://discourse.cmake.org/u/jwm)
#### Post date: [September 27, 2024, 9:20pm UTC](https://discourse.cmake.org/t/propagate-c-standard-to-export/11785/3 "2024-09-27T21:20:04Z")

</div>

Be careful with this. I used a project that exports `-std=c++17` as compile flags, but we want to build with C++20. The resulting compilation command includes our `-std=c++20` followed by the imported `-std=c++17`, meaning no matter what we do, we can’t use C++20 features.

I don’t have the answer, but it would be better to specify the features you require or just let a project that doesn’t support a new enough standard fail to compile when they try to use your project.

---

<div class="post-metadata">

### Author: ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)
#### Post date: [September 28, 2024, 1:59am UTC](https://discourse.cmake.org/t/propagate-c-standard-to-export/11785/4 "2024-09-28T01:59:28Z")

</div>

The right way to apply that constraint is with compile features:

```cmake
target_compile_features(someTarget PUBLIC cxx_std_17)

```

That will make the `someTarget` compile with at least C++17, and anything that links to `someTarget` will also compile with at least C++17. Compile features support transitive requirements just like compile options, compile definitions and header search paths.

Unfortunately, you can’t set a variable to define a default value for compile features. If specifying them individually is tedious for you to do, then the alternative is you iterate over all targets within a directory and its children and you add something like the above call for each target. You’ll need the `BUILDSYSTEM_TARGETS` and `SUBDIRECTORIES` directory properties to iterate over and to walk the directory structure (there are caveats, but if you’re not loading a source directory multiple times, you’ll be fine). It’s a bit of a brute force approach, and I wouldn’t recommend doing it this way. Even if I have to manually edit a project once to update 100 targets, it’s not hard and you only need to do it once, and it is clearer what you’re doing.
