7
votes

I tried this dummy example:

CMakeLists.txt

cmake_minimum_required( VERSION 2.8 )
project( testcmake )

add_custom_command(
  OUTPUT testcmake.h
  COMMAND xxd -i testcmake.txt testcmake.h
  DEPENDS testcmake.txt
)

add_executable( testcmake testcmake.c testcmake.h )

testcmake.c

#include <stdio.h>
#include "testcmake.h"

int main()
{
    int i;

    for ( i = 0 ; i < testcmake_txt_len ; i++ )
    {
        fputc( testcmake_txt[ i ] , stdout );
    }
}

testcmake.txt

foo
bar
baz

The problem

It fails with:

[...]
xxd: testcmake.txt: No such file or directory
[...]

Adding WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} makes everything works fine but I don't want the output of my custom command appears in my source directory, I want that all the intermediate files remain in the CMake build directory just like any non custom rule.

2

2 Answers

6
votes

You need to copy testcmake.txt to your build folder before executing xxd. You'll also need to add your build directory to the includes so that #include "testcmake.h" works:

add_custom_command(
  OUTPUT testcmake.h
  COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/testcmake.txt testcmake.txt
  COMMAND xxd -i testcmake.txt testcmake.h
  DEPENDS testcmake.txt
)

include_directories(${CMAKE_CURRENT_BINARY_DIR})
2
votes

With CMake 3.2, file gained a new feature. Quoting from the release announcement:

the "file(GENERATE)" command can now generate files that are used as source files for build system targets.

Maybe this is easier to use, given you can switch to CMake 3.2.