CMake link do zewnętrznej biblioteki
Jak zmusić CMake do połączenia pliku wykonywalnego z zewnętrzną biblioteką współdzieloną, która nie jest zbudowana w ramach tego samego projektu CMake?
Samo robienie 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)
, która nie powiodła się z RESULT-NOTFOUND
.
4 answers
Ustaw najpierw ścieżkę wyszukiwania bibliotek:
LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/res)
And then just do
TARGET_LINK_LIBRARIES(GLBall mylib)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-08 08:59:16
Odpowiedź Arrowdodgera jest poprawna i preferowana przy wielu okazjach. Chciałbym po prostu dodać alternatywę dla jego odpowiedzi:
Możesz dodać" zaimportowany " cel biblioteki zamiast katalogu z linkami. Coś w stylu:
# Your-external "mylib", add GLOBAL if the imported library is located in directories above the current.
add_library( mylib SHARED IMPORTED )
# You can define two import-locations: one for debug and one for release.
set_target_properties( mylib PROPERTIES IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/res/mylib.so )
A następnie Linkuj tak, jakby ta biblioteka została zbudowana przez twój projekt:
TARGET_LINK_LIBRARIES(GLBall mylib)
Takie podejście dałoby ci trochę więcej elastyczności: spójrz na polecenie add_library( ) i wiele właściwości docelowych związanych z importowanym biblioteki .
Nie wiem, czy to rozwiąże twój problem z "zaktualizowanymi wersjami libs".
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-07 16:21:50
Zakładam, że chcesz połączyć się z biblioteką o nazwie foo , jej nazwa pliku to zwykle coś link foo.dll
lub libfoo.so
.
1. Znajdź bibliotekę
Musisz znaleźć bibliotekę. To dobry pomysł, nawet jeśli znasz ścieżkę do swojej biblioteki. CMake spowoduje 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ć ścieżkę w FOO_LIB
użycie
find_library(FOO_LIB foo)
CMake sam się zorientuje, jaka jest rzeczywista nazwa pliku. Sprawdza zwykłe miejsca jak /usr/lib
, /usr/lib64
i ścieżek w PATH
.
CMAKE_PREFIX_PATH
po wywołaniu CMake, wtedy CMake będzie również szukał Twojej biblioteki w przekazywanych ścieżkach.
Czasami musisz dodać podpowiedzi lub przyrostki ścieżek, zobacz dokumentację szczegóły: https://cmake.org/cmake/help/latest/command/find_library.html
2. Połącz bibliotekę
Od 1. pełna nazwa biblioteki znajduje się w FOO_LIB
. Możesz użyć tego, aby połączyć bibliotekę z docelowym mylib
jak w
target_link_libraries(mylib "${FOO_LIB}")
Możesz dodać PRIVATE
, PUBLIC
, lub INTERFACE
przed biblioteką, por. dokumentacja:
https://cmake.org/cmake/help/latest/command/target_link_libraries.html
3. Dodaj includes (ten krok może nie być obowiązkowe.)
Jeśli chcesz również dołączyć pliki nagłówkowe, użyj find_path
podobnego do find_library
i wyszukaj plik nagłówkowy. Następnie Dodaj katalog include z target_include_directories
podobny do target_link_libraries
.
Dokumentacja: https://cmake.org/cmake/help/latest/command/find_path.html oraz https://cmake.org/cmake/help/latest/command/target_include_directories.html
Jeśli jest dostępny dla zewnętrznego oprogramowania, możesz zastąpić find_library
i find_path
przez find_package
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-30 12:23:56
Jeszcze jedna alternatywa, w przypadku, gdy pracujesz z Appstore, potrzebują "uprawnień" i jako takie muszą połączyć się z Apple-Framework.
Dla uprawnień do pracy (np. GameCenter) musisz mieć "Link Binary with Libraries"-buildstep, a następnie link z "GameKit.framework". CMake "wstrzykuje" biblioteki na "niskim poziomie" do wiersza poleceń, dlatego Xcode nie wie o tym naprawdę i jako taki będziesz Nie włączyć GameKit w Ekran możliwości.
Jednym ze sposobów użycia CMake i posiadania "łącza z binariami"-buildstep jest wygenerowanie xcodeproj za pomocą CMake, a następnie użycie ' sed ' do 'search & replace' i dodanie GameKit w sposób, w jaki Xcode go lubi...
Skrypt wygląda tak (dla Xcode 6.3.1).
s#\/\* Begin PBXBuildFile section \*\/#\/\* Begin PBXBuildFile section \*\/\
26B12AA11C10544700A9A2BA \/\* GameKit.framework in Frameworks \*\/ = {isa = PBXBuildFile; fileRef = 26B12AA01C10544700A9A2BA \/\* GameKit.framework xxx\*\/; };#g
s#\/\* Begin PBXFileReference section \*\/#\/\* Begin PBXFileReference section \*\/\
26B12AA01C10544700A9A2BA \/\* GameKit.framework xxx\*\/ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameKit.framework; path = System\/Library\/Frameworks\/GameKit.framework; sourceTree = SDKROOT; };#g
s#\/\* End PBXFileReference section \*\/#\/\* End PBXFileReference section \*\/\
\
\/\* Begin PBXFrameworksBuildPhase section \*\/\
26B12A9F1C10543B00A9A2BA \/\* Frameworks \*\/ = {\
isa = PBXFrameworksBuildPhase;\
buildActionMask = 2147483647;\
files = (\
26B12AA11C10544700A9A2BA \/\* GameKit.framework in Frameworks xxx\*\/,\
);\
runOnlyForDeploymentPostprocessing = 0;\
};\
\/\* End PBXFrameworksBuildPhase section \*\/\
#g
s#\/\* CMake PostBuild Rules \*\/,#\/\* CMake PostBuild Rules \*\/,\
26B12A9F1C10543B00A9A2BA \/\* Frameworks xxx\*\/,#g
s#\/\* Products \*\/,#\/\* Products \*\/,\
26B12AA01C10544700A9A2BA \/\* GameKit.framework xxx\*\/,#g
Zapisz to do " gamecenter.sed", a następnie "zastosować" to tak ( zmienia XCODEPROJ! )
sed -i.pbxprojbak -f gamecenter.sed myproject.xcodeproj/project.pbxproj
Być może będziesz musiał zmienić skrypt-polecenia, aby dopasować się do Twoich potrzeb.
Warning: it ' s prawdopodobnie zerwać z różnych wersji Xcode jako format projektu może się zmienić, (hardcoded) unikalny numer może nie naprawdę przez unikalne - i ogólnie rozwiązania przez innych ludzi są lepsze - więc chyba że trzeba wspierać Appstore + uprawnienia ( i zautomatyzowanych kompilacji), 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-15 19:34:32