Wie kann ich CMake anweisen, eine Verknüpfung in einer statischen Bibliothek im Quellverzeichnis herzustellen?

88

Ich habe ein kleines Projekt mit einem Makefile, das ich in CMake konvertieren möchte, hauptsächlich, um Erfahrungen mit CMake zu sammeln. Für die Zwecke dieses Beispiels enthält das Projekt eine Quelldatei (C ++, obwohl ich die Sprache nicht für besonders relevant halte) und eine statische Bibliotheksdatei, die ich von einer anderen Stelle kopiert habe. Nehmen Sie aus Gründen der Argumentation an, dass der Quellcode für die Bibliothek nicht verfügbar ist. Ich habe nur die .a-Datei und den entsprechenden Header.

Mein handgemachtes Makefile enthält diese Build-Regel:

main: main.o libbingitup.a
    g++ -o main main.o libbingitup.a

das funktioniert gut. Wie kann ich CMake anweisen, dies zu reproduzieren? Natürlich nicht genau dieses Makefile, sondern etwas, das einen äquivalenten Verknüpfungsbefehl enthält. Ich habe die offensichtlichen, aber naiven Wege ausprobiert

add_executable(main main.cpp libbingitup.a)

oder

add_executable(main main.cpp)
target_link_libraries(main libbingitup.a)

sowie verschiedene Dinge mit link_directories(.)oder add_library(bingitup STATIC IMPORTED)etc., aber bisher nichts, was zu einer erfolgreichen Verknüpfung führt. Was soll ich tun


Versionsdetails: CMake 2.8.7 unter Linux (Kubuntu 12.04) mit GCC 4.6.3

David Z.
quelle

Antworten:

116

CMake bevorzugt die Übergabe des vollständigen Pfads zur Verknüpfung von Bibliotheken. Unter der Annahme, dass libbingitup.a aktiviert ist ${CMAKE_SOURCE_DIR}, sollte Folgendes erfolgreich sein:

add_executable(main main.cpp)
target_link_libraries(main ${CMAKE_SOURCE_DIR}/libbingitup.a)
Fraser
quelle
2
Großartig, das funktioniert, danke! Es scheint ein wenig hackisch zu sein, hier den vollständigen Pfad explizit angeben zu müssen, aber ich denke, das ist nur der CMake-Weg ...
David Z
4
Ich bin damit einverstanden, dass es hier wie ein Overkill erscheint, aber die explizite Angabe des vollständigen Pfads zahlt sich aus, wenn Sie mehrere verschiedene Versionen derselben Bibliothek installiert haben.
Fraser
1
Erstaunlich wie immer! In meinem Fall wurde ein Problem mit Bibliotheken gelöst, die von einer anderen erstellten dynamischen Bibliothek abhängig waren, die von einer statischen Bibliothek abhängig war: Die abhängigen Bibliotheken versuchten auch, eine Verknüpfung zu dieser statischen Bibliothek herzustellen.
Antonio
1
Woher weiß main über die Include-Verzeichnisse Bescheid?
ManuelSchneid3r
3
Sie müssten target_include_directoriesoder verwenden include_directories(ersteres ist der bevorzugte Weg, da es spezifischer ist).
Fraser
29

Wenn Sie nicht den vollständigen Pfad einschließen möchten, können Sie dies tun

add_executable(main main.cpp)
target_link_libraries(main bingitup)

bingitup ist derselbe Name, den Sie einem Ziel geben würden, wenn Sie die statische Bibliothek in einem CMake-Projekt erstellen:

add_library(bingitup STATIC bingitup.cpp)

CMake fügt automatisch die libauf die Vorder- und die .aam Ende auf Linux, und .libam Ende unter Windows.

Wenn die Bibliothek extern ist, möchten Sie möglicherweise den Pfad zur Bibliothek mit hinzufügen

link_directories(/path/to/libraries/)
Cris Luengo
quelle
1
Und wenn es .a und .so Dateien mit demselben Namen gibt, wie Sie angeben, möchten Sie in diesem Fall eine Verknüpfung mit der .a oder der .so herstellen?
George
1
@ George: Das kannst du nicht. Wenn beide Typen vorhanden sind, geben Sie den vollständigen Namen der Datei an, mit der Sie eine Verknüpfung herstellen möchten.
Cris Luengo
21

Ich fand das hilfreich ...

http://www.cmake.org/pipermail/cmake/2011-June/045222.html

Aus ihrem Beispiel:

ADD_LIBRARY(boost_unit_test_framework STATIC IMPORTED)
SET_TARGET_PROPERTIES(boost_unit_test_framework PROPERTIES IMPORTED_LOCATION /usr/lib/libboost_unit_test_framework.a)
TARGET_LINK_LIBRARIES(mytarget A boost_unit_test_framework C)
stu
quelle
2
Was ist mit INCLUDE_DIRECTORIES?
Kyb
1
Dies funktioniert nur, wenn die Bibliothek Teil des cmake-Builds ist, aber fremde, dies funktioniert nicht
truthadjustr
Die Frage lautet: "Das Projekt enthält eine Quelldatei (C ++, obwohl ich die Sprache nicht für besonders relevant halte) und eine statische Bibliotheksdatei, die ich von einer anderen Stelle kopiert habe."
stu