Jak sprawić, by CMake połączył plik wykonywalny z zewnętrzną biblioteką udostępnioną, która nie jest skompilowana w ramach tego samego projektu CMake?
Samo działanie target_link_libraries(GLBall ${CMAKE_BINARY_DIR}/res/mylib.so)
daje błąd
make[2]: *** No rule to make target `res/mylib.so', needed by `GLBall'. Stop.
make[1]: *** [CMakeFiles/GLBall.dir/all] Error 2
make: *** [all] Error 2
(GLBall is the executable)
po skopiowaniu biblioteki do katalogu binarnego bin/res
.
Próbowałem użyć find_library(RESULT mylib.so PATHS ${CMAKE_BINARY_DIR}/res)
Co się nie udaje RESULT-NOTFOUND
.
link_directories
, nawet w jego własnej dokumentacji. Myślę, że byłoby lepiej, gdybyśmy rozwiązali problem zawartyfind_library
w pierwotnym pytaniu lub skorzystali z rozwiązania @ Andre.find_library
tej ścieżki i używać jej zamiast sztywnego kodowania, por. moja odpowiedź .Odpowiedź arrowdodger jest poprawna i często preferowana. Chciałbym po prostu dodać alternatywę do jego odpowiedzi:
Zamiast katalogu dowiązań można dodać „zaimportowaną” bibliotekę docelową. Coś jak:
A następnie połącz tak, jakby ta biblioteka została zbudowana przez twój projekt:
Takie podejście zapewniłoby nieco większą elastyczność: spójrz na polecenie add_library () i wiele właściwości docelowych związanych z importowanymi bibliotekami .
Nie wiem, czy to rozwiąże problem ze „zaktualizowanymi wersjami bibliotek”.
źródło
add_library( mylib SHARED IMPORTED )
lub pojawi sięadd_library called with IMPORTED argument but no library type
błądIMPORTED_LOCATION
nawiasie otwierającym jest źleGLOBAL
po,IMPORTED
jeśli chcesz uzyskać dostęp do zaimportowanej biblioteki w katalogach powyżej bieżącego:add_library(breakpad STATIC IMPORTED GLOBAL)
Zakładam, że chcesz utworzyć link do biblioteki o nazwie foo , jej nazwa to zwykle coś, co łączy
foo.dll
lublibfoo.so
.1. Znajdź bibliotekę
Musisz znaleźć bibliotekę. To dobry pomysł, nawet jeśli znasz ścieżkę do swojej biblioteki. CMake wyświetli błąd, jeśli biblioteka zniknie lub otrzyma nową nazwę. Pomaga to wcześnie wykryć błąd i wyjaśnić użytkownikowi (może samemu), co powoduje problem.
Aby znaleźć bibliotekę foo i zapisać
FOO_LIB
używaną ścieżkęCMake sam zorientuje się, jaka jest rzeczywista nazwa pliku. Sprawdza typowe miejsca takie jak
/usr/lib
,/usr/lib64
i ścieżkamiPATH
.Znasz już lokalizację swojej biblioteki. Dodaj go do
CMAKE_PREFIX_PATH
wywołania CMake, a następnie CMake będzie szukał Twojej biblioteki również w przekazanych ścieżkach.Czasami trzeba dodać wskazówki lub sufiksy ścieżek, szczegółowe informacje można znaleźć w dokumentacji: https://cmake.org/cmake/help/latest/command/find_library.html
2. Połącz bibliotekę Od 1. masz pełną nazwę biblioteki w
FOO_LIB
. Używasz tego, aby połączyć bibliotekę z celem,GLBall
jak wNależy dodać
PRIVATE
,PUBLIC
lubINTERFACE
po docelowej, cf. dokumentacja: https://cmake.org/cmake/help/latest/command/target_link_libraries.htmlJeśli nie dodasz jednego z tych specyfikatorów widoczności, będzie on zachowywał się tak jak
PRIVATE
lubPUBLIC
, w zależności od wersji CMake i ustawionych zasad.3. Dodaj dołączenia (ten krok może nie być obowiązkowy).
Jeśli chcesz dołączyć również pliki nagłówkowe, użyj funkcji
find_path
podobnej dofind_library
i wyszukaj plik nagłówkowy. Następnie dodaj katalog include ztarget_include_directories
podobnym dotarget_link_libraries
.Dokumentacja: https://cmake.org/cmake/help/latest/command/find_path.html i https://cmake.org/cmake/help/latest/command/target_include_directories.html
Jeśli jest dostępne dla oprogramowania zewnętrznego, możesz wymienić
find_library
ifind_path
przezfind_package
.źródło
find_package
jest o wiele prostsze niż wykonanie tych czynnościtarget_link_libraries(mylib "${FOO_LIB}")
? Cel jestmylib
zamiast prawdziwego celuGLBall
,? nie ma dla mnie większego sensuJeszcze jedna alternatywa, w przypadku gdy pracujesz z Appstore, potrzebujesz „Entitlements” i jako takiej musisz połączyć się z Apple-Framework.
Aby uprawnienia działały (np. GameCenter), musisz mieć krok kompilacji „Link Binary with Libraries”, a następnie link do „GameKit.framework”. CMake „wstrzykuje” biblioteki na „niskim poziomie” do wiersza poleceń, stąd Xcode tak naprawdę nie wie o tym i jako taki nie włączysz GameKit na ekranie Możliwości.
Jednym ze sposobów używania CMake i posiadania „Link with Binaries” -buildstep jest wygenerowanie xcodeproj za pomocą CMake, a następnie użycie 'sed' do 'wyszukiwania i zamiany' oraz dodanie GameKit tak, jak lubi to XCode ...
Skrypt wygląda następująco (dla Xcode 6.3.1).
zapisz to na „gamecenter.sed”, a następnie „zastosuj” w ten sposób (zmieni to twój xcodeproj!)
Być może będziesz musiał zmienić polecenia skryptów, aby dopasować je do swoich potrzeb.
Ostrzeżenie: prawdopodobnie zepsuje się z inną wersją Xcode, ponieważ format projektu może się zmienić, unikalny numer (zakodowany na stałe) może nie być unikalny - i ogólnie rozwiązania innych osób są lepsze - więc chyba że musisz wspierać Appstore + Uprawnienia (i automatyczne kompilacje), nie rób tego.
To jest błąd CMake, zobacz http://cmake.org/Bug/view.php?id=14185 i http://gitlab.kitware.com/cmake/cmake/issues/14185
źródło