2014-12-29 6 views
1

Мне нужно создать библиотеку, которая использует другую библиотеку, как я могу сделать переменные этой другой библиотеки, не отображаемой в CMake-Gui, и использовать вместо нее значения, которые настроены по моему сценарию CMake?Обертывание переменных кэша библиотеки при настройке моего кода в CMake

Например, когда мое приложение создано для Mobile, у меня уже есть флаг OpenGL ES, но переменная SDL «VIDEO_OPENGLES» все еще отображается в графическом интерфейсе. Проблема в том, что, поскольку мой скрипт сборки уже знает, что происходит, он может с радостью предварительно настроить другие сценарии, а не загрязнять Gui пользователей, которые должны скомпилировать мой код.

Также я хочу знать, что произойдет, если 2 библиотеки имеют случайно 2 переменные с одинаковым именем, но используются по-другому.

+0

Наконец-то я снова нашел свой ответ :) Это стоило каждой щедрости ответить на этот вопрос, и я могу, наконец, использовать его :) – GameDeveloper

ответ

3

Ключевое слово INTERNAL Свойство переменной. Посмотрите на этот пример:

Test/CMakeLists.txt:

cmake_minimum_required(VERSION 2.8) 

Project(Test) 

add_subdirectory(Component1) 
add_subdirectory(Component2) 

Test/COMPONENT1/CMakeLists.txt:

cmake_minimum_required(VERSION 2.8.11) 

project(Component1) 

set(SOURCES test1.c) 

set(Component1_CONF "SomeValue" CACHE STRING "Component1_CONF description") 
message(STATUS "Component1_CONF=${Component1_CONF}") 

add_library(Component1 ${SOURCES}) 
target_include_directories(
    Component1 INTERFACE 
    "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>" 
    "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>" 
) 

Test/COMPONENT2/CMakeLists.txt:

project(Component2) 

set(SOURCES test1.c) 

set(Component2_CONF "/etc/passwd" CACHE FILEPATH "Component2_CONF description") 

add_executable(Component2 ${SOURCES}) 
target_link_libraries(Component2 Component1) 

На самом деле Component2 может быть библиотекой статической или общей не исполняемой, это не имеет значения.

Теперь, если вы запустите cmake-gui на верхней директории и запустить Configure вы увидите, как Component1_CONF и Component2_CONF. Но если изменить верхний уровень CMakeLists.txt и добавьте строку, которая принудительно устанавливает Component1_CONF:

cmake_minimum_required(VERSION 2.8) 

Project(Test) 

set(Component1_CONF "Other value" CACHE INTERNAL "Component1_CONF forced value" FORCE) 
add_subdirectory(Component1) 
add_subdirectory(Component2) 

вы будете эффективно скрыть Component1_CONF от cmake-gui и даже из командной строки (-DComponent1_CONF=Boo) конфигурации.

Также вы должны заметить, что обычно переменные устанавливаются только в текущей области (если не используется ключевое слово PARENT). Таким образом, переменные, заданные в каком-то каталоге, не влияют на переменные, заданные в одноранговых подкаталогах и родительский подкаталог. Однако, если переменные установлены в одной и той же области (например, когда вы запускаете тесты конфигурации из родителя CMakeLists.txt), тогда да, они могут мешать друг другу. Чтобы предотвратить этот CMake, используется соглашение об именах, которое явно разделяет переменные из разных пакетов. Большинство макросов конфигурации получает параметр «префикс», который указывает префикс имени для переменных, заданных в макросах, поэтому пользователи макросов (то есть приложения CMakeLists.txt) могут явно разделять тестовые переменные из разных зависимых пакетов.

+0

Вы имеете в виду, что если Component1 задает значение переменной «BlaBla», то я могу ссылаться на него верхнего уровня как «Component1_BlaBla» и установить это для внутреннего? Это важный момент, потому что вручную добавление префикса во избежание конфликтов может оказаться невозможным (просто подумайте о сценариях cmake Ogre или SDL). – GameDeveloper

+0

№. Имя является дословным, то есть, если Component1 устанавливает переменную Blabla, тогда это будет «BlaBla», переменная, буквально. Но по умолчанию эта переменная существует только в подкаталоге Component1 и его потомках, вне Component1 переменная не задана. Вы можете установить переменную в родительском контексте (то есть в моем примере из «Компонент1» в «Тесте»), используя ключевое слово «PARENT».Но помните, что в этом случае вы не устанавливаете переменную в текущем контексте, только в родительской. – user3159253

+0

Вариант с префиксами кажется немного хрупким, но на практике этого достаточно для чего-то разумного. – user3159253