Collegamento CMake alla libreria esterna

Come ottenere CMake per colbind un eseguibile a una libreria condivisa esterna che non è stata creata all’interno dello stesso progetto CMake?

Basta fare target_link_libraries(GLBall ${CMAKE_BINARY_DIR}/res/mylib.so) dà l’errore

 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) 

dopo ho copiato la libreria in bin/res .

Ho provato a usare find_library(RESULT mylib.so PATHS ${CMAKE_BINARY_DIR}/res)

Che fallisce con RESULT-NOTFOUND .

Imposta prima il percorso di ricerca delle librerie:

 LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/res) 

E poi basta

 TARGET_LINK_LIBRARIES(GLBall mylib) 

La risposta di arrowdodger è corretta e preferita in molte occasioni. Vorrei semplicemente aggiungere un’alternativa alla sua risposta:

È ansible aggiungere una destinazione della libreria “importata” anziché una directory di collegamento. Qualcosa di simile a:

 # 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 ) 

Quindi collega come se questa libreria fosse stata creata dal tuo progetto:

 TARGET_LINK_LIBRARIES(GLBall mylib) 

Un simile approccio ti darebbe un po ‘più di flessibilità: dai un’occhiata al comando add_library () e alle molte proprietà di destinazione relative alle librerie importate .

Non so se questo risolverà il tuo problema con “versioni aggiornate di libs”.

Presumo che tu voglia colbind a una libreria chiamata foo , il suo nome file è solitamente qualcosa link foo.dll o libfoo.so .

1. Trova la biblioteca
Devi trovare la biblioteca. Questa è una buona idea, anche se conosci il percorso della tua biblioteca. CMake genererà un errore se la libreria sparirà o avrà un nuovo nome. Ciò aiuta a individuare precocemente l’errore ea chiarire all’utente (si può) ciò che causa un problema.
Per trovare una libreria foo e memorizzare il percorso in FOO_LIB utilizzare

  find_library(FOO_LIB foo) 

CMake scoprirà da solo in che modo si tratta del vero nome del file. Controlla i soliti posti come /usr/lib , /usr/lib64 e i percorsi in PATH .

Conosci già la posizione del tuo grimorio. Aggiungilo a CMAKE_PREFIX_PATH quando chiami CMake, quindi CMake cercherà anche la tua libreria nei percorsi passati.

A volte è necessario aggiungere suggerimenti o suffissi del percorso, consultare la documentazione per i dettagli: https://cmake.org/cmake/help/latest/command/find_library.html

2. Collega la libreria Da 1. hai il nome completo della libreria in FOO_LIB . Lo usi per colbind la libreria al mylib target mylib come in

  target_link_libraries(mylib "${FOO_LIB}") 

Potresti voler aggiungere PRIVATE , PUBLIC o INTERFACE davanti alla libreria, cf. la documentazione: https://cmake.org/cmake/help/latest/command/target_link_libraries.html

3. Aggiungi include (questo passaggio potrebbe non essere obbligatorio).
Se si desidera includere anche i file di intestazione, utilizzare find_path simile a find_library e cercare un file di intestazione. Quindi aggiungi la directory include con target_include_directories simile a target_link_libraries .

Documentazione: https://cmake.org/cmake/help/latest/command/find_path.html e https://cmake.org/cmake/help/latest/command/target_include_directories.html

Se disponibile per il software esterno, è ansible sostituire find_library e find_path con find_package .

Un’altra alternativa, nel caso si stia lavorando con l’Appstore, richiede “Entitlement” e come tale è necessario collegarsi a un framework Apple.

Affinché gli Entitlement funzionino (ad es. GameCenter) è necessario avere un “Link Binary with Libraries” -buildstep e quindi un collegamento con “GameKit.framework”. CMake “inietta” le librerie su un “livello basso” nella riga di comando, quindi Xcode non ne è a conoscenza, e come tale non abiliterà GameKit abilitato nella schermata delle capacità.

Un modo per usare CMake e avere un “Link with Binaries” -buildstep è generare xcodeproj con CMake, quindi usare ‘sed’ in ‘search & replace’ e aggiungere il GameKit nel modo in cui piace a XCode …

Lo script ha questo aspetto (per 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 

salva questo in “gamecenter.sed” e poi “applica” in questo modo (cambia il tuo xcodeproj!)

 sed -i.pbxprojbak -f gamecenter.sed myproject.xcodeproj/project.pbxproj 

Potrebbe essere necessario modificare i comandi di script in base alle proprie esigenze.

Attenzione: è probabile che si rompa con una versione di Xcode diversa in quanto il formato di progetto potrebbe cambiare, il numero univoco (hardcoded) potrebbe non essere davvero unico – e generalmente le soluzioni di altre persone sono migliori – quindi a meno che non sia necessario Supportare l’AppStore + Diritti (e build automatizzati), non farlo.

Questo è un bug di CMake, vedi http://cmake.org/Bug/view.php?id=14185 e http://gitlab.kitware.com/cmake/cmake/issues/14185