it-swarm.com.de

cmake - find_library - Speicherort der benutzerdefinierten Bibliothek

Ich versuche gerade, CMake für mein Projekt (unter Windows) zum Laufen zu bringen. Ich möchte einen benutzerdefinierten Speicherort verwenden, in dem alle Bibliotheken installiert sind. Um CMake über diesen Weg zu informieren, versuchte ich das:

set(CMAKE_PREFIX_PATH D:/develop/cmake/libs)

Aber wenn ich versuche, die Bibliothek mit zu finden

find_library(CURL_LIBRARY NAMES curl curllib libcurl_imp curllib_static)

CMake kann es nicht finden. .__ Wenn ich meinen Präfixpfad auf

set(CMAKE_PREFIX_PATH D:/develop/cmake/libs/curl)

... befindet sich die Bibliothek. 

Meine Frage ist also: Wie kann ich CMake richtig konfigurieren, um mit einer Verzeichnisstruktur an einem benutzerdefinierten Speicherort zu arbeiten, der so aussieht:

D:/develop/cmake/libs/
-> libA
   -> include
   -> lib
-> libB
   -> include
   -> lib
-> ...
   -> include
   -> lib

In "include" liegen die öffentlichen Header und in "lib" die kompilierten Bibliotheken.

Hoffe, jemand kann mir helfen - Danke im Voraus

edit: Die aktuelle Problemumgehung für mich ist, dies zu tun, bevor ich nach Bibliotheken suche:

