首页 > 解决方案 > cmake add_custom_command 依赖于对象库

问题描述

我正在尝试使用 cmake 生成版本文件add_custom_command。如果另一个目标(对象库)有任何更改,我只希望(重新)生成版本文件。

这是我当前的简化 CMakeLists.txt:

cmake_minimum_required(VERSION 3.1)
project (version-test)

# Object file compilation target.
add_library(version-test-objects OBJECT main.cpp)

# Version object file target.
add_custom_command(OUTPUT version.cpp
    COMMAND date "+char const *getVersion\\\(\\\) { return \\\"%Y-%m-%d %H:%M:%S\\\"\; }"
    > version.cpp
    DEPENDS version-test-objects
)
add_library(version-test-version OBJECT
    version.cpp
)

# Binary target.
add_executable(version-test
    $<TARGET_OBJECTS:version-test-objects>
    $<TARGET_OBJECTS:version-test-version>
)

为了完整起见,我简化了 main.cpp:

#include <iostream>

extern char const *getVersion();

int main() {
    std::cout << getVersion() << std::endl;
}

version.cpp与第一个构建一起生成很好。但是,对源代码的更改(例如touch main.cpp)只会重新构建version-test-objects和链接可执行文件,而不会重新生成version.cpp.

version.cpp当且仅当version-test-objects有任何更改时,如何让 cmake 重新生成?

标签: cmake

解决方案


DEPENDS version-test-objects仅指定目标级别的依赖关系,这意味着该命令可能会在构建目标后运行version-test-objects。您声明了每当更新任何目标文件部分时都应运行该命令的要求version-test-objects。所以这些也必须列出来DEPENDS。这可能被认为是关于 OBJECT 库和普通库之间差异的错误。

# Version object file target.
add_custom_command(OUTPUT version.cpp
    COMMAND date "+char const *getVersion\\\(\\\) { return \\\"%Y-%m-%d %H:%M:%S\\\"\; }"
    > version.cpp
    DEPENDS version-test-objects $<TARGET_OBJECTS:version-test-objects>
)

这适用于我使用 CMake 3.13 Makefile 生成器。这在 CMake 3.8 或更早版本中可能不起作用,因为发行说明指出此表达式直到 3.9 才添加。如果是这种情况,您可能需要创建一个使用所有对象的虚拟存档,然后将其用作依赖项。


推荐阅读