unknownperson
unknownperson

Reputation: 579

cmake not rebuilding a non-download external project after manually editing its sources

I'm working on some modifications to the openEMS project. This project uses cmake to build all of its components. The top level CMakeLists.txt file contains the following:

# ...
ExternalProject_Add( openEMS
  DEPENDS     fparser CSXCAD
  SOURCE_DIR  ${PROJECT_SOURCE_DIR}/openEMS
  CMAKE_ARGS  -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} -DFPARSER_ROOT_DIR=${CMAKE_INSTALL_PREFIX} -DCSXCAD_ROOT_DIR=${CMAKE_INSTALL_PREFIX} -DWITH_MPI=${WITH_MPI} -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
)
# ...

Inside the openEMS directory, there's another CMakeLists.txt with the following:

# ...
set(SOURCES
  openems.cpp
)
# ...
add_library( openEMS SHARED ${SOURCES})
# ...

After building the project successfully once, make does not rebuild anything when, for example, openems.cpp is modified. Why?

$ mkdir build
$ cd build
$ cmake -DBUILD_APPCSXCAD=NO
$ make
[builds all files]

$ touch ../openEMS/openems.cpp
$ make
[ 33%] Built target fparser
[ 66%] Built target CSXCAD
[100%] Built target openEMS
(noting is built)

I have checked and the modification date of openems.cpp is newer than the target. Even deleting the produced library files and binaries, both in the install directory and in the build directory, does not cause it to rebuild anything. The only way I can get it to rebuild is by deleting everything in the build directory and re-running cmake which, of course, rebuilds everything.

Upvotes: 2

Views: 869

Answers (1)

starball
starball

Reputation: 50345

This looks like a case of the following. Quoting from the docs for ExternalProject_Add at the section titled "Build Step Options":

BUILD_ALWAYS <bool>

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 that's the case, the solution would be to add the BUILD_ALWAYS argument to the ExternalProject_Add call like.

ExternalProject_Add( openEMS
  DEPENDS     fparser CSXCAD
  SOURCE_DIR  ${PROJECT_SOURCE_DIR}/openEMS
  CMAKE_ARGS  -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} -DFPARSER_ROOT_DIR=${CMAKE_INSTALL_PREFIX} -DCSXCAD_ROOT_DIR=${CMAKE_INSTALL_PREFIX} -DWITH_MPI=${WITH_MPI} -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
  BUILD_ALWAYS TRUE
)

If you confirm that this solves the issue, you might want to raise this as an issue to the maintainers of openEMS.

Also note that since the external project there is using CMake as a buildsystem, you could also add the CONFIGURE_HANDLED_BY_BUILD TRUE to the argument list. See the docs for more info.

Edit: The asker opened a GitHub Pull-Request.

Upvotes: 3

Related Questions