[CMake] Project Structure and add_subdirectory()

Avraham Shukron avraham.shukron at gmail.com
Fri Sep 27 17:22:47 EDT 2019


I think option 2 (keeping track on transitive dependencies) should be out
of the question.
It is bound to fail.

Superbuild setup makes sense where all the components are part of a bigger
whole.
But if each application may depend on a different "flavor" of  a
dependency library, I think it should be reflected in your project
structure, E.g each application in a separate repository, with all the
dependencies as submodules.

alternatively, you can create a multi-root setup, where you have a
project-root-directory for each application, with a top-level CMakeLists
that adds all the necessary subdirectories.
This way, you get the best of all worlds:
1. Each component's source code is kept only once, and changes are
immediately affecting all products.
2. You can compile each application independently from one another.

Consider the following structure:

-top/
    - app1_root/
        - CMakeLists.txt
    - app2_root/
        - CMakeLists.txt
    - app3_root/
        - CMakeLists.txt
    - components/
        - CMakeLists.txt
        - libA/
        - libB/
        - libC/

The only issue I can think of is that in each application's top-level
CMakeLists.txt you have to add_subdirectory(../components) and the ".." is
kind of ugly.
Other than that I think it should work


On Fri, Sep 27, 2019 at 7:00 PM Marek Vojtko <marek.vojtko at oxidegames.com>
wrote:

> Using add_subdirectory() in a "superbuild" setup is straightforward:
> Create a root CMakeLists.txt which calls add_subdirectory() on all
> directories of your project and each target can then use
> target_link_libraries() without worrying where the target came from.
>
> Unfortunately the "superbuild" setup also means that each target is
> compiled exactly once, which means that you cannot change a target's build
> environment per-application (e.g. preprocessor definitions that change the
> sizes of stack arrays).
>
> If I need per-application control of its dependencies' build environment I
> can have each application's CMakeLists.txt call add_subdirectory() for all
> of its dependencies. However, that means that each application now has to
> know all of its *transitive* dependencies and the application's
> CMakeLists.txt has to be kept up-to-date with any changes in its dependency
> tree, no matter how deep. So if AppA depends on LibA, which depends on
> LibB, which depends on LibC. Not only does AppA's CMakeLists.txt have to
> call add_subdirectory() on LibA, LibB, and LibC, but if LibC is modified to
> depend on LibX, now AppA's CMakeLists.txt has to also be modified to call
> add_subdirectory() on LibX.
>
> Having each target call add_subdirectory() on its own dependencies seems
> silly, because that would create an insane number of duplicated targets. If
> LibA depends on LibB and LibC, and both LibB and LibC depend on LibD, this
> approach would result in both LibB and LibC calling add_subdirectory() on
> LibD, creating the target twice, which would likely not compile.
>
> Are these my only two options? Either:
> - use a superbuild to have CMake handle my transitive dependencies, but
> give up per-application build environment changes, or
> - track all transitive dependencies manually in each application's
> CMakeLists.txt, but retain the ability to change the build environment per
> application.
> --
>
> Powered by www.kitware.com
>
> Please keep messages on-topic and check the CMake FAQ at:
> http://www.cmake.org/Wiki/CMake_FAQ
>
> Kitware offers various services to support the CMake community. For more
> information on each offering, please visit:
>
> CMake Support: http://cmake.org/cmake/help/support.html
> CMake Consulting: http://cmake.org/cmake/help/consulting.html
> CMake Training Courses: http://cmake.org/cmake/help/training.html
>
> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
>
> Follow this link to subscribe/unsubscribe:
> https://cmake.org/mailman/listinfo/cmake
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://cmake.org/pipermail/cmake/attachments/20190928/6eb6eb5f/attachment.html>


More information about the CMake mailing list