Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

cmake doesnt rebuild externalProject on changes

Tags:

cmake

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 ?

like image 428
Jeremy Fouriaux Avatar asked Oct 12 '17 11:10

Jeremy Fouriaux


1 Answers

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).

like image 123
Ryan Feeley Avatar answered Nov 12 '22 01:11

Ryan Feeley