I have the following CMakeLists.txt:
cmake_minimum_required( VERSION 3.0)
project(addProject)
include (ExternalProject)
set(ExternalProjectCMakeArgs
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-DCMAKE_INSTALL_PREFIX=${PROJECT_BINARY_DIR}/external/genLib
)
ExternalProject_Add(genLib
SOURCE_DIR ${PROJECT_SOURCE_DIR}/external/genLib
BINARY_DIR ${PROJECT_BINARY_DIR}/external/genLib
INSTALL_COMMAND ""
INSTALL_DIR ${PROJECT_BINARY_DIR}/external
CMAKE_ARGS ${ExternalProjectCMakeArgs}
)
add_custom_command( OUTPUT "generated.cpp"
COMMAND ${PROJECT_BINARY_DIR}/external/genLib/genLib "generated.cpp"
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
add_executable(add main.cpp ${CMAKE_CURRENT_BINARY_DIR}/generated.cpp)
add_dependencies (add genLib)
first time build is always correct:
mkdir build; cd build; cmake -GNinja ../; ninja
giving the following output:
-- The C compiler identification is GNU 4.4.7
-- The CXX compiler identification is GNU 4.4.7
-- Check for working C compiler using: Ninja
-- Check for working C compiler using: Ninja -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler using: Ninja
-- Check for working CXX compiler using: Ninja -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /Devel/scratc/testingExternalProject2/build
41% 5/[email protected] 0: Performing configure step for 'genLib'
-- The C compiler identification is GNU 4.4.7
-- The CXX compiler identification is GNU 4.4.7
-- Check for working C compiler using: Ninja
-- Check for working C compiler using: Ninja -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler using: Ninja
-- Check for working CXX compiler using: Ninja -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /Devel/scratc/testingExternalProject2/build/external/genLib
50% 6/[email protected] 0: Performing build step for 'genLib'
50% 1/2@? 1: Building CXX object CMakeFiles/genLib.dir/genLib.cpp.o
100% 2/[email protected] 1: Linking CXX executable genLib
100% 12/[email protected] 0: Linking CXX executable add
Now if I modify a source file in external project: touch ../external/genLib/genLib.cpp
and recompile ninja nothing changes: ninja: no work to do.
I have tested it using make instead of Ninja with exactly same behavior. I also have tested to add DEPENDS clause in my custom_command, which is working for individual files but not the full project (and it seems very hacky to add all source files of the external project as DEPENDS clause...)
Does anyone have more experience using external project and can explain the behavior of cmake decision to rebuild or not dependencies ?
If you can use at least cmake version 3.1, try adding BUILD_ALWAYS 1
to your ExternalProject_Add
command:
ExternalProject_Add(genLib
SOURCE_DIR ${PROJECT_SOURCE_DIR}/external/genLib
BINARY_DIR ${PROJECT_BINARY_DIR}/external/genLib
BUILD_ALWAYS 1
INSTALL_COMMAND ""
INSTALL_DIR ${PROJECT_BINARY_DIR}/external
CMAKE_ARGS ${ExternalProjectCMakeArgs}
)
According to the documentation of the ExternalProject_Add command
Enabling this option forces the build step to always be run. This can be the easiest way to robustly ensure that the external project’s own build dependencies are evaluated rather than relying on the default success timestamp-based method. This option is not normally needed unless developers are expected to modify something the external project’s build depends on in a way that is not detectable via the step target dependencies (e.g. SOURCE_DIR is used without a download method and developers might modify the sources in SOURCE_DIR).
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