1

With a growing codebase, it makes sense to organize it between separate repositories, each repo being a separate CMake-managed project.

Because of modularity, this usually means you end up in a situation where a CMake-managed project Application depends on another CMake-managed project Library, while both are internal code (i.e., code owned and maintained by your structure).

The automatic dependency recompilation issue

Then, if some sources in Library are modified, it needs to be recompiled in order to build Application. The question being:

Is it possible to have the "build Application" command (a button in an IDE, or a call to make on the command line) to first rebuild Library if Library files changed ?

Ad N
  • 7,930
  • 6
  • 36
  • 80

2 Answers2

1

I'd suggest to use the ExternalProject_Add command.

The documentation has slightly changed for the different versions:

In case you encounter problems with getting the dependencies right, this thread might help you.

normanius
  • 8,629
  • 7
  • 53
  • 83
0

By looking at how the OpenChemistry parent-project does it, and with the confirmation by normanius's answer, it turns out this can be achieved with relatively few CMake script code.

It turns out that CMake CLI is offering an abstraction over the "build" action of the targeted build systems. See --build option.
ExternalProject_Add can be seen as a wrapper to use this CLI interface directly from CMake scripts.


Imagine there is a CMake-managed repository, building libuseful, and a separate CMake-managed repo, building appawesome with a dependency on libuseful.

find_package(libuseful CONFIG) # The usual way to find a dependency

# appawesome is the executable we are building, it depends on libuseful
add_executable(appawesome main.cpp)
target_link_libraries(appawesome libuseful)

 Adding automatic rebuild

Then it is possible to make building appawesome systematically first try to rebuild libuseful with some code looking like:

ExternalProject_Add(EP_libuseful)
    SOURCE_DIR <libuseful_sourcedir>  # containing libuseful's root CMakeLists.txt
    BINARY_DIR <libuseful_binarydir>  # containing libuseful's CMakeCache.txt
    BUILD_ALWAYS 1                    # Always rebuild libuseful
)

add_dependencies(libuseful EP_libuseful)

The last line is quite important: find_package() in config mode should make a libuseful imported targed available. The call to ExternalProject_Add made a build target EP_libuseful available (which is a custom build step, building libuseful). The last line just makes sure that libuseful depends on its build step.

Ad N
  • 7,930
  • 6
  • 36
  • 80