Makefile e opzioni compilatore C

Documenti analoghi
La seconda linea deve iniziare con un TAB (non la scritta 'TAB') e contiene cosa il programmatore scriverebbe per ottenere quel target.

Makefile. Il file dependency system di Unix (serve ad automatizzare il corretto aggiornamento di più file che hanno delle dipendenze)

Compilazione e Makefile

Makefile. Il file dependency system di Unix (serve ad automatizzare il corretto aggiornamento di più file che hanno delle dipendenze)

perror: individuare l errore quando una system call restituisce -1

Un codice sorgente. Introduzione alla compilazione automatica: Make e Makefile. Generazione di un programma eseguibile. Un codice sorgente

Compilazione e Makefile

Le direttive del Preprocessore

Il comando make. Per produrre un eseguibile da un programma C sono necessari tre passi compiuti dai seguenti moduli:

Utilizzo di make e di Makefile per compilare programmi in C e in C++

Preprocessore (cpp) Compilatore (gcc)

Introduzione al C. Unità 10 Preprocessore. D. Bloisi, S. Peluso, A. Pennisi, S. Salza

Introduzione al C. Unità 10 Preprocessore

Il preprocessore. Direttiva define Direttiva include Direttiva if

Uso di GCC da riga di comando

Programmare. Definire una sequenza di istruzioni che specificano come effettuare una elaborazione

BREVISSIMA GUIDA AL SISTEMA UNIX / LINUX

Il linguaggio C. Il preprocessore...

Esercitazione 1 la shell

Bloodshed Dev-C++ Bloodshed Dev-C++ è l IDE usato durante le esercitazioni/laboratorio. IDE = Integrated Development Environment. Codice corso: 21012

prova.c #include <stdio.h> char funzione(char); codice oggetto del main()

Cenni sul preprocessore e il suo utilizzo

Unità Didattica 1 Linguaggio C. Fondamenti. Struttura di un programma.

Laboratorio di Programmazione 1. Docente: dr. Damiano Macedonio Lezione 4 24/10/2013

LABORATORIO DI SISTEMI OPERATIVI

Introduzione alla programmazione nella shell di Unix 10 Maggio 2005

I Fondamenti del Linguaggio

Introduzione al linguaggio C Primi programmi

Corso Linux Base. 2. Uso del Sistema

Il linguaggio C. Il preprocessore...

Programmare. Definire una sequenza di istruzioni che specificano come effettuare una elaborazione

Analizzatori Lessicali con JLex. Giuseppe Morelli

Debug di un programma

Preprocessore. Unità 9. Corso di Laboratorio di Informatica Ingegneria Clinica BCLR. Domenico Daniele Bloisi Si ringrazia Raffaele Nicolussi

Page 1. Programmazione. Shell e programmazione. File comandi (script) Introduzione alla programmazione nella shell di Unix

L ambiente UNIX/Linux. Strumenti per la programmazione C Stefano Quer Dipartimento di Automatica e Informatica Politecnico di Torino

Laboratorio di Algoritmi e Strutture Dati

Ambienti Operativi: Make

Linguaggio di Riferimento: C

IDE DevC

Preprocessore, linker e libreria standard

Bloodshed Dev-C++ Bloodshed Dev-C++ è l IDE usato durante le esercitazioni/laboratorio. IDE = Integrated Development Environment. Codice corso: 21012

Introduzione al DEV C++

Comandi principali di Linux (1)

Classi di memorizzazione

Introduzione alla programmazione in linguaggio C

Directory. Le directory unix sono file.

Lezione 6 Introduzione al C++ Mauro Piccolo

Introduzione a Visual Studio 2005

Elementi di Informatica A. A. 2016/2017

Laboratorio reti AA 2008/2009. Dott. Matteo Roffilli Ricevimento in ufficio dopo la lezione

Cosa è importante: pom.xml Goal Plug-in Repository

Preprocessing, compilazione ed esecuzione. Utilizzando strumenti GNU...

Introduzione al C. Lez. 1 Elementi. Rossano Venturini

COSTRUZIONE DI UN APPLICAZIONE

Corso di Laboratorio di Sistemi Operativi

Corso di Laboratorio di Sistemi Operativi A.A

Il comando Make: : uno strumento per la compilazione ed esecuzione di software applicativo. A. Murli - Cacolo Scientifico a.a.

Il generatore di numeri casuali

