# Setting C++ standard on INTERFACE libraries

**URL:** https://discourse.cmake.org/t/setting-c-standard-on-interface-libraries/10933
**Category:** Usage
**Created:** [June 3, 2024, 7:03am UTC](https://discourse.cmake.org/t/setting-c-standard-on-interface-libraries/10933 "2024-06-03T07:03:01Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![Zingam](https://discourse.cmake.org/user_avatar/discourse.cmake.org/zingam/32/3756_2.png) [@Zingam](https://discourse.cmake.org/u/Zingam)
#### Post date: [June 3, 2024, 7:03am UTC](https://discourse.cmake.org/t/setting-c-standard-on-interface-libraries/10933/1 "2024-06-03T07:03:01Z")

</div>

I try to understand why setting the C++ standard properties on an interface library doesn’t work. I can’t find this documented or properly explained anywhere. CMake doesn’t seem to issue any warnings or errors.

```auto
add_library(CMakeTestLib INTERFACE)
set_target_properties(CMakeTestLib 
    PROPERTIES
        CXX_STANDARD 23
        CXX_STANDARD_REQUIRED ON
        CXX_EXTENSIONS OFF
)

# or
set_property(TARGET CMakeTestLib PROPERTY CXX_STANDARD 23)
set_property(TARGET CMakeTestLib PROPERTY CXX_STANDARD_REQUIRED ON)
set_property(TARGET CMakeTestLib PROPERTY CXX_EXTENSIONS OFF)

```

If I set the standard version via compile features, why aren’t there “compile features” to also turn off compiler extensions?:

```auto
target_compile_features(CMakeTestLib
  INTERFACE
    cxx_std_23
)

```

Then I need to go for a mixed solution or

```auto
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

```

According to the documentation

> add\_library( INTERFACE)
> 
> Add an [Interface Library](https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#interface-libraries) target that may specify usage requirements for dependents but does not compile sources and does not produce a library artifact on disk.
> 
> An interface library with no source files is not included as a target in the generated buildsystem. However, it may have properties set on it and it may be installed and exported. Typically, `INTERFACE_*` properties are populated on an interface target using the commands:

If I understand the above correctly I can use an interface library to define all my properties in a single consistent way and to apply them to all targets that link to the interface library transitively.  
Is that so or am I “holding it wrongly”?

---

<div class="post-metadata">

### Author: ![adaldev](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/a/9dc877/32.png) [@adaldev](https://discourse.cmake.org/u/adaldev)
#### Post date: [June 5, 2024, 8:14am UTC](https://discourse.cmake.org/t/setting-c-standard-on-interface-libraries/10933/2 "2024-06-05T08:14:29Z")

</div>

For interface libraries, I’m using:

```cmake
target_compile_features(${TARGET_NAME} INTERFACE ${Standard})
set_target_properties(${TARGET_NAME} PROPERTIES INTERFACE_CXX_EXTENSIONS OFF)

```

And I don’t have any issues.

You’re saying that “it doesn’t work”. Can you detail in what way?

Regards,  
A.

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [June 5, 2024, 12:32pm UTC](https://discourse.cmake.org/t/setting-c-standard-on-interface-libraries/10933/3 "2024-06-05T12:32:20Z")

</div>

> [@adaldev](#):
>
> `INTERFACE_CXX_EXTENSIONS`

I can’t find any trace of such a property.

CMake doesn’t model language extensions through usage requirements at the moment, so I don’t think there’s any way of doing it today, sorry.

---

<div class="post-metadata">

### Author: ![adaldev](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/a/9dc877/32.png) [@adaldev](https://discourse.cmake.org/u/adaldev)
#### Post date: [June 5, 2024, 12:37pm UTC](https://discourse.cmake.org/t/setting-c-standard-on-interface-libraries/10933/4 "2024-06-05T12:37:24Z")

</div>

Hi,

I can’t recall where I found `INTERFACE_CXX_EXTENSIONS`.  
Oddly enough, it’s mentioned in [https://gitlab.kitware.com/cmake/cmake/-/issues/17183](https://gitlab.kitware.com/cmake/cmake/-/issues/17183) by someone you know ;-).

I’ve juste made a test and replaced `CXX_EXTENSIONS` without any change in behavior. As stated in previous link, I’m beginning to suspect that this property is useless for headers-only libraries.

Regards

---

<div class="post-metadata">

### Author: ![Zingam](https://discourse.cmake.org/user_avatar/discourse.cmake.org/zingam/32/3756_2.png) [@Zingam](https://discourse.cmake.org/u/Zingam)
#### Post date: [June 6, 2024, 10:10am UTC](https://discourse.cmake.org/t/setting-c-standard-on-interface-libraries/10933/5 "2024-06-06T10:10:39Z")

</div>

I skimmed over the issue: [https://gitlab.kitware.com/cmake/cmake/-/issues/17183](https://gitlab.kitware.com/cmake/cmake/-/issues/17183)

There is a comment proposing a policy to disable extensions:  
[https://gitlab.kitware.com/cmake/cmake/-/issues/17183#note\_558723](https://gitlab.kitware.com/cmake/cmake/-/issues/17183#note_558723)  
I like that and it would be good if it is set by default.

Attempting this:

```auto
set_target_properties(CMakeTestLib 
    PROPERTIES
        INTERFACE_CXX_STANDARD 23
        INTERFACE_CXX_STANDARD_REQUIRED ON
        INTERFACE_CXX_EXTENSIONS OFF
)

```

still produces and doesn’t seem to report any errors (with GCC):

```auto
  FLAGS = -g -std=gnu++23

```

Obviously I’d like to have:

```auto
  FLAGS = -g -std=c++23

```

The last comment in this issue:  
[https://gitlab.kitware.com/cmake/cmake/-/issues/16495](https://gitlab.kitware.com/cmake/cmake/-/issues/16495)  
explaince CXX\_STANDARD properties better than the documentation (IMO):

> the `CXX_STANDARD` property itself only affects how sources within that target are built. Since interface libraries have no sources it doesn’t matter. Transitive usage requirements are of the form `INTERFACE_...` where `...` is the property on the dependent targets to extend. This only works for a specific set of properties, and `CXX_STANDARD` is not among them. The intended way to propagate C++ language requirements is with `INTERFACE_COMPILE_FEATURES`.

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [June 8, 2024, 2:11am UTC](https://discourse.cmake.org/t/setting-c-standard-on-interface-libraries/10933/6 "2024-06-08T02:11:48Z")

</div>

> [@adaldev](#):
>
> Oddly enough, it’s mentioned in [https://gitlab.kitware.com/cmake/cmake/-/issues/17183](https://gitlab.kitware.com/cmake/cmake/-/issues/17183) by someone you know ;-).

Yeah, I was saying what the property would be named to have the requested effect. Alas, no such property actually exists.
