programing

변경된 파일만 다시 컴파일하도록 Makefile을 만들려면 어떻게 해야 합니까?

copyandpastes 2022. 7. 2. 21:37
반응형

변경된 파일만 다시 컴파일하도록 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일치시키는 규칙)

기타 몇 가지 포인트:

  1. @paxdiablo가 지적했듯이

    a_functions.o: a_functions.c a.h
    main.o: main.c main.h
    
  2. 이 오브젝트들을 링크하는 것은 의미가 없습니다.단, (아마도) 하나의 것이 아닌 한main.o)가 상대편(메시지)으로 무언가를 호출한다.a_functions.o따라서 다음과 같은 종속성을 볼 수 있습니다.

    main.o: a.h
    

    그래서 나는 당신이 잘못된 선언을 가지고 있다고 의심한다.

  3. 당신이 선언하는 것은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

반응형