È un errore di runtime causato da Dynamic Linker
dyld: Library not loaded: @rpath/...
...
Reason: image not found
L'errore Library not loaded
con @rpath
indica che Dynamic Linker
non è possibile trovare il binario.
Controlla se è stato aggiunto il framework dinamico General -> Embedded Binaries
Verifica l' @rpath
impostazione tra consumatore (applicazione) e produttore (quadro dinamico):
- Quadro dinamico:
Build Settings -> Dynamic Library Install Name
- Applicazione:
Build Settings -> Runpath Search Paths
Build Phases -> Embed Frameworks -> Destination, Subpath
Linker dinamico
Dynamic Library Install Name(LD_DYLIB_INSTALL_NAME)
che viene utilizzato da loadable bundle
( Dynamic framework
come derivato) dove dyld
entra in gioco
Dynamic Library Install Name
- percorso del file binario (non .framework). Sì, hanno lo stesso nome, ma MyFramework.framework
è un file binario packaged bundle
con MyFramework
risorse all'interno.
Questo percorso di directory può essere assoluta o relativa (ad esempio @executable_path
, @loader_path
, @rpath
). Il percorso relativo è più preferibile perché viene modificato insieme a un'ancora utile quando si distribuisce il pacchetto in un'unica directory
percorso assoluto - Esempio di Framework1
//Framework1 Dynamic Library Install Name
/some_path/Framework1.framework/subfolder1
@executable_path
@executable_path - relativo alla voce binary -
caso d'uso esempio Framework2
: incorporare a Dynamic framework
in un'applicazione
//Application bundle(`.app` package) absolute path
/some_path/Application.аpp
//Application binary absolute path
/some_path/Application.аpp/subfolder1
//Framework2 binary absolute path
/some_path/Application.аpp/Frameworks/Framework2.framework/subfolder1
//Framework2 @executable_path == Application binary absolute path
/some_path/Application.аpp/subfolder1
//Framework2 Dynamic Library Install Name
@executable_path/../Frameworks/Framework2.framework/subfolder1
//Framework2 binary resolved absolute path by dyld
/some_path/Application.аpp/subfolder1/../Frameworks/Framework2.framework/subfolder1
/some_path/Application.аpp/Frameworks/Framework2.framework/subfolder1
@loader_path
@loader_path - relativo al bundle proprietario di questo
caso d'uso binario : framework con framework incorporato - Framework3_1 con Framework3_2 all'interno
//Framework3_1 binary absolute path
/some_path/Application.аpp/Frameworks/Framework3_1.framework/subfolder1
//Framework3_2 binary absolute path
/some_path/Application.аpp/Frameworks/Framework3_1.framework/Frameworks/Framework3_2.framework/subfolder1
//Framework3_1 @executable_path == Application binary absolute path
/some_path/Application.аpp/subfolder1
//Framework3_1 @loader_path == Framework3_1 @executable_path
/some_path/Application.аpp/subfolder1
//Framework3_2 @executable_path == Application binary absolute path
/some_path/Application.аpp/subfolder1
//Framework3_2 @loader_path == Framework3_1 binary absolute path
/some_path/Application.аpp/Frameworks/Framework3_1.framework/subfolder1
//Framework3_2 Dynamic Library Install Name
@loader_path/../Frameworks/Framework3_2.framework/subfolder1
//Framework3_2 binary resolved absolute path by dyld
/some_path/Application.аpp/Frameworks/Framework3_1.framework/subfolder1/../Frameworks/Framework3_2.framework/subfolder1
/some_path/Application.аpp/Frameworks/Framework3_1.framework/Frameworks/Framework3_2.framework/subfolder1
@rpath - Percorso di ricerca del percorso
Esempio di Framework2
In precedenza dovevamo impostare un Framework per lavorare con dyld. Non è conveniente perché lo stesso Framework non può essere utilizzato con configurazioni diverse
@rpath
è un concetto composto che si basa su parti esterne (applicazione) e nidificate (quadro dinamico):
Applicazione:
Quadro dinamico:
//Application Runpath Search Paths
@executable_path/../Frameworks
//Framework2 Dynamic Library Install Name
@rpath/Framework2.framework/subfolder1
//Framework2 binary resolved absolute path by dyld
//Framework2 @rpath is replaced by each element of Application Runpath Search Paths
@executable_path/../Frameworks/Framework2.framework/subfolder1
/some_path/Application.аpp/Frameworks/Framework2.framework/subfolder1
* ../
- vai al genitore della directory corrente
otool
- strumento di visualizzazione dei file oggetto
//-L print shared libraries used
//Application otool -L
@rpath/Framework2.framework/subfolder1/Framework2
//Framework2 otool -L
@rpath/Framework2.framework/subfolder1/Framework2
//-l print the load commands
//Application otool -l
LC_LOAD_DYLIB
@rpath/Framework2.framework/subfolder1/Framework2
LC_RPATH
@executable_path/../Frameworks
//Framework2 otool -l
LC_ID_DYLIB
@rpath/Framework2.framework/subfolder1/Framework2
install_name_tool
cambia i nomi di installazione dinamici della libreria condivisa usando -rpath
CocoaPods
usa use_frameworks!
[Informazioni] per regolare aDynamic Linker
[Vocabolario]
Link Binary with Libraries
e in qualche modo Xcode sa copiarli nel bundle dell'app, mentre per i framework personalizzati questo semplicemente non accade.