• Non ci sono risultati.

nitore, cioè Oracle o OpenJDK). Avendo compilato più versioni di Android, ho dovuto installare più versioni di Java e selezionare quella corretta prima di ogni compilazione, tramite i comandi del terminale update-alternatives –config java e update-alternatives –config javac. Le versioni sono:

– 7 per compilare l’ultima versione su branch master di git (Lollipop richiede necessariamente Open JDK 7);

– 6 per compilare versioni da Gingerbread a KitKat (KitKat richiede neces- sariamente Oracle JDK 6);

– 5 per compilare versioni da Cupcake a Froyo.

• Una connessione ad internet estremamente veloce, infatti scaricare il sorgente di Android ha richiesto diverse ore, anche con una fibra ottica a 1MB/s ed un’intera notte non è stata sufficiente).

• Il processo di compilazione di Android richiede alcune ore anche su macchine di ultima generazione, quindi ho usato un MacBook Pro (mid 2012) modificato con 16GB di RAM Corsair Vengeance DDR3 1600 MHz, Intel Core i7 2,3 GHz (Turbo Boost 3,3 GHz) quad core, disco da 750 GB 7200 RPM Seagate Momentus XT ibrido con 8GB di SSD. Nonostante queste specifiche, nella macchina virtuale, la compilazione di Lollipop ha richiesto 2 ore e 40 minuti. • Evitare qualunque tipo di aggiornamento di Ubuntu. Nel mio caso, l’instal-

lazione di alcuni aggiornamenti ha reso impossibile la compilazione ed è sta- to necessario ripristinare 200GB di macchina virtuale da un disco esterno di backup, con notevoli difficoltà.

• Android NDK 10d 64 bit [33] o superiore per la compilazione (nonostante non sia obbligatorio, dato che il sorgente di Android contiene già il toolchain [92] necessario, in tutta la procedura ho utilizzato quello incluso nell’NDK, perché mi ha dato meno problemi).

4.4 Inizializzare l’ambiente di sviluppo

Prima di procedere, ho aggiornato Ubuntu 14.04.2 via terminale con i comandi nell’Algoritmo 4.1 e ho disattivato gli aggiornamenti automatici per evitare problemi in futuro.

Algoritmo 4.1 Aggiornare Ubuntu $ sudo apt-get update $ sudo apt-get upgrade

4. Architettura, kernel e Build System di Android

4.4.1 Installare Java, Android NDK e le dipendenze

Mi sono assicurato di rimuovere tutte le versioni di Java da Ubuntu e dopo il riavvio, ho eseguito l’installazione tramite linea di comando come nell’Algoritmo 4.2 scegliendo la versione da utilizzare con gli ultimi due comandi update-alternatives. Algoritmo 4.2 Installare Java 7 e 6 e scegliere la versione da usare

$ sudo apt-get install openjdk-7-jdk

$ sudo add-apt-repository ppa:webupd8team/java $ sudo apt-get update

$ sudo apt-get install oracle-java6-installer $ sudo update-alternatives --config java $ sudo update-alternatives --config javac

La guida ufficiale di Google per Ubuntu 14.04 fornisce già i comandi da utilizzare per installare le dipendenze (vedi Algoritmo 4.3). Però, non specifica che bisogna installare anche altri programmi perché le procedure di compilazione possano avere successo. Quindi, in base alla mia esperienza ho aggiunto all’Algoritmo 4.3 quattro righe con altri software utili a tale scopo. Dopodiché, ho installato Android NDK, cioè ho scaricato NDK Linux x64 da [33] ed eseguito i comandi nell’Algoritmo 4.4 dalla mia cartella home. In questo lavoro di tesi ho utilizzato l’ultima versione disponibile, cioè la r10d.

Algoritmo 4.3 Installare le dipendenze in Ubuntu

$ sudo apt-get install bison g++-multilib git $ sudo apt-get install gperf libxml2-utils $ sudo apt-get install libncurses5-dev

$ sudo apt-get install libc6-i386 lib32stdc++6 $ sudo apt-get install lib32gcc1 lib32ncurses5 $ sudo apt-get install zlib1g lib32z1

Algoritmo 4.4 Installare Android NDK $ mkdir ~/androidNdk

$ cd ~/Scaricati

$ mv android-ndk-r10d-linux-x86_64.bin

../androidNdk/android-ndk-r10d-linux-x86_64.bin $ cd ../androidNdk

