Jak zrobić Makefile, aby przekompilować tylko zmienione pliki?
Trochę się starałem, aby make skompilował tylko pliki, które zostały edytowane. Jednak nie odniosłem większego sukcesu i wszystkie pliki zostały przekompilowane. Czy ktoś może mi wyjaśnić dlaczego?
Moje Pliki to:
main.c
a_functions.c
Gdzie główna.c zawiera main.h i a_functions.c obejmuje a. h
Oto mój makefile:
CC=gcc
CFLAGS=-Wall -I. -c
EXEC_FILE=program1
all: program
a_functions.o: a_functions.c
a_functions.c: a.h
main.o: main.c
main.c: main.h
objects: a_functions.c main.c
$(CC) a_functions.c main.c $(CFLAGS)
program: a_functions.o main.o
$(CC) a_functions.o main.o -o $(EXEC_FILE)
Zmiana pliku makefile zgodnie z sugestiami wydaje się mieć ten sam problem::
all: program
a_functions.o: a_functions.c a.h
gcc a_functions.c -c
main.o: main.c main.h
gcc main.c -c
program: a_functions.o main.o
gcc a_functions.o main.o -o program1
2 answers
Specyficzny problem, o którym mówisz -- Make rebuilds program1
(poprzez ponowne połączenie obiektów) nawet jeśli nic się nie zmieniło -- jest w tej zasadzie:
program: a_functions.o main.o
gcc a_functions.o main.o -o program1
Celem tej reguły jest program
i Make zakłada, że jest to plik. Ale ponieważ nie ma takiego pliku, za każdym razem, gdy uruchamiasz Make, Make myśli, że ten plik musi zostać przebudowany i wykonuje regułę. Proponuję:
program1: a_functions.o main.o
gcc a_functions.o main.o -o program1
Albo lepiej, to:
program1: a_functions.o main.o
gcc $^ -o $@
Albo jeszcze lepiej to:
$(EXEC_FILE): a_functions.o main.o
$(CC) $^ -o $@
(i nie zapomnij zmienić regułę all
na dopasowaną.)
Kilka innych punktów:
-
Jak zauważył @paxdiablo,
a_functions.o: a_functions.c a.h main.o: main.c main.h
-
Łączenie tych obiektów ze sobą nie ma sensu, chyba że coś w jednym (prawdopodobnie
main.o
) wywoła coś w drugim (prawdopodobniea_functions.o
), więc spodziewałbym się takiej zależności:
Więc podejrzewam, że masz jakieś zagubione deklaracje.main.o: a.h
-
Deklarujesz
objects
zasadę, ale nigdy Zobacz też Więc nigdy go nie używasz; Make używa domyślnej reguły dla%.o: %.c
. Proponuję:OBJECTS = a_functions.o main.o $(OBJECTS): %: %.c $(CC) $< $(CFLAGS) -o $@
(W takim przypadku możesz zmienić
$(EXEC_FILE): a_functions.o main.o
na$(EXEC_FILE): $(OBJECTS)
.) Lub po prostu to:%.o: %.c $(CC) $< $(CFLAGS) -o $@
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-28 17:03:17
Nie wiem, czy to powoduje twój konkretny problem, ale dwie linie:
a_functions.c: a.h
main.c: main.h
Są zdecydowanie błędne, ponieważ generalnie nie ma polecenia, aby odtworzyć plik C na podstawie nagłówka, który zawiera.
Pliki C nie zależą od ich plików nagłówkowych, tak robią obiekty utworzone przez te pliki C.
Na przykład, a main.c
z:
#include <hdr1.h>
#include <hdr2.h>
int main (void) { return 0; }
Byłoby w makefile
jako coś like:
main.o: main.c hdr1.h hdr2.h
gcc -c -o main.o main.c
Zmiana:
a_functions.o: a_functions.c
a_functions.c: a.h
main.o: main.c
main.c: main.h
Do:
a_functions.o: a_functions.c a.h
main.o: main.c main.h
(zakładając, że a_functions.c
zawiera a.h
i main.c
zawiera main.h
) i spróbuj ponownie.
Jeśli powyższe założenie jest błędne, będziesz musiał nam powiedzieć, jakie pliki C zawierają nagłówki, abyśmy mogli powiedzieć Ci poprawne reguły.
Jeśli twierdzisz, że makefile
nadal wszystko buduje, nawet po tych zmianach, musisz spojrzeć na dwie rzeczy.
Pierwszy to wyjście z ls -l
na wszystkich odpowiednie pliki, dzięki czemu można zobaczyć, jakie daty i godziny mają.
Drugi jest faktycznym wyjściem z make
. Wyjście make -d
będzie szczególnie pomocne, ponieważ pokazuje jakie pliki i daty make
używają, aby dowiedzieć się, co zrobić.
Jeśli chodzi o dochodzenie, make
wydaje się działać dobrze zgodnie z następującym zapisem:
=====
pax$ cat qq.h
#define QQ 1
=====
pax$ cat qq.c
#include "qq.h"
int main(void) { return 0; }
=====
pax$ cat qq.mk
qq: qq.o
gcc -o qq qq.o
qq.o: qq.c qq.h
gcc -c -o qq.o qq.c
=====
pax$ touch qq.c qq.h
=====
pax$ make -f qq.mk
gcc -c -o qq.o qq.c
gcc -o qq qq.o
=====
pax$ make -f qq.mk
make: `qq' is up to date.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-19 01:47:49