Makefile的简单示例
一、Makefile介绍
Makefile是一套用于自动化构建的脚本工具,定义了源文件的依赖关系,如何编译和链接程序
二、简单的Makefile模板
.PHONY: clean all
CC ?= gcc
CFLAGS := -Wall -g -O2 -I./
LDFLAGS := -L./
LIBS :=
targets := hello
sources := main.c xx.c
objects := main.o xx.o
all: ${targets}
@echo "all done"
${targets}: ${objects}
${CC} ${LDFLAGS} $^ ${LIBS} -o $@
${objects}: ${sources}
${CC} ${CFLAGS} -c $< -o $@
clean:
rm -rf *.o ${targets}
三、语法介绍
.PHONY指定伪目标,例如make clean和make all- 变量,
?=没有定义则定义,:=定义的时候直接展开 - 命令前加@可以不打印命令本身
- $(变量)引用变量,等价于${}
- *.o匹配所有的o文件
- 编译时使用CFLAGS指定选项,链接时使用LDFLAGS指定链接目录,使用LIBS指定链接库
- make和一些选项,f指定文件,n打印执行命令但是不执行,-C指定目录
- $<表示第一个依赖,$^表示所有依赖,$@表示目标文件
- -I指定头文件目录,-L指定库文件目录,-l指定动态库文件
四、驱动程序的Makefile模板
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
KERNEL_DIR = /home/uisrc/zynq-lab/kernel
all:
make -C ${KERNEL_DIR} M=`pwd` modules
clean:
make -C ${KERNEL_DIR} M=`pwd` module clean
rm -rf modules.order
obj-m += my_driver.o
五、驱动程序模板的解释
- C选项表示make命令切换到内核源码目录进行编译
- M选项指令了模块源码的路径
- obj-m表示需要增加一个编译成模块的驱动
六、Makefile生成静态库和动态库
AR ?= ar
ARFLAGS := rcs
LIBNAMES := libmlist.a
${LIBNAMES}: m_list.o
${AR} ${ARFLAGS} $@ $<
CC ?= gcc
CFLAGS := -Wall -g -O2
SHARED_FLASG := -shared -fPIC
DYNAMIC_LIB := libmlist.so
${DYNAMIC_LIB}: m_list.shared.o
${CC} ${SHARED_FLAGS} -Wl,-soname,${DYNAMIC_LIB} -o $@ $^
m_list.shared.o: m_list.c
${CC} ${CFLAGS} -fPIC -c $< -o $@
七、语法解释
- 静态库是o文件的归档集合,链接时会被复制到最终文件中
- 工具是ar,选项rcs表示创建并替换现有文件并创建索引
- 静态库一般libxxx.a,并在链接是使用-l指定库(去掉lib和.a)
- 创建静态库的依赖文件是对应的o文件,可以是多个,
$<可以替换为$^ - 创建动态库需要将先将.c文件生成.o文件,需要加入-fPIC选项
- 工具gcc,选项-shared、-fPIC、并使用-Wl,-soname,指定动态库名称
- 根据观察linux的动态库一般有xx.so,xx.so.1,xx.so.1.0,应该使用
ln -sf source target建立符号链接 - -shared告诉工具链生成动态库,-fPIC生成位置无关代码,-Wl,-soname,指定动态库名称
八、其他注意事项
- Makefile中引用变量的时候,使用$()和${}是等价的,但是在CMake中变量引用的时候使用的是${},shell中也是${}

浙公网安备 33010602011771号