From 8a2d9bf52b522a71f94016ba6855ac0413403bed Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Thu, 12 Jul 2007 23:15:04 +0000 Subject: [PATCH] Aggiunto del vecchio materiale su make e CVS, per una appendice sugli strumenti di ausilio allo sviluppo. Grazie ad Alessio Frusciante per avermene ricordato l'esistenza ... --- build.tex | 421 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ gapil.tex | 1 + 2 files changed, 422 insertions(+) create mode 100644 build.tex diff --git a/build.tex b/build.tex new file mode 100644 index 0000000..8f2bfbb --- /dev/null +++ b/build.tex @@ -0,0 +1,421 @@ +%% build.tex +%% +%% Copyright (C) 1999-2007 Simone Piccardi. Permission is granted to copy, +%% distribute and/or modify this document under the terms of the GNU Free +%% Documentation License, Version 1.1 or any later version published by the +%% Free Software Foundation; with the Invariant Sections being "Un preambolo", +%% with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the +%% license is included in the section entitled "GNU Free Documentation +%% License". +%% + +\chapter{Gli strumenti di ausilio per la programmazione} +\label{cha:build_manage} + +Tratteremo in questa appendice in maniera superficiale i principali strumenti +che vengono utilizzati per programmare in ambito Linux, ed in particolare gli +strumenti per la compilazione e la costruzione di programmi e librerie, e gli +strumenti di gestione dei sorgenti e di controllo di versione. + +Questo materiale è ripreso da un vecchio articolo, ed al momento è molto +obsoleto. + + +\section{L'uso di \texttt{make} per la compilazione} + +Il comando \texttt{make} serve per effettuare una compilazione intelligente di +tutti i file relativi a un programma (corpo principale, funzioni ausiliarie, +librerie collegate, ecc.) ricompilando solo i file necessari. + +\subsection {Introduzione a \texttt{make}} + +Con \texttt{make} si possono definire i simboli del preprocessore C che +consentono la compilazione condizionale dei programmi (anche in Fortran); è +pertanto possibile gestire la ricompilazione dei programmi con diverse +configurazioni con la modifica di un unico file. + +La sintassi normale del comando (quella che si usa quasi sempre, per le +opzioni vedere la pagina di manuale) è semplicemente \texttt{make}. Questo +comando esegue le istruzioni contenute in un file standard (usualmente +\texttt{Makefile}, o \texttt{makefile} nella directory corrente). + +Il formato normale dei comandi contenuti in un \texttt{Makefile} è: +\begin{verbatim} +bersaglio: dipendenza1 dipendenza2 ... + regola1 + regola2 + ... +\end{verbatim} +dove lo spazio all'inizio deve essere un tabulatore (metterci degli spazi è un +errore comune, fortunatamente ben segnalato dalle ultime versioni del +programma), il bersaglio e le dipendenze nomi di file e le regole comandi di +shell. + +Il concetto di base è che se uno dei file di dipendenza è più recente (nel +senso di tempo di ultima modifica) del file bersaglio quest'ultimo viene +ricostruito di nuovo usando le regole elencate nelle righe successive. + +Il comando \texttt{make} ricostruisce di default il primo bersaglio che viene +trovato nella scansione del \texttt{Makefile}, se in un \texttt{Makefile} sono +contenuti più bersagli indipendenti, si può farne ricostruire un altro che non +sia il primo passandolo esplicitamente al comando come argomento, con qualcosa +del tipo di: \texttt{make altrobersaglio}. + +Si tenga presente che le dipendenze stesse possono essere dichiarate come +bersagli dipendenti da altri file; in questo modo è possibile creare una +catena di ricostruzioni. + +In esempio comune di quello che si fa è mettere come primo bersaglio il +programma principale che si vuole usare, e come dipendenze tutte gli oggetti +delle funzioni subordinate che utilizza, con i quali deve essere collegato; a +loro volta questi oggetti sono bersagli che hanno come dipendenza i relativi +sorgenti. In questo modo il cambiamento di una delle funzioni subordinate +comporta solo la ricompilazione della medesima e del programma finale. + + +\subsection{Utilizzo di \texttt{make}} + +Il comando \texttt{make} mette a disposizione una serie molto complesse di +opzioni e di regole standard predefinite e sottintese, che permettono una +gestione estremamente rapida e concisa di progetti anche molto complessi; per +questo piuttosto che fare una replica del manuale preferisco commentare un +esempio di \texttt{makefile}, quello usato per ricompilare i programmi di +analisi dei dati dei test su fascio del tracciatore di Pamela. + +\small +\begin{verbatim} +#---------------------------------------------------------------------- +# +# Makefile for a Linux System: +# use GNU FORTRAN compiler g77 +# Makefile done for tracker test data +# +#---------------------------------------------------------------------- +# Fortran flags +FC=g77 +FFLAGS= -fvxt -fno-automatic -Wall -O6 -DPC # -DDEBUG +CC=gcc +CFLAGS= -Wall -O6 +CFLADJ=-c #-DDEBUG +# +# FC Fortran compiler for standard rules +# FFLAGS Fortran flags for standard rules +# CC C Compiler for standard rules +# CFLAGS C compiler flags for standard rules +LIBS= -L/cern/pro/lib -lkernlib -lpacklib -lgraflib -lmathlib +OBJ=cnoise.o fit2.o pedsig.o loop.o badstrp.o cutcn.o readevnt.o \ +erasepedvar.o readinit.o dumpval.o writeinit.o + +riduzione: riduzione.F $(OBJ) commondef.f readfile.o + $(FC) $(FFLAGS) -o riduzione riduzione.F readfile.o $(OBJ) $(LIBS) + +readfile.o: readfile.c + $(CC) $(CFLAGS) -o readfile.o readfile.c + +$(OBJ): commondef.f + +.PHONY : clean +clean: + rm -f *.o + rm -f *~ + rm -f riduzione + rm -f *.rz + rm -f output +\end{verbatim} +\normalsize + +Anzitutto i commenti, ogni linea che inizia con un \texttt{\#} è un +commento e non viene presa in considerazione. + +Con \texttt{make} possono essere definite delle variabili, da potersi riusare +a piacimento, per leggibilità si tende a definirle tutte maiuscole, +nell'esempio ne sono definite varie: \small +\begin{verbatim} +FC=g77 +FFLAGS= -fvxt -fno-automatic -Wall -O6 -DPC # -DDEBUG +CC=gcc +CFLAGS= -Wall -O6 +CFLADJ=-c #-DDEBUG +... +LIBS= -L/cern/pro/lib -lkernlib -lpacklib -lgraflib -lmathlib +OBJ=cnoise.o fit2.o pedsig.o loop.o badstrp.o cutcn.o readevnt.o \ +\end{verbatim} +\normalsize + +La sintassi è \texttt{NOME=}, alcuni nomi però hanno un significato speciale +(nel caso \texttt{FC}, \texttt{FLAGS}, \texttt{CC}, \texttt{CFLAGS}) in quanto +sono usati da \texttt{make} nelle cosiddette \textsl{regole implicite} (su cui +torneremo dopo). + +Nel caso specifico, vedi anche i commenti, abbiamo definito i comandi di +compilazione da usare per il C e il Fortran, e i rispettivi flag, una variabile +che contiene il pathname e la lista delle librerie del CERN e una variabile con una +lista di file oggetto. + +Per richiamare una variabile si usa la sintassi \texttt{\$(NOME)}, ad esempio +nel makefile abbiamo usato: +\begin{verbatim} + $(FC) $(FFLAGS) -o riduzione riduzione.F readfile.o $(OBJ) $(LIBS) +\end{verbatim} +e questo significa che la regola verrà trattata come se avessimo scritto +esplicitamente i valori delle variabili. + +Veniamo ora alla parte principale del makefile che esegue la costruzione del +programma: +\begin{verbatim} +riduzione: riduzione.F $(OBJ) commondef.f readfile.o + $(FC) $(FFLAGS) -o riduzione riduzione.F readfile.o $(OBJ) $(LIBS) +readfile.o: readfile.c + $(CC) $(CFLAGS) -o readfile.o readfile.c +$(OBJ): commondef.f +\end{verbatim} + +Il primo bersaglio del makefile, che definisce il bersaglio di default, è il +programma di riduzione dei dati; esso dipende dal suo sorgente da tutti gli +oggetti definiti dalla variabile \texttt{OBJ}, dal file di definizioni +\texttt{commondef.f} e dalla routine C \texttt{readfile.o}; si noti il +\texttt{.F} del sorgente, che significa che il file prima di essere compilato +viene fatto passare attraverso il preprocessore C (cosa che non avviene per i +\texttt{.f}) che permette di usare i comandi di compilazione condizionale del +preprocessore C con la relativa sintassi. Sotto segue il comando di +compilazione che sfrutta le variabili definite in precedenza per specificare +quale compilatore e opzioni usare e specifica di nuovo gli oggetti e le +librerie. + +Il secondo bersaglio definisce le regole per la compilazione della routine +in C; essa dipende solo dal suo sorgente. Si noti che per la compilazione +vengono usate le variabili relative al compilatore C. Si noti anche che se +questa regola viene usata, allora lo sarà anche la precedente, dato che +\texttt{riduzione} dipende da \texttt{readfile.o}. + +Il terzo bersaglio è apparentemente incomprensibile dato che vi compare +solo il riferimento alla variabile \texttt{OBJ} con una sola dipendenza e +nessuna regola, essa però mostra le possibilità (oltre che la +complessità) di \texttt{make} connesse alla presenza di quelle regole +implicite a cui avevamo accennato. + +Anzitutto una una peculiarità di \texttt{make} è che si possono anche usare +più bersagli per una stessa regola (nell'esempio quelli contenuti nella +variabile \texttt{OBJ} che viene espansa in una lista); in questo caso la +regola di costruzione sarà applicata a ciascuno che si potrà citare nella +regola stessa facendo riferimento con la variabile automatica: \texttt{\$@}. +L'esempio usato per la nostra costruzione però sembra non avere neanche la +regola di costruzione. + +Questa mancanza sia di regola che di dipendenze (ad esempio dai vari sorgenti) +illustra le capacità di funzionamento automatico di \texttt{make}. +Infatti è facile immaginarsi che un oggetto dipenda da un sorgente, e che +per ottenere l'oggetto si debba compilare quest'ultimo. + +Il comando \texttt{make} sa tutto questo per cui quando un bersaglio è un +oggetto (cioè ha un nome tipo \texttt{qualcosa.o}) non è necessario +specificare il sorgente, ma il programma lo va a cercare nella directory +corrente (ma è possibile pure dirgli di cercarlo altrove, il caso è trattato +nel manuale). Nel caso specifico allora si è messo come dipendenza solo il +file delle definizioni che viene incluso in ogni subroutine. + +Inoltre come dicevamo in genere per costruire un oggetto si deve compilarne il +sorgente; \texttt{make} sa anche questo e sulla base dell'estensione del +sorgente trovato (che nel caso sarà un \texttt{qualcosa.f}) applica la regola +implicita. In questo caso la regola è quella di chiamare il compilatore +fortran applicato al file oggetto e al relativo sorgente, questo viene fatto +usando la variabile \texttt{FC} che è una delle variabili standard usata dalle +regole implicite (come \texttt{CC} nel caso di file \texttt{.c}); per una +maggiore flessibilità poi la regola standard usa anche la variabile +\texttt{FFLAGS} per specificare, a scelta dell'utente che non ha che da +definirla, quali flag di compilazione usare (nella documentazione sono +riportate tutte le regole implicite e le relative variabili usate). + +In questo modo è stato possibile usare una sola riga per indicare la serie di +dipendenze e relative compilazioni delle singole subroutine; inoltre con l'uso +della variabile \texttt{OBJ} l'aggiunta di una nuova eventuale routine +\texttt{nuova.f} comporta solo l'aggiunta di \texttt{nuova.o} alla definizione +di \texttt{OBJ}. + + +\section{Cuncurrent Version System -- CVS} + +Il programma CVS è un sistema di archiviazione dei programmi che consente di +tenere traccia di tutte le modifiche e di condividere un archivio comune per +progetti portati avanti da diverse persone. + +\subsection{Introduzione} +CVS è basato sul concetto di repositorio, un archivio in cui vengono riposti +e da cui vengono presi i sorgenti dei programmi. L'archivio tiene traccia delle +diverse versioni registrate; i programmatori inviano le modifiche usando una +copia locale che hanno nella loro directory di lavoro. + +CVS può gestire più di un progetto, esso organizza i progetti in +\textsl{moduli} identificati dal nome della directory in cui sono messi i file +relativi, ad esempio: +\small +\begin{verbatim} +[piccardi@pcpamela ~]$ ls /usr/local/cvsroot/ +CVSROOT adidsp geometry muonacq pamela +\end{verbatim} +\normalsize %$ +in questo caso si hanno i moduli \texttt{adidsp geometry muonacq pamela}; un +utente potrà recuperare tutti i file relativi al modulo \texttt{pamela} che +andaranno nella directory \texttt{pamela}; è anche possibile gestire una +gerarchia di moduli, inseriti in un albero di directory. + +CVS ha una directory base dove tiene gli archivi (che nel è appunto +\texttt{/usr/local/cvsroot}) e i vari file amministrativi; ogni progetto deve +fare riferimento ad essa; in un progetto attivo essa viene memorizzata nei +file amministrativi locali del progetto (ad esempio per un utente che ha il +progetto \texttt{muonacq} nella sua home directory sarà in +\texttt{\tild/muonacq/CVS}) e non è necessario specificarla; in generale essa +viene tenuta dalla variabile di shell \texttt{CVSROOT} (inizializzata allo +startup), o specificata direttamente dall'utente con l'apposita opzione +\texttt{-d} (ex. \texttt{cvs -d /usr/local/cvsroot comando opzioni}). + +Normalmente l'archivio si tiene su una macchina remota e vi si accede via +rete. Per repositori esterni esistono varie modalità di accesso, la via più +semplice è quella dell'uso di \texttt{ssh} come rimpiazzo di \texttt{rsh} per +l'accesso esterno; in tal caso la directory del repositorio si può accedere +con la sintassi: \small +\begin{verbatim} +cvs -d :ext:utente@server:/usr/local/cvsroot comando +\end{verbatim} +\normalsize + +questo però comporta che sulla macchina remota \texttt{server} sia installato +il server \texttt{ssh} ed esista l'utente \texttt{utente} con privilegi di +accesso ai file; inoltre sulla macchina ospite deve esser stata definita la +variabile di shell \texttt{CVS\_RSH=ssh}. + +In questo modo ssh si collega alla macchina remota ed esegue il comando CVS con +una connessione criptata dopo aver richiesto la password di \texttt{utente}. + + +\subsection{Utilizzo di \texttt{cvs}} + +Per creare un repositorio a partire da un gruppo di programmi esistente basta +dare il comando \texttt{cvs import project tag release} nella directory dei +sorgenti; verrà creato nel repositorio il modulo di nome \texttt{project} a +cui poi si potrà accedere con i successivi comandi; \texttt{tag} è una +etichetta di versione iniziale (ex. \texttt{1.1.1}) dato a tutto il blocco e +\texttt{release} una etichetta di versione data ai programmi. + +Una volta creato il repositorio è d'uopo cancellare la directory e ripartire +dal progetto appena creato. Per recuperare ex-novo tutti i file di un progetto +il comando da dare è: +\small +\begin{verbatim} +cvs [-d ...] checkout project [-r rel] [-D date] +\end{verbatim} +\normalsize che creerà la directory \texttt{project} nella directory corrente +con l'ultima versione dei file archiviata; se non si vuole la versione più +aggiornata, ma una versione precedente si può usare l'opzione \texttt{-r} che +scaricherà la versione identificata dall'etichetta specificata (vedi la parte +seguente sul comando \texttt{tag}) o l'opzione \texttt{-D} che scaricherà la +versione più recente prima della data specificata. + +Una volta scaricato il progetto è possibile evitare di specificare la +directory base del repositorio con l'opzione \texttt{-d} qualora i comandi +vengano dati all'interno della directory creata, essa viene tenuta nel file +\texttt{CVS/Root}, e può essere cambiata (qualora si usino più repositori) +editando detto file. + +Una volta creata la propria copia locale dei programmi, è possibile lavorare +su di essi stando nella relativa directory, +e apportare tutte le modifiche che si vogliono; due comandi +permettono di schedulare la rimozione o l'aggiunta di file al repositorio: +\small +\begin{verbatim} +cvs add file1.c +cvs remove file2.c +\end{verbatim} +\normalsize +ma niente viene modificato nel repositorio fintanto che non viene dato il +comando \texttt{commit}: +\small +\begin{verbatim} +cvs commit [file] +\end{verbatim} +(è possibile mandare le modifiche anche per il singolo file). + +Questi comandi comunque non effettuano le modifiche se i file del repositorio +nel frattempo sono stati modificati; in questo caso rilevano le differenze e +restituiscono un \textit{merging} delle versioni locale/globale nella +directory di lavoro, che è compito del programmatore esaminare per eliminare +eventuali contrasti. + +Per esempio viene eseguito un commit su una versione già modificata da un +altro sul repositorio, il programma segnalerà che c'è un conflitto e +chiederà al ``committente'' di intervenire sui file per i quali sono stati +rilevati i conflitti . + +Le sezioni di codice in conflitto sono separate come: +\begin{verbatim} +<<<<<<< Makefile + $(CC) $(CFLAGS) -o pamacq pamacq.c -lm +======= + $(CC) $(CFLAGS) -o pamacq pamacq.c + +>>>>>>> 1.22 +\end{verbatim} +nel caso si c'è stata una modifica sul file (mostrata nella parte superiore) +incompatibile con quella fatta nel repositorio (mostrata nella parte +inferiore). Prima di eseguire un \textit{commit} occorre pertanto integrare le +modifiche e risalvare il file; a questo punto il \textit{commit} diventa +possibile. + +\subsection{I principali sotto comandi} + +I principali sottocomandi di \texttt{cvs} utilizzati per controllare lo stato +dei sorgenti sono: + +\begin{itemize} +\item \texttt{cvs update} \\ + scarica le eventuali modifiche dei file del repositorio e le applica ai file + nella directory corrente. In caso di conflitti con modifiche locali effettua + un \textit{merging} con le caratteristiche esposte in precedenza. + +\item \texttt{cvs status} \\ + compara i file nella directory locale con quelli del repositorio e stampa a + schermo le informazioni di stato di ciascuno di essi: +\begin{itemize} +\item \texttt{Locally Modified} il file è stato modificato localmente +\item \texttt{Locally Added} il file è stato aggiunto localmente +\item \texttt{Up to date} il file è identico +\item \texttt{Needs Patch} il file è cambiato sul repositorio (va aggiornato) +\item \texttt{Needs Merge} il file è cambiato sul repositorio e localmente, le + differenze vanno riunite prima del commit, in genere basta un \texttt{cvs + update}, ma in caso di conflitti questi vanno sanati. + +\end{itemize} + +\item \texttt{cvs log} \\ + legge il giornale del modulo corrente; in questo modo si hanno le + informazioni sullo stato del progetto all'interno del repositorio, per + ciascun file è vengono mostrati informazioni generali su: +\begin{itemize} +\item release attuale +\item presenza di eventuali ramificazioni +\item lista di etichette simboliche +\item i messaggi di commento salvati ad ogni \textit{commit} +\end{itemize} + +\item \texttt{cvs rtag Etichetta modulo} \\ + permette di associare una etichetta alla corrente versione dei file nel + progetto così come sono nel repositorio; in modo da poter ritornare a quello + stato del software con il comando \texttt{cvs checkout -rEtichetta module}. + +\end{itemize} + +%TODO mettere SVN al posto di CVS + + +% LocalWords: make Makefile makefile shell FC FLAGS CFLAGS pathname CERN +% LocalWords: OBJ commondef readfile FFLAGS Cuncurrent Version System CVS home +% LocalWords: adidsp geometry muonacq andaranno CVSROOT startup cvs ssh rsh to +% LocalWords: project tag Root commit update merging Locally Modified Added +% LocalWords: Needs Patch Merge log rtag checkout module + + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "gapil" +%%% End: diff --git a/gapil.tex b/gapil.tex index 0c329e6..65be67f 100644 --- a/gapil.tex +++ b/gapil.tex @@ -175,6 +175,7 @@ \include{netlayer} \include{trasplayer} \include{errors} +\include{build} \include{ringraziamenti} \include{fdl} -- 2.30.2