2011-05-03 16 views
12

Possiedo un codice sorgente FORTRAN composto da molti file .F e .h diversi. Ho bisogno di creare un eseguibile da esso, ma sto avendo alcuni problemi. Il makefile che ho prodotto finora (che può avere errori come io sono nuovo a questo) è:Creazione di un makefile FORTRAN

# compiler 
FC = /usr/bin/gfortran-4.5 

# compile flags 
FCFLAGS = -g -c -fdefault-real-8 -fbacktrace -fno-align-commons 
# link flags 
FLFLAGS = -g -fbacktrace 

# source files and objects 
SRCS = $(patsubst %.F, %.o, $(wildcard *.F)) \ 
     $(patsubst %.h, %.mod, $(wildcard *.h)) 

# program name 
PROGRAM = blah 

all: $(PROGRAM) 

$(PROGRAM): $(SRCS) 
    $(FC) $(FCFLAGS) [email protected] $< 

%.o: %.F 
    $(FC) $(FLFLAGS) -o [email protected] $< 

%.mod: %.h 
    $(FC) $(FLFLAGS) -o [email protected] $< 

clean: 
    rm -f *.o *.mod 

Quando provo a rendere il programma, però, sto diventando una sfilza di errori di riferimento non definiti. Voglio dire, ogni chiamata di subroutine e funzione nel primo file .File compilato restituisce un errore di riferimento non definito. Pensavo che questo fosse dovuto al fatto che gfortran stava cercando di collegare i file invece di compilarli e quindi di collegarli alla fine, ma pensavo che l'opzione '-c' avrebbe dovuto impedirlo.

UPDATE:

Come commentatori hanno fatto notare, ho mescolato le flag di compilazione e di collegamento. Inoltre, non dovresti compilare i file * .h. Ecco l'ultima, makefile corretto:

# compiler 
FC = /usr/bin/gfortran-4.4 

# compile flags 
FCFLAGS = -g -c -fdefault-real-8 -fbacktrace -fno-align-commons -fbounds-check -std=legacy 
# link flags 
FLFLAGS = 

# source files and objects 
SRCS = $(patsubst %.F, %.o, $(wildcard *.F)) 

# program name 
PROGRAM = blah 

all: $(PROGRAM) 

$(PROGRAM): $(SRCS) 
    $(FC) $(FLFLAGS) -o [email protected] $< 

%.o: %.F 
    $(FC) $(FCFLAGS) -o [email protected] $< 

clean: 
    rm -f *.o *.mod 

Ora Quando eseguo make, che verrà compilare ogni file * .F nel codice, ma non riesce nella fase di collegamento. Ricevo un sacco di errori di riferimento non definiti nel primo file * .F. Il compilatore sembra andare su ogni file * .F individualmente nella fase di collegamento, che non sono sicuro sia corretto. Poi ho un errore:

/usr/lib/gcc/x86_64-linux-gnu/4.4.5/libgfortranbegin.a(fmain.o): In function `main': 
(.text+0x26): undefined reference to `MAIN__' 
collect2: ld returned 1 exit status 

Tuttavia, se digito il comando:

gfortran -o blah *.o 

L'eseguibile sarà costruito, così sembra come se avessi fatto qualcosa di sbagliato nel makefile per la fase di collegamento.

UPDATE: 5/9/2011

Sverre rilevare il problema finale con il mio makefile. Nel mio primo target che crea il programma, utilizzo il comando di scelta rapida solo per la prima dipendenza ($ <), ma ho bisogno di includere tutte le dipendenze (cioè tutti i file * .o) usando il collegamento ($ ^). Il makefile finale funzionante è il seguente:

# compiler 
FC  := /usr/bin/gfortran-4.5 

# compile flags 
FCFLAGS = -g -c -fdefault-real-8 -fbacktrace -fno-align-commons -fbounds-check 
# link flags 
FLFLAGS = 

# source files and objects 
SRCS = $(patsubst %.F, %.o, $(wildcard *.F)) 
#  $(patsubst %.h, %.mod, $(wildcard *.h)) 

# program name 
PROGRAM = vipre 

all: $(PROGRAM) 

$(PROGRAM): $(SRCS) 
    $(FC) $(FLFLAGS) -o [email protected] $^ 

%.o: %.F 
    $(FC) $(FCFLAGS) -o [email protected] $< 

# %.mod: %.h 
# $(FC) $(FCFLAGS) -o [email protected] $< 

clean: 
    rm -f *.o *.mod 
+0

Creazione è solo un modo per automatizzare le attività che è possibile eseguire a mano. Puoi compilare questo codice sulla riga di comando, senza Make? In caso contrario, giocherellare con il makefile non aiuterà. – Beta

+5

Si stanno applicando i flag di collegamento alla compilation e viceversa. –

+0

Ci sono troppi file sorgente e header con troppe dipendenze per farmi fare questo manualmente. unapersson, hai ragione. Ho scioccamente commutato queste due variabili. Passandoli indietro mi permise di creare i file .f. gfortran mi sta dando errori per i file .h però. Sembra pensare che siano file C. Ma questa è un'altra domanda. Grazie per l'aiuto. – Bob

risposta

11

Stai utilizzando GNU make? Se è così,

$(FC) $(FLFLAGS) -o [email protected] $< 

può essere il colpevole. $< è il nome del prerequisito, , ma si desidera tutti i file *.o. Prova a utilizzare $^ invece.

+2

Sì, questo è perfetto. Ho fatto il cambiamento e ha funzionato. Il makefile finale funzionante è pubblicato nella mia domanda originale. La cosa divertente è che in realtà ho rintracciato un makefile per questo codice nel mio ufficio l'altro giorno. Tuttavia, è 20 volte più lungo del mio perché elenca ogni singola dipendenza. Molto felice di aver imparato il modo giusto per farlo. – Bob

+1

se una risposta risolve il tuo problema, dovresti contrassegnarlo come tale – steabert

+0

In genere la gente usa '$ (FFLAGS)' invece di '$ (FLFLAGS)' –