Execute target output as a dependency for another
I have the following directory structure:
.
βββ CMakeLists.txt
βββ generator
β βββ CMakeLists.txt
β βββ main.cpp
βββ include
βββ src
βββ CMakeLists.txt
βββ mylib.cpp
I would like to build generator
and then use a generator to generate a source file that will be used to build mylib. I've tried this:
Generator / CMakeLists.txt:
add_executable(gen main.cpp)
add_custom_command(
OUTPUT
${CMAKE_BINARY_DIR}/generated.cpp
DEPENDS
gen
COMMAND
${CMAKE_BINARY_DIR}/gen -d /tmp
VERBATIM
)
Csi / CMakeLists.txt:
add_library(py-cppast
${CMAKE_BINARY_DIR}/generated.cpp
mylib.cpp)
CMakeLists.txt:
cmake_minimum_required(VERSION 3.1.2)
project(my-project)
add_subdirectory(generator)
add_subdirectory(src)
However, the command fails. Instead, I just get the error:
CMake Error at src / CMakeLists.txt: 2 (add_library): Cannot find source file: /home/....(the cmake binary dir) .... / generated.cpp Tried extensions .c .C .c ++ .cc .cpp .cxx .m .M .mm .h .hh .h ++ .hm .hpp .hxx .in .txx
How can I tell cmake to execute the program I am building with it? Is this possible in one assembly?
source to share
The problem occurs because you generate a file generated.cpp
in one directory and then try to add it to a target defined in another directory. CMake only supports adding generated files to targets defined in the same directory area. The documentation add_custom_command()
explicitly mentions this limitation.
You probably want to move the generation generated.cpp
to a directory src
. You should also only use the target name gen
to refer to the executable to run, not ${CMAKE_BINARY_DIR}/gen
which will not be correct for all types of CMake generators. It would also be better to use the current binary rather than the top level binary as the output directory. Yours src/CMakeLists.txt
should look something like this:
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/generated.cpp
DEPENDS gen
COMMAND gen -d /tmp
VERBATIM
)
add_library(py-cppast
${CMAKE_CURRENT_BINARY_DIR}/generated.cpp
mylib.cpp
)
CMake will automatically replace the location of the target gen
for you even though it was defined in a different directory. There are a few more subtleties to be aware of when using generated sources, especially with regard to dependencies. You can find this article to fill in some of the blanks.
source to share