메이크파일이란 무엇입니까?
gcc hello.c -o 안녕하세요
gcc aa.c bb.c cc.c dd.c ...
make 도구와 Makefile
make와 Makefile의 관계는 무엇입니까?
make 도구: 수정된 파일을 찾고 종속성에 따라 영향을 받는 관련 파일을 찾은 다음 규칙에 따라 이러한 파일을 별도로 컴파일합니다.
Makefile: 종속성 및 컴파일 규칙을 기록합니다.
Makefile을 배워야 하나요?
Makefile을 배우는 방법?
Makefile의 본질: 구문이 아무리 복잡하더라도 프로젝트 파일 간의 종속성을 더 잘 해결하는 것입니다.
Makefile의 세 가지 요소
Makefile의 세 가지 요소는 무엇입니까?
대상, 종속성, 명령
세 요소 간의 관계를 설명하는 방법은 무엇입니까?
대상: 종속 파일 또는 기타 대상(TAB 문자를 추가해야 함)
<탭>명령 1
<탭>명령 2
<탭>...
실험 시연
.PHONY: 의사 대상을 지정할 수 있습니다.
gec@ubuntu:~/makefile/part_1$ sudo vi Makefile
gec@ubuntu:~/makefile/part_1$ sudo make
echo "targetb"
targetb
echo "targetc"
targetc
echo "targeta"
targeta
gec@ubuntu:~/makefile/part_1$ cat Makefile
#Makefile格式
#目标:依赖的文件或其它目标
#Tab 命令1
#Tab 命令2
#第一个目标,是最终目标及make的默认目标
#目标a,依赖于目标targetc和targetb
#目标要执行的shell命令 ls -lh,列出目录下的内容
targeta: targetb targetc
echo "targeta"
#目标b,无依赖
#目标要执行的shell命令,使用touch创建test.txt文件
targetb:
echo "targetb"
#目标c,无依赖
#目标要执行的shell命令,pwd显示当前路径
targetc:
echo "targetc"
#目标d,无依赖
#由于abc目标都不依赖于目标d,所以直接make时目标d不会被执行
#可以使用make targetd命令执行
# targetd:
# rm -f test.txt
gec@ubuntu:~/makefile/part_1$
위 다이어그램에 포함된 개략도는 다음과 같습니다.
명령을 내리다:
make 명령이 터미널에서 실행되면 make는 현재 디렉터리에서 "Makefile" 또는 "makefile"이라는 파일을 검색한 다음 파일의 규칙에 따라 구문 분석하고 실행합니다. 다른 파일을 입력 규칙으로 지정하려면 "make -f 파일 이름"과 같이 "-f" 매개 변수를 통해 입력 파일을 지정할 수 있습니다.
여기서 make 명령이 Makefile을 읽은 후 targeta가 Makefile의 첫 번째 대상임을 확인하고 기본 대상으로 실행됩니다.
그리고 targeta는 targetc 및 targetb 대상에 의존하기 때문에 자체 명령을 실행하기 전에 targetc 및 targetb를 완료합니다.
targetc의 명령은 현재 경로를 보여주는 pwd입니다.
targetb의 명령어는 touch test.txt이고 test.txt 파일이 생성된다.
마지막으로 targeta 자체 명령 ls -lh를 실행하여 현재 디렉터리의 내용을 나열하면 추가 test.txt 파일이 있음을 확인할 수 있습니다.
.PHONY
대상이 실제 파일과 일치하지 않음을 나타내기 위해 Makefile에서 사용되는 특수 대상 레이블(의사 대상)입니다.
일반적으로 Makefile의 대상은 생성해야 하는 파일에 해당하며 이러한 대상을 "실제 대상"이라고 합니다. 그러나 때때로 make 명령이 실행될 때 수행해야 하는 일부 작업을 정의해야 하며 이러한 작업은 해당 파일을 생성하지 않습니다. .PHONY
그런 다음 를 사용하여 이러한 대상을 정의 할 수 있습니다 .
.PHONY
의 효과는 동일한 이름을 가진 파일이 존재하는지 여부에 관계없이 수행할 작업으로 표시해야 하는 대상을 make 도구에 알리는 것입니다. 이와 같이 타겟을 실행할 때 make는 자신과 같은 이름의 파일이 있는지 여부를 확인하지 않고 Makefile에 정의한 명령에 따라 해당 작업을 실행합니다.
일반적인 사용 시나리오는 임시 파일을 정리하거나 모든 대상을 빌드하는 .PHONY
것과 같이 Makefile에서 몇 가지 일반적인 작업을 정의하는 것입니다 .clean
all
예:
.PHONY: clean clean: rm -f *.o
위의 예에서 .PHONY: clean
표시된 clean
대상은 어떤 파일에도 해당하지 않는 유사 대상입니다. 명령이 실행되면 make clean
명령이 실행되고 로 끝나는 rm -f *.o
모든 임시 파일이 삭제됩니다 ..o
요약하면, .PHONY
대상이 어떤 파일에도 해당하지 않지만 일부 특정 작업을 수행해야 함을 make 도구에 알리는 유사 대상을 정의하는 데 사용됩니다.
Makefile의 실제 적용에서는 일반적으로 컴파일과 최종 연결 프로세스가 분리됩니다.
즉, 우리의 hello_main 대상 파일은 본질적으로 hello_main.c 및 hello_func.c 파일에 의존하지 않고 hello_main.o 및 hello_func.o에 의존합니다.이 두 파일을 연결하면 최종 hello_main 개체 파일에서 원하는 것을 얻을 수 있습니다. 또한 make에는 기본 규칙이 있으므로 xxx.o 파일을 찾을 수 없는 경우 컴파일할 디렉터리에서 같은 이름의 xxx.c 파일을 검색합니다. 이러한 규칙에 따라 다음과 같이 Makefile을 수정할 수 있습니다.
#Makefile格式
#目标文件:依赖的文件
#Tab 命令1
#Tab 命令2
hello_main: hello_main.o hello_func.o
gcc -o hello_main hello_main.o hello_func.o
#以下是make的默认规则,下面两行可以不写
#hello_main.o: hello_main.c
# gcc -c hello_main.c
#以下是make的默认规则,下面两行可以不写
#hello_func.o: hello_func.c
# gcc -c hello_func.c
위 코드의 5~6행은 종속 파일을 C 파일에서 .o 파일로 변경하고 이에 따라 gcc 컴파일 명령도 수정했습니다. 8~13행은 각각 hello_main.o 파일과 hello_func.o 파일의 종속성 및 컴파일 명령이지만 C는 make의 기본 규칙과 동일한 이름의 .o 파일로 컴파일되므로 이 부분의 내용은 보통 쓰지 않습니다.
Makefile 변수, 패턴 일치
변하기 쉬운
시스템 변수
맞춤 변수
=, 지연 할당
:=, 즉시 할당
?=, 빈 할당(예: const)
할당은 이 변수가 비어 있는 경우에만 작동합니다.
+=, 할당 추가
추가 할당을 사용하여 변수에 값을 할당하면 변수 값을 덮어쓰지 않지만 변수의 원래 값 뒤에 새 값이 추가됩니다.
자동화 변수
$<: 첫 번째 종속 파일
$^: 모든 종속 파일
$@:대상
최적화
패턴 매칭
%: 비어 있지 않은 모든 문자와 일치
쉘: * 와일드카드
기본 규칙
.o 파일은 현재 디렉토리의 해당 .c 파일을 사용하여 기본적으로 컴파일합니다.
Makefile 조건 분기
조건 분기
같다면 ifeq (var1,var2) ... 또 다른 ... endif
ifneq (var1,var2) ... 또 다른 ... endif
Makefile의 일반적인 기능
Makefie 공식 매뉴얼:
GNU Make 매뉴얼 - GNU 프로젝트 - 자유 소프트웨어 재단
팟츠스트:
텍스트가 새 패턴과 일치합니다.
노트:
- $(notdir <이름...>)
-
이름: 파일 가져오기 기능 - notdir.
-
기능:
<names>
파일 이름 시퀀스에서 비디렉토리 부분을 제거합니다. 비디렉토리 부분은 마지막 백슬래시(/
) 다음 부분입니다. -
반환값: 파일 이름 시퀀스의 비디렉토리 부분을 반환합니다
<names>
. -
예:
$(notdir src/foo.c hacks)
반환 값은 입니다foo.c hacks
.
와일드카드:
예:
(wildcard *.c)
반환 값은 현재 디렉터리에 있는 모든 .c 소스 파일의 목록입니다.
각각:
Makefile은 헤더 파일 종속성을 해결합니다.
1. 헤더 파일을 작성하고 헤더 파일을 컴파일러의 헤더 파일 경로에 추가합니다.
gcc -I + "헤더 파일"
2. 헤더 파일의 업데이트 상태를 실시간으로 확인 헤더 파일이 변경되면 관련된 모든 파일을 다시 컴파일해야 합니다.
gcc -MM
ARCH ?= x86
ifeq ($(ARCH),x86)
CC=gcc
else
CC=arm-linux-gnueabihf-gcc
endif
TARGET=mp3
#OBJS=main.o mp3.o
BUILD_DIR=build
SRC_DIR=module1 module2
INC_DIR=include
CFLAGS=$(patsubst %,-I%,$(INC_DIR))
INCLUDES=$(foreach dir,$(INC_DIR),$(wildcard $(dir)/*.h))
SOURCES= $(foreach dir,$(SRC_DIR),$(wildcard $(dir)/*.c))
OBJS=$(patsubst %.c,$(BUILD_DIR)/%.o,$(notdir $(SOURCES)))
VPATH=$(SRC_DIR)
$(BUILD_DIR)/$(TARGET):$(OBJS)
$(CC) $^ -o $@
#main.o:main.c
# $(CC) -c main.c -o main.o
#mp3.o:mp3.c
# $(CC) -c mp3.c -o mp3.o
$(BUILD_DIR)/%.o:%.c $(INCLUDES) | creat_build
$(CC) -c $< -o $@ $(CFLAGS)
.PHONY:clean creat_build
clean:
rm -r $(BUILD_DIR)
creat_build:
mkdir -p $(BUILD_DIR)