В чем разница между переменными CMake и свойствами?

user1489829 спросил: 28 марта 2018 в 03:26 в: cmake

Переменные и свойства CMake, похоже, выполняют очень похожие вещи, и я не мог понять разницу между ними.

У каждого из них есть свои собственные разделы документации, но оба могут влиять на систему сборки, оба "предсуществуют", и оба могут динамически генерироваться на основе других команд CMake. Похоже, что у них должны быть отдельные цели. Что они?


1 ответ

Stephen Newell ответил: 28 марта 2018 в 04:15

Очень короткий и простой способ думать о том, что свойства - это переменные, ограниченные целью. Например:

add_executable(foo foo.cpp)
set_target_properties(foo PROPERTIES
    CXX_STANDARD 14
    CXX_EXTENSIONS OFF
)
# Build foo with c++11 for some reason
add_executable(foo11 foo.cpp)
set_target_properties(foo11 PROPERTIES
    CXX_STANDARD 11
    CXX_EXTENSIONS OFF
)

Если CMakeLists.txt был написан на C ++, это может выглядеть примерно так:

const char * src_files[] = { "foo.cpp" };
executable foo{src_files};
foo.setCxxStandard(14);
foo.setCxxExtensions(false);executable foo11{src_files};
foo.setCxxStandard(11);
foo.setCxxExtensions(false);

Если бы мы использовали переменные для этих вещей, это будет выглядеть примерно так:

// globals
int CMAKE_CXX_STANDARD = 14;
bool CMAKE_CXX_EXTENSIONS = false;// later, in a function
const char * src_files[] = { "foo.cpp" };
executable foo{src_files}; // foo copies global settingsCMAKE_CXX_STANDARD = 11;
executable foo11{src_files};

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

set_target_properties(Foo::bar PROPERTIES
    INTERFACE_COMPILE_FEATURES "cxx_std_14"
    INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include/"
    INTERFACE_SOURCES "${_IMPORT_PREFIX}/include/foo/bar.hpp"
)

Это означает, что если вы импортируете Foo::bar (возможно, через что-то вроде find_package(Foo)), ваш проект уже знает, что вещи, ссылающиеся на Foo::bar, должны использовать C ++ 14 (INTERFACE_COMPILE_FEATURES), ему нужно что-то добавить к пути включения (INTERFACE_INCLUDE_DIRECTORIES), и там некоторые исходные файлы, о которых он заботится (мои заголовки, INTERFACE_SOURCES).

user1489829 ответил: 28 марта 2018 в 09:07
Ах, я думаю, что я могу понять разницу, поскольку свойства могут быть ограничены, тогда как переменные всегда глобальные. За исключением случаев, описанных в документации по свойствам, свойства cmake.org/cmake/help/v3.11/manual/cmake-properties.7.html также могут быть глобальными, поэтому в этом случае они все еще сбивают меня с толку, и различие кажется произвольным.
Stephen Newell ответил: 28 марта 2018 в 11:27
@ user1489829 - Я признаю, что не знал о глобальных свойствах, поэтому мне придется выяснить это. Мой ответ специально для свойств на цели, но сравнение может быть расширено для любого неглобального свойства.
Fedorov7890 ответил: 22 апреля 2018 в 11:43
Как обозначено user1489829, есть также свойства Global Scope, что делает этот ответ неверным. Итак, я все еще хотел бы получить правильный и более полный ответ. По состоянию на май 2018 года поиск в этом вопросе ничего не дает.