Verwenden von CMake mit Bibliotheken mit Diamantabhängigkeiten

Sagen wir, ich habe vier separate Projekte. Drei sind Bibliotheken,Common, Foo, undBar, und einer von ihnen ist eine ausführbare Datei,App. BeideFoo undBar hängt von der allgemeinen Bibliothek ab undApp kommt drauf anFoo undBar. Darüber hinaus verfügen einige dieser Projekte über Skripts, die ausgeführt werden müssen, um Header- und Quelldateien zu generieren.

Right now Ich habe ein Durcheinander von Anrufen wie folgt:

if (NOT TARGET common)
  add_subdirectory(${common_lib_directory})
endif()

Aber das fühlt sich nicht nach der richtigen Lösung an. Wenn ich es nicht in das if guard einpacke, dann gibt es Fehler, weil es versucht, @ zu baueCommon mehr als einmal. Das Einfügen von Wachen in die CMakeLists für jedes Projekt scheint ebenfalls nicht richtig zu sein. Soll ich @ schreibFind<Library> Skripte für jede Bibliothek? Ich habe versucht, nach Beispielen oder bewährten Methoden zum Einrichten meiner CMakeLists-Dateien zu suchen. Die einzigen Beispiele, die ich finden kann, sind entweder zu trivial oder decken ganz unterschiedliche Anwendungsfälle ab.

Es wurde in den Kommentaren verlangt, dass ich Code poste. So ungefähr sieht meine CMakeLists.txt-Datei aus:

cmake_minimum_required(VERSION 2.8.12)

project(app)

# Temporary files (like object files) created while compiling projects.
set(tmp_dir ${CMAKE_BINARY_DIR}/obj)

# Directory which contains the source for 3rd party libraries.
if(NOT DEFINED dependencies_root)
  get_filename_component(
    dependencies_root "${CMAKE_CURRENT_SOURCE_DIR}/../../../../external"
    REALPATH)
endif()

set(dependencies_foo_dir "${dependencies_root}/foo"
    CACHE PATH "Directory containing the foo library.")
set(dependencies_bar_dir "${dependencies_root}/bar"
    CACHE PATH "Directory containing the bar library.")

if(NOT TARGET foo)
  add_subdirectory("${dependencies_foo_dir}" ${tmp_dir}/foo)
endif()

if(NOT TARGET bar)
  add_subdirectory("${dependencies_bar_dir}" ${tmp_dir}/bar)
endif()

include_directories(${dependencies_foo_dir}/include)
include_directories(${foo_generated_include_dir})

include_directories(${dependencies_bar_dir}/include)
include_directories(${bar_generated_include_dir})

set(app_srcs ...)

add_executable(app ${app_SRCS})

target_link_libraries(app foo bar common)

Wie bereits erwähnt, der Grund, warum ich das @ haif (NOT TARGET blah) Wachen ist, weil, wenn ich es nicht tue, ich Fehler wie diese bekomme:

CMake Error at /path/to/my/project/CMakeLists.txt:267 (add_library):
  add_library cannot create target "blah" because another target with the
  same name already exists.  The existing target is a static library created
  in source directory
  "/path/to/blah".
  See documentation for policy CMP0002 for more details.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage