请考虑以下最小示例:
.
??? bar
? ??? CMakeLists.txt
??? CMakeLists.txt
Run Code Online (Sandbox Code Playgroud)
这里./CMakeLists.txt是
project( foo )
cmake_minimum_required( VERSION 2.8 )
set( FOO "Exists in both, parent AND in child scope." )
add_subdirectory( bar )
message( STATUS "Variable BAR in ./ = ${BAR}" )
message( STATUS "Variable FOO in ./ = ${FOO}" )
Run Code Online (Sandbox Code Playgroud)
并且./bar/CMakeLists.txt是
set( BAR "Exists in parent scope only." PARENT_SCOPE )
message( STATUS "Variable BAR in ./bar/ = ${BAR}" )
Run Code Online (Sandbox Code Playgroud)
输出的相关部分cmake是这样的:
...
-- Variable BAR in ./bar/ =
-- Variable FOO in ./bar/ = Exists in both, parent AND in child scope.
-- Variable BAR in ./ = Exists in parent scope only.
-- Variable FOO in ./ = Exists in both, parent AND in child scope.
...
Run Code Online (Sandbox Code Playgroud)
由于变量BAR放在父作用域中,我希望它在当前的子作用域中(以及FOO后面的作用域)可用 - 就像变量一样,它定义为父作用域的开头.但是从上面的行可以看出变量BAR是空的./bar/CMakeLists.txt,这引出了以下问题:
为什么修改后的父作用域不能在子作用域中立即访问./bar/?这可以减轻吗?如果有,怎么样?如果不是,什么是解决方案?还是我完全错过了一些明显的东西?
上下文:我的项目由几个可执行文件和库组成.对于库,例如bar,我想设置一个变量bar_INCLUDE_DIR,该变量被添加到任何依赖可执行文件的包含路径中,即target_include_directories( my_target PUBLIC bar_INCLUDE_DIR ).
如果存在PARENT_SCOPE,则变量将在当前范围上方的范围内设置.每个新目录或函数都会创建一个新范围.此命令将变量的值设置为父目录或调用函数(适用于手头的情况).
./bar/CMakeLists.txt
set( BAR "This is bar." PARENT_SCOPE ) #<-- Variable is set only in the PARENT scope
message( STATUS "Variable BAR in ./bar/ = ${BAR}" ) #<--- Still undefined/empty
Run Code Online (Sandbox Code Playgroud)
你可以随时做:
set( BAR "This is bar." ) #<-- set in this scope
set( BAR ${BAR} PARENT_SCOPE ) #<-- set in the parent scope too
Run Code Online (Sandbox Code Playgroud)
PARENT_SCOPE在安装中交付的模块中使用Grep ,例如FindGTK2
if(GTK2_${_var}_FOUND)
set(GTK2_LIBRARIES ${GTK2_LIBRARIES} ${GTK2_${_var}_LIBRARY})
set(GTK2_LIBRARIES ${GTK2_LIBRARIES} PARENT_SCOPE)
endif()
Run Code Online (Sandbox Code Playgroud)
彼得很好地解释了这种行为的原因.
我通常在这种情况下使用的解决方法是设置一个缓存变量,该变量随处可见:
set(BAR "Visible everywhere"
CACHE INTERNAL ""
)
Run Code Online (Sandbox Code Playgroud)
INTERNAL是让它从cmake-gui看不到.INTERNAL如果您在文件夹结构中更改某些内容,则确保它已更新.空字符串是一个描述字符串,如果您认为有必要,可以填写该字符串.
但请注意,只要有可能,正确的方法是尽可能将属性附加到目标,例如使用FORCE,并通过设置依赖项将它们传播到其他目标.
上下文:我的项目由几个可执行文件和库组成。对于一个库,例如 bar,我想设置一个变量 bar_INCLUDE_DIR,它被添加到任何依赖的可执行文件的包含路径中。
有比在父作用域中设置变量更好的方法来做到这一点。CMake 允许目标指定依赖目标可以使用的包含目录、预处理器符号等。在您的情况下,您可以使用target_include_directories。
例如:
target_include_directories(my_target PUBLIC my_inc_dir)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
14200 次 |
| 最近记录: |