Search code examples
c++cmakegit-submodules

CMake build git submodules and its dependencies


I am a novice in CMake,

I would like to use a C++ library A in my CMake project. This library A is included as a git submodule and I include it in my CMakeFile using

add_subdirectory("extern/A")

which works so far.

However, my library A has two other dependencies B and C. They are included in the CMakeFile of library A using find_package().

Now, I would like CMake to build these dependencies B and C, so that library A can use them. I want to include B and C as git submodules as well.

Simply concatenating

add_subdirectory("extern/B")
add_subdirectory("extern/C")
add_subdirectory("extern/A")

obviously doesn't work. I thought using add_dependencies could help here, but I couldn't find a way to make it work yet...

Is it even possible to do what I want to do here? If yes, could someone give me a hint which commands I might have to use?


Solution

  • Your mistake adding B as a dependency to RootProject where A needs it.

    Solution

    In the following directory structure:

    RootProject
    |__ .git
    |__ CMakeLists.txt
    |__ src
    |   |__ main.c
    |   |__ ...
    |
    |__ vendor
        |__ A
            |__ .git
            |__ CMakeLists.txt
            |__ src
                |__ ...
    
    • RootProject depends on A.
    • A is a library that has no dependencies.

    If you want to add B as a dependency to A, you would treat A as completely separate project from RootProject and add B directly to A.

    The directory structure of A becomes:

    A
    |__ .git
    |__ CMakeLists.txt
    |__ src
    |    |__ ...
    |
    |__ vendor
        |__ B
            |__ .git
            |__ CMakeLists.txt
            |__ src
                |__ ...
    

    Using git submodules to "manage" the dependencies:

    # Adding `B` as a dependency to `A`
    cd vendor/A
    mkdir -p vendor
    cd vendor
    git submodule add https://github.com/username/B.git
    

    This will add B as a dependency to A, and not to RootProject.

    Now simply add the following to vendor/A/CMakeLists.txt:

    add_subdirectory("vendor/B")
    # ......
    target_link_libraries(A PUBLIC B)
    

    Also note that each of A, B and RootProject must have a top level CMakeLists.txt in order for add_subdirectory to work.

    See also: