How to handle transitive dependency conflict using Git and CMake submodules?

We have several Git repositories, some of which contain our own code, and some contain slightly modified third-party library code. A simplified dependency graph is as follows:

  executable_A
    |     |
    |     v
    |  library_B
    |     |
    v     v
   library_C

Thus, the executable file has two dependencies library_C, one direct and one transitive. I hope to connect all this with the use of the Git and CMake submodules, so the simplified directory structure looks like this:

executable_A/
  CMakeListst.txt
  library_B/
    CMakeLists.txt
    library_C/
      CMakeLists.txt
  library_C/
    CMakeLists.txt

As you can see, the repository is library_Cincluded as a submodule twice. Suppose both submodules point to the same commit (any ideas on how to enforce this are welcome, but not the topic of this question).

add_subdirectory, target_link_libraries target_include_directories . .

, CMake , , :

CMake _C/CMakeLists.txt: 13 (add_library):
add_library "library_C", . - , ".../library_B/library_C".
. CMP0002.

executable_A library_C, , library_B, library_B, . , , , executable_A --> library_D --> library_C.

( , , .)

+6
1

, .

- - :

# When include 'C' subproject
if(NOT TARGET library_C)
    add_subdirectory(C)
endif()

( , C target library_C.)

.

( executable_A library_B). library_B library_C executable_A .

:

# At the beginning of 'C' project
cmake_minimum_required(...)
if(TARGET library_C)
    return() # The project has already been built.
endif()

project(C)
...

, CMake , < PROJECT-NAME > _BINARY_DIR . , , , cmake (, CMakeLists.txt ), .

# When include 'C' subproject
if(NOT C_BINARY_DIR # Check that the subproject has never been included
    OR C_BINARY_DIR STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/C" # Or has been included by us.
)
    add_subdirectory(C)
endif()

:

# At the beginning of 'C' project
cmake_minimum_required(...)
if(NOT C_BINARY_DIR # Check that the project has never been created
    OR C_BINARY_DIR STREQUAL "${CMAKE_CURRENT_BINARY_DIR}" # Or has been created by us.
    project(C)
else()
    return() # The project has already been built
endif()
+4

Source: https://habr.com/ru/post/1015966/


All Articles