【问题标题】:How to build and install cmake targets only if the other targets depend on them?仅当其他目标依赖于它们时,如何构建和安装 cmake 目标?
【发布时间】:2013-05-14 21:00:10
【问题描述】:

我的应用程序由核心、许多共享库和许多使用这些共享库的插件组成。我正在使用 cmake option() 命令来启用/禁用每个插件。

我想做的是仅在启用的插件之一需要共享库时构建和安装共享库。

我尝试在共享库的目录中使用以下内容:

set_directory_properties(PROPERTIES EXCLUDE_FROM_ALL true)

但是,目标仍在 Visual Studio 中构建。 Linux 中的 GNU make 正确地避免了构建它们。但是,不再使用install() 安装所需的库 系统。

我还尝试将EXCLUDE_FROM_DEFAULT_BUILD false 添加到库目标中, 但 cmake 抱怨 install() 的未定义行为与禁用目标。

【问题讨论】:

  • 当我想选择性地包含子目录时,我将add_subdirectory 代码包装在if 语句中。在你的情况下这可能吗?
  • 不,我不这么认为。如果由于我没有调用add_subdirectory而导致目标尚不存在,我怎么知道某事是否取决于目标?
  • 我明白了。我不知道你需要 CMake 来为你确定依赖关系......对于我的项目,我提前知道这一点,所以我不必以编程方式进行。
  • 很难提前知道,因为有很多插件并且库(或其add_subdirectory)不应该知道特定插件是否使用它。此外,如果它被禁用,省略 add_subdirectory 会导致无法手动构建库。
  • 在 Main CMakeLists.txt 的末尾添加 if(target) add_dependencies() 语句怎么样?在这一点上,您最有可能知道存在哪些目标。

标签: cmake


【解决方案1】:

听起来你有这样的东西:

OPTION( BUILD_OPTIONAL_PLUGINS "Build plugins that are not required for core install" FALSE) 
IF(${BUILD_OPTIONAL_PLUGINS}) 
    ADD_SUBDIRECTORY( Plugins/Optional) # Whatever it really is. 
ENDIF()

到目前为止一切顺利。但是,如果所有这些选项标志都为假,您现在可以拥有像“libCommon”这样没有人需要的库。

所以,您最简单的解决方案是:将库视为可选 TOO!

毕竟,如果不构建任何消费项目本身,您甚至不需要构建它。因此,在同一个顶级 CMakeLists.txt 中有一个普通的“SET”变量,如“BUILD_COMMON”,默认为 TRUE。然后这样做:

SET( BUILD_COMMON 0) 
IF(${BUILD_OPTIONAL_1} OR ...) # Detect if you need to build the lib 
    SET( BUILD_COMMON 1) 
ENDIF()

IF(${BUILD_COMMON}) 
   ADD_SUBDIRECTORY( common)
ENDIF()

然后,当您最终在此版本上执行“make install”时,一切都会按预期工作。如果关闭所有可选插件,则仅由它们使用的库也永远不会构建。由于它从未在构建中,因此您无需尝试使其安装逻辑知道是否需要它。

您还应该在库以及每个可选插件的 INSTALL() 命令中添加这样的一行:

INSTALL( TARGETS <plugin> .... OPTIONAL)

这告诉“make install”如果没有看到它的二进制文件,就不要尝试构建或安装目标。

【讨论】:

    猜你喜欢
    • 2016-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-25
    • 2023-04-07
    • 1970-01-01
    相关资源
    最近更新 更多