임베디드 Linux 드라이버 개발 시리즈 6: Makefile

메이크파일이란 무엇입니까?

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에서 몇 가지 일반적인 작업을 정의하는 것입니다 .cleanall

예:

.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 프로젝트 - 자유 소프트웨어 재단

팟츠스트:

 텍스트가 새 패턴과 일치합니다.

노트:

  1. $(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)

 

추천

출처blog.csdn.net/qq_51519091/article/details/132146072