Ninja needs OBJECT_DEPENDS on external_project if that generates cpp-file???
Hi,
below there's an example that prints a higher and higher number on each rebuild.
Like this:
cmake -GNinja ..
cmake --build . && ./inc_exe # prints 0
cmake --build . && ./inc_exe # prints 1
cmake --build . && ./inc_exe # prints 2
cmake --build . && ./inc_exe # prints 3
How does it work? -> An external_project re-writes a file inc/build/inc.cpp
on each build, and writes a higher and higher number (below e.g. with 3)
#include <iostream>
void inc() {
std::cout << 3 << std::endl;
}
The number itself is stored in a file inc/build/num
.
Here's the code:
(PS: Don't try to hard to understand the external project stuff below... Suggestion: better: just look at generated ${CMAKE_BINARY_DIR}/inc
which is the external project (and it then will be easy to understand).)
Click to show code
cmake_minimum_required(VERSION 3.11)
project(incremeter)
file(WRITE ${CMAKE_BINARY_DIR}/main.cpp
"
void inc();
int main()
{
inc();
}
")
#### external project stuff
###############################
set(INC_SOURCE_DIR ${CMAKE_BINARY_DIR}/inc)
set(INC_BINARY_DIR ${CMAKE_BINARY_DIR}/inc/build)
file(MAKE_DIRECTORY ${INC_SOURCE_DIR})
set(WRITE_AND_INC ${INC_SOURCE_DIR}/write_and_inc.cmake)
file(WRITE ${INC_SOURCE_DIR}/CMakeLists.txt
"
cmake_minimum_required(VERSION 3.11)
add_custom_target(FileGen ALL
\${CMAKE_COMMAND} -D OUTFILE=${INC_BINARY_DIR}/inc.cpp
-P \${WRITE_AND_INC}
BYPRODUCTS ${INC_BINARY_DIR}/inc.cpp
)
")
file(WRITE ${WRITE_AND_INC}
"
if (NOT EXISTS ${INC_BINARY_DIR}/num)
set(NUM 0)
else()
file(READ ${INC_BINARY_DIR}/num NUM)
math(EXPR NUM \${NUM}+1)
endif()
file(WRITE ${INC_BINARY_DIR}/num \${NUM})
file(WRITE \${OUTFILE}
\"#include <iostream>
void inc() {
std::cout << \${NUM} << std::endl;
}
\")
"
)
include(ExternalProject)
ExternalProject_Add(inc_gen
SOURCE_DIR ${INC_SOURCE_DIR}
BINARY_DIR ${INC_BINARY_DIR}
CMAKE_ARGS -DWRITE_AND_INC=${WRITE_AND_INC}
BUILD_ALWAYS TRUE
INSTALL_COMMAND ""
)
#### inc_exe
###############################
add_executable(inc_exe
${CMAKE_BINARY_DIR}/main.cpp
${INC_BINARY_DIR}/inc.cpp)
add_dependencies(inc_exe inc_gen)
set_source_files_properties(${INC_BINARY_DIR}/inc.cpp
PROPERTIES GENERATED TRUE
)
if("${CMAKE_GENERATOR}" STREQUAL "Ninja")
set_source_files_properties(${INC_BINARY_DIR}/inc.cpp
PROPERTIES OBJECT_DEPENDS inc_gen ## is it correct that this is needed for ninja????
)
endif()
I've found that this only works cleanly with ninja, if the generated file OBJECT_DEPENDS on the external_project inc_gen
. (see right at the end of the code... above)
Question:
- Is it correct Ninja generator needs OBJECT_DEPENDS?
- Is it safe that the OBJECT_DEPENDS actually depends on the external project
inc_gen
(as opposed to a file -- documentation states that OBJECT_DEPENDS "Specifies a ;-list of full-paths to files on which any object files compiled from this source file depend" ref)?
Thanks.
Edited by user706