2009-05-24 12 views
14

Pytanie prawdopodobnie nie najlepiej opisuje mój problem, ale nie mogłem wymyślić lepszego. Mój plik Makefile jest taki:Jak poprawnie utworzyć plik Makefile, aby skompilować i uruchomić?

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) 

Kiedy chcę skompilować i uruchomić, po prostu wykonuję "make run". Problem polega na tym, że mój program obsługuje sygnał generowany przez Ctrl + Z i jeśli uruchomię program z "make run", sygnał zostanie wysłany do "make run", a nie do samego programu.

Zasadniczo, nazywając „make run” to nie to samo, co wywołanie bezpośrednio „make & & ./prog”, ponieważ w pierwszym przypadku, „make run” nie będzie obowiązywać, o ile „prog” kończy pierwszy.

Czy istnieje sposób obejścia tego?

Odpowiedz

12

Uruchamianie z pliku makefile jest nieco niezwykłe. Czy może próbujesz zduplikować element menu "Kompiluj i uruchom", który zapewnia niektóre IDE? Make nie jest dobrze przygotowany do tego.

Wszystko, co dzieje się w poleceniach docelowych, dzieje się w podprocesach, które nie są dołączone bezpośrednio do terminala, dlatego też otrzymuje kluczowe uderzenie.

Kolejna rzecz, na którą należy zwrócić uwagę: zazwyczaj plik-obiekt do etapu wykonawczego (łączenia) używa innego zestawu flag (LDFLAGS i LIBS), a następnie etapu kompilacji. W tym prostym przykładzie możesz sobie z tym poradzić, ale jeśli skopiujesz ten plik Makefile do użycia w bardziej skomplikowanym przypadku, wpadniesz w kłopoty.

+0

I lepiej nie używać go w ten sposób wtedy ... :) –

3

Zgodnie z odpowiedzią dmckee, make (1) robi coś, a nie kompilację i uruchamianie.

Oczywiście, nic nie zatrzyma cię do tworzenia Shell alias make-run która robi zamierzony 'zrobić & & ./prog args'.

13

można uprościć „Uruchom” cel poprzez to zależeć od tego, czy program jest na bieżąco, a następnie po prostu uruchomić program:

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

Nie ma sensu w prowadzeniu make kiedy jesteś już działa make - przynajmniej nie w tym kontekście. Może dla operacji rekursywnych (w różnych katalogach), ale zobacz "Recursive Make Considered Harmful".

Również twój plik_produktu powinien normalnie dostarczyć cel "all" i powinien zwykle być pierwszym, a więc domyślnym celem.

4

Jeśli masz zamiar zbudować i uruchomić w kółko, można użyć komendy history pomóc z tym:

# Run this once 
make && ./foo 

# Repeat last command 
!! 
+2

Nawet lepiej , w Bashu możesz użyć '! make', aby powtórzyć ostatnie polecenie zaczynając od" make ", nawet jeśli uruchomisz inne komendy pomiędzy. Ten przepływ pracy działa bardzo dobrze dla mnie. –