I have to build a library that is using another library, how can I make variables of that another library not showing in the CMake-Gui and use instead values that are configured by my CMake script?
For example when my application is built for Mobile, I already have a flag for OpenGL ES, but the SDL "VIDEO_OPENGLES" variable still shows up in the GUI. The problem is that since my build script already have knowledge of what happens, it can happily pre-configure other scripts instead of polluting the Gui of the users that need to compile my code.
Also I want to know what happens if 2 libraries have by accident 2 variables with same name but used in a different fashion.
The key word is INTERNAL
property of the variable. Take a look at this example:
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)
Actually Component2
can be a library static or shared not an executable, it doesn't matter.
Now if you run cmake-gui
on the top directory and run Configure
you will see both Component1_CONF
and Component2_CONF
. But if you change the top-level CMakeLists.txt
and add the line which forcibly sets 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)
you will effectively hide Component1_CONF
from cmake-gui
and even from command-line (-DComponent1_CONF=Boo
) configuration.
Also you should note that usually variables are set only in the current scope (unless PARENT
keyword is used). Thus variables set in some directory don't affect variables set in peer subirectories and the parent subdirectory. However if variables are set in the very same scope (say, when you run configuration tests from within the parent CMakeLists.txt
) then yes, they could interfere one another. To prevent this CMake uses naming convention which explicitly separates variables from different packages. Most of configuration macros receives "prefix" parameter which specifies the name prefix for variables being set in the macros, so macro users (that is applications CMakeLists.txt) can explicitly separate test variables from different dependent packages.