Funzionalità. Il preprocessore C. Inclusione di file. Inclusione di file

Agenda. Agenda. Credenziali. Configurazione del Proxy (1/2) Configurazione del Proxy (2/2) Fondamenti di Informatica T2 Modulo 2

Laboratorio di Elementi di Architetture e Sistemi Operativi Soluzioni degli esercizi del 16 Maggio 2012

La direttiva #include

Unix e comandi di base

ISTRUZIONI DEVC++ Autore: Luca Florio (luca.florio<at>polimi.it)

Struttura dei programmi e Variabili

Laboratorio Progettazione Web Le funzioni in PHP. Angelica Lo Duca IIT-CNR 2012/2013

Sistemi Operativi. Corso di Laurea Triennale in Ingegneria Informatica. Daniel Cesarini

Primo passo: il preprocessor. Il preprocessore. Esempi di direttive al preprocessore: #include. Esempi di direttive al preprocessore: #define

Funzioni, Stack e Visibilità delle Variabili in C

#include <stdio.h> /* l esecuzione comincia dalla funzione main */ int main()

Lab. di Sistemi Operativi - Esercitazione n 2- - comando di ricerca: grep -

scrivere window.alert(). 2 Nell esempio sarebbe scritto solo var hello, senza pertanto attribuire alla variabile hello alcun valore

Programmazione I - Laboratorio

Esercitazione di Laboratorio - 4

Elementi di Base. Introduzione a Python.

Lezione 1. Programmazione. Lab di Programmazione. Linux e la sua shell: questi sconosciuti. Filippo Gaudenzi. Università degli Studi di Milano

Il corpo di tutte le funzioni deve essere contenuto tra parentesi graffe

Fondamenti di Informatica T2 Modulo 2. Corso di Laurea in Ingegneria Informatica Anno accademico 2008/2009. Agenda

Lezione 5: Introduzione alla programmazione in C

Primi programmi in C

Sistemi Operativi. Esercitazione 2 Compilazione, Makefile e Processi

Funzioni. Unità 1. Domenico Daniele Bloisi. Corso di Fondamenti di Informatica Ingegneria delle Comunicazioni BCOR Ingegneria Elettronica BELR

Concetti base programmazione. Antonio Gallo

BASH: Bourne Again Shell (3)

L AMBIENTE CODE BLOCKS E L IO

#include <stdio.h> main() { - 1 -

Linguaggi di Programmazione

CORSO DI SISTEMI OPERATIVI A - ESERCITAZIONE 4

Fondamenti di Informatica T-1 modulo 2

NOTE SULL USO DI ECLIPSE per la compilazione di programmi c

PREFAZIONE... IX Lo scopo di questo libro... ix La metodologia di insegnamento... ix Panoramica sul libro... xiii

- Controllo di flusso: for -

Laboratorio Programmazione Anno Lezione 3

Funzioni, Stack e Visibilità delle Variabili in C

Transcript:

Makefile e opzioni compilatore C Massimo Bernaschi massimo.bernaschi@cnr.it materiale originale di David A. Gaitros

Introduzione Il comando Unix make è uno degli strumenc disegnac da S. I. Fieldman degli AT&T Bell labs nel (circa) 1977. Ne esistono ormai molte versioni. L obieqvo originale di make è permerere agli sviluppatori di compilare efficientemente grandi programmi composc da molc componenc in maniera semplice. Si possono ovviamente inserire tuq i comandi necessari per la compilazione in uno script ma in questo modo vengono ricompilac ogni volta tuq i componenc. Il comando make permere di compilare solo i moduli che sono cambiac e quelli che dipendono da quesc.

Come funziona? Quando si lancia il comando make il sistema operacvo cerca un file con il nome makefile o Makefile. È comunque possibile specificare un nome diverso con l opzione -f. Il makefile concene una serie di dire2ve che dicono al comando make come compilare il programma ed in quale ordine. Ad ogni file è associata una lista di altri file da cui dipende. La lista è chiamata linea di dipendenze. Se uno qualsiasi dei file contenuc nella lista è stato modificato, il comando make esegue il comando che è immediatamente soro la linea di dipendenza.

Come funziona? Il comando make è ricorsivo. Per esempio, anche se un solo componente da cui dipende una catena di moduli viene cambiato, potrebbe comunque essere eseguita la ricompilazione (o almeno il re-link) di tuq i moduli. Quando il comando finisce la scansione del file, esegue un secondo controllo per assicurarsi che ture le dipendenze siano state risolte.

Un esempio (semplice) hello: main.o factorial.o hello.o g++ main.o factorial.o hello.o -o hello main.o: main.cpp g++ -c main.cpp factorial.o: factorial.cpp g++ -c factorial.cpp hello.o: hello.cpp g++ -c hello.cpp clean: rm -rf *o hello

Il corrispondente albero hello main.o factorial.o hello.o factorial.o factorial.cpp hello.cpp main.cpp clean

ComponenC di un Makefile CommenC Regole Linee di dipendenza Linee per l interprete di comandi (shell) Macro Regole di inferenza

CommenC Un commento viene indicato dal cararere #. TuRo ciò che viene dopo viene ignorato fino a quando non viene rilevato il cararere di fine linea. I commenc possono iniziare in qualunque punto. Esempi # # This is a comment projecte.exe : main.obj io.obj # this is also a comment.

Regole Le regole dicono a make quando e cosa fare per creare un file. Il formato è il seguente: Una regola deve avere un linea di dipendenze e può avere una linea di azione o un comando di shell dopo di essa. La linea di azione è eseguita se la linea di dipendenza non è aggiornata. Esempio: hello.o: hello.cpp g++ -c hello.cpp hello.o è un modulo che richiede hello.cpp come codice sorgente. Se la data di ulcma modifica di hello.cpp è più recente di hello.o, allora viene eseguita la linea successiva ed hello.cpp viene ricompilato.. Le due linee unite definiscono una regola

Linee di dipendenza Le linee con un : sono dere linee di dipendenza. Alla sinistra ci sono le dipendenze Alla destra ci sono i sorgenc necessari per costruire le dipendenze. Quando si lancia il comando make, vengono controllate la data e l ora in cui il target (le dipendenze) è stato creato e confrontate con quelle dei sorgenc necessari per costruirle. Se uno qualsiasi ha una data più recente, allora viene eseguita la linea comandi dopo la linea di dipendenza. Il processo di make è ricorsivo nel senso che controlla ture le dipendenze per essere sicuri che turo sia aggiornato prima di completare il processo di costruzione dei target. È importante che tu6e le dipendenze siano piazzate in ordine discendente nel makefile. Alcuni file possono avere le stesse dipendenze. Supponiamo, ad esempio che due file dipendano dal file bitvect.h. Possiamo avere la linea di dipendenza: main.o this.o: bitvect.h

Linee comandi (shell) Le linee indentate (devono avere un tab iniziale!) che seguono ogni linea di dipendenza sono dere linee di shell. Le linee di shell dicono a make come costruire il target. Un target può essere seguito da più linee comandi. Ogni linea deve essere preceduta da un tab. Dopo che ogni comando è eseguito, make controlla che non ci siano stac errori. Gli errori possono essere ignorac (opzione i) ma non è consigliabile.

Linee comandi (shell) Le linee di shell che ritornano un codice zero (0) sono state eseguite senza errori mentre un codice diverso da zero indica un errore. La prima linea comandi che ritorna un codice diverso da zero forza la terminazione del comando make che mostra l errore che ha generato la terminazione. Si può modificare questo comportamento inserendo un - di fronte al comando (ma non è consigliabile) Esempio: - gcc o my my.o mylib.o

Macro Viene dal Greco makros (significa grande ). In breve è un modo comparo per rappresentare qualcosa o un alias usato in the makefile Un stringa di carareri è associata con un altra (in genere) più lunga stringa Nel makefile, per espandere una macro, si deve inserire la stringa in $( ). La stringa viene espansa (per sosctuzione) durante l esecuzione del comando make.

Macro Esempi di macro: HOME = /home/corso/pds/spring17 CPP = $(HOME)/cpp TCPP = $(HOME)/tcpp PROJ =. INCL = -I $(PROJ) I$(CPP) I$(TCPP) Si possono definire macro anche sulla linea comandi Make HOME = /home/esame/aaa/finale Queste macro hanno la precedenza sulle corrispondenc definite nel makefile.

Regole di inferenza Le regole di inferenza sono un metodo per generalizzare il processo di costruzione. In sostanza è una sorta di notazione basata su wild card. Il cararere % è usato per indicare una wild card. Esempio: %.o : %.c $(CC) $(FLAGS) c $(.SOURCE) TuQ i.o files hanno dipendenze da tuq i %.c file dello stesso nome.

Variabili predefinite Sono disponibili variabili predefinite che fanno riferimento a parc specifiche delle regole target : dipendenze TAB commandi #comandi di shell eval.o : eval.c eval.h g++ -c eval.c $@ - Il nome del target della regola (eval.o). $< - Il nome della prima dipendenza (eval.c). $^ - I nomi di ture le dipendenze (eval.c eval.h). $? - I nomi di ture le dipendenze che sono più nuove del target

Phony target Phony target: Target che non hanno dipendenze. Sono usac solo come nomi per comandi da eseguire su richiesta. clean: rm $(OBJS) Per invocarlo: make clean Tipici phony target: all costruisce tuq i target di primo livello o.phony : all all: my_prog1 my_prog2.phony : clean clean: rm $(OBJS) clean cancella tuq i file che sono normalmente creac da make print stampa il listato dei sorgenc che sono stac modificac

DireQve Condizionali Le direqve condizionali sono: if ifeq ifneq ifdef ifndef TuQ devono essere chiusi da endif. È possibile uclizzare elif ed else. Esempio: libs_for_gcc = -lgnu normal_libs = ifeq ($(CC),gcc) else libs=$(libs_for_gcc) libs=$(normal_libs) endif #no tab at the beginning #no tab at the beginning

Esempio di makefile CC = gcc DIR = /home/massimo/corso/lib CFLAGS = -g -I$(DIR) -I. -c LFLAGS = -g opt: analysis.o flow.o io.o misc.o opt.o opts.o peephole.o regs.o vect.o $(CC) $(LFLAGS) -o opt analysis.o flow.o io.o misc.o opt.o opts.o peephole.o regs.o vect.o analysis.o: analysis.c analysis.h $(DIR)/misc.h $(DIR)/opt.h $(DIR)/vect.h $(CC) $(CFLAGS) analysis.c flow.o: $(DIR)/flow.c $(DIR)/flow.h $(DIR)/opt.h $(CC) $(CFLAGS) $(DIR)/flow.c io.o: $(DIR)/io.c $(DIR)/io.h analysis.h $(DIR)/misc.h $(DIR)/opt.h peephole.h $(DIR)/regs.h $(CC) $(CFLAGS) $(DIR)/io.c

misc.o: $(DIR)/misc.c $(DIR)/misc.h $(DIR)/opt.h $(CC) $(CFLAGS) $(DIR)/misc.c opt.o: $(DIR)/opt.c $(DIR)/opt.h $(CC) $(CFLAGS) $(DIR)/opt.c opts.o: opts.c $(DIR)/misc.h $(DIR)/regs.h $(DIR)/opt.h opts.h $(CC) $(CFLAGS) opts.c peephole.o: peephole.c $(DIR)/misc.h $(DIR)/regs.h $(DIR)/opt.h peephole.h $(CC) $(CFLAGS) peephole.c regs.o: $(DIR)/regs.c $(DIR)/regs.h $(DIR)/opt.h $(CC) $(CFLAGS) $(DIR)/regs.c vect.o: $(DIR)/vect.c $(DIR)/vect.h $(DIR)/opt.h $(CC) $(CFLAGS) $(DIR)/vect.c

Principali opzioni compilatore C -c: richiede la sola compilazione senza link -O: aqva l oqmizzazione (più livelli) -o name: crea un file con il nome name -g: include nell object file informazioni ucli durante il debugging -pg: include informazioni per il profiling -s: elimina i simboli (striping) -W: fornisce maggiori informazioni sul processo di compilazione (vari livelli)

La funzione rand() La funzione rand() della libreria C standard può essere uclizzata per generare numeri interi random nel range [0 RAND_MAX] (definito in stdlib.h. Per inizializzare il generatore random, si uclizza la srand(unsigned seed). Ovviamente partendo dallo stesso seme si rioqene esaramente la stessa sequenza di numeri pseudo-random.

Come cancellare un file La funzione UNIX #include <unistd.h> int unlink(const char *path) rimuove il link di path con la sua directory e decrementa il contatore nell inode. La funzione window equivalente è: BOOL DeleteFile(LPCTSTR lpfilename); ARenzione ai valori di ritorno! La funzione unix ritorna 0 in caso di successo Quella windows torna 1 in caso di successo