set(CUSTOM_LIBRARY_PATH D:/develop/cmake/libs)
file(GLOB sub-dir ${CUSTOM_LIBRARY_PATH}/*)
foreach(dir ${sub-dir})
    if(IS_DIRECTORY ${dir})
        set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH};${dir})
    endif()
endforeach()

Auf diese Weise wird das Standardmodul für Boost es jedoch nicht finden, da die Verzeichnisstruktur von Boost etwas anders ist. 

boost -> include -> boost-1_50 -> *.hpp

Wenn ich den Inhalt bei "boost-1_50" in "include" versetze, kann die Bibliothek gefunden werden. Auf diese Weise können jedoch nicht mehrere Versionen richtig gehandhabt werden.

44
Daniel

Ich habe gesehen, dass zwei Leute diese Frage zu ihren Favoriten gestellt haben, also werde ich versuchen, die Lösung zu beantworten, die für mich funktioniert: Statt Suchmodule zu verwenden, schreibe ich Konfigurationsdateien für alle installierten Bibliotheken. Diese Dateien sind extrem einfach und können auch verwendet werden, um nicht standardisierte Variablen festzulegen. CMake sucht (zumindest unter Windows) nach diesen Konfigurationsdateien in 

CMAKE_PREFIX_PATH/<<package_name>>-<<version>>/<<package_name>>-config.cmake

(kann über eine Umgebungsvariable gesetzt werden) ..__ So befindet sich beispielsweise die Boost-Konfiguration im Pfad

CMAKE_PREFIX_PATH/boost-1_50/boost-config.cmake

In dieser Konfiguration können Sie Variablen einstellen. Meine Konfigurationsdatei für boost sieht so aus:

set(boost_INCLUDE_DIRS ${boost_DIR}/include)
set(boost_LIBRARY_DIR ${boost_DIR}/lib)
foreach(component ${boost_FIND_COMPONENTS}) 
    set(boost_LIBRARIES ${boost_LIBRARIES} debug ${boost_LIBRARY_DIR}/libboost_${component}-vc110-mt-Gd-1_50.lib)
    set(boost_LIBRARIES ${boost_LIBRARIES} optimized ${boost_LIBRARY_DIR}/libboost_${component}-vc110-mt-1_50.lib)
endforeach()
add_definitions( -D_WIN32_WINNT=0x0501 )

Ziemlich einfach + Es ist möglich, die Größe der Konfigurationsdateien noch weiter zu verkleinern, wenn Sie einige Hilfsfunktionen schreiben. Das einzige Problem, das ich mit diesem Setup habe, ist, dass ich keinen Weg gefunden habe, Konfigurationsdateien Vorrang vor Suchmodulen zu geben. Sie müssen also die Suchmodule entfernen.

Hoffe das ist hilfreich für andere Leute.

12
Daniel

Die einfachste Lösung kann darin bestehen, HINTS zu jeder find_* - Anfrage hinzuzufügen.

Zum Beispiel:

find_library(CURL_LIBRARY
    NAMES curl curllib libcurl_imp curllib_static
    HINTS "${CMAKE_PREFIX_PATH}/curl/lib"
)

Für Boost würde ich dringend empfehlen, das Standardmodul FindBoost zu verwenden und die Variable BOOST_DIR so einzustellen, dass sie auf Ihre Boost-Bibliotheken verweist.

21
Silas Parker

Es gibt keine Möglichkeit, automatisch CMAKE_PREFIX_PATH in der gewünschten Weise festzulegen. Ich sehe folgende Möglichkeiten, um dieses Problem zu lösen:

  1. Legen Sie alle Bibliotheksdateien im selben Verzeichnis ab. Das heißt, include/ würde Header für alle libs, lib/-Binärdateien usw. enthalten.

  2. Setzen Sie die globale Umgebungsvariable CMAKE_PREFIX_PATH auf D:/develop/cmake/libs/libA;D:/develop/cmake/libs/libB;.... Wenn Sie CMake ausführen, wird diese Env-Variable automatisch abgerufen und mit ihrem eigenen CMAKE_PREFIX_PATH gefüllt.

  3. Schreiben Sie ein Wrapper-.bat-Skript, das den Befehl cmake mit dem Argument -D CMAKE_PREFIX_PATH=... aufrufen würde.

7
arrowd

Sie haben eine zusätzliche Schachtelungsebene . CMAKE sucht unter $CMAKE_PREFIX_PATH/include nach Kopfzeilen und $CMAKE_PREFIX_PATH/libs nach Bibliotheken. 

Aus CMAKE Dokumentation :

Für jeden Pfad in der Liste CMAKE_PREFIX_PATH prüft CMake "PATH/include" und "PATH" beim Aufruf von FIND_PATH () "PATH/bin" und "PATH" beim Aufruf von FIND_PROGRAM () und "PATH/lib" und "PATH" beim Aufruf von FIND_LIBRARY ().

4
Sameer Asal

Verwenden Sie CMAKE_PREFIX_PATH, indem Sie mehrere Pfade hinzufügen (durch Semikolons und keine Leerzeichen getrennt). Sie können es als Umgebungsvariable festlegen, um zu vermeiden, dass in Ihren cmake-Konfigurationsdateien absolute Pfade verwendet werden

Beachten Sie, dass cmake in den folgenden folgenden Ordnern Nach der Konfigurationsdatei sucht. Dabei steht der Pfad in CMAKE_PREFIX_PATH und name ist der Name der Bibliothek, nach der Sie suchen

<prefix>/                                               (W)
<prefix>/(cmake|CMake)/                                 (W)
<prefix>/<name>*/                                       (W)
<prefix>/<name>*/(cmake|CMake)/                         (W)
<prefix>/(lib/<Arch>|lib|share)/cmake/<name>*/          (U)
<prefix>/(lib/<Arch>|lib|share)/<name>*/                (U)
<prefix>/(lib/<Arch>|lib|share)/<name>*/(cmake|CMake)/  (U)

In Ihrem Fall müssen Sie die folgenden zwei Pfade zu CMAKE_PREFIX_PATH hinzufügen:

D:/develop/cmake/libs/libA;D:/develop/cmake/libB
4
Pierluigi

Ich bin auf ein ähnliches Szenario gestoßen. Ich habe es gelöst, indem ich den folgenden Code kurz vor find_library() eingefügt habe:

set(CMAKE_PREFIX_PATH /the/custom/path/to/your/lib/)

dann kann es den Speicherort der Bibliothek finden.

0
vivi