How to make cmake finden eine shared-library in einem Unterordner
Ich versuche zu lernen, wie man eine gemeinsam genutzte Bibliothek. Und das folgende scheint zu funktionieren (bitte kommentieren, wenn Sie haben ein feedback zu dieser Methode, der ich im Grunde keine Ahnung, was ich mache).
In "meine Bibliothek" - Projekt, ich habe die header-Dateien in einen Ordner namens "include", und die source-Dateien in "src".
Meine Bibliothek CMakeLists.txt:
cmake_minimum_required(VERSION 2.4.0)
project(mycustomlib)
# Find source files
file(GLOB SOURCES src/*.cpp)
# Include header files
include_directories(include)
# Create shared library
add_library(${PROJECT_NAME} SHARED ${SOURCES})
# Install library
install(TARGETS ${PROJECT_NAME} DESTINATION lib)
# Install library headers
file(GLOB HEADERS include/*.h)
install(FILES ${HEADERS} DESTINATION include)
Meine Anwendung CMakeLists.txt:
cmake_minimum_required(VERSION 2.4.0)
project(myprogram)
# Find source files
file(GLOB SOURCES src/*.cpp)
# Create executable
add_executable(${PROJECT_NAME} ${SOURCES})
# Find and link library
find_library(MYCUSTOMLIB mycustomlib)
target_link_libraries(${PROJECT_NAME} ${MYCUSTOMLIB})
Und das ist arbeiten. Das problem ist, dass ich möchte sowohl den Header und die Bibliothek in Unterordner (speziell: /usr/local/include/mycustomlib/
für die Header, und die /usr/local/lib/mycustomlib/
für die Bibliothek).
Dies ist also mein Versuch:
Meine Bibliothek ist neu CMakeLists.txt:
cmake_minimum_required(VERSION 2.4.0)
project(mycustomlib)
# Find source files
file(GLOB SOURCES src/*.cpp)
# Include header files
include_directories(include)
# Create shared library
add_library(${PROJECT_NAME} SHARED ${SOURCES})
# Install library
install(TARGETS ${PROJECT_NAME} DESTINATION lib/${PROJECT_NAME})
# Install library headers
file(GLOB HEADERS include/*.h)
install(FILES ${HEADERS} DESTINATION include/${PROJECT_NAME})
Meine Anwendung neuer CMakeLists.txt:
cmake_minimum_required(VERSION 2.4.0)
project(myprogram)
# Find source files
file(GLOB SOURCES src/*.cpp)
# Create executable
add_executable(${PROJECT_NAME} ${SOURCES})
# Find and link library
find_library(MYCUSTOMLIB mycustomlib/mycustomlib)
target_link_libraries(${PROJECT_NAME} ${MYCUSTOMLIB})
Und das ist nicht arbeiten. Nun, ich bin gezwungen, angeben .so-Datei der Bibliothek, wie diese:
find_library(MYCUSTOMLIB mycustomlib/libmycustomlib.so)
Wie kommt das?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Werde ich viel mit deinem eigentlichen problem und bieten zusätzliche Kommentare danach. Technisch gesehen, werden Sie gefragt, CMake, um eine Bibliothek namens
mycustomlib/mycustomlib
, aber was Sie wirklich sagen wollen ist, dass Sie wollen findenmycustomlib
und es kann gefunden werden in ein Unterverzeichnis namensmycustomlib
. Ein paar alternative Möglichkeiten zu nennenfind_library()
um dies zu erreichen für den zweiten Fall:Letzteres macht mehr Annahmen, als es sein sollte darüber, wo Sie die Bibliothek installiert haben, so würde ich zugunsten der ersten option. Die erste option geht davon aus, CMake würde sich schon finden, die Bibliotheken in /usr/local/lib, was es scheint, ist es aus Ihrer Frage. Sie können beeinflussen, wo CMake sieht für Bibliotheken ändern CMAKE_PREFIX_PATH und CMAKE_LIBRARY_PATH. Ich würde erwarten, dass die oben genannten Optionen, um Ihren zweiten Fall arbeiten.
Nun zu weiteren Beobachtungen. Sie haben angefordert sehr alt mindestens CMake-version in der ersten Zeile der einzelnen
CMakeLists.txt
- Dateien. Sie wahrscheinlich wollen prüfen, zumindest machen diese 2.8 (persönlich, ich würde vorschlagen, mehr wie 3,2 oder höher, aber es hängt davon ab, was Ihr Projekt braucht Unterstützung).Ihnen verwendeten Datei-globbing zu erhalten, Ihre Liste der Quellen und Header. Dies ist nicht robust und sollte im Allgemeinen vermieden werden (siehe eine Diskussion dieser hier). Sie sehen jede Menge Beispiel-code verwenden Sie diese Methode für Einfachheit, aber es wird nicht empfohlen für Projekte aus der realen Welt (die CMake-Dokumentation auch sagt nicht, es zu benutzen). Explizit Liste aus Ihrem Quell-und header-Dateien individuell, wenn Sie wollen robuste baut.
Wenn Sie glücklich sind, zu verlangen, CMake 2.8.11 oder später (und sollten Sie in diesen Tagen), sondern als Berufung
include_directories()
das macht alles abholen der header-Suchpfad Sie angegeben haben, sollten Sie lieber zum befestigen der Suchpfad Voraussetzung, um das Ziel, das Sie braucht. Sie tun dies mittarget_include_directories()
. Das Pendant zu Ihrem obigen code wäre:Dieser gibt eine viel bessere Kontrolle Ihrer inter-target-Abhängigkeiten, wie Sie Ihr Projekt an Größe und Komplexität zunimmt. Für eine ausführlichere Erörterung dieses Themas finden Sie unter dieser Artikel und vielleicht auch diese eine (Offenlegung: ich habe die beiden Artikel).
Sind die Bibliothek und die Programm völlig separaten Quellcode-repositories? Können Sie eingebaut werden in ein und demselben Projekt? Sie erstellen können mehrere Ziele in einem
CMakeLists.txt
- Datei. Das Projekt name nicht haben keine Beziehung zu den Namen aller Ziele (sehen Sie oft diePROJECT_NAME
variable erneut für den Ziel-Namen in einfache Beispiele, was bedauerlich ist, da es suggeriert eine Beziehung zwischen den beiden, aber für einfache Projekte ist dies nicht der Fall ist). Wenn Sie in der gleichen repository, baut Sie zusammen wäre viel einfacher zu bauen, da Sie nicht haben, um die Bibliothek zu installieren auf die ausführbare Datei, um es zu finden und ihn verlinken.Wenn Sie gebaut werden müssen in separaten Projekten, dann so etwas wie die folgenden für die Anwendung Projekt bekommen sollte, Sie zu schließen:
Für extra-Punkte, die Sie könnten versuchen, um zu bestätigen, dass der header Weg ist in der gleichen Gegend wie die Bibliothek durch die überprüfung der gemeinsamen Pfad-Präfix, oder Sie könnten einfach ableiten
die MCL_HEADER_PATH aus der MYCUSTOMLIB Pfad durch Annahme einer directory-Struktur. Beide Ansätze haben Vorteile und Nachteile. Wenn Sie möchten, erkunden Sie die letztere, die get_filename_component() Befehl wird dein Freund sein.
Hoffentlich, die Punkte, die Sie in die richtige Richtung.
target_include_directories()
tut. Im obigen habe ich Ihnen gezeigt, wie Sie dieinclude
Verzeichnis der header-Suchpfad beim Bau der${PROJECT_NAME}
Ziel. Wenn das Verzeichnis, das Sie hinzufügen, wird als ein relativer Pfad angegeben, den CMake-docs nicht wirklich sagen, was Sie relativ zu der build (Sie erwähnen nur das, was Sie sind im Vergleich zu für eine Installation). Möglicherweise müssen Sie Experimentieren, um zu sehen, was das Verhalten ist. Versuchen${CMAKE_CURRENT_SOURCE_DIR}/include
statt nurinclude
wenn man nicht immer das Verhalten, die Sie erwarten.target_include_directories
ermöglicht es, ein Paket zu "speichern" den Speicherort des headers, die es braucht, damit die Anwendung über "meine Bibliothek" hat nicht haben, dieses Verzeichnis für die Bibliothek zu laufen. Ist das richtig? Weil es scheint, dass, wenn meine Bibliothek braucht einige Kopf -, bin ich verpflichtet, diese Header in meiner Anwendung, obwohl ich frühertarget_include_directories
in meiner Bibliothek...find_package()
stattfind_library()
. Das ist eine ganze Reihe von anderen lernen Sie, bekommen Sie bis zu Geschwindigkeit auf, obwohl, und ich denke, dass geht über den Rahmen Ihrer ursprünglichen Frage. Ein guter Ausgangspunkt wäre die CMake-docs auf Pakete.