Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use CMake add_custom_command to generate source for another target

Tags:

cmake

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.

like image 566
cYrus Avatar asked Jul 21 '12 12:07

cYrus


2 Answers

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})
like image 174
Fraser Avatar answered Nov 08 '22 19:11

Fraser


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.

like image 4
usr1234567 Avatar answered Nov 08 '22 17:11

usr1234567