1

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.

CoffeDeveloper
  • 7,961
  • 3
  • 35
  • 69

1 Answers1

3

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.

user3159253
  • 16,836
  • 3
  • 30
  • 56
  • Do you mean that if Component1 set "BlaBla" cache variable then I can refer to it from top level as "Component1_BlaBla" and set that to internal? That's a important point because manually adding a prefix to avoid conflicts may not be feasible (just thinking at cmake scripts of Ogre or SDL) – CoffeDeveloper Jan 10 '15 at 10:44
  • No. The name is verbatim, that is if Component1 sets variable Blabla, then it will be 'BlaBla' variable, literally. But by default this variable exists only within Component1 subdirectory and its descendants, outside Component1 the variable is not set. You may set a variable in the parent context (that is, in my example from `Component1` in the `Test`) using `PARENT` keyword. But remember that in this this case you don't set the variable in the current context, only in the parent one. – user3159253 Jan 10 '15 at 11:56
  • The variant with prefixes seems a bit fragile, but in practice it's enough for anything reasonable. – user3159253 Jan 10 '15 at 11:57
  • So basically regarding **cache** variables I have to hope all third party libraries would setup prefixed names – CoffeDeveloper Jan 10 '15 at 13:47
  • Yes, they do indeed. Don't bother yourself. – user3159253 Jan 17 '15 at 01:13