Meysam
Meysam

Reputation: 18177

CMake: How to create a file with make command

I need to create the following always-out-of-date file: ${CMAKE_BINARY_DIR}/version.hpp.in
before any target is executed in the make file. The content of file is exactly as the following:

#define RELEASE_VERSION "${RELEASE}"
#define MAJOR_VERSION "${MAJOR}"
#define MINOR_VERSION "${MINOR}"
#define PATCH_VERSION "${PATCH}"
#define REVISION "${REVISION}"
#define SVNPATH "${SVNPATH}"

I've got the following piece of code in my CMake file, but it's executed only after running the cmake command:

FILE(WRITE ${CMAKE_BINARY_DIR}/version.hpp.in
"#define RELEASE_VERSION \"${RELEASE}\"\n"
"#define MAJOR_VERSION \"${MAJOR}\"\n"
"#define MINOR_VERSION \"${MINOR}\"\n"
"#define PATCH_VERSION \"${PATCH}\"\n"
"#define REVISION \"${REVISION}\"\n"
"#define SVNPATH \"${SVNPATH}\"\n"
)

I want to generate the version.hpp.in file each time I run the make command. How can I do that?

Upvotes: 13

Views: 19799

Answers (2)

ollo
ollo

Reputation: 25380

You can use configure_file() for this:

configure_file(version.hpp.in ${DESTPATH}/version.hpp)

Where DESTPATH is optional and set to the path you want that file.

If the file is modified the build system will re-run CMake to re-configure the file and generate the build system again.

(Source: Documentation, see below)

File version.hpp:

#define RELEASE_VERSION "${RELEASE}"
#define MAJOR_VERSION "${MAJOR}"
#define MINOR_VERSION "${MINOR}"
#define PATCH_VERSION "${PATCH}"
#define REVISION "${REVISION}"
#define SVNPATH "${SVNPATH}" 

Syntax:

configure_file(<input> <output>
               [COPYONLY] [ESCAPE_QUOTES] [@ONLY]
               [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])

Documentation:


# 'example' is the targetname here, eg. using add_executable(example example.cpp)

add_custom_command(TARGET example PRE_BUILD COMMAND <CMAKE COMMAND HERE>)

Minimal Example

Version.h.in

#define VERSION ${VERSION}

Just for testing …

CMakeLists.txt

cmake_minimum_required(VERSION 2.8.12)

set(VERSION 1.10)
set(TEMPLATE_DIR ${CMAKE_CURRENT_SOURCE_DIR})

add_executable(example example.cpp)

add_custom_command(TARGET example PRE_BUILD 
        COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/SetVersion.cmake)

SetVersion.cmake

configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../Version.h.in ${CMAKE_CURRENT_SOURCE_DIR}/../Version.h)
message("Version set") # For testing only

Now run cmake and make as usual and check if HELLO is printed on make.

Upvotes: 8

John Zwinck
John Zwinck

Reputation: 249602

You can use add_custom_command (and perhaps add_custom_target) to do this sort of thing.

Since you're asking about building version symbols into your program, I will tell you about a slightly different method that I use. I asked a question related to it here, with some code: Embed Git revision in executable during remote build with NetBeans

The concept I use is to generate actual symbols in an object file directly from a textual file which I write at build (or git pull) time. Then I link this file into the executable.

Upvotes: 0

Related Questions