Warum ist CMake so ausgelegt, dass es entfernt-runtime-Pfad bei der Installation
Baute ich mein shared library(benutze ich eine lib die Berechnung der fibonacci-Zahl für Beispiel) für mich und möchte es in meinem anderen c++ - Projekt, gebaut von CMake
Sagen wir, die shared-Bibliothek und-Header befindet sich in /path/to/my/lib
, die gemeinsam genutzte Bibliothek libfib.so
ist in /path/to/my/lib/lib
und der header fib.h
ist in /path/to/my/lib/include
und mein eigenes Projekt befindet sich in /path/to/my/project
Hier ist mein original CMakeLists.txt
:
cmake_minimum_required(VERSION 3.2)
project(learn-lib)
set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
set(FIB_INCLUDE "${FIB_PREFIX}/include")
set(FIB_LIB "${FIB_PREFIX}/lib")
set(EXE mybin)
include_directories(${FIB_INCLUDE})
link_directories(${FIB_LIB})
add_executable(${EXE} main.cpp)
target_link_libraries(${EXE} fib)
install(TARGETS ${EXE} RUNTIME DESTINATION bin)
Und ich nutze dieses Skript zu erstellen und installieren Sie mein Projekt:
mkdir -p build_dir
cd build_dir
cmake -DFIB_PREFIX=/path/to/my/lib \
-DCMAKE_INSTALL_PREFIX=/path/to/my/project \
..
make
make install
cd ..
Nun, nach dem ausführen des install-Skript, habe ich zwei Dateien, eine in build_dir
man in das Installationsverzeichnis path/to/my/project/bin
, wenn das Programm läuft in build_dir
ist alles in Ordnung, aber beim ausführen des installierten Programms, erhalte ich:
./bin/mybin: error while loading shared libraries: libfib.also: nicht öffnen können shared object-Datei: Keine solche Datei oder das Verzeichnis
Nach einiger Suche bei google und stackoverflow, ich wusste, dass es scheint, dass CMake
entfernt der Laufzeit-Suchpfad, gebunden, um die ausführbare Datei beim Bau. Ich weiß jetzt zwei Möglichkeiten, um ihn herum:
- Fügen Sie den library-Pfad, wo
libfib.so
sucht, um die UmgebungsvariableLD_LIBRARY_PATH
- Hinzufügen
set_target_properties(${EXE} PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE)
in meineCMakeLists.txt
So, meine Fragen sind:
- Warum ist
CMake
so ausgelegt? Bei der Installation, warum sollte es entfernen runtime Pfad von ausführbaren Dateien, anstatt nur das kopieren der integrierten ausführbaren Dateien, die zum installieren ein Ziel oder was auch immer halten Sie die link-Pfad für das zu installierende Programm? - Welcher Weg ist der beste-Praxis(oder gibt es eine best practice) um dieses problem zu beseitigen? Um die Umgebung oder das hinzufügen
set_target_properties(...)
inCMakeLists.txt
?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Möchten Sie vielleicht einen Blick in CMake ist RPATH handling Einstellungen
Dieses Zitat in allem scheint relevant für Ihre missliche Lage:
Können Sie die RPATH, das für Binärdateien installiert und mit der
CMAKE_INSTALL_RPATH
variable, zum Beispiel:- und Sie können auch deaktivieren Sie die RPATH-stripping während der installation:
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
nachadd_executable(${EXE} main.cpp)
, cmake, der immer noch Streifen die runtime-Pfad, währendset_target_properties(${EXE} PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE)
würde immer funktionieren, unabhängig Ihrer position inCMakeLists.txt
Ich will einfach nur Antwort Frage 1. Der Grund, warum dies geschehen ist. Alex schon gepostet, eine Lösung wie man dieses Verhalten ändern.
Der Grund ist, dass wenn du es baust Sie wirklich wollen, verwenden Sie die Bibliotheken, die das build-Skript sah auf Ihre Maschine. Wenn Sie bauen einen ganzen Stapel von Bibliotheken für Ihre Anwendung, die Sie wollen keinen Fehler, dass Sie nicht wieder durch die Bibliothek. Daher macht es Sinn, die volle rpath in die Bibliothek. Auch Sie bewegen Ihre Anwendung um zwischen Kompilation und wenn es Debuggen und ausführen.
Aber, wenn installiert, der übliche Fall in der unix-Welt, wurde für die gemeinsame Nutzung der /usr/lib und /usr/local/lib-Verzeichnisse. Sie sind in der Regel abgeholt (es sei denn, LD_LIBRARY_PATH benutzt wird) und das ist normalerweise das, was Sie wollen.
Wie Sie sehen, durch meine Formulierung, das ist alles ein Durcheinander, weil es so viele implizite Entscheidungen, wie organisieren Sie Ihre build-und deployment. Es ist einer der Gründe, warum der Begriff "DLL-Hölle" einmal nur beliebt auf Windows umgestellt, Unix, wenn es wurde mehr weit verbreitet. Es gibt keine technische Lösung, da es kein technisches problem (das Teil ist gelöst). Seine ein organisatorisches problem, und CMake hat zu entscheiden über das Aroma unterstützt es auf einer Plattform standardmäßig. Und IMHO haben Sie mit bedacht gewählt.