#////////////////////////////////
Makefile五大特性:顯式規則、隱晦規則、變數定義$、檔案指示和註釋(#)
#Tab鍵開始
#//////////////////////////////////
#標準寫法
objects = main.o led.o uart.o /
gpio.o spi.o
edit : $(objects)
gcc -o edit $(objects)
main.o : main.c includes.h
gcc -c main.c
led.o : led.c led.h includes.h
gcc -c led.c
uart.o : uart.c uart.h includes.h
gcc -c uart.c
gpio.o : gpio.c gpio.h includes.h
gcc -c gpio.c
spi.o : spi.c spi.h includes.h
gcc -c spi.c
clean :
rm edit $(objects)
#////////////////////////////
#自動依賴檔案寫法(如找到led.o檔案,那麼led.c就會變為依賴檔案,同時會推匯出 gcc -c led.c)
objects = main.o led.o uart.o \
gpio.o spi.o
edit : $(objects)
gcc -o edit $(objects)
main.o : includes.h
led.o : led.h includes.h
uart.o : uart.h includes.h
gpio.o : gpio.h includes.h
spi.o : spi.h includes.h
#偽目標檔案
.PHONY : clean
clean :
rm edit $(objects)
#///////////////////////////
#最新另類寫法
objects = main.o led.o uart.o \
gpio.o spi.o
edit : $(objects)
gcc -o edit $(objects)
$(objects) : includes.h
led.o : led.h
uart.o : uart.h
gpio.o : gpio.h
spi.o : spi.h
#偽目標檔案
.PHONY : clean
clean :
-rm edit $(objects)
#////////////////////////
#更簡潔寫法
#wildcard : 擴充套件萬用字元
#notdir : 去除路徑
#patsubst :替換萬用字元
src = $(wildcard *.c ./bsp/*.c) # wildcard把 指定目錄 ./ 和 ./bsp/ 下的所有字尾是c的檔案全部展開;得到main.c ./bps/led.c
file = $(notdir $(src)) #notdir把展開的檔案去除掉路徑資訊; 得到main.c led.c
obj = $(patsubst%.c,%.o,$(src)) #patsubst把$(file)中的變數符合字尾是.c的全部替換成.o;得到main.o led.o
#編譯並連結所有.c和.o檔案
objects = $(patsubst %.c, %.o, $(wildcard *.c))
main : $(objects)
gcc -o main $(objects)
#檔案搜尋
#"src"和“../headers”兩個路徑順序搜尋,:進行分隔。
VPATH = src : ../headers
#要求make在“../headers”目錄下搜尋所有以 .h 結尾的檔案
vpath %.h ../headers
#偽目標
.PHONY : clean
clean
rm -f *.o #刪除所有.o檔案
all :prog1 prog2 prog3
.PHONY : all
#自動生成依賴
#/////////////////////////////
1、編譯驅動一般將驅動編譯成模組(.ko檔案),然後載入到核心,這用到make modules命令
//=======================================================//
2、單個.c檔案編譯成一個.ko檔案
#linux核心原始碼目錄
KERNEL_DIR := /home/alientek/workspace/im6ull-kernel/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek
#當前路徑
CURRENT_DIR := $(shell pwd)
#obj-m 編譯為獨立的驅動模組
obj-m := led.o
build : kernel_modules
kernel_modules:
$(MAKE) -C(KERNEL_DIR) M=$(CURRENT_DIR) modules
.PHONY:clean
clean:
$(MAKE) -C((KERNEL_DIR) ) M=$(CURRENT_DIR) clean
//========================================================//
3、多個檔案編譯成一個.ko檔案
假設我們要將 add.c、sub.c 編譯成一個ko檔案,只有 add.c 包含了模組初始化函式(module_init),sub.c 只是add.c 的依賴原始檔。大體和上面單檔案單模組類似,不同之處如下:
obj-m += 模組名.o
模組名-objs += 原始檔名.o ...
#linux核心原始碼目錄
KERNEL_DIR := /home/alientek/workspace/im6ull-kernel/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek
#當前路徑
CURRENT_DIR := $(shell pwd)
#obj-m += 模組名.o
obj-m += led.o
#模組名-objs += 原始檔名.o ...
led-obj += add.o sub.o
build : kernel_modules
kernel_modules:
$(MAKE) -C(KERNEL_DIR) M=$(CURRENT_DIR) modules
.PHONY:clean
clean:
$(MAKE) -C((KERNEL_DIR) ) M=$(CURRENT_DIR) clean
//===================================================//
4、多個模組編譯
#linux核心原始碼目錄
KERNEL_DIR := /home/alientek/workspace/im6ull-kernel/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek
#當前路徑
CURRENT_DIR := $(shell pwd)
#obj-m += 模組名1.o 模組名2.o
obj-m += led.o uart.o usb.o
build : kernel_modules
kernel_modules:
$(MAKE) -C(KERNEL_DIR) M=$(CURRENT_DIR) modules
.PHONY:clean
clean:
$(MAKE) -C((KERNEL_DIR) ) M=$(CURRENT_DIR) clean
//===================================================//
#RK3566的gpio-led核心級應用程式的makefile
PWD ?= $(shell pwd)
KERNELDIR := /home/zbl/tspi-rk3566/sdk/linux/kernel
CROSS_COMPILE ?= /home/zbl/tspi-rk3566/sdk/linux/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
CC := $(CROSS_COMPILE)gcc
obj-m += gpioled.o
module:
make -C $(KERNELDIR) M=$(PWD) ARCH=arm64 modules
@# -C 表示從當前目錄切換到核心原始碼目錄下,藉助核心原始碼makefile進行make編譯
@# M=$(PWD) 表示只編譯當前目錄下的驅動
@# ARCH=arm64 指定編譯架構
$(CC) gpioledapp.c -o app
@# 交叉編譯應用程式
.PHONE:clean
clean:
make -C $(KERNELDIR) M=$(PWD) ARCH=arm64 clean
rm app