Manuale di sviluppo applicazioni AROS
Index
Avvertenza
L'ultima revisione maggiore di questa guida è iniziata a Novembre 2006.
I cambiamenti al build system successivi a questa data non impattano su
questa guida.
Nota
NOTA DEL TRADUTTORE: Questo capitolo del manuale è stato parecchio
difficoltoso da tradurre, alcuni termini sono praticamente
intraducibili in Italiano. Li ho lasciati così come sono per mantenerne
l'espressività e la correttezza.
TAD
Ci si potrebbe chiedere perchè AROS necessiti di un build system. La
risposta è che esso semplifica il building di binari più complessi e riduce
molto del lavoro manuale che, altrimenti, sarebbe necessario per compilare,
linkare e copiare i file. Inoltre, il sistema crea un albero di dipendenze su
un grosso albero dei sorgenti e creerà i binari nel giusto ordine in modo tale
che tutte le dipendenze siano soddisfatte quando viene creato un certo binario.
Il sistema, inoltre, rende modulare l'albero dei sorgenti: potete aggiungere o
rimuovere certe directory e il build system prenderà atto di queste
modifiche (ovviamente bisogna sempre stare attenti a non cancellare del codice
necessario ad altre parti).
AROS utilizza diversi strumenti di sviluppo nel suo build system. Una breve
lista dei componenti più importanti è la seguente:
GNU make: la versione GNU del programma make.
Il compito di questo programma è di rigenerare un file di output dalle sue
dipendenze usando un programma definito dall'utente come un compilatore, un
processore di testi, ecc. Il vantaggio principale rispetto a una normale
lista di comandi è che esso controllerà se è stato modificato qualcosa nei
file sorgente e fa risparmiare tempo evitando di rilanciare comandi non
necessari.
Non è strettamente necessaria familiarità con GNU make e la sintassi dei suoi
file di ingresso quando i bisogni di uno sviluppatore sono coperti dalle
macro ad alto livello discusse più avanti in questo capitolo.
Se questo non è il caso, uno può usare direttamente la sintassi dei makefile
GNU. L'uso del programma GNU make non sarà discusso in queste pagine, ma le
pagine di documentazione GNU sul programma make sono una buona fonte di
documentazione.
MetaMake: Un programma supervisore di make. Può mantenere un quadro
generale di tutti i makefile esistenti nelle sottodirectory di una certa
directory radice. Una spiegazione più dettagliata verrà data in seguito.
genmf: (generate makefile) Un linguaggio di macro per i makefile. Semplifica
la scrittura dei makefile fornendo delle macro ad alto livello per un facile
building dei file binari di AROS.
Diversi altri strumenti saranno usati dalle istruzioni di build. Questi
contengono strumenti specifici AROS e non-AROS. Maggiori spiegazioni di
questi strumenti saranno date quando appropriato.
Per illustrare come questi strumenti interagiscono l'uno con l'altro
spiegheremo cosa succede sotto il cofano quando compilate il programma
HelloWorld illustrato nel capitolo precedente.
Se avete seguito il tutorial per compilare il programma col build system, avete
prima di tutto aggiunto la directory local/helloworld con qualche file
sorgente; in seguito avete chiamato make local-helloworld nella directory
più alta di make. Durante l'esecuzione di questo comando sono stati fatti i
seguenti passi:
- Il programma make ha chiamato il programma MetaMake col seguente comando
mmake AROS.local-helloworld. Questo ha detto al programma MetaMake di
creare il meta-target local-helloworld del progetto AROS. Se fate il build
dal normale albero dei sorgenti di AROS, AROS è l'unico e il solo progetto
conosciuto dal MetaMake.
- La prima cosa che il MetaMake fa quando viene lanciato è andare sull'albero
dei sorgenti per vedere se ci sono directory aggiunte o cancellate.
- Durante la scansione dell'albero delle directory, MetaMake controllerà anche
se ci sono mmakefiles da (ri)generare. Il programma permette di generare un
mmakefile da un file mmakefile.src. Questa caratteristica è usata da AROS per
implementare delle macro ad alto livello. Nell'esempio helloworld è stata
usata la macro %build_prog. Se avete seguito l'esempio helloworld potete
dare uno sguardo alle istruzioni di build risultati in
local/helloworld/mmakefile. MetaMake determina anche se un file
mmakefile.src è più recente del file mmakefile esistente e lo rigenera.
- L'ultima cosa che il MetaMake fa quando scansione l'albero dei sorgenti è
collezionare i target metamake da tutti i file mmakefile disponibili e le
dipendenze tra i target metamake. Nell'esempio helloworld il meta-target è
stato definito come local-helloworld passando l'argomento
mmake=local-helloworld alla macro %build_prog.
Se guardaye nel mmakefile potete vedere diverse righe che iniziano con
#MM; queste sono le righe che definiscono i meta-target e le dipendenze
fra di loro. Non è necessario comprendere l'esatto significato di queste
istruzioni per essere in grado di usare le macro di build ad alto livello
fornite da AROS.
- Quando MetaMake ha esaminato tutto l'albero dei sorgenti e raccolto tutte le
informazioni sui meta-target, proverà a fare il build del meta-target
specificato. Nel passo precedente il programma ha costruito un albero di
dipendenze dei meta-target. Prima di fare il build del meta-target
specificato prima farà il build dei meta-target da cui esso dipende. Nel
nostro esempio non c'è una dipendenza e farà direttamente il build da
local/helloworld chiamanto direttamente il programma GNU make in quella
directory.
In questa sezione viene data una descrizione delle più importanti macro per lo
sviluppo di applicazioni AROS. Lo scopo non è quello di fornire una conoscenza
approfondita, ma di dare abbastanza informazioni per eseguire le operazioni più
importanti per lo sviluppo. Una discussione in profondità sugli strumenti di
build viene data nella sezione riferimenti di questo manuale.
Come visto nell'esempio helloworld precedente, il build system si usa mettendo
un file mmakefile.src nella directory contenente i vostri file sorgente. Per
fare in modo che il build system trovi il vostro file, la directory che lo
contiene deve stare sotto la directory principale dei sorgenti di AROS (il
nome di questa directory è probabilmente AROS). Quindi per il momento avete
bisogno dei sorgenti di AROS per poter usare il build system, che è trattato in
un altro capitolo. Un buon punto dove mettere i vostri sorgenti è sotto la
directory AROS/local, come fatto per l'esempio helloworld. Un mmakefile
aros deve iniziare con la riga seguente:
include $(TOP)/config/make.cfg
...
La riga iniziale setterà l'ambiente nel makefile per la compilazione di AROS.
Deve essere inclusa perchè questo ambiente viene usato dalle macro metamake.
Dopo questa prima riga, nella maggior parte dei casi seguiranno una o più
chiamate a una macro genmf. Una macro di questo tipo ha la seguente
sintassi:
%macro param1=... param2=... ...
Dove il file mmakefile.src viene tradotto in un file mmakefile e la riga
sopra verrà sostituita dai comandi make definiti nella macro. Una macro viene
chiamata tramite il suo nome seguito da zero o più parametri, con un valore
opzionale assegnato al parametro. L'ordine dei parametri non è importante e non
tutti i parametri definiti da una macro devono necessariamente avere dei valori;
verrà usato un valore di default quando non viene fornito un parametro. Alcuni
parametri potrebbero essere obbligatori e potrebbe essere generato un messaggio
d'errore quando uno di essi viene tralasciato.
Una chiamata di macro può essere estesa su più righe chiudendo la riga con un
backslash e continuando la macro sulla riga successiva. Quindi, la macro di
esempio potrebbe essere scritta anche così:
%macro \
param1=... \
param2=... \
...
Normalmente gli spazi non sono ammessi nei valori dati a un parametro, se
questo fosse necessario, bisogna racchiuderli tra virgolette (").
Nei seguenti capitoli verranno trattati i più importanti comandi ad alto
livello. Verranno discussi solo i parametri più importanti per le macro, verrà
data una lista e una descrizione di tutti i parametro di una macro nella
sezione riferimenti.
Potete fare il build di un programma usando la seguente macro nel vostro file
mmakefile.src:
%build_prog mmake=MetaTarget progname=Prog files=FilesSorgente
Questo farà il build di un programma chiamato Prog dalla lista dei
SourceFiles. Passando l'argomento mmake il programma MetaMake saprà che
questo programma può essere compilato da MetaTarget; ad es. lanciando
make MetaTarget dalla radice dei sorgenti di AROS verrà fatto il build del
programma. Lanciando questo comando, verrà fatto il build anche delle
dipendenze, ogni volta che volete ricompilare questo modulo. Inoltre, verrà
definito un meta-target MetaTarget-quick che permette di fare il build del
programma senza che siano ricompilate le dipendenze, questo può far
risparmiare tempo quando state modificando il codice sorgente di un programma e
volete rifare il build molto spesso.
La lista di file SourceFiles sono i nomi dei file di input C senza il suffisso
.c. Come spiegato sopra, questa lista deve essere racchiusa da doppi apici se
contiene più di un file.
Di default, il programma verrà messo nell'albero dei binari di AROS, a partire
dalla radice, nella stessa sottodirectory relativa a quella di dove si trovavano
i file sorgente. Potete cambiare questa directory specificando l'argomento
targetdir=.... L'ultimo argomento deve contenere il path completo, sicchè
il più delle volte inizierà con $(AROSDIR)/ per mettere il programma da
qualche parte nell'albero di binari di AROS. Quindi, se volete mettere il
programma nella directory Extras potete fare così:
%build_prog ... targetdir=$(AROSDIR)/Extras
Come spiegato prima, l'argomento di una macro deve essere racchiuso tra
virgolette se contiene più di un file. Attualmente, la lista non può essere
divisa in più di una linea e spesso vengono usate le variabili del make per
passare la lista dei file di cui fare il build. I prossimi tre esempi fanno
la stessa cosa, ma con sintassi diversa. Prima, la versione in-line:
%build_prog \
mmake=myprog progname=MyProg \
files="file1 file2 file3"
Adesso usando una variabile del make:
FILES := file1 file2 file3
%build_prog \
mmake=myprog progname=MyProg \
files=$(FILES)
O usando la continuazione di linea del make:
FILES := \
file1 \
file2 \
file3
%build_prog \
mmake=myprog progname=MyProg \
files=$(FILES)
Un altro tipo di binario di cui si fa spesso il build su AROS è una libreria
condivisa. Prima verrà data una base su come fare il build di una libreria
e poi vedremo alcune comode estensioni.
Il build di una libreria condivisa viene fatto con la macro %build_module
con una riga come questa:
%build_module mmake=MetaTarget modname=mylib modtype=library files=SourceFiles
Questa macro può fare il build di diversi moduli di AROS come dispositizi,
classi Zune, HIDD, ... ma noi ci concentreremo su una libreria condivisa e
perciò assumiamo che specifichiate il parametro modtype=library.
I parametri mmake e files si comportano analogamente a come con la macro
%build_prog. Oltre ai meta-target MetaTarget e MetaTarget-quick,
vengono definiti anche MetaTarget-includes, MetaTarget-includes-quick e
MetaTarget-linklib. Questo permette di fare il build di un sottoinsieme di
file normalmente generati. Saranno il più delle volte utilizzati per
specificare delle dipendenze.
Per fare il build di una libreria condivisa sono necessarie più informazioni di
quelle date alla macro %build_module. Queste informazioni sono memorizzate
in un altro file che di default è chiamato mylib.conf quando modname=mylib
è specificato. Questo file può contenere molte informazioni ma qui vedremo un
esempio minimale. Maggiori informazioni si trovano nella reference section
della macro %build_module. Ecco un file .conf di esempio:
##begin config
version 1.0
##end config
##begin functionlist
void func1(LONG a, LONG b)
int func2(char *s, ULONG a)
##end functionlist
Come potete vedere, questo è un file con due sezioni, ognuna di esse inizia con
##begin sectionname e finisce con ##end sectionname. La sezione
config serve per fornire le informazioni necessarie ad AROS quando ha
bisogno di utilizzare la libreria condivisa e per fornire delle opzioni per
influenzare il tipo di modulo di cui fare il build. Una discussione approfondita
si trova nella reference section. La sezione functionlist fornisce una
lista di funzioni che saranno incluse nella libreria, questa lista è composta
da prototipi di funzione. L'ordine della lista è importante perchè determinerà
il posizionamento della funzione nella tabella di lookup. Anche le righe vuote
sono importanti perchè una riga vuota nella lista di funzioni creerà uno slot
vuoto nella tabella. Le righe di commento iniziano con un carattere '#', queste
righe saranno ignorate e non creeranno uno slot vuoto nella tabella della
libreria.
Se tutte queste informazioni sono presenti ed eseguite il comando make
MetaTarget verranno generati i seguenti file ($(AROSDIR) corrisponde alla
directory dell'albero dei binari):
- $(AROSDIR)/Libs/mylib.library: il modulo stesso
- alcuni file inlude in $(AROSDIR)/Development/include con il file include
principale proto/mylib.h. Quest'ultimo file può essere incluso nel codice
usando la libreria per i prototipi di funzione.
- $(AROSDIR)/Development/lib/libmylib.a: una libreria a link statico che può
essere linkata con altro codice e che può prendersi cura di auto-aprire la
libreria e contiene delle funzioni stub. Quando queste funzioni vengono
chiamate, redirigerà al codice nella libreria usando la tabella di lookup
nella libbase.
Nell'esempio precedente sono stati usati dei tipi di variabili standard del C
o tipi standard di exec per gli argomenti delle funzioni. Se volete usare i
vostri tipi o dei tipi definiti in altri file include saranno necessari dei
passaggi aggiuntivi. E' possibile fare questa operazione nella sezione cdef
come mostrato nel prossimo esempio dove vengono usati altri file include:
##begin config
...
##end config
##begin cdef
#include <exec/semaphores.h>
##end cdef
##begin functionlist
...
BOOL func3(struct SignalSemaphore *sig)
##end functionlist
Le righe nella struttura cdef sono normale codice C e faranno parte dei file
include generati, prima dei prototipi di funzione delle librerie. Potere anche
definire le vostre strutture in questo modo:
##begin cdef
struct MyStruct
{
...
};
##end cdef
##begin functionlist
...
int func4(struct MyStruct *sig)
##end functionlist
Se fatto in questo modo, la definizione delle strutture sarà parte integrante
dei file include generati. Il metodo che si raccomanda in AROS è quello di
tenere le definizioni in un file header separato e quindi includere quel file
header. Un possibile modo di farlo è quello di definire il vostro file chiamato
libraries/mylib.h con i seguenti contenuti:
#ifndef __LIBRARIES_MYLIB_H
#define __LIBRARIES_MYLIB_H
struct MyStruct
{
...
};
...
#endif /* __LIBRARIES_MYLIB_H */
Questo file viene quindi copiato come spiegato in un altro paragrafo e
quindi semplicemente incluso dalla sezione cdef:
##begin cdef
#include <libraries/mylib.h>
##end cdef
Finora, le funzioni inserite nella tabella di vettori di libreria sono state
normali funzioni C. Ai tempi dell' Amiga m68k i parametri per le funzioni di
libreria erano quasi sempre passati nei registri e non nello stack. Per
mantenere la retrocompatibilità potete sempre definire funzioni dove gli
argomenti vengono passati in registri m68k. Quando la vostra libreria verrà
compilata per m86k userà i registri specificati, su altre architetture verranno
usate le convenzioni di quell'architettura sia usando i registri disponibili
sulla CPU specifica, sia usando passaggio di parametri basato su stack. Per
definire una funzione con registri m68k bisognerà aggiungere i registri nella
riga nella lista delle funzioni e usare delle macro per l'header della funzione
nel codice sorgente. La riga nella lista di funzioni è fatta così:
##begin functionlist
...
ULONG func5(ULONG a, STRPTR b) (D0,A0)
...
##end functionlist
E la funzione nel codice sorgente è definita come segue:
AROS_LH2(ULONG, func5,
AROS_LHA(ULONG, a, D0),
AROS_LHA(STRPTR, b, A0),
struct Library *, MylibBase, 9, Mylib
)
{
AROS_LIBFUNC_INIT
...
AROS_LIBFUNC_EXIT
}
Il nome di questa macro è AROS_LHn, dove n è il numero di argomenti passati alla
funzione. La macro ha i seguenti argomenti:
- Il tipo di ritorno della funzione
- Il nome della funzione
- La lista degli argomenti della funzione che usano la macro AROS_LHA(vartype,
varname, register). vartype è il tipo dell'argomento, varname è il nome
dell'argomento e register è il registro m68k da usare. Il registro viene
specificato come D0-D7 per gli argomenti numerici e A0-A5 per i puntatori (A6
e A7 sono riservati per altri usi).
- Il tipo base della libreria. Quando non avete definito il vostro tipo libbase
come spiegato in questo paragrafo
- La variabile per la libbase, può essere usata nella funzione per accedere
alla libbase
- Il numero di vettori nella tabella vettori. Per le librerie la prima funzione
nella lista di funzioni ha numero 5, la successiva 6 e così via. Sebbene
questa informazione non sia necessaria in quanto la lista di funzioni nel
file .conf già determina questo numero, è sempre necessario specificarlo per
ragioni di retrocompatibilità.
- Il nome base della libreria. Se questo non viene sovrascritto nella sezione
config del file .conf, il nome della libreria assumerà il nome specificato
nel parametro modname con la prima lettera maiuscola.
Su AROS e altri sistemi amiga-like, ogni libreria condivisa ha una base di
libreria. La base di una libreria contiene la tabella dei vettori e alcune
informazioni sulla libreria usata dal sistema. Può essere anche estesa con dati
definiti dall'utente. Per farlo dovete fornire la vostra struct C per il tipo
della libbase. Ci sono due opzioni di config che vi permettono di decidere il
tipo di libbase:
##begin config
...
libbasetype struct MyLibIntBase
libbasetypeextern struct MyLibBase
...
##end config
libbasetype è il tipo usato internamente nel codice della libreria, questo
tipo stabilisce anche quanta memoria viene allocata per la libbase. Se questo
tipo non viene specificato viene preso struct Library come valore di
default. libbasetypeextern è il tipo per i programmi esterni che usano la
vostra libreria. Anche qui, se non specificato viene utilizzato
struct Library come tipo. Sia il tipo interno che quello esterno devono
iniziare con una struttura struct Library. Se il tipo esterno viene
specificato, la prima parte del tipo interno deve corrispondere a quella del
tipo esterno.
Per mantenere la vostra libreria retrocompatibile non dovete cambiarne il tipo
esterno. Potete estenderlo solo al momento del rilascio di una versione al
pubblico. Il tipo interno può essere modificato dal momento in cui tutto il
codice interno della vostra libreria viene adattato alle modifiche della
struttura interna della libreria.
Il tipo esterno deve anche essere esportato agli utenti della vostra libreria.
Analogamente all' utilizzo di altri tipi non standard. Al contrario, il
tipo interno spesso non è concepito per essere esportato agli utenti, per
questo motivo è possibile inserire una sezione cdefprivate nel file config.
In questo modo, il codice di inizializzazione della libreria ha a disposizione
tutte le informazioni sul vostro tipo interno senza avere l'intera struttura
esterna esportata pubblicamente. Una convenzione comune è quella di dichiarare
le vostre strutture interne nel file mylib_intern.h e quindi includerlo nella
sezione cdefprivate. Il file mylib_intern.h includerà quindi il seguente
codice:
struct MyLibIntBase
{
struct Library base;
...
};
E il file di config la sezione seguente:
...
##begin cdefprivate
#include "mylib_intern.h"
##end cdefprivate
...
Finora, solo una libbase viene creata per una libreria. Tutti gli utenti che
aprono la libreria ottengono un puntatore alla base della libreria. A volte
c'è bisogno di ottenere dati diversi dalla singola apertura della libreria.
Questo si può fare usando una opzione speciale nella sezione config:
##begin config
...
options peropenerbase
##end config
L'uso di una base per ogni apertura della libreria non ha molto senso quando non
si usa una libbase estesa. Al momento l'unico modo per passare la libbase
alle funzioni della libreria è quello di usare il passaggio dei registri m68k.
(E' in fase di sviluppo la possibilità to poter ottenere la libbase nelle
funzioni di libreria usando il normale passaggio di argomenti in C). Potete
anche aggiungere la libbase come argomento esplicito alla funzione, ma questa
pratica è sconsigliata.
Nota
Su AROS il bisogno di usare una libbase estesa è inferiore a quello
sul classico AmigaOS. Sull' AmigaOS classico l'uso di variabili
globali nelle librerie e l'uso del libbase per memorizzare variabili
era scoraggiato. Su AROS le variabili globali vengono gestite bene,
quindi l' uso di una libbase estesa è necessario solo per usare
una libbase per singola apertura.
A volte potreste aver bisogno di eseguira un'inizializzazione quando la vostra
libreria viene caricata o quando viene aperta. Potete usare lo stesso
meccanismo come per i programmi attraverso ADD2INIT e ADD2EXIT come nel
seguente esempio:
static int InitFunc(void)
{
...
}
static void ExitFunc(void)
{
...
}
ADD2INIT(InitFunc, 0);
ADD2EXIT(ExitFunc, 0);
Quando aggiungete questo codice in uno dei vostri file sorgente, il codice in
InitFunc verrà eseguito quando la libreria viene inizializzata e il codice in
ExitFunc quando la libreria viene rilasciata. Il valore di ritorno di InitFunc
indica il successo o il fallimento, quando ritorna zero (== FALSE) significa
che c'è stato un errore nell'inizializzazione e la libreria verrà scaricata e
non sarà utilizzabile. La funzione ExitFunc non dovrebbe fallire e quindi non ha
valore di ritorno.
Spesso si desidera inizializzare parte della libbase e quindi i metodi visti
prima non sono adatti. Per le librerie sono disponibili modalità aggiuntive per
aggiungere codice di inizializzazione o di pulizia:
static int InitFunc(struct Library *lh);
ADD2INITLIB(InitFunc, 0);
static int ExpungeFunc(struct Library *lh);
ADD2EXPUNGELIB(ExpungeFunc, 0);
static int OpenFunc(struct Library *lh);
ADD2OPENLIB(OpenFunc, 0);
static void CloseFunc(struct Library *lh);
ADD2CLOSELIB(CloseFunc, 0);
La funzione InitFunc verrà chiamata una volta sola durante
l'inizializzazione e ExpungeFunc durante il rilascio del modulo. Le funzioni
OpenFunc e CloseFunc vengono chiamate rispettivamente ogni volta che il
modulo viene aperto o chiuso. InitFunc, ExpungeFunc e 'OpenFunc`
restituiscono un valore che indica il successo della funzione. Se InitFunc
fallisce, il modulo verrà rilasciato, se OpenFunc fallisce fallirà
l'apertura della libreria e se ExpungeFunc fallisce nel rilasciare la
libreria il rilascio verrà ritardato. Se accade quest'ultima ipotesi la volta
successiva che verrà tentato il rilascio, verranno richiamate tutte le funzioni
registrate per il rilascio. Questo significa che se più di una funzione viene
registrata e la seconda funzione restituisce 0, la prima funzione verrà
chiamata una seconda volta la volta successiva che AROS tenterà di rilasciare
il modulo. Se implementate una funzione ExpungeFunc che può tornare 0
dovete assicurarvi che le altre funzioni ExpungeFunc possano essere
chiamate più di una volta.
Se guardate le macro ADD2...LIB sopra specificate, potete anche vedere che
vicino al nome della funzione c'è un numero extra. Questo numero indica la
priorità di chiamata della funzione. InitFunc e OpenFunc con un numero
maggiore verranno chiamate dopo quelle con un numero minore. Per CloseFunc
e ExpungeFunc viene usato l'ordine opposto, qiundi numero più alti vengono
chiamati prima dei numeri più bassi. Il numero è un byte con segno, questo
significa che deve avere un valore tra -127 e 128. Molto spesso questo valore
viene mantenuto a 0.
Se viene usata un base per apertura verrà fatta una copia della libbase
ogni volta che il modulo viene aperto. InitFunc verrà chiamata prima della
copia, in questo modo l'inizializzazione dei valore della libbase verrà vista
da tutto gli opener. OpenFunc viene chiamata dopo la copia della libbase e
le modifiche effettuate alla libbase sono private per l'opener.
Spesso quando si scrive una libreria, bisogna usare degli include aggiuntivi
che possono essere inclusi dal programma che utilizza la vostra libreria, usando
#include <...> nel codice. Per questo scopo esiste una macro
copy_includes. Nella riga seguente gli argomenti vengono specificati alla
macro con i loro valori di default:
%copy_includes mmake=includes-copy includes=$(INCLUDE_FILES) path=. dir=
Qui segue una spiegazione degli argomenti e dopo viene fatto qualche esempio:
- Similmente alle macro viste prima in questo document, l'argomento mmake
indica il meta-target che copierà gli include. Il valore di default è
includes-copy cosicchè se l'argomento non viene specificato, gli include
verranno copiati da questo meta-target.
- includes: questi sono i file che verranno copiati nella directory
include di sistema. Può essere una lista che contiene file in sottodirectory.
Di default viene usato $(INCLUDE_FILES). Questo significa che potete
mettere la lista dei file da copiare nella variabile di make INCLUDE_FILES.
- path: questo argomento permette di copiare gli include in una
sottodirectory della directory di include di sistema. Questo nome viene
aggiunto davanti ai file include prima che vengano copiati, cosicchè il path
viene aggiunto nell'istruzione di include, ad esempio: #include <path/...>
- dir: questo argomento permette di togliere una directory dalla lista dei
file include prima che vengano copiati nella directory di include di sistema.
Questo viene usato spesso per mettere i file include in una sottodirectory
chiamata include. Specificando quindi l'argomento dir=include i file
include vengono copiati da questa sottodirectory ma in un percorso nella
directory di sistema che non contiene la directory include.
Alcuni esempi per chiarire il tutto:
Esempio 1: copiare i file *.h dalla directory corrente alla directory di
include di sistema:
INCLUDE_FILES := $(wildcard *.h)
%copy_includes mmake=MyIncludes
Esempio 2: copiare il file mylib.h nella directory libraries:
%copy_includes mmake=MyLib-includes includes=mylib.h path=libraries
I programmi possono quindi usare #include <libraries/mylib.h> per
accedere al tuo file include.
Esempio 3: copiare i file dalla sottodirectory include alla directory di
include di sistema:
INCLUDE_FILES := $(wildcard include/*.h)
%copy_includes mmake=MyIncludes dir=include
Quindi se un file include/myinclude.h è disponibile, i programmi non possono
usare #include <include/myinclude.h> ma devono invece usare
#include <myinclude.h>.
Prima che i programmi o altre libreria possano usare una libreria che non fa
parte delle librerie principali di AROS, devono aggiungerla alla lista di
librerie da usare l'argomento uselibs per le macro %build_prog o
build_module. Quindi se volete che il vostro programma utilizzi la libreria
mylib dovete fare così:
%build_prog ... uselibs=mylib
Per le librerie è praticamente la stessa cosa:
%build_module ... uselibs=mylib
Avvertenza
Questo manuale di riferimento non è aggiornato e le cose sono cambiate
considerevolmente. Per favore, consultate config/make.tmpl nell'albero dei
sorgenti per vedere l'implementazione corrente.
Se volete aiutarci ad aggiornare questa sezione, per favore contattateci.
MetaMake è una versione di make che permette di fare il build ricorsivo
nelle varie directory di un progetto. Esegue una ricerca nell'albero di
directory cercando i makefiles e i "metatargets". Quindi tenta di fare il build
di tutti i metatarget. Potete anche specificare un programma che converte i
makefile "sorgente" in makefile prima che MetaMake invochi il make.
MetaMake utilizza la normale sintassi dei makefile, ma attribuisce un
significato speciale alle righe di commento che iniziano con #MM. Questa
riga è utilizzata per definire i cosiddetti metatarget. Il nome del makefile
stesso è definito nel file config MetaMake che verrà discusso in una delle
seguenti sezioni.
Ci sono tre modi per definire un metatarget in un makefile:
Questo definisce un metatarget con i suoi metaprerequisiti:
#MM metatarget : metaprerequisites
Quando un utente richiede il build di questo metatarget, verrà fatto prima il
build dei suoi metaprerequisiti e dopo del metatarget specificato.
In questo modo viene anche indicato che in questo makefile è presente un
target con lo stesso nome. Questo target deve essere ancora definito.
Questa è la stessa definizione del paragrafo precedente, ma in questo caso non
è presente nessun target normale con lo stesso nome del metatarget. Usando
questi metatarget 'virtuali' si velocizza il build perchè make non viene
chiamato con questo target:
#MM- metatarget : metaprerequisites
Questo definisce sia un metatarget che un target make con lo stesso nome.
I prerequisiti non sono metaprerequisiti:
#MM
metatarget : prerequisites
La riga per la definizione di un metatarget può essere distribuita su varie
righe chiudendo ogni riga con il carattere \ e iniziando la riga successiva con
#MM.
Potete definire un metatarget con lo stesso nome in vari file differenti. I
metaprerequisiti verranno collezionati.
Se un metatarget viene definito sia con #MM che con #MM-, allora #MM
ha la priorità.
MetaMake viene lanciato chiamando make nella directory di root
dell'albero dei sorgenti di AROS.
Prima di tutto MetaMake costruirà un albero di tutti i makefile presenti nella
directory di root e nelle sottodirectory. Allo stesso tempo costruirà un albero
di tutti i metatarget e delle loro dipendenze.
A quel punto, farà il build di tutti i metaprerequisiti necessari al metatarget
e quindi, finalmente, il metatarget stesso. Attualmente si potrebbe osservare
che ogni metaprerequisito diventa un metatarget quando bisogna farne il build.
Per ognuno dei metatarget viene fatta un'analisi di tutte le directory. In ogni
makefile dove i metatarget vengono definiti con il primo o il terzo metodo visti
nella sezione precedente, viene chiamato make col nome del target come
target di make.
Quando MetaMake chiama il normale make vengono definite due variabili.
$(TOP) contiene il valore della directory di root e $(CURDIR) il path relativo
a questa directory di root.
Dei metatarget che non sono prerequisiti di un altro target non viene fatto il
build di default. Se volete fare il build di questi metatarget dovete scrivere
make metatarget nella directory di root dell'albero dei sorgenti di AROS.
Un'altra caratteristica del MetaMake è la generazione automatica di un
makefile a partire da un makefile sorgente. Quando l'albero delle directory
viene analizzato, viene viene verificato se ci sono makefile con il suffisso
.src. Se c'è ed è più recente del makefile presente in quella directory verrà
chiamato uno script per rigenerare il makefile dal suo makefile sorgente.
Lo script da chiamare è definito nel file di configurazione.
I prossimi esempi sono presi dal progetto AROS.
#MM contrib-regina-module : setup linklibs includes contrib-regina-includes
Questo esempio dice che in questo makefile è presente un contrib-regina-module
di cui deve essere fatto il build. Prima di ciò, però, bisogna fare il build dei
metatarget setup, linklibs ecc... Questo assicura che gli include, le
linklibs ecc siano presenti prima di fare il build del modulo.
#MM- contrib-freetype : contrib-freetype-linklib \
#MM contrib-freetype-graph \
#MM contrib-freetype-fonts \
#MM contrib-freetype-demos
Qui si dice che il metatarget contrib-freetype richiede il build di linklib,
graph, fonts e demos di freetype. Se c'è bisogno di fare del lavoro
extra nel makefile in cui si trova questo metatarget, la definizione può
iniziare con #MM e un normale target make contrib-freetype deve essere
presente nel makefile.
Qui si vede anche l'utilizzo della continuazione di linea nella definizione del
metatarget.
#MM workbench-utilities : includes linklibs setup-clock-catalogs
#MM
workbench-utilities-quick : workbench-utilities
Quando un utente esegue MetaMake con argomento workbench-utilities verrà
chiamato make in tutte le directory dove sono presenti i metaprerequisiti nel
makefile. Questo può diventare molto tedioso durante il debug del programmi.
Quando il secondo metatarget workbench-utilities-quick viene definito come
mostrato sopra, allora verrà fatto il build solo di quel target in questa
directory. Ovviamente l'utente deve assicurarsi che i metatarget da cui dipende
workbench-utilities siano aggiornati.
Il file di configurazione di MetaMake si trova in $(TOP)/mmake.config. Ecco
una breve spiegazione del suo contenuto:
- [AROS]
- Inizia la sezione di configurazione del progetto AROS
- maketool $(HOST_MAKE) $(MKARGS) TOP=$(TOP) CURDIR=$(CURDIR) TARGET=$(TARGET)
- Specifica il nome degli strumenti per fare il build di un target,
generalmente make.
- defaultmakefilename mmakefile
- Questo definisce che mmakefile è il nome dei makefile MetaMake.
- genmakefilescript $(GENMF) $(TOP)/config/make.tmpl --listfile $(MMLIST)
- MetaMake permette di generare makefile con uno script. Il makefile verrà
rigenerato se non esiste, se il file sorgente è più recente o se il file
specificato con genmakefiledeps è più recente. Il nome del file sorgente
è generato concatenando defaultmakefilename e ".src"
- genmakefiledeps $(GENMF) $(TOP)/config/make.tmpl
- Se questo file è più recente del makefile, verrà lanciato lo script
specificato.
- globalvarfile $(TOP)/bin/$(AROS_HOST_ARCH)-$(AROS_HOST_CPU)/gen/config/host.cfg
- MetaMake leggerà questo file e ogni variabile in questo file sarà
disponibile dovunque possiate usare una variabile.
- genglobalvarfile sh $(TOP)/configure
- Questo definisce uno script per rigenerare il globalvarfile.
- ignoredir ...
- Questo dice a MetaMake di ignorare queste directory.
Genmf utilizza due file per generare un makefile. Il primo è il file con le
definizioni delle macro e il secondo è il makefile sorgente (mmakefile.src)
dove queste macro possono essere usate. Le macro di AROS sono nel file
$(TOP)/config/make.tmpl.
In generale, il carattere % è usato come carattere speciale per i makefile
sorgente di genmf.
Una definizione di macro ha la seguente sintassi:
%define macroname option1[=[default][\A][\M]] option2[=[default][\A][\M]] ...
...
%end
macroname è il nome della macro. option1, option2, ... sono gli argomenti
per la macro. Queste opzioni possono essere usate nel corpo di questo template
scrivendo %(option1), che verrà sostituito dal valore di option1.
L'argomento può essere seguito da un valore di default. Se non viene specificato
un valore di default verrà inserita una stringa vuota. Normalmente non vengono
ammessi spazi nel valore di default di un argomento. Se ce n'è bisogno potete
farlo circondando il valore con le doppie virgolette (").
Possono essere specificati anche due switch:
- \A
- E' lo switch che ha sempre bisogno di un valore. Quando la macro viene
istanziata bisogna sempre assegnare un valore a questo argomento.
- \M
- E' lo switch per attivare parole multiple. Questo significa che tutte
le parole che seguono questo argomento saranno assegnate a questo
argomento. Significa anche che dopo l'uso di questo argomento nessun
altro argomento può essere presente, in quanto diverrebbe parte di
questo argomento.
Una macro può essere istanziata usando il carattere '%' seguito dal nome della
macro da istanziare (senza parentesi):
%macro_name [option1=]value [option2=]value
E' possibile specificare argomenti a una macro in due modi:
- value
- Questo assegna il primo valore al primo argomento, il secondo valore al
secondo argomento e così via.
- option1=value
- Questo assegna il valore specificato all'opzione col nome specificato.
Quando si assegnano valori agli argomenti, bisogna usare le virgolette se si
vogliono includere spazi nei valori degli argomenti.
E' possibile usare l'istanziamento di una macro dentro il corpo di una macro,
anche macro che verranno definite in seguito o nel file di definizione delle
macro.
Nota
Nella definizione delle regole di genmf, a volte le variabili
MetaMake vengono usate come valori di default di un argomento
(es. dflags=%(cflags)). Questo non è possibile nella file di
definizione ma viene fatto usando del testo che ha lo stesso effetto.
I seguenti metatargets vengono spesso usati come prerequisiti:
- includes: I file *.h
- linklibs: librerie statiche
FIXME: da completare
Nota
Questo enormi target metamake furono introdotti all'inizio del progetto.
L'uso di questi metatarget è ora considerato deprecato e dovrebbe essere
evitato.
Bisognerebbe utilizzare target più specifici per le dipendenze, es. se un
certo programma usa una certa libreria dovrebbe specificare questa libreria
come dipendenza e non tutte le linklibs usando il metatarget linklibs.
Ci sono due macro per fare il build dei programmi. Una macro %build_progs
che compilerà ogni file di input in un eseguibile separato e una macro
%build_prog che compilerà e linkerà tutti i file di input in un solo
eseguibile.
Questa macro compilerà e linkerà ogni file di input in un file eseguibile
separato e ha la seguente definizione:
%define build_progs mmake=/A files=/A \
objdir=$(GENDIR)/$(CURDIR) targetdir=$(AROSDIR)/$(CURDIR) \
cflags=$(CFLAGS) dflags=$(BD_CFLAGS$(BDID)) ldflags=$(LDFLAGS) \
uselibs= usehostlibs= usestartup=yes detach=no
Con i seguenti argomenti:
- mmake=/A
- Questo è il nome del metatarget che farà il build dei programmi. Verrà
definito anche un metatarget %(mmake)-quick.
- files=/A
- I nomi dei file sorgente C che saranno compilati e linkati in file
eseguibili. Per ogni nome presente in questa lista verrà generato un
eseguibile con lo stesso nome.
- objdir=$(GENDIR)/$(CURDIR)
- La directory dove verranno salvati i file oggetto compilati.
- targetdir=$(AROSDIR)/$(CURDIR)
- La directory dove verranno salvati gli eseguibili.
- cflags=$(CFLAGS)
- I flag da aggiungere quando vengono compilati i file .c. Di default
verranno considerate le variabili di make dei cflag standard di AROS
(i $(CFLAGS)). Questo significa anche che alcuni flag possono
essere aggiunti assegnandoli alle variabili di make USER_CFLAGS e
USER_INCLUDES prima di usare questa macro.
- dflags=%(cflags)
- I flag da aggiungere quando si fa il controllo delle dipendenze. Di
default è lo stesso dei cflags.
- ldflags=$(LDFLAGS)
- I flags da usare quando si linkano gli eseguibili. Di default verranno
usati i flag di link standard di AROS.
- uselibs=
Una lista delle librerie statiche da aggiungere quando si linkano gli
eseguibili. Questo è il nome della libreria senza il prefisso lib o
il suffisso .a e senza il prefisso -l usato nei flag per il
compilatore C.
Di default, non viene usata alcuna libreria linkando gli eseguibili.
- usehostlibs=
Una lista di librerie statiche dell'host da aggiungere quando si
linkano gli eseguibili. Questo è il nome della libreria senza il
prefisso lib o il suffisso .a e senza il prefisso -l usato nei
flag per il compilatore C.
Di default, non viene usata alcuna libreria linkando gli eseguibili.
- usestartup=yes
- Usa il codice di startup standard per gli eseguibili. Di default è
impostato a yes ed è anche quello che si vuole nella maggioranza dei
casi. Disabilitatelo solo se sapete cosa state facendo.
- detach=no
- Stabilisce se l'eseguibile girerà isolato. Di default no.
Questa macro compilerà e linkerà i file di input in un eseguibile e ha la
seguente definizione:
%define build_prog mmake=/A progname=/A files=%(progname) asmfiles= \
objdir=$(GENDIR)/$(CURDIR) targetdir=$(AROSDIR)/$(CURDIR) \
cflags=$(CFLAGS) dflags=$(BD_CFLAGS$(BDID)) ldflags=$(LDFLAGS) \
aflags=$(AFLAFS) uselibs= usehostlibs= usestartup=yes detach=no
Con i seguenti argomenti:
- mmake=/A
- Questo è il nome del metatarget che farà il build dei programmi. Verrà
definito anche un metatarget %(mmake)-quick.
- progname=/A
- Il nome dell'eseguibile.
- files=
- I nomi dei file sorgenti C che saranno compilati e linkati nel file
eseguibile. Di default, viene considerato solo il nome dell'eseguibile.
- asmfiles=
- I file assembler da assemblare e includere nell'eseguibile. Di default
nessun file asm è incluso nell'eseguibile.
- objdir=$(GENDIR)/$(CURDIR)
- La directory dove verranno salvati i file oggetto compilati.
- targetdir=$(AROSDIR)/$(CURDIR)
- La directory dove verranno salvati gli eseguibili.
- cflags=$(CFLAGS)
- I flag da aggiungere quando vengono compilati i file .c. Di default
verranno considerate le variabili di make dei cflag standard di AROS
(i $(CFLAGS)). Questo significa anche che alcuni flag possono
essere aggiunti assegnandoli alle variabili di make USER_CFLAGS e
USER_INCLUDES prima di usare questa macro.
- dflags=%(cflags)
- I flag da aggiungere quando si fa il controllo delle dipendenze. Di
default è lo stesso dei cflags.
- aflags=$(AFLAGS)
- I flag da aggiungere quando si compilato i file asm. Di default
vengono considerati gli aflags standard di AROS (es. $(AFLAGS)).
Questo significa anche che alcuni flag possono essere aggiunti
assegnandoli alla variabile di make SPECIAL_AFLAGS prima di usare
questa macro.
- ldflags=$(LDFLAGS)
- I flag da usare quando si linka l'eseguibile. Di default verranno usati
i flag di link standard di AROS.
- uselibs=
Una lista delle librerie statiche da aggiungere quando si linkano gli
eseguibili. Questo è il nome della libreria senza il prefisso lib o
il suffisso .a e senza il prefisso -l usato nei flag per il
compilatore C.
Di default, non viene usata alcuna libreria linkando gli eseguibili.
- usehostlibs=
Una lista di librerie statiche dell'host da aggiungere quando si
linkano gli eseguibili. Questo è il nome della libreria senza il
prefisso lib o il suffisso .a e senza il prefisso -l usato nei
flag per il compilatore C.
Di default, non viene usata alcuna libreria linkando gli eseguibili.
- usestartup=yes
- Usa il codice di startup standard per gli eseguibili. Di default è
impostato a yes ed è anche quello che si vuole nella maggioranza dei
casi. Disabilitatelo solo se sapete cosa state facendo.
- detach=no
- Stabilisce se l'eseguibile girerà isolato. Di default no.
%define common
Questo aggiunge alcune cose di uso comune come un target clean nel makefile.
Il target clean cancella solo i makefile generati.
La definizione della macro è quella che segue:
%define build_catalogs mmake=/A name=/A subdir=/A \
catalogs="$(basename $(wildcard *.ct))" source="../strings.h" \
description="$(basename $(wildcard *.cd))" dir=$(AROS_CATALOGS) \
sourcedescription="$(TOOLDIR)/C_h_orig"
Il significato degli argomenti è il seguente:
- mmake=/A
- Questo è il nome del metatarget che farà il build dei catalogs. Verr
definito anche un metatarget %(mmake)-clean.
- name=/A
- Questo è il nome del catalog di destinazione, senza il suffisso
.catalog.
- subdir=A
- Questa è la sottodirectory di destinazione dei catalogs.
- catalogs
- Questa è la lista dei catalogs, senza il suffisso .ct (default *.ct)
- source
- Questo è il percorso del file sorgente generato. Il valore di default
crea il file strings.h nella directory superiore. Ricordate che i
file generati non devono essere committati su SVN.
- description
- Questo è il file descrizione del catalog (.cd) (default *.cd).
- dir
- Questa è la directory di destinazione di base (default $(AROS_CATALOGS)).
- sourcedescription
- Questo è il percorso al file di descrizione del sorgente FlexCat, senza
il suffisso .sd.
Esempio:
%build_catalogs mmake=workbench-system-wanderer-tools-info-catalogs \
name=Info subdir=System/System/Wanderer/Tools
Serve per creare le icone. Le icone devono essere nel formato PNG o ILBM.
L'icona viene configurata da un file di testo aggiuntivo con il nome
%(nomeicona).info.src. Potete trovare la documentazione di questo file in
$(TOP)/tools/ilbmtoicon/README
La definizione della macro è quella che segue:
%define build_icons mmake=/A icons=/A dir=/A
Il significato degli argomenti è il seguente:
- mmake
- E' il nome del metatarget. Verrà definito anche un metatarget
%(mmake)-clean
- icons
- Questa è una lista di nomi base di icone (senza il suffisso .info)
- dir
- Questa è la directory di destinazione.
Esempio:
%build_icons mmake=workbench-system-wanderer-tools-newdrawer-icons \
icons=newdrawer dir=$(AROS_WANDERER)/Tools
Il nome del file di definizione è newdrawer.info.src.
Creare una libreria statica è semplice. Una lista di file viene compilata o
assemblata e raccolta in una libreria in una directory target specificata.
La definizione della macro è quella che segue:
%define build_linklib mmake=/A libname=/A files="$(basename $(wildcard *.c)) \
asmfiles= cflags=$(CFLAGS) dflags=%(cflags) aflags=$(AFLAGS) \
objdir=$(OBJDIR) libdir=$(LIBDIR)
Il significato degli argomenti è il seguente:
- mmake=/A
- Questo è il nome del metatarget che farà il build della linklib.
- libname=/A
- Il nome base della libreria da generare. Il file generato si chiamerà
lib%(nomelibreria).a
- files=$(basename $(wildcard *.c))
- I file C da compilare e includere nella libreria. Di default, verranno
usati tutti i file .c nella directory dei sorgenti.
- asmfiles=
- I file assembler da assemblare e includere nella libreria. Di default,
non viene incluso alcun file assembler nella libreria.
- cflags=$(CFLAGS)
- I flag da usare nella compilazione dei file .c. Di default vengono usati
i cflag standard di AROS (es. $(CFLAGS)). Questo significa anche
che alcuni flag possono essere aggiunti assegnandoli alle variabili di
make USER_CFLAGS e USER_INCLUDES prima di usare questa macro.
- dflags=%(cflags)
- I flag da aggiungere quando si fa il controllo delle dipendenze. Di
default è lo stesso dei cflags.
- aflags=$(AFLAGS)
- I flag da aggiungere quando si compilato i file asm. Di default
vengono considerati gli aflags standard di AROS (es. $(AFLAGS)).
Questo significa anche che alcuni flag possono essere aggiunti
assegnandoli alla variabile di make SPECIAL_AFLAGS prima di usare
questa macro.
- objdir=$(OBJDIR)
- La directory dove generare i file intermedi. Il valore di default è
$(OBJDIR) che di default è uguale a $(GENDIR)/$(CURDIR).
- libdir=$(LIBDIR)
- La directory dove salvare la libreria. Di default verrà usata la
directory standard per le librerie $(LIBDIR).
Il build dei moduli consiste di due parti. La prima è una macro da usare nei
file mmakefile.src. La seconda è un file di configurazione che descrive il
contenuto del modulo.
Questo è l'header di definizione della macro build_module:
%define build_module mmake=/A modname=/A modtype=/A \
conffile=%(modname).conf files="$(basename $(wildcard *.c))" \
cflags=$(CFLAGS) dflags=%(cflags) objdir=$(OBJDIR) \
linklibname=%(modname) uselibs=
Ecco la lista degli argomenti di questa macro:
- mmake=/A
- Questo è il nome del metatarget che farà il build del modulo. Verranno
definiti anche dei metatarget %(mmake)-quick e %(mmake)-clean.
- modname=/A
- Questo è il nome del modulo senza il suffisso.
- modtype=/A
- Questo è il tipo di modulo e corrisponde al suffisso del modulo. Al
momento sono supportati solo library, mcc, mui e mcp. E' pianificato
per il futuro il supporto ad altri moduli.
- conffile=%(nomemodulo).conf
- Il nome del file di configurazione. Di default è nomemodulo.conf.
- files="$(basename $(wildcard *.c))"
- Una lista di tutti i file sorgente C senza il suffisso .c che contengono
il codice di questo modulo. Di default, verranno presi tutti i file .c
presenti nella directory corrente.
- cflags=$(CFLAGS)
- I flag da usare nella compilazione dei file .c. Di default vengono usati
i cflag standard di AROS (es. $(CFLAGS)). Questo significa anche
che alcuni flag possono essere aggiunti assegnandoli alle variabili di
make USER_CFLAGS e USER_INCLUDES prima di usare questa macro.
- dflags=%(cflags)
- I flag da aggiungere quando si fa il controllo delle dipendenze. Di
default è lo stesso dei cflags.
- objdir=$(OBJDIR)
- La directory dove generare i file intermedi. Il valore di default è
$(OBJDIR) che di default è uguale a $(GENDIR)/$(CURDIR).
- linklibname=%(nomemodulo)
Il nome da usare per la libreria statica che contiene il codice di
autoinit di librerie e gli stub che convertono la convenzione C di
chiamata stack in una chiamata dalla tabella di funzioni della
libreria con il meccanismo di chiamata appropriato. Questi stub
normalmente non sono necessari quando le definizioni per le funzioni
del modulo non sono disabilitate.
Ci sarà sempre un file generato con il seguente nome
$(LIBDIR)/lib%(nomelinklib).a e di default il nomelinklib sarà lo
stesso del nomemodulo.
- uselibs=
Una lista di librerie statiche da aggiungere quando si linka il modulo.
I nomi delle librerie senza il prefisso lib o il suffisso .a e
senza il prefisso -l da usare come flag per il compilatore C.
Di default, nessuna libreria viene linkata col modulo.
Il file di configurazione del modulo è suddiviso in diverse sezioni. Una
sezione viene definita dalle seguenti righe:
## begin nomesezione
...
## end nomesezione
L'interpretazione delle righe tra #begin e ##end è diversa per ogni
sezoine. Vengono definite le seguenti sezioni:
config
Le righe in questa sezione hanno tutte lo stesso formato:
nomeopzione stringa
con la stringa che inizia con il primo carattere non spazio dopo optionname
e finisce all'ultimo carattere non spazio su quella riga.
Ecco una lista di tutte le opzioni disponibili:
- basename
Seguita da nome base del modulo. Verrà usato come prefisso per diversi
simboli. Di default viene preso il nome del modulo specificato nel
makefile con la prima lettera maiuscola.
- libbase
Il nome variabile contenente la base della libreria. Di default viene
considerato il basename con Base aggiunto alla fine.
- libbasetype
Il tipo da utilizzare come libbase ad uso interno del codice della
libreria. Es. l'operatore sizeof applicato a questo tipo deve restituire
la grandezza reale dell'oggetto. State attenti al fatto che potrebbe non
essere specificato come puntatore. Di default viene considerato
'struct LibHeader'.
- libbasetypeextern
Il tipo da usare per la libbase per il codice che utilizza la libreria
dall'esterno. Di default è 'struct Library'.
- version
La versione da compilare nel modulo. Deve essere specificata come
major.minor. Di default verrà usata 0.0.
- date
La data in cui è stata creata la libreria. Deve avere il formato
GG.MM.AAAA. Di default viene usato 00.00.0000.
- libcall
Il meccanismo per il passaggio dei parametri usato per le funzioni di
questo modulo. Può essere sia 'stack' che 'register'. Di default viene
usato 'stack'.
- forcebase
Questo forzerà l'uso di una certa variabile base nella libreria statica
per l'autoapertura del modulo. Questo vale solo per i moduli che
supportano l'autoapertura. Questa opzione può essere presente più di una
volta nella sezione config e quindi tutte queste basi saranno presenti
nella link library. Di default, nessuna variabile base sarà presente nella
link library.
cdef
In questa sezione deve essere scritto tutto il codice C che dichiara tutti i
tipi di argomenti di funzione elencati nella funzione stessa. E' possibile
inserire qualunque codice C valido, incluso l'uso degli #include.
functionlist
In questa sezione ci sono tutte le funzioni accessibili ai programmi
dall'esterno.
Per il passaggio di argomenti tramite stack deve essere fornita solo una
lista di funzioni. Per il passaggio di argomenti tramite i registri deve
essere specificato il nome del registro tra parentesi tonde. Se avete una
funzione foo con il primo argomento in D0 e il secondo argomento in A0,
inserita la seguente riga nella lista:
foo(D0,A0)
Nel paragrafo precedente è stato spiegato come fare il build di un modulo con
la macro genmf di AROS. A volte è necessario sostituire alcuni file in un
modulo con un'implementazione valida solo per una certa architettura o una
certa CPU.
I file per architetture specifiche vengono gestiti da una macro chiamata
%build_archspecific e che ha il seguente header:
%define build_archspecific mainmmake=/A maindir=/A arch=/A files= asmfiles= \
cflags=$(CFLAGS) dflags=%(cflags) aflags=$(AFLAGS) compiler=target
E i seguenti argomenti:
- mainmmake=/A
- Il mmake del modulo di cui si vogliono sostituire o aggiungere file.
- maindir=/A
- La directory dove vengono memorizzati i file oggetto del modulo
principale. E' un path relativo a $(GENDIR). La maggior parte delle
volte questa è la directory dove vengono memorizzati i file sorgente
del modulo.
- arch=/A
- L'architettura per la quale bisogna fare il build di questi file. Può
avere tre forme diverse ARCH-CPU, ARCH o CPU. Per esempio, quando viene
specificato linux-i386, questi file verranno compilati solo per il port
per linux i386. Con ppc verranno compilati per tutti i processori ppc e
con linux verranno compilati per tutti i porting di linux.
- files=
- Il nome base dei file sorgente C da sostituire o aggiungere al modulo.
- asmfiles=
- Il nome base dei file sorgente asm da sostituire o aggiungere al modulo.
- cflags=$(CFLAGS)
- I flag da usare nella compilazione dei file .c. Di default vengono usati
i cflag standard di AROS (es. $(CFLAGS)). Questo significa anche
che alcuni flag possono essere aggiunti assegnandoli alle variabili di
make USER_CFLAGS e USER_INCLUDES prima di usare questa macro.
- dflags=%(cflags)
- I flag da aggiungere quando si fa il controllo delle dipendenze. Di
default è lo stesso dei cflags.
- aflags=$(AFLAGS)
- I flag da aggiungere quando si compilato i file asm. Di default
vengono considerati gli aflags standard di AROS (es. $(AFLAGS)).
Questo significa anche che alcuni flag possono essere aggiunti
assegnandoli alla variabile di make SPECIAL_AFLAGS prima di usare
questa macro.
- compiler=target
- Indica quale compilatore utilizzare durante la compilazione dei file
sorgente C. Può essere sia il target che l'host a usare il compilatore
target o host. Di default viene usato il compilatore target.
Una seconda macro, chiamata %rule_archalias permette di creare un'architettura
virtuale. E il codice scritto per questa architettura virtuale è condiviso tra
le diverse architetture. Molto probabilmente questo verrà usato per codice che
utilizza un'API condivisa tra le diverse architettura, ma non tutte.
La macro ha il seguente header:
%define rule_archalias mainmmake=/A arch=/A alias=/A
Con i seguenti argomenti:
- mainmmake=/A
- Il mmake del modulo di cui si vogliono sostituire o aggiungere file.
- arch=/A
- L'architettura da cui si vogliono creare degli alias.
- alias=/A
- L'architettura per cui si vogliono creare degli alias.
Questo è un estratto dal file config/linux/exec/mmakefile.src che
sostituisce il file principale init.c di exec con uno specializzato per
linux:
%build_archspecific \
mainmmake=kernel-exec maindir=rom/exec arch=linux \
files=init compiler=host
Per la dos.library alcuni file specifici per un'architettura vengono
raggruppati insieme nell'architettura unix. Le righe seguenti si trovano in
vari mmakefile per rendere questo possibile:
In config/linux/mmakefile.src:
%rule_archalias mainmmake=kernel-dos arch=linux alias=unix
In config/freebsd/mmakefile.src:
%rule_archalias mainmmake=kernel-dos arch=freebsd alias=unix
E infine in config/unix/dos/mmakefile.src:
%build_archspecific \
mainmmake=kernel-dos maindir=rom/dos \
arch=unix \
files=boot \
compiler=host
Il file $(TOP)/config/make.tmpl contiene altre macro. Leggete i commenti in
quel file per il loro utilizzo.
Di solito il file $(TOP)/config/make.cfg è incluso in tutti i makefile.
Contiene parecchie variabili usate spesso nei makefile. Le più importanti sono
i path assoluti per le directory standard (es. AROS_C) e i nomi degli
strumenti (es: MMAKE, GENMF).
Le definizioni dipendenti dalla piattaforma si trovano in:
- $(TOP)/bin/$(AROS_HOST_ARCH)-$(AROS_HOST_CPU)/gen/config/host.cfg
- $(TOP)/bin/$(AROS_HOST_ARCH)-$(AROS_HOST_CPU)/gen/config/target.cfg
|
|