CMake范围规则
我对cmake的范围规则有点困惑。 我有像这样的文件和目录CMake范围规则,cmake,Cmake,我对cmake的范围规则有点困惑。 我有像这样的文件和目录 ├── test │ CMakeLists.txt │ ├── cmake │ │ MyCMake │ │ MyCMake2 │ ├── child │ │ CMakeLists.txt 内容包括: cmake/MyCMake: set(MY_NAME MyName) message("MyCMake: " ${MY_NAME} " " ${YOUR_
├── test
│ CMakeLists.txt
│ ├── cmake
│ │ MyCMake
│ │ MyCMake2
│ ├── child
│ │ CMakeLists.txt
内容包括:
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})
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})
test/CMakeLists.txt:
set(YOUR_NAME YourName)
set(HIS_NAME HisName PARENT_SCOPE)
message("Child: " ${MY_NAME} " " ${YOUR_NAME} " " ${HIS_NAME})
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})
结果是
MyCMake: MyName
Child: MyName YourName
Parent1: MyName HisName
MyCMake2: MyName NewName
Parent2: MyName NewName
第一行还可以,第二和第三个变量还没有定义。
对于第二行,它看起来是一个仅限父级的设置,即定义的变量仅在父级中具有作用域。(那么,我可以/应该使用本地范围的相同变量吗?)第三行仅显示具有父范围的变量,OK。第四行显示我设置了一个局部范围变量。但是,在第5行中,我看到父作用域的值已经更改,我希望在子目录中只在本地更改。
这是怎么回事?(看起来我可以覆盖不在我作用域内的变量值)
为什么我开始实验:在某些情况下,我在父目录中看不到子目录中定义的变量(如include目录、库名称等)。是否有一种标准的方法可以在一个子系统中使用库名进行构建,在另一个子系统中使用相同的名称进行链接
还有一个问题:我有一个应用程序,由一个库和一个可执行文件组成。看起来CMake不允许对这两个对象使用相同的目标名称。在我看来,如果我对二进制目标和库目标都使用名称“A”,这应该不会导致混淆,因为真正的第二个目标是“libA”。我错了吗?基本规则很简单:
添加子目录
建立一个新范围,包含
没有。因此,您的示例只涉及两个范围:
- 顶级CMakeList的范围,受
和MyCMake
中的MyCMake2
命令的影响,以及受set(…)
子/CMakeList.txt中的
命令的影响set(…父范围)
- 子CMakeList
,受child/CMakeLists.txt
命令的影响,该命令在set(…)
中不使用child/CMakeLists.txt
父范围
PARENT\u SCOPE
仅在父作用域中设置值。如果要同时为当前范围和父级设置值,则必须发出两个set
命令:
set(var Value)
set(var Value PARENT_SCOPE)
关于堆栈溢出,我们通常希望每个问题有一个问题,但我也会回答目标命名问题:CMake目标名称是CMake目标的逻辑名称,它们必须是唯一的。想象一下,如果不是这样的话:
add_library(L STATIC ...)
add_library(A SHARED ...)
add_executable(A ...)
target_link_libraries(A L)
最后一行会有什么影响?库A
会链接到L
,还是可执行文件A
会这样做?或者两者都有?Dtto用于设置属性等
您可以独立于目标名称控制生成的二进制文件的名称:有关详细信息,请参阅目标属性,如。有关第一个问题,请参阅。关于你的第二个问题,我想你正在寻找。对于你的第三个问题,你可能想看一看基本上,我同意“每个问题一个问题”的规则,但这一次这三个问题是相互关联的,问题之间的强制性延迟意味着我需要4.5小时来发布三个问题。关于逻辑名称:您是对的,但此方案阻止使用库libA创建名为的二进制文件。@katang不,它根本不阻止二进制文件库方案。您只需给目标逻辑名称
A_bin
和A_lib
,并将它们的OUTPUT_NAME
属性设置为A
。没有什么能阻止你那样做。