18

I'm trying to add a custom build step in CMake that generates some files. I haven't found a description how it works.

I have an project where source, header & implementation files have to be generated by ODB for C++. ODB takes class headers as arguments and generates source files that I want to use in my project.

Right now I have the following command in my CMakeLists.txt:

add_custom_command(TARGET ${PROJECT_NAME}
    PRE_BUILD
    COMMAND odb -o /home/david/dev/ --std c++11 -I/home/david/dev/ -d sqlite --generate-    query --generate-schema ${PROMOTER_LIB_PREFIX}/entities/person.hpp
    DEPENDS ${PROJECT_NAME}
    VERBATIM
)

For a file person.hpp ODB should generate person-odb.hxx, person-odb.cxx, person-odb.ixx but the CMake command I''ve used doesn't generate anything. In a terminal this command works fine.

What am I doing wrong?

EDIT: The problem can be solved by adding the following lines:

set(FAKE_TARGET fakeTarget)
add_custom_target(fakeTarget
    odb -o /home/david/dev/ --std c++11 -I/home/david/dev/ -d sqlite --generate-query --generate-schema ${PROMOTER_LIB_PREFIX}/entities/person.hpp
)
add_dependencies(${PROJECT_NAME} ${FAKE_TARGET})
David Bulczak
  • 443
  • 1
  • 4
  • 13

2 Answers2

19

For me, with something similar, I just use :

add_custom_command(TARGET ${PROJECT_NAME}
    PRE_BUILD
    COMMAND odb -o /home/david/dev/ --std c++11 -I/home/david/dev/ -d sqlite --generate-    query --generate-schema ${PROMOTER_LIB_PREFIX}/entities/person.hpp
)

We don't use DEPENDS or VERBATIM.

The DEPENDS option specify that the command must be executed only after that the project you gave to this option is built.

EDIT :

Note that the PRE_BUILD option is only supported on Visual Studio 7 or later. For all other generators PRE_BUILD will be treated as PRE_LINK.

Maybe that's why it doesn't work for you.

A work around could be (a bit ugly) :

  • Create a fake project
  • Add your custom command on it as POST_BUILD
  • Make you current project dependent on the fake one
Pierre Fourgeaud
  • 14,290
  • 1
  • 38
  • 62
  • @DavidBulczak look at my edit. I use VS at work, that's why it is working for me. – Pierre Fourgeaud Aug 25 '13 at 10:19
  • Ok. Thanks. I use gcc/make and other GNU tools. Are there any other ways do add custom pre build steps in CMake? – David Bulczak Aug 25 '13 at 10:23
  • @DavidBulczak I don't think so... I have a work around but really ugly : Create a fake project, add your custom command on it as `POST_BUILD` and make you current project dependent on the fake one... Do you understand what I mean ? – Pierre Fourgeaud Aug 25 '13 at 10:27
  • Thank you for the hint. I think I've understood what you mean. Then I have one more question. How can I create project dependencies? – David Bulczak Aug 25 '13 at 10:37
  • 1
    @DavidBulczak With `add_dependencies(${PROJECT_NAME} FAKE_PROJECT)` – Pierre Fourgeaud Aug 25 '13 at 10:38
  • One more idea: Maybe it is possible to create a custom target and in this target my custom command will be executed. Then I've only to create a dependency between the custom target and the main target and it should work... I hope so. First I will try your approach @Pierre, then my idea. – David Bulczak Aug 25 '13 at 10:39
  • @DavidBulczak Ok, tell me your results ! – Pierre Fourgeaud Aug 25 '13 at 10:42
  • 1
    I've added the following lines to my project and now it works fine! `set(FAKE_TARGET fakeTarget) add_custom_target(fakeTarget odb -o /home/david/dev/ --std c++11 -I/home/david/dev/ -d sqlite --generate-query --generate-schema ${PROMOTER_LIB_PREFIX}/entities/person.hpp ) add_dependencies(${PROJECT_NAME} ${FAKE_TARGET})` – David Bulczak Aug 25 '13 at 10:54
  • @DavidBulczak Nice! I added the steps I told you in the comments in my answer. – Pierre Fourgeaud Aug 25 '13 at 10:56
3

Way I'm using it is:

add_custom_command(
    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/gen_icinstrtab.hpp
    COMMAND xsltproc --output ${CMAKE_CURRENT_BINARY_DIR}/gen_icinstrtab.hpp ${CMAKE_SOURCE_DIR}/xml/genictabc.xslt ${CMAKE_SOURCE_DIR}/xml/icminstr.xml
)

add_executable(
    du4

    ${CMAKE_CURRENT_BINARY_DIR}/gen_icinstrtab.hpp
    .
    .
    .
)

The key was to add even .hpp files into add_executable block.

graywolf
  • 7,092
  • 7
  • 53
  • 77