$ chmod a+x android-ndk-r10d-linux-x86_64.bin $ ./android-ndk-r10d-linux-x86_64.bin

4.4. Inizializzare l’ambiente di sviluppo

4.4.2 Configurare l’accesso USB in Ubuntu

Per configurare l’accesso USB in Ubuntu, l’approccio raccomandato da Google è di creare o modificare il file /etc/udev/rules.d/51-android.rules accedendo coi privilegi di root in Ubuntu. Il problema è che la guida ufficiale è per Ubuntu 8.04 e 10.04, mentre ora il sistema operativo consigliato per lo sviluppo è Ubuntu 14.04. Quindi ho utilizzato il file 51-android.rules nell’appendice A.

4.4.3 Variabili d’ambiente e CChace

I dispositivi Android non hanno la stessa architettura di un normale PC, infatti si basano principalmente su ARM. Quindi, le istruzioni compilate devono essere per ARM e non per processori Intel o AMD.

Quando su una macchina con una certa architettura si compila un programma per un’altra, si dice “cross-compilazione”. Non è da confondere con la “compilazione source-to-source”, perché in quest’ultima è il codice sorgente ad essere tradotto, men- tre nella cross-compilazione è il codice binario. Per fortuna, Google fornisce tutti i programmi per svolgere questa procedura, ma è necessaria un’accurata configura- zione. Spesso, il principale errore nella compilazione di Android è l’uso di variabili d’ambiente sbagliate. Ciò comporta errori, che potrebbero non essere visibili all’i- nizio del processo, ma solo in seguito, interrompendolo e quindi perdendo tempo. In questo lavoro di tesi mi sono concentrato su Android 4.4.4 e 5.0.1 per Nexus 4 e Nexus 5, cioè architetture ARM a 32 bit molto diffuse.

Per impostare le variabili d’ambiente, ho dovuto visualizzare i file nascosti in Ubuntu ed aggiungere le righe nell’Algoritmo 4.5 al file ~/.bashrc (se non presente crearne uno). Questa operazione permetterà la cross-compilazione del kernel. La pri- ma riga specifica l’architettura verso cui cross-compilare, che nel mio caso è ARM [7], la seconda la sotto-architettura, cioè sempre ARM ed infine il parametro da passare per cross-compilare, cioè il nome del toolchain scelto, seguito da “-”. Dopodiché, ho modificato il file ~/.profile (eventualmente crearlo) aggiungendo le righe nell’Algo- ritmo 4.6. Da notare che il primo export aggiunge alla variabile d’ambiente PATH il percorso del toolchain di NDK, mentre le altre configurano la Ccache. Modificati questi due file, ho riavviato il sistema operativo per applicare le modifiche.

Algoritmo 4.5 Configurazione variabili d’ambiente in .bashrc export ARCH=arm

export SUBARCH=arm

export CROSS_COMPILE=arm-linux-androideabi-

Quando inizia la compilazione di Android, sono compilati molti file C e C++. Per migliorare le performance in caso di ricompilazioni, modifiche, passaggi tra diver- se versioni di Android, consiglio di attivare la Ccache [18] con USE_CCACHE=1,

4. Architettura, kernel e Build System di Android

Algoritmo 4.6 Configurazione variabili d’ambiente in .profile export PATH=$PATH:~/androidNdk/android-ndk-r10d/

toolchains/arm-linux-androideabi-4.6/ prebuilt/linux-x86_64/bin

#cache per compilare android export USE_CCACHE=1

export CCACHE_DIR=~/androidsource/aosp-main/cache/.ccache

e la cartella della Ccache nella variabile CCACHE_DIR. Ccache è una cache del compilatore C/C++/Objective-C/Objective-C++ che rendere più veloce la ricom- pilazione, poiché memorizza i file in una cartella sul disco. Ovviamente, al primo avvio sarà vuota e ogni operazione sarà un miss, ma successive ricompilazione pote- ranno a degli hit facendo risparmiare tempo. Ccache è sicura perché fornisce sempre lo stesso output, cioè produce sempre lo stesso file oggetto. Purtroppo è limitata ai file C/C++ di Android e non a quelli Java, ciò vuol dire che il framework Android e tutte le app predefinite devono essere ricompilate ogni volta. In realtà, l’uso di que- sta cache è comunque vantaggioso, perché Android è costituito da una consistente parte in C/C++ e grazie a Ccache si può risparmiare quasi un’ora.