1

I'm writing a C++ project which use a code generator (perl xsubpp). It generates C/C++ source code from XS file. As xsubpp sometimes produce incomplete output file, I want to have it run before the actual binary target is built, regardless there exists generated source file.

I can find out two ways to achieve it:

# the target is always out-of-date, so the command is always run add_custom_target(...) add_library(lib_name ...) add_dependencies(lib_name ...) 

and

add_library(lib_name ...) # the command is always run before lib_name is build add_custom_command(TARGET lib_name PRE_BUILD ...) 

However, none of them works, because add_library() checks source file at configure time. The source file must either exist, or as an output target of add_custom_command().

For the first way, the add_custom_target() don't have the concept of output target; and for the second way, the add_custom_command() is used as an auxiliary of lib_name, which also don't have the concept of output target.

1
  • 1
    Using a generated header/source should not be a problem, as the source will be marked as GENERATED and thus safe to use in add_library (this is at least what I get from reading the CMake FAQ). Commented May 30, 2014 at 9:47

1 Answer 1

2

The following works for me. I hope that this is what you want.

The source (foo.cpp) is re-generated every time I run make.

src/C_generated/CMakeLists.txt:

add_custom_target(generate_foo touch ${CMAKE_CURRENT_SOURCE_DIR}/script.sh COMMENT "add_custom_target, touch script.sh" ) ADD_CUSTOM_COMMAND( TARGET generate_foo COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/script.sh ARGS "some args" COMMENT "custom commands, executing script.sh" ) set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/foo.cpp PROPERTIES GENERATED 1) add_library(LIBC ${CMAKE_CURRENT_BINARY_DIR}/foo.cpp) ADD_DEPENDENCIES(LIBC generate_foo) 

src/C_generated/script.sh:

#!/bin/bash echo "Running script.sh" echo "#include <stdio.h>" > foo.cpp echo "/*" >> foo.cpp date >> foo.cpp echo "*/" >> foo.cpp echo >> foo.cpp echo "void testC()" >> foo.cpp echo "{" >> foo.cpp echo " printf(\"Generated source.\");" >> foo.cpp echo "}" >> foo.cpp 

Main CMakeLists.txt which combines generated source with non-generated source:

project(test) cmake_minimum_required(VERSION 2.8) INCLUDE_DIRECTORIES(src) ADD_SUBDIRECTORY(src/A) ADD_SUBDIRECTORY(src/B) # Generated files only. ADD_SUBDIRECTORY(src/C_generated) # Combine the different libraries into one. add_library(TESTLIB STATIC src/dummy.c) ADD_DEPENDENCIES(TESTLIB LIBA) ADD_DEPENDENCIES(TESTLIB LIBB) ADD_DEPENDENCIES(TESTLIB LIBC) GET_TARGET_PROPERTY(LIBA_LOC LIBA LOCATION) GET_TARGET_PROPERTY(LIBB_LOC LIBB LOCATION) GET_TARGET_PROPERTY(LIBC_LOC LIBC LOCATION) SET_TARGET_PROPERTIES(TESTLIB PROPERTIES STATIC_LIBRARY_FLAGS "${LIBA_LOC} ${LIBB_LOC} ${LIBC_LOC}") 

Download this example from:

https://dl.dropboxusercontent.com/u/68798379/cmake-code-generator.tar.bz2

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.