Cmake lost in the concept of global variables (and alternatives to PARENT_SCOPE or add_subdirectory)

I have a cmake project in which I have several modules and I use Find - *. cmake to include common modules in the application. In order to ignore every module that is added, I have defined global LIB variables for the linker:

 # inside a Find-*.cmake or in the CMakeLists.txt of the modules: set(LIB ${LIB} ...) 

so in one of the final applications, which uses some modules, I can simply do:

 target_link_libraries(${APP_NAME} ${LIB}) 

Then I would like to have compiled modules in /project_path/modules/foo/build , so if the module is really big to compile, it can be compiled once for all applications that use it. The way I achieve this is to load the CMakeLists.txt module from Find - *. Cmake as follows:

 # Inside FindFoo.cmake, for loading /project_path/modules/foo/CMakeLists.txt # and compile it in /project_path/modules/foo/build add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../modules/${PACKAGE_NAME} ${CMAKE_CURRENT_LIST_DIR}/../modules/${PACKAGE_NAME}/build ) include_directories(${CMAKE_CURRENT_LIST_DIR}/../modules/${PACKAGE_NAME}/include) 

But sometimes it happened that for some module other modules are required, so add_subdirectory creates new add_subdirectory and can load the LIB correctly, but cannot write it (when I use set , it is in a deeper region and does not change the upper region). To work around this I have to add PARENT_SCOPE to set ). Therefore, I tried to add it to some module, which, I think, may be nested and hidden in some dependencies, but I suddenly ran into compiling the entire application:

 CMake Warning (dev) at /path_to_repo/cmake/FindFooX.cmake:6 (set): Cannot set "LIB": current scope has no parent. Call Stack (most recent call first): CMakeLists.txt:14 (find_package) This warning is for project developers. Use -Wno-dev to suppress it. 

I am afraid that this may change from application to application in terms of which module I need, or in relation to the dependency tree in the modules themselves, so I am looking for a cleaner solution.

+9
scope global-variables dependencies cmake
Oct 13 '13 at 13:46 on
source share
2 answers

All variables in CMake are local by default. Although you can use the PARENT_SCOPE parameter to increase the volume of a local variable by one level, this basically makes sense for the return values โ€‹โ€‹of functions .

To search for scripts, on the other hand, you usually want the behavior of a global variable: after any user finds a script, you want the results to be available everywhere. In particular, the second call of the same find script should simply reuse the results of the first call. In CMake, this is achieved by storing variables in the cache. The various calls to find_* already do this automatically, so you should use them where applicable. For any additional custom variables, set offers the ability to store in cache:

 set(MY_GLOBAL_VARIABLE "Some value" CACHE STRING "Description") 

Note that local variables can hide cached variables of the same name in their scope.

+20
Oct 14 '13 at 9:02
source share

You can "simulate" the behavior of GLOBAL variables using properties with the GLOBAL scope:

 SET_PROPERTY(GLOBAL PROPERTY MyGlobalProperty "MyGlobalPropertyValue") 

Then you can retrieve the global property using

 GET_PROPERTY(MyLocalVariable GLOBAL PROPERTY MyGlobalProperty) 

Then MyLocalVariable contains "MyGlobalPropertyValue".

Since PARENT_SCOPE expands the definitions of variables to a single parent directory (and not its parents), in some cases this is not enough, for example, if you have a deep source tree ...

+25
Mar 25 '15 at 8:16
source share



All Articles