Makefile

Makefile

Makefile: Quando ho visitato per la prima volta uno dei nostri famosi produttori di TV in Cina, non avevo idea delle capacità del loro team dedicato allo sviluppo del software.

Quando ho fatto una dimostrazione del software della mia compagnia per avere una loro valutazione, il leader del team e’ rimasto sorpreso nel vedere la programmazione modulare del software divisa in molti singoli file. Il direttore del team ha persino commentato: “La struttura del vostro software e’ molto stupida, perché mettere ogni cosa di tutte queste funzioni in così tanti file più piccoli invece di utilizzare un unico file? E’ molto difficile trovare le variabili in file diversi e la compilazione richiede un tempo più lungo”. Ero quasi scioccato dalle sue parole, ma non potevo discutere animatamente con il nostro cliente, sarebbe stato estremamente dannoso per i nostri affari. Così ho lasciato a lui trovare la vera risposta, quale era la struttura più stupida?

Posso immaginare il motivo per cui avevano avuto un approccio del genere ( ossia utilizzare un solo file di grandi dimensioni ) e quindi fermarsi lì. Prima di tutto nessuno del loro team aveva esperienza in programmazione UNIX, essi conoscevano solo DOS e Windows. In pratica le loro esperienze erano solo in MS C++ o Turbo C++, i quali utilizzano strumenti IDE. E avevano avuto il loro primo codice di base dalla Toshiba. Non so perché la Toshiba diede loro un singolo file sorgente per lo sviluppo, forse era un espediente per i loro affari. Tuttavia ho capito che dovevo dimostrare i vantaggi del nostro software rispetto al loro. Così ho modificato un file del mio software ed il grande file del loro software, e poi li ho compilati separatamente. Ci sono voluti 3 minuti per compilare il loro file sorgente. La compilazione del mio software e’ stata fatta in 5 secondi utilizzando un comando make. Anche se hanno visto la differenza, insistevano sui loro punti di vista, ma ho saputo che hanno riorganizzato l’intera struttura del software dopo questo training.

La maggior parte degli ingegneri elettronici non sono esperti di software, quindi sono sprovveduti su molti importanti concetti di ingegneria del software. Grazie a Microsoft e Borland, questo tipo di sprovveduto può andare bene per programmare un PC. Questi IDE hanno già delle embedded make utilities. Per esempio, nmake per MS C++, tmake per Borland Turbo C++. Ma molti dei primi strumenti di sviluppo embedded non offrivano una make utility inclusa nel pacchetto, naturalmente non offrivano nemmeno IDE. In quel momento, o persino oggi, molti ingegneri utilizzano un file batch per compilare il loro codice sorgente. Non sanno che si può dividere il sorgente in differenti head file e source file. Non sanno come utilizzare il make per compilare soltanto i file modificati invece di compilare l’intero progetto. Non sanno come utilizzare un’altra utility per generare automaticamente head file dai file di configurazione. Non hanno nessuna idea di come gestire un progetto di grandi dimensioni. Mi piacerebbe parlare di questi argomenti nelle prossime settimane, ma intanto iniziamo con il makefile.

Che cos’è il makefile

In realtà makefile è un vecchio concetto derivante dallo sviluppo di UNIX. Makefile si basa sulle regole di compilazione per un progetto e migliora l’efficienza dello sviluppo del progetto. In un progetto di grandi dimensioni ci sono molti file in cartelle differenti. Naturalmente si può scrivere un file batch DOS per costruire l’intero progetto. Ma makefile può stabilire quali passi devono essere fatti per primi, quali passi possono essere ignorati e può stabilire obiettivi persino più complicati. Tutti questi passi sono decisi da regole presenti nel makefile, invece di specificarli manualmente. Naturalmente, per utilizzare le caratteristiche del make, un progetto dovrebbe essere scritto con il metodo di programmazione modulare, un progetto costituito da un file di grandi dimensioni può appena essere programmato una volta sola. PS: La programmazione modulare ha molti altri vantaggi nell’ingegneria del software, non solo per makefile.

La regola di makefile è:


  target … : prerequisites …
    command
    …
    …


Ciò significa, nella prospettiva di costruire un obiettivo (per es. file oggetto), che dovremmo avere dei file con requisiti indispensabili ( per es. head file ), gli strumenti di conversione sono comandi (per es. c compiler). Queste regole sono il nucleo di un makefile. Ecco un semplice makefile per GNU make (gmake). Una regola implicita è che la conversione avviene solo se uno dei file con requisiti indispensabili è più recente dell’obiettivo. Questo significa che è cambiato dall’ultimo make. A proposito, è necessario digitare una tabella di parole chiave prima del comando, altrimenti il gmake non lo processerà.


  edit : main.o kbd.o command.o display.o \
      insert.o search.o files.o utils.o
    cc -o edit main.o kbd.o command.o display.o \
      insert.o search.o files.o utils.o
  main.o : main.c defs.h
    cc -c main.c
  kbd.o : kbd.c defs.h command.h
    cc -c kbd.c
  command.o : command.c defs.h command.h
    cc -c command.c
  display.o : display.c defs.h buffer.h
    cc -c display.c
  insert.o : insert.c defs.h buffer.h
    cc -c insert.c
  search.o : search.c defs.h buffer.h
    cc -c search.c
  files.o : files.c defs.h buffer.h command.h
    cc -c files.c
  utils.o : utils.c defs.h
    cc -c utils.c
  clean :
    rm edit main.o kbd.o command.o display.o \
      insert.o search.o files.o utils.o

Se defs.h è cambiato, allora tutti gli obiettivi correlati (per es. tutti gli *.o file) saranno generati, e finalmente il file edit sarà generato. Se main.c e’ cambiato, il makefile genererà solo main.o e edit. E’ questa la regola di un makefile. Potete anche digitare “make clean” per rimuovere tutti i file generati nella lista eseguendo il comando rm. L’esempio non si adatta ad uno scopo dimostrativo, sarà molto efficiente in un progetto enorme come il DTV. Se siete ancora alle prese con un file batch DOS , ogni singolo cambiamento metterà alla prova la vostra pazienza.

Diversi make tools hanno sintassi differenti. Con l’obiettivo di avere un unico sistema di sviluppo embedded, GNU gmake e’ un buon strumento per la maggior parte dei sistemi embedded. Ma GNU gmake e’ uno strumento abbastanza complesso, potreste essere non interessati alle 200 pagine del suo manuale. Personalmente raccomando, per vostro riferimento, il makefile template di AVR, dove il makefile e’ stato suddiviso in un comune makefile ed in un progetto make. Questo vi offre un valido makefile come punto di partenza per il vostro progetto. Potete scaricare gli strumenti GCC da questo sito, il makefile ed un progetto demo sono inclusi. Potete facilmente portarlo nei vostri progetti già esistenti su 8051, PIC, MSP… Non preoccupatevi per ARM o MIPS perché le loro “ tool chains “ hanno già integrato gmake.

Makefile ha un suo proprio risultato, il make ricorsivo, che divide un makefile centrale in makefile distribuiti in cartelle differenti e sottocartelle. Quello che è assai comune è il progetto Linux. L’autore di Safer C ha presentato un articolo – Harmful Recursive Makefile. Leggetelo se siete interessati a questo argomento, ma il makefile dell’AVR e’ sufficiente per un progetto di media dimensione.

Nel prossimo articolo parleremo di come utilizzare gawk per generare automaticamente la regole di dipendenza di un make file”. E’ divertente. Potete anche riutilizzare questo principio per generare un documento. Lo so che odiate scrivere i documenti e sincronizzare in ogni momento le modifiche del codice ai documenti.

Reference

 

P.Miller’s Safer C e makefile

 

 

 

 

AVRFreak web site

 

 

 

 

 

Repost: 27 Maggio 2008

Leave a Reply