Question

This seems like something that should be easy to do, but I cant for the life of me figure out how to do it.

Basically, I want to take a source lists (for now, just a variable ${HDR_LIST}), and write them ALL as includes in a file. so if HDR_LIST="foo.h;bar.h;baz.h;quz.h" it would make the file

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

I'd like this file to only update if HDR_LIST changes.

The only way I can think to do it is to make a configure_file command...but this macro may be in a ton of places. Each each project sets the variable, I'm not sure how safe that is. I feel like there should be a better way...

Was it helpful?

Solution

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 has a built-in write-only-if-different.

OTHER TIPS

I think you are looking for some combination of foreach() and file(APPEND ...):

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

Whenever HDR_LIST is changed, CMake will be run again and the file will be regenerated.


If you want to write the file only if different, it is a bit hard, because AFAIK, there are not dependencies on variables in CMake. But you could do e.g. this workaround with some hashing:

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()
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top