2009-05-24 24 views
14

La domanda probabilmente non è la migliore per descrivere il mio problema, ma non riuscivo a pensarne uno migliore. Il mio makefile va così:Come eseguire correttamente il makefile per compilare ed eseguire?

PROGRAM_NAME = prog 

OBJECT_FILES = $(PROGRAM_NAME).o 
CFLAGS = -O2 -Wall -g 

$(PROGRAM_NAME) : $(OBJECT_FILES) 
    gcc $(CFLAGS) -o [email protected] $(OBJECT_FILES) 

$(PROGRAM_NAME).o : $(PROGRAM_NAME).c data.h 
    gcc $(CFLAGS) -c $< 

clean : 
    $(RM) $(PROGRAM_NAME) 
    $(RM) $(OBJECT_FILES) 
    $(RM) *~ *.bak 

run : 
    @$(MAKE) && ./$(PROGRAM_NAME) $(ARGS) 

Quando voglio compilare ed eseguire, faccio semplicemente "make run". Il problema con questo è che il mio programma gestisce il segnale prodotto da Ctrl + Z e se avvio il mio programma con "make run", il segnale verrà inviato a "make run" e non il mio programma stesso.

In sostanza, chiamando "make run" non è la stessa cosa di chiamando direttamente "fare & & ./prog", perché nel primo caso, "make run" non terminerà a meno che "prog" termina prima.

C'è un modo per aggirare questo?

risposta

12

L'esecuzione dal makefile è un po 'insolita. Stai forse cercando di duplicare la voce di menu "Compila ed esegui" fornita da qualche IDE? Fare non è ben attrezzato per farlo.

Tutto ciò che accade nei comandi di destinazione avviene in sottoprocessi che non sono collegati direttamente al terminale, motivo per cui make riceve il tratto chiave.

Un'altra cosa da osservare: in genere il file oggetto in fase eseguibile (collegamento) utilizza un diverso gruppo di flag (LDFLAGS e LIBS) quindi la fase di compilazione. In questo semplice esempio puoi farla franca, ma se copi questo makefile per usarlo in un caso più complicato, ti troverai nei guai.

+0

ho meglio non usarlo in questo modo, allora ... :) –

3

Come ha detto la risposta di dmckee, make (1) sta facendo qualcosa, non per compilare ed eseguire.

Naturalmente, nulla si ferma per la creazione di un guscio alias make-run che fa l'intesa 'fanno & & args ./prog'.

13

È possibile semplificare il vostro target 'run' da averlo dipende dal fatto che il vostro programma è aggiornato, e poi semplicemente eseguire il programma:

run: ${PROGRAM_NAME} 
     ./${PROGRAM} ${ARGS} 

Non c'è molto senso in esecuzione make quando sei già in esecuzione make - almeno, non in questo contesto. Forse per operazioni ricorsive (in diverse directory), ma vedi 'Recursive Make Considered Harmful'.

Inoltre, il makefile dovrebbe normalmente fornire un target "all" e normalmente dovrebbe essere il primo e quindi il target predefinito.

4

Se avete intenzione di costruire e gestire più e più volte, è possibile utilizzare il comando history per aiutare con questo:

# Run this once 
make && ./foo 

# Repeat last command 
!! 
+2

Ancora meglio , in Bash puoi usare '! make' per ripetere l'ultimo comando che inizia con" make ", anche se esegui altri comandi in mezzo. Quel flusso di lavoro funziona molto bene per me. –

Problemi correlati