CMake中的全局变量用于依赖关系跟踪 [英] Global variables in CMake for dependency tracking

查看:261
本文介绍了CMake中的全局变量用于依赖关系跟踪的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Hallo,

我在我的一个项目中使用CMake作为构建系统,这是相当复杂的。该项目包括几个库和几个应用程序。我的目标是使以下方式成为可能:

I'm using CMake as build system in one of my projects which is quite complex. The project includes several libraries and several applications. My goal is, to make the following possible:


  1. 库可以根据用户的要求构建(由缓存的CMake变量实现)

  2. 应用程序是根据用户的要求构建的(见上文),但应用程序可以选择需要哪些库并在没有用户选择的情况下构建它们

  3. 不更改缓存的用户选择要构建的库(如果应用程序构建被关闭,则禁用自动构建库)

我的构建系统布局如下:我有一个父目录,其中包含一个CMakeLists.txt,它将库和应用程序添加为子目录。每个库和应用程序都有自己的CmakeLists.txt,它定义了要存储在缓存中的用户可定义的配置选项,要构建的目标以及它所依赖的项目的其他库。应用程序不一定位于父目录的下一个子目录中,但也可能是某些级别较低的,因此我无法使用PARENT_SCOPE,因为父进程并不是最重要的父进程,而是必须知道依赖关系

My build system layout is the following: I have a parent directory which contains a CMakeLists.txt that adds the libraries and applications as subdirectory. Each library and application has its own CmakeLists.txt which defines the user definable configuration options to be stored in cache, the targets to be built and on which other libraries of the project it depends. Applications are not necessarily located in the next subdirectory of the parent directory, but could also be some levels lower, so that I cannot make use of PARENT_SCOPE, because the parent hasn't to be the topmost parent, but the dependencies have to be known on top.

我尝试将GLOBAL属性设置为PROJECT_BUILD_SOMELIBRARY设置为on,并尝试在SOMELIBRARY的CMakeLists.txt中检索它们,以决定是否构建,但属性没有不会传递给图书馆,所以即使事实上这样做也不会建立,因为另一个图书馆或应用程序表示它依赖于这个图书馆。使用包含每个应用程序或库目标的名称的列表,具体取决于库和缓存内部的内容不起作用。

I tried setting GLOBAL properties like PROJECT_BUILD_SOMELIBRARY set to on and tried to retrieve them in SOMELIBRARY's CMakeLists.txt to decide whether to build or not, but the properties didn't get passed on to the library, so it never built even if it in fact would have had to, because another library or application indicated that it depended on this library. Using a LIST containing the name of each application or library target depending on a library and caching that one internally didn't work either.

为了总结这些许多单词,我'寻找一种方法来影响CMakeLists在一些子目录中负责构建一个库的CMakeLists在一些其他子目录(这不一定是与其他子目录相同的子目录级别)构建该库,即使用户没有不明确地通过cmake调用的配置选项来指定它。

To sum these many words up, I'm looking for a way to influence a CMakeLists in some subdirectory responsible for building a library by a CMakeLists in some other subdirectory (which isn't necessarily the same subdirectory level as the other subdir) to build that library, even if the user didn't specify it explicitly via the configuration option on cmake invocation.

有人知道这可以实现还是CMake不可能实现?有没有其他方法来解决这个问题,但是,包括使用CMake?你知道任何可以舒适地处理这个要求的其他构建系统吗?

Does someone know how this could be achieved or is this impossible with CMake? Are there suggestions for other approaches towards this problem that, however, include using CMake? Do you know of any other build system that could handle this requirements comfortably?

非常感谢,
crispinus

Many thanks, crispinus

推荐答案

我在此期间自己解决了这个问题。实际上,实现我上面介绍的设置是非常简单的。我使用EXCLUDE_FROM_ALL选项到所有目标,具体取决于用户是否明确选择(=省略EXCLUDE_FROM_ALL)。

I solved the problem by myself in meantime. In fact, it was quite straightforward to implement the setup I explained above. I used the EXCLUDE_FROM_ALL option to all targets depending on whether they were explicitly selected by user (=leave out the EXCLUDE_FROM_ALL) or not.

EXCLUDE_FROM_ALL选项具有目标不包括在all-Target中的效果,除非另一个目标(未标记为EXCLUDE_FROM_ALL)取决于此目标。即使在子目录中也是如此,因为CMake目标是真正的全局性的,即使是最顶层的父级也知道最底层的子目录,甚至同一级别的子目录也知道另一个子目录的目标。

The EXCLUDE_FROM_ALL option has the effect that a target is not included in the all-Target, unless another target (which is not marked as EXCLUDE_FROM_ALL) depends on this target. This works even over subdirectories, because CMake targets are really global and even the topmost parent knows about the bottommost subdirectory's target, and even a subdirectory at the same level knows about the targets of another subdirectory.

在我的布局中,我的项目的每个单独的部分都包含自己的CMakeLists.txt,并将自己的选项添加到缓存中,因此示例子项目将以这种方式看起来:

In my layout, each separate part of my project contains its own CMakeLists.txt and adds its own options to the cache, so a sample subproject would look this way:


SET(PART_NAME SAMPLE_PART)
SET(PART_TARGET_NAME samplepart)

SET(BUILD_${PART_NAME} off CACHE BOOL "Build part ${PART_NAME}")
SET(${PART_NAME}_FILES some_file.c another_file.c)

IF(NOT BUILD_${PART_NAME})
SET(EXCLUDE_${PART_NAME} EXCLUDE_FROM_ALL)
ENDIF(NOT BUILD_${PART_NAME})

ADD_LIBRARY(${PART_TARGET_NAME} SHARED ${EXCLUDE_SAMPLE_PART} ${PART_NAME}_FILES)
TARGET_LINK_LIBRARY(${PART_TARGET_NAME} some_other_target)

所以如果用户选择t o BUILD_SAMPLE_PART,目标未设置为EXCLUDE_FROM_ALL,并将包含在所有内容中;如果没有,目标设置为EXCLUDE_FROM_ALL,只有当另一个目标依赖于此目标时才会构建。如果这个目标是构建的,那么也将构建some_other_target,无论它本身是否包含在内。

So if the user chooses to BUILD_SAMPLE_PART, the target is not set to EXCLUDE_FROM_ALL and will be included in all; if not, the target is set to EXCLUDE_FROM_ALL and will be built only if another target depends on this. If this target is build, also the "some_other_target" will be built, whether it's included in all by itself or not.

这篇关于CMake中的全局变量用于依赖关系跟踪的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