변경된 파일만 다시 컴파일하도록 Makefile을 만들려면 어떻게 해야 합니까?
편집한 파일만 컴파일 할 수 있도록 만드는 데 조금 애를 먹고 있습니다.하지만 큰 성공을 거두지 못했고 모든 파일이 다시 컴파일 되었습니다.누가 이유를 설명해 줄 수 있나요?
파일은 다음과 같습니다.
main.c
a_functions.c
여기서 main.c는 main.h를 포함하며 a_main.c는 a.h를 포함합니다.
make file은 다음과 같습니다.
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)
제안사항에 따라 makefile을 변경해도 다음과 같은 문제가 있는 것 같습니다.
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
특정 문제 -- 재구축하기program1
(오브젝트를 다시 링크함으로써) 아무것도 변경되지 않은 경우에도 --는 다음 규칙에 있습니다.
program: a_functions.o main.o
gcc a_functions.o main.o -o program1
이 규칙의 대상은 다음과 같습니다.program
및 Make는 파일이라고 가정합니다.그러나 이러한 파일이 없기 때문에 Make를 실행할 때마다 Make는 이 파일을 재구축해야 한다고 생각하고 규칙을 실행합니다.다음을 제안합니다.
program1: a_functions.o main.o
gcc a_functions.o main.o -o program1
또는 다음과 같이 하는 것이 좋습니다.
program1: a_functions.o main.o
gcc $^ -o $@
더 좋은 것은 다음과 같습니다.
$(EXEC_FILE): a_functions.o main.o
$(CC) $^ -o $@
(또한 잊지 말고all
일치시키는 규칙)
기타 몇 가지 포인트:
@paxdiablo가 지적했듯이
a_functions.o: a_functions.c a.h main.o: main.c main.h
이 오브젝트들을 링크하는 것은 의미가 없습니다.단, (아마도) 하나의 것이 아닌 한
main.o
)가 상대편(메시지)으로 무언가를 호출한다.a_functions.o
따라서 다음과 같은 종속성을 볼 수 있습니다.main.o: a.h
그래서 나는 당신이 잘못된 선언을 가지고 있다고 의심한다.
당신이 선언하는 것은
objects
규칙이지만 절대 참조하지 마세요.따라서 실제로는 사용하지 않습니다.Make는 다음 기본 규칙을 사용합니다.%.o: %.c
. 제안합니다.OBJECTS = a_functions.o main.o $(OBJECTS): %.o: %.c $(CC) $< $(CFLAGS) -o $@
(이 경우 변경할 수 있습니다.
$(EXEC_FILE): a_functions.o main.o
로.$(EXEC_FILE): $(OBJECTS)
.) 또는 이것만:%.o: %.c $(CC) $< $(CFLAGS) -o $@
이것이 특정 문제의 원인인지 아닌지는 모르지만, 다음의 2개의 행이 있습니다.
a_functions.c: a.h
main.c: main.h
C파일에 포함된 헤더를 기반으로 C파일을 재작성하는 명령어는 일반적으로 존재하지 않기 때문에 확실히 틀렸습니다.
C 파일은 헤더 파일에 의존하지 않습니다.C 파일에 의해 작성된 오브젝트는 의존합니다.
예를 들어,main.c
대상:
#include <hdr1.h>
#include <hdr2.h>
int main (void) { return 0; }
에 있을 것이다.makefile
예를 들어 다음과 같습니다.
main.o: main.c hdr1.h hdr2.h
gcc -c -o main.o main.c
변경:
a_functions.o: a_functions.c
a_functions.c: a.h
main.o: main.c
main.c: main.h
대상:
a_functions.o: a_functions.c a.h
main.o: main.c main.h
(단,a_functions.c
포함한다a.h
그리고.main.c
포함한다main.h
를 다시 시도합니다.
위의 가정이 틀리면 올바른 규칙을 알려드릴 수 있도록 어떤 C파일에 어떤 헤더가 포함되어 있는지 알려주셔야 합니다.
당신의 주장이 맞다면makefile
이러한 변화 후에도 여전히 모든 것을 구축하고 있습니다. 두 가지 사항을 살펴봐야 합니다.
첫 번째 출력은ls -l
모든 관련 파일에 저장하여 날짜와 시간을 확인할 수 있습니다.
는 실제 입니다.make
<>make -d
특히 도움이 되는 것은 어떤 파일이나 날짜를 표시하기 때문입니다.make
어떻게 해야 할지 고민하고 있습니다.
조사에 있어서,make
다음의 것 .
=====
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.
사실 팍스디아블로의 훌륭한 답변에 근거한 것입니다만, 실험해 본 결과, 뭔가 영리한 일을 하고 있지 않는 한, 각각의 .o 파일 마다 다른 타겟이 필요 없는 것을 알 수 있었습니다.
make file은 다음과 같습니다.
all: program
program: a_functions.o main.o
gcc a_functions.o main.o -o program
clean:
rm -f *.o
rm -f program
make 4.1에서는 .o 파일이 자동으로 컴파일되므로 .o 파일의 이름이 소스 파일과 같으면 아무것도 할 필요가 없습니다.따라서 a_functions.c, a_functions.h, main.h 및 main.c를 자동으로 헌팅합니다.예상 소스 코드 이름이 없는 경우 다음과 같은 오류가 발생합니다.
make: *** No rule to make target 'a_functions.o', needed by 'program'. Stop.
당신을 위해 "깨끗한" 타겟도 추가했습니다."클린"은 소프트웨어를 소스 코드로 릴리스해야 하거나 컴파일된 객체 파일 및 이진 파일을 모두 삭제하려는 경우에 유용합니다.
그리고 이게 네가 해야 할 전부야.
이 파일을 "Makefile"에 저장하고 다음을 실행합니다.
$ make
바이너리를 구축합니다.그리고.
$ make clean
코드 내의 컴파일된 오브젝트 및 바이너리를 정리합니다.
언급URL : https://stackoverflow.com/questions/7815400/how-do-i-make-makefile-to-recompile-only-changed-files
'programing' 카테고리의 다른 글
VueJ가 0이면 입력 값이 표시되지 않음 (0) | 2022.07.02 |
---|---|
set/getsockopt SO_SNDBUF 사이즈가 2배가 되는 것을 이해한다. (0) | 2022.07.02 |
C 프로그래밍에서 트리플 마이너스 부호가 나올 수 있나요?그것은 무엇을 뜻하나요? (0) | 2022.07.02 |
TypeError: Vue2에 정의되지 않은 속성 '구성 요소'를 읽을 수 없습니다. (0) | 2022.07.02 |
vue 3에서 vue-chartjs 사용 : createElement는 함수가 아닙니다. (0) | 2022.07.02 |