2012-04-30 9 views
9

Ho eseguito il cross-compiling di alcuni strumenti Linux (e alcuni del mio codice C) su Android e una delle sfide che devo affrontare è che la libc di Android ha alcuni componenti mancanti/spogliati e Finisco per aggiustare il mio codice per farlo funzionare con la libc di Android (ad esempio un problema come questo http://credentiality2.blogspot.com/2010/08/compile-ncurses-for-android.html)Collegamento statico Android vs collegamento dinamico contro glibc

Q1: Come faccio a fare un collegamento statico con glibc (e altre dipendenze) durante la compilazione incrociata con la toolchain arm (o ndk-build)?

Q2: È consigliabile collegare staticamente glibc per i binari per Android? Devo aspettarmi che qualcosa si rompa se inizio a linkare staticamente? Ci sono problemi di prestazioni/memoria?

ho capito la maggior parte dei pro e dei contro di statica e il collegamento dinamico da qui - C++ application - should I use static or dynamic linking for the libraries? e Static linking vs dynamic linking

Quindi vorrei sapere se devo essere linkare staticamente glibc per Android, quando i binari cross-compilazione.

risposta

5

Prima una piccola nota sulla libc. La libc di Android è la libica di Bionic (https://github.com/android/platform_bionic/) anziché GNU libc (glibc). Quindi la libc contenuta nell'NDK è Bionic, così come la libc disponibile sui dispositivi Android.

Per quanto riguarda glibc, è possibile costruirlo con NDK. Tuttavia, il nome si scontrerà con la libc di sistema quando installata sui dispositivi Android. Nota che questo è solo se si va a costruire una libreria dinamica. Se si crea GNU libc come libreria statica, l'intero problema sopra riportato viene aggirato, poiché non è mai necessario installare una libreria statica.

Ora rispondere alle vostre domande:

  1. Q1: Se si sta costruendo la glibc utilizzando l'NDK, poi l'Android.mk utilizza la BUILD_STATIC_LIBRARY variabile per costruire librerie statiche. Tuttavia, se non usi NDK, probabilmente avrai bisogno di entrare in un sacco di mal di testa (non so quanto). Non posso dirti di più su questo perché non ho provato una build di glibc, né statica né dinamica. Inoltre, sembra che il collegamento statico con glibc sia altamente scoraggiato, almeno per le piattaforme non mobili.

  2. Da un punto di vista della rottura, non vi è alcuna differenza tra collegamento statico e collegamento dinamico. Da un punto di vista di avvio, un eseguibile statico si avvia più rapidamente mentre il passaggio di caricamento delle librerie dinamiche non è necessario. Non c'è penalità di memoria o di velocità di esecuzione in eseguibili collegati statici o dinamici. I requisiti di archiviazione su disco sono maggiori per eseguibili statici.

Per quanto riguarda i problemi con la funzionalità libc bionico mancante, è possibile utilizzare il metodo utilizzato dalla maggior parte dei software GNU, che è, di fornire la propria implementazione di una funzione nel caso in cui manca dalle librerie di sistema. Ho compilato file-5.11, GNU make 3.82, diffutils-2.8 per Android passando gli strumenti NDK/include/libs agli autotools (./configure ...). Sembra che questi programmi contengano implementazioni della maggior parte della funzione di libreria non core, nel caso in cui le librerie standard non li forniscano (in questo caso Bionic).

Nota: cercherò di creare un glibc statico e aggiornare la risposta come e quando riesco/non riesco.

+1

Non si tratta solo dell'utilizzo su disco, ma anche dell'utilizzo in memoria. Quando si collegano le librerie jni dell'app Android contro Bionic libc, si eredita l'accesso condiviso di sola lettura a una copia già in memoria. –

+0

Potrebbe indicarmi la vostra fonte di informazioni su questo? Voglio saperne di più, ma non riesco a trovare nulla su questo. So che se le librerie contengono dati, i dati non sembrano condivisi tra i processi, tuttavia potrebbe trattarsi solo di replica copy-on-write delle pagine di memoria se il codice della libreria modifica le sue variabili di dati interne. – Samveen

+0

Credo che ChrisStratton menzioni - il caso della libc collegata staticamente. Ogni processo finirebbe con la sua copia intera di TUTTE le sezioni della stessa libreria. Con il collegamento dinamico, sei corretto @Samveen – Tuxdude

2

Se si utilizzerà glibc anziché bionico, può valere la pena di utilizzare la toolchain di una generazione (generazione di kernel compatibile) arm-linux piuttosto che l'ndk.Questo sarebbe particolarmente vero se si stesse generando un eseguibile da riga di comando. (Le persone hanno spinto sperimentalmente ambienti chroot debian su dispositivi Android fino al G1)

Per un jni sub (che rimane l'unico veicolo ufficialmente approvato per il codice dell'applicazione nativo) potrebbe diventare un po '"interessante" con entrambi toolchain, dato che verrà eseguito in un processo che ha già mappato e sta facendo un uso continuo della libc bionica per supportare la VM di Dalvik. Presumibilmente, se si collegano staticamente le dipendenze della libreria, non si incontrano conflitti di nomi, ma mi aspetto che qualunque percorso tu scelga sarà un'esperienza di apprendimento sul funzionamento interno - non che sia necessariamente una cosa negativa.

Devi avere ncurses? Ho creato con successo maledizioni per Android con il ndk una volta. Considera anche se il programma sta sfruttando seriamente questo (cioè stai effettivamente facendo una sostanziale formattazione del testo?), O semplicemente usandolo per qualche piccola cosa perché si supponeva che fosse disponibile sui sistemi di destinazione?

+0

Potresti venire a rispondere a questa domanda: http://stackoverflow.com/questions/10798357/want-to-compile-native-android-binary-i-can- run-in-terminal-on-the-phone –