I am a bit confused about scoping rules of cmake. I do have files and directories like
├── test
│ CMakeLists.txt
│ ├── cmake
│ │ MyCMake
│ │ MyCMake2
│ ├── child
│ │ CMakeLists.txt
The contents are:
cmake/MyCMake:
set(MY_NAME MyName)
message("MyCMake: " ${MY_NAME} " " ${YOUR_NAME} " " ${HIS_NAME})
cmake/MyCMake2:
set(HIS_NAME NewName)
message("MyCMake2: " ${MY_NAME} " " ${YOUR_NAME} " " ${HIS_NAME})
child/CMakeLists.txt:
set(YOUR_NAME YourName)
set(HIS_NAME HisName PARENT_SCOPE)
message("Child: " ${MY_NAME} " " ${YOUR_NAME} " " ${HIS_NAME})
test/CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
include(MyCMake)
add_subdirectory(child)
message("Parent1: " ${MY_NAME} " " ${YOUR_NAME} " " ${HIS_NAME})
include(MyCMake2)
message("Parent2: " ${MY_NAME} " " ${YOUR_NAME} " " ${HIS_NAME})
The result is
MyCMake: MyName
Child: MyName YourName
Parent1: MyName HisName
MyCMake2: MyName NewName
Parent2: MyName NewName
This first line is OK, the 2nd and third variables are not yet defined. With the second line, it looks like it is a parent-only setting, i.e. the defined variable has a scope ONLY in the parent. (So, I can/shall the same variable with local scope?) The third line shows only variable with parent scope, OK. The 4th line shows that I set a LOCAL scope variable. In the 5th line, however, I see that the PARENT scope value has changed, which I expected to be changed ONLY locally, in the child subdirectory. What is going on here? (it looks like I can overwrite a value of the variable, which is not in my scope)
Why I started to experiment: under some conditions I do not see in the parent directory the variables (like include directories, library names, etc.) defined in the child directory. Is there a standard way to use say a library name for building in one child, and use the same name in another child for linking?
Also a question: I have an application, consisting of a library and an executable. It looks like that CMake does not allow to use the same target name for both. In my eyes, if I use name 'A' both for binary target and library target, it should not result in confusion, because the real second target is 'libA'. Am I wrong?