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
, then use generator to generate a source file that will be used to build mylib. I 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
)
src/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 is not executed. 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'm building with it? Is this even possible in a single build?
The problem comes from the fact that you are generating the file generated.cpp
in one directory and then trying to add it to a target defined in a different directory. CMake only supports adding generated files to targets defined in the same directory scope. The add_custom_command()
documentation explicitly mentions this restriction.
You probably want to move the generation of generated.cpp
into the src
directory. You should also use just the gen
target name to refer to the executable to run, not ${CMAKE_BINARY_DIR}/gen
which is not going to be correct with all CMake generator types. It would also be better style to use the current binary directory rather than the top level binary directory as the output dir. Your 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 substitute the location of the gen
target for you, even though it was defined in a different directory. There are some further subtleties to be aware of when using generated sources, particularly relating to dependencies. You may find this article helpful to fill in some gaps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With