执行cmake目标的输出作为另一个的依赖项

Tam*_*lei 5 c++ cmake

我有以下目录结构:

.
??? CMakeLists.txt
??? generator
?   ??? CMakeLists.txt
?   ??? main.cpp
??? include
??? src
    ??? CMakeLists.txt
    ??? mylib.cpp
Run Code Online (Sandbox Code Playgroud)

我想构建generator,然后使用generator生成将用于构建mylib的源文件。我尝试了这个:

generator / CMakeLists.txt:

add_executable(gen main.cpp)

add_custom_command(
    OUTPUT
        ${CMAKE_BINARY_DIR}/generated.cpp
    DEPENDS
        gen
    COMMAND
        ${CMAKE_BINARY_DIR}/gen -d /tmp
    VERBATIM
)
Run Code Online (Sandbox Code Playgroud)

src / CMakeLists.txt:

add_library(py-cppast
        ${CMAKE_BINARY_DIR}/generated.cpp
        mylib.cpp)
Run Code Online (Sandbox Code Playgroud)

CMakeLists.txt:

cmake_minimum_required(VERSION 3.1.2)
project(my-project)

add_subdirectory(generator)    
add_subdirectory(src)
Run Code Online (Sandbox Code Playgroud)

但是,该命令未执行。相反,我只是得到错误:

src / CMakeLists.txt:2(add_library)的CMake错误:
  找不到源文件:

    /home/....(cmake二进制目录).... / generated.cpp

  尝试扩展名.c .C .c ++ .cc .cpp .cxx .m .M .mm .h .hh .h ++ .hm .hpp
  .hxx .in .txx

我怎样才能告诉cmake执行我正在使用它构建的程序?在单个构建中甚至可能吗?

Cra*_*ott 4

问题源于这样一个事实:您generated.cpp在一个目录中生成文件,然后尝试将其添加到在不同目录中定义的目标。CMake 仅支持将生成的文件添加到同一目录范围中定义的目标。文档add_custom_command()明确提到了此限制。

您可能希望将 的生成移至目录generated.cppsrc。您还应该仅使用gen目标名称来引用要运行的可执行文件,${CMAKE_BINARY_DIR}/gen这对于所有 CMake 生成器类型来说都是不正确的。使用当前二进制目录而不是顶级二进制目录作为输出目录也是更好的风格。你的src/CMakeLists.txt应该看起来像这样:

add_custom_command(
    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/generated.cpp
    DEPENDS gen
    COMMAND gen -d /tmp
    VERBATIM
)
add_library(py-cppast
    ${CMAKE_CURRENT_BINARY_DIR}/generated.cpp
    mylib.cpp
)
Run Code Online (Sandbox Code Playgroud)

CMake 会自动为您替换目标的位置gen,即使它是在不同的目录中定义的。使用生成的源时,还需要注意一些进一步的微妙之处,特别是与依赖关系相关的微妙之处。您可能会发现这篇文章有助于填补一些空白。