1

I'm in the process of splitting a library of mine into a header-only lib and a compiled lib, so, for the first time, I'm trying to use CMake to "build", or rather expose, a header-only library.

Reading this and the CMake documentation, I understand I need to use an INTERFACE library, without sources. But - my headers must be compiled with a C++ language standard version of at least C++11. When I was actually compiling something, I made do with:

set_property(TARGET foo PROPERTY CXX_STANDARD 11)
set_property(TARGET foo PROPERTY CXX_STANDARD_REQUIRED ON)
set_property(TARGET foo PROPERTY CXX_EXTENSIONS OFF)

but that's:

  1. Not exactly what I need for code using the header-only lib - I need to say "at least C++11".
  2. Can't be used on INTERFACE libraries.

I noticed there is no set_property(... INTERFACE). So how am I suppoed to force dependent code to use C++11-or-later?

Edit: I am interested both in answers for constraining an exact C++ version choice in dependents, and for constraining "at least" - in case the latter is problematic/difficult/impossible.

einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • I searched a bit and I found [this SO thread](https://stackoverflow.com/questions/48148275/inducing-minimal-c-standard-version-in-cmake). Both answers are interesting. But it seems you don't have a clean way to specify the "at least". – Fareanor Jun 29 '20 at 08:45
  • I'd put it somewhere in the header file `static_assert(__cplusplus >= 201103L, "C++11 or later required");` – Ted Lyngmo Jun 29 '20 at 08:47
  • 1
    @TedLyngmo: That's useful, I suppose. But - I want a failure during the build configuration phase, not during compilation. – einpoklum Jun 29 '20 at 08:48

1 Answers1

2

If you have a fairly recent version of cmake, you can try

target_compile_features(foo INTERFACE cxx_std_11)

This ensures that every library that uses foo, i.e.

target_link_libraries(bar PRIVATE foo)

will be compiled with C++11. For example if bar uses source file bar.cpp, then bar.cpp will be compiled with std=c++11 by cmake.

stardust
  • 5,918
  • 1
  • 18
  • 20
  • "with C++11" - exactly, or at least? – einpoklum Jun 29 '20 at 09:47
  • well If you specify std=c++11 you get exactly c++11 so I would say exact :) – stardust Jun 29 '20 at 09:52
  • If you need some fine grained control of features. for example if you want constexpr support but do not want to fix things to c++11 or 17 you can use `target_compile_features(foo INTERFACE cxx_constexpr)`. CMake will make sure that it is supported and `bar` is compiled with that support. – stardust Jun 29 '20 at 09:57
  • Ok, just making sure. I know about the fine-grained control of features, maybe that's a good idea - since it's a bit like "at least C++11". But - do these cover all C++11 features, or just some? – einpoklum Jun 29 '20 at 09:59
  • 1
    ... Ah, wait: CMake documentation says that "cxx_std_11: Compiler mode is at least C++ 11." ! – einpoklum Jun 29 '20 at 10:01
  • 1
    Use the `target_*` commands instead of `set_property()` ones when you can. You can see the target_compile_features() here. https://cmake.org/cmake/help/latest/manual/cmake-compile-features.7.html – stardust Jun 29 '20 at 10:02