问题描述
我有一个 cmake 项目,其中有一些模块,我正在使用 Find-*.cmake 将共享模块包含在应用程序中.为了不考虑我添加的每个模块,我定义了一种全局 LIB
变量到链接器:
I have a cmake project in which I have some modules and I'm using Find-*.cmake for including the shared modules in the application.For not taking in account every module that I add, I have defined a kind of global LIB
variables tor the linker:
# inside a Find-*.cmake or in the CMakeLists.txt of the modules:
set(LIB ${LIB} ...)
所以在使用某些模块的最终应用程序之一中,我可以做到:
so in one of the final applications that uses some modules I can just do:
target_link_libraries(${APP_NAME} ${LIB})
然后,我想在 /project_path/modules/foo/build
中有编译好的模块,这样如果一个模块真的很大,可以编译它可以为所有应用程序编译一次使用它.我实现这一点的方法是以这种方式从 Find-*.cmake 加载模块的 CMakeLists.txt:
Then, I'd like to have the compiled modules in the /project_path/modules/foo/build
so that if a module is really big to compile it can be compiled once for all the application that use it. The way I'm achieving this is to load the CMakeLists.txt of the module from the Find-*.cmake in this way:
# 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)
但有时会发生某些模块需要另一个模块,以便 add_subdirectory
创建新范围并可以正确加载 LIB
但无法写入它(当我使用 set
是在更深的范围内,不会改变上层的范围).为了绕过这个,我必须在 set
中添加 PARENT_SCOPE.. 所以我试图将它添加到我认为可以嵌套并隐藏在某些依赖项中的某个模块中,但是编译我突然遇到的所有应用程序:
But it happened sometimes that some module require another modules so that the add_subdirectory
creates new scopes and can correctly load LIB
but cannot write it (when I use set
it is in the deeper scope and not changes the upper scope). For bypass this I have to add PARENT_SCOPE in the set
).. So I have tried to add it in some module that I think could be nested and hidden in some dependencies but compiling all the application I suddenly faced with:
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 can change from app to app in respect to which module I need or in respect of the dependecies tree in the modules itself so I'm looking for a cleaner solution.
推荐答案
默认情况下,CMake 中的所有变量都是本地变量.虽然您可以使用 PARENT_SCOPE
参数将局部变量的范围增加一层,但对于 函数.
All variables in CMake are local by default. While you can use the PARENT_SCOPE
parameter to increase the scope of a local variable by one layer, that mostly makes sense for return values of functions.
另一方面,对于查找脚本,您通常需要全局变量的行为:一旦任何人调用查找脚本,您都希望结果随处可用.特别是,对同一个 find 脚本的第二次调用应该只重用第一次调用的结果.在 CMake 中,这是通过将变量存储到缓存来实现的.各种 find_*
调用已经自动执行此操作,因此您应该更喜欢使用那些适用的调用.对于任何其他自定义变量,set
还提供了存储到缓存的功能:
For find scripts on the other hand you usually want the behavior of a global variable: Once the find script is called by anyone, you want the results to be available everywhere. In particular, a second call to the same find script should just reuse the results of the first call.In CMake this is achieved by storing variables to the cache. The various find_*
calls already do this automatically, so you should prefer using those where applicable. For any additional custom variables, set
offers the capability to store to the cache as well:
set(MY_GLOBAL_VARIABLE "Some value" CACHE STRING "Description")
请注意,局部变量可以在其作用域内隐藏同名的缓存变量.
Note that local variables can hide cached variables of the same name in their scope.
这篇关于cmake,迷失在全局变量的概念中(和 PARENT_SCOPE 或 add_subdirectory 替代品)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!