【问题标题】:configure_file list of files -> #includes cmakeconfigure_file 文件列表 -> #includes cmake
【发布时间】:2014-05-09 20:33:05
【问题描述】:

这似乎应该很容易做到,但我终其一生都无法弄清楚如何去做。

基本上,我想获取一个源列表(现在,只是一个变量 ${HDR_LIST}),并将它们全部写入文件中。所以如果HDR_LIST="foo.h;bar.h;baz.h;quz.h" 它会生成文件

#include "foo.h"
#include "bar.h"
#include "baz.h"
#include "quz.h"

我希望此文件仅在 HDR_LIST 更改时更新。

我能想到的唯一方法是创建一个 configure_file 命令...但是这个宏可能在很多地方。每个项目都设置变量,我不确定这有多安全。我觉得应该有更好的方法...

【问题讨论】:

    标签: c++ cmake


    【解决方案1】:
    cmake_minimum_required(VERSION 2.8)
    
    project(MyTest)
    
    set(CMAKE_CONFIGURABLE_FILE_CONTENT
      "#include \"inc1.h\"")
    set(CMAKE_CONFIGURABLE_FILE_CONTENT
      "${CMAKE_CONFIGURABLE_FILE_CONTENT}\n#include \"inc2.h\"")
    set(CMAKE_CONFIGURABLE_FILE_CONTENT
      "${CMAKE_CONFIGURABLE_FILE_CONTENT}\n#include \"inc3.h\"")
    set(CMAKE_CONFIGURABLE_FILE_CONTENT
      "${CMAKE_CONFIGURABLE_FILE_CONTENT}\n#include \"inc4.h\"")
    
    configure_file("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in"
      "${CMAKE_CURRENT_BINARY_DIR}/myfile.h"
      @ONLY
    )
    unset(CMAKE_CONFIGURABLE_FILE_CONTENT)
    

    configure_file 有一个内置的 write-only-if-different。

    【讨论】:

    • 我在考虑使用配置文件。但是,我正在编写此函数以在一堆项目中使用。如果 CMAKE_CONFIGURABLE_FILE_CONTENT 设置在一堆不同的目录中会有什么风险吗?
    • 您可以取消设置。我刚刚扩展了我的示例来做到这一点。
    • 很棒的功能感谢您的指出。在这里使用@ONLY 有意义吗?
    • 什么是CMAKE_CONFIGURABLE_FILE_CONTENT?它似乎没有记录在任何地方
    • @MaëlNison 它只是一个自定义变量,用于保存该自定义文件的内容,@steveire 将其命名为CMakeConfigurableFile.in
    【解决方案2】:

    我认为您正在寻找foreach()file(APPEND ...) 的组合:

    file(REMOVE "includes.h")
    foreach(filename ${HDR_LIST})
        file(APPEND "includes.h" "#include \"${filename}\"")
    endforeach(filename)
    

    每当HDR_LIST 更改时,CMake 将再次运行并重新生成文件。


    如果你想只写不同的文件,这有点难,因为AFAIK,CMake中没有对变量的依赖。但是你可以做例如这个解决方法有一些散列:

    set(new_includes "")
    foreach(filename ${HDR_LIST})
        set(new_includes "${new_includes}#include \"${filename}\"")
        if(WIN32)
            set(new_includes "${new_includes}\r\n")
        else()
            set(new_includes "${new_includes}\n")
        endif()
    endforeach()
    string(SHA256 new_includes_hash "${new_includes}")
    
    file(SHA256 "includes.h" current_includes_hash)
    if(NOT current_includes_hash STREQUAL new_includes_hash)
        file(WRITE "includes.h" "${new_includes}")
    endif()
    

    【讨论】:

    • 是和不是。如果我做了你所拥有的,它将在每个构建上运行。每次构建时都会触及(并因此重建)头 C 文件,这……很烦人。
    • 只有当 CMake 再次运行时才会发生,只有当 CMake 检测到您修改了一些 CMakeLists.txt 或更改了变量时才会发生这种情况。即使在这些情况下,您也想避免它?
    • 是的,这可能是不可能的。但我为答案添加了另一种可能的解决方案 - 使用哈希显式检测更改。
    猜你喜欢
    • 2018-06-07
    • 2022-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    相关资源
    最近更新 更多