Как заставить иждивенцев моей библиотеки INTERFACE использовать C++11 или более позднюю версию?

Я нахожусь в процессе разделения своей библиотеки на библиотеку только для заголовков и скомпилированную библиотеку, поэтому впервые я пытаюсь использовать CMake для создания или, скорее, предоставления библиотеки только для заголовков.

Читая это и документацию CMake, я понимаю, что мне нужно использовать библиотеку INTERFACE без источники. Но мои заголовки должны быть скомпилированы со стандартной версией языка C++ не ниже C++11. Когда я действительно что-то компилировал, я обходился:

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)

но это:

  1. Не совсем то, что мне нужно для кода, использующего библиотеку только для заголовков - мне нужно сказать как минимум С++ 11.
  2. Нельзя использовать в библиотеках INTERFACE.

Я заметил, что нет set_property(... INTERFACE). Итак, как мне заставить зависимый код использовать С++ 11 или более позднюю версию?

Редактировать: меня интересуют как ответы на ограничение выбора точной версии C++ в зависимых, так и ограничение, по крайней мере, в случае, если последнее проблематично/сложно/невозможно.


person einpoklum    schedule 29.06.2020    source источник
comment
Я немного поискал и нашел этот поток SO. Оба ответа интересны. Но, похоже, у вас нет четкого способа указать хотя бы.   -  person Fareanor    schedule 29.06.2020
comment
Я бы поместил куда-нибудь в заголовочный файл static_assert(__cplusplus >= 201103L, "C++11 or later required");   -  person Ted Lyngmo    schedule 29.06.2020
comment
@TedLyngmo: Полагаю, это полезно. Но мне нужен сбой на этапе настройки сборки, а не во время компиляции.   -  person einpoklum    schedule 29.06.2020


Ответы (1)


Если у вас довольно свежая версия cmake, вы можете попробовать

target_compile_features(foo INTERFACE cxx_std_11)

Это гарантирует, что каждая библиотека, использующая foo, т.е.

target_link_libraries(bar PRIVATE foo)

будет скомпилирован с C++11. Например, если bar использует исходный файл bar.cpp, тогда bar.cpp будет скомпилирован с std=c++11 с помощью cmake.

person stardust    schedule 29.06.2020
comment
с С++ 11 - точно или хотя бы? - person einpoklum; 29.06.2020
comment
хорошо, если вы укажете std=c++11, вы получите именно c++11, поэтому я бы сказал точно :) - person stardust; 29.06.2020
comment
Если вам нужен точный контроль функций. например, если вам нужна поддержка constexpr, но вы не хотите исправлять ситуацию до С++ 11 или 17, вы можете использовать target_compile_features(foo INTERFACE cxx_constexpr). CMake позаботится о том, чтобы он поддерживался, и bar был скомпилирован с этой поддержкой. - person stardust; 29.06.2020
comment
Хорошо, просто удостоверяюсь. Я знаю о тонком контроле функций, может быть, это хорошая идея, так как это немного похоже, по крайней мере, на С++ 11. Но охватывают ли они все функции С++ 11 или только некоторые? - person einpoklum; 29.06.2020
comment
... Ах, подождите: в документации CMake сказано, что cxx_std_11: Режим компиляции не ниже C++ 11. ! - person einpoklum; 29.06.2020
comment
По возможности используйте команды target_* вместо set_property(). Вы можете увидеть target_compile_features() здесь. cmake.org/cmake/help/latest/manual/ - person stardust; 29.06.2020