webentwicklung-frage-antwort-db.com.de

Wie erstelle ich eine cmake-Header-Bibliothek, die von externen Header-Dateien abhängt?

Ich habe ein Projekt mit folgender Dateistruktur:

project
 |
 |-------> lib1
 |           |----> lib1.h
 |
 |-------> lib2
 |           |----> lib2.h
 |
 |-------> main.cc

Die beiden Bibliotheken lib1 und lib2 enthalten nur Header-Dateien, während lib2.hlib1.h und main.cclib2.h enthält.

Wie schreibe ich jetzt die cmake-Datei für dieses Projekt? Ich habe versucht, eine interface-Bibliothek zu erstellen für lib2, aber der Compiler kann lib1.h nicht finden. Hier sind die Inhalte meiner cmake-Dateien:

CMakeLists.txt für lib2:

add_library(lib2 INTERFACE)
target_sources(lib2 INTERFACE lib2.h)
target_include_directories(lib2 INTERFACE ../lib1/lib1.h)

CMakeLists.txt für das gesamte Projekt:

add_executable(project main.cc)
target_link_libraries(project lib2)

Was ist das Problem in den cmake-Dateien?

7
X. Liu

Wie in den Kommentaren angegeben, sollte target_include_directories ein Pfad zu einem Verzeichnis und nicht zu einer Datei angegeben werden.

Wenn Sie für lib2 eine Abhängigkeit von lib1 erstellen möchten, sollten Sie dies auch über target_link_libraries tun: Bei einer Abhängigkeit geht es nicht nur um Include-Verzeichnisse, sondern auch um Kompilierungsoptionen, Definitionen, Zieleigenschaften ...

target_sources funktioniert nicht mit Schnittstellenbibliotheken. Mit dieser Antwort können Sie ein benutzerdefiniertes Ziel ohne Befehle verwenden, um die Quellen einem Ziel zuzuordnen, ohne den Erstellungsprozess zu beeinträchtigen es ist für andere Build-Tools nutzlos).

Ihr cmake kann so aussehen:

add_library(lib1 INTERFACE)
target_sources(lib1 INTERFACE lib1.h)

target_include_directories(lib1 INTERFACE
    "${PROJECT_SOURCE_DIR}/lib1"
)

add_library(lib2 INTERFACE)
if(MSVC)
    add_custom_target(lib2.headers SOURCES lib2.h)
endif()

target_include_directories(lib2 INTERFACE
    "${PROJECT_SOURCE_DIR}/lib2"
)

target_link_libraries(lib2 INTERFACE lib1)

add_executable(project main.cc)
target_link_libraries(project lib2)

Tipp für Fortgeschrittene: Sie können in target_include_directories ein anderes Verzeichnis für den Build- und den Installationsbaum angeben (siehe documentation ):

target_include_directories(lib1 INTERFACE
    $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/lib1>
    $<INSTALL_INTERFACE:${YOUR_INSTALL_DIR}/lib1>
)
13
wasthishelpful

Ich habe eine leere _only_for_compiling_the_lib.cpp-Datei als einfachste und schnellste Problemumgehung verwendet. Die oben genannte Lösung wird jedoch dringend empfohlen.

Mir war das INTERFACE-Schlüsselwort einfach nicht bewusst.

1

Dieses Problem wurde durch ein Problem mit dem vollständigen Pfad der INTERFACE-Bibliotheksdateien verursacht, das in cmake Version 3.13 behoben wurde.

Für weitere Informationen: https://gitlab.kitware.com/cmake/cmake/issues/17556

Diese Seite enthält auch ein Beispiel zum besseren Verständnis.

0
Pankaj Misra