关于cmake的范围规则,我有点困惑.我有文件和目录,如
??? test
? CMakeLists.txt
? ??? cmake
? ? MyCMake
? ? MyCMake2
? ??? child
? ? CMakeLists.txt
Run Code Online (Sandbox Code Playgroud)
内容如下:
cmake的/ MyCMake:
set(MY_NAME MyName)
message("MyCMake: " ${MY_NAME} " " ${YOUR_NAME} " " ${HIS_NAME})
Run Code Online (Sandbox Code Playgroud)
cmake的/ MyCMake2:
set(HIS_NAME NewName)
message("MyCMake2: " ${MY_NAME} " " ${YOUR_NAME} " " ${HIS_NAME})
Run Code Online (Sandbox Code Playgroud)
子/的CMakeLists.txt:
set(YOUR_NAME YourName)
set(HIS_NAME HisName PARENT_SCOPE)
message("Child: " ${MY_NAME} " " ${YOUR_NAME} " " ${HIS_NAME})
Run Code Online (Sandbox Code Playgroud)
测试/的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})
Run Code Online (Sandbox Code Playgroud)
结果是
MyCMake: MyName
Child: MyName YourName
Parent1: MyName HisName
MyCMake2: MyName NewName
Parent2: MyName NewName
Run Code Online (Sandbox Code Playgroud)
第一行是OK,第二和第三个变量尚未定义.对于第二行,它看起来像是仅父项设置,即定义的变量仅在父项中具有范围.(那么,我可以/应该使用本地范围的相同变量吗?)第三行仅显示具有父范围的变量,OK.第4行显示我设置了LOCAL范围变量.但是,在第5行中,我看到PARENT范围值已更改,我希望仅在本地更改子子目录中.这里发生了什么?(看起来我可以覆盖变量的值,这不在我的范围内)
为什么我开始尝试:在某些情况下,我没有在父目录中看到子目录中定义的变量(如include目录,库名等).是否有一种标准方法可以使用一个库名来构建一个子节点,并在另一个子节点中使用相同的名称进行链接?
还有一个问题:我有一个应用程序,包括一个库和一个可执行文件.看起来CMake不允许为两者使用相同的目标名称.在我看来,如果我使用名称'A'作为二进制目标和库目标,它不应该导致混淆,因为真正的第二个目标是'libA'.我错了吗?
基本规则很简单:add_subdirectory建立一个新范围,include但不是.所以你的例子只涉及两个范围:
set(...)中的命令MyCMake和MyCMake2,并通过set(... PARENT_SCOPE)内部命令child/CMakeLists.txt.child/CMakeLists.txt受其中不使用的set(...)命令的影响.child/CMakeLists.txtPARENT_SCOPE您是正确的,仅PARENT_SCOPE在父作用域中设置值.如果要为当前作用域和父作用域设置值,则必须发出两个set命令:
set(var Value)
set(var Value PARENT_SCOPE)
Run Code Online (Sandbox Code Playgroud)
我们通常在Stack Overflow上更喜欢每个问题一个问题,但我也会回答目标命名问题:CMake目标名称是CMake目标的逻辑名称,它们必须是唯一的.想象一下,如果不是这样的话:
add_library(L STATIC ...)
add_library(A SHARED ...)
add_executable(A ...)
target_link_libraries(A L)
Run Code Online (Sandbox Code Playgroud)
最后一行会有什么影响?库会A链接L,还是可执行文件A会这样做?或两者?Dtto用于设置属性等.
您可以独立于目标名称控制生成的二进制文件的名称:OUTPUT_NAME有关详细信息,请参阅目标属性.