Makefile实战论(一)

简介: Makefile实战论(一)

为什么写这个呢,其实我有系统学过Makefile和CMake。但是因为用的不是很多或者说没有深入的使用场景,导致我不是很熟练,或者说没法优雅地使用。刚好最近对Linux的嵌入式编程比较感兴趣,借着demo来分析一下资深工程师写的Makefile,学习一下。由易到难吧,先来第一个,是一个GPIO的Makefile。

Makefile文件

BIN = test_gpio  
CC = $(CROSS)gcc  
CPP = $(CROSS)g++  
LD = $(CROSS)ld  
#
INCS = 
LIBS =  
SUBDIRS =  
#
DEFINC = -I ./ \
  
# LIBVAR =-shared -fPIE -L.
#
INCS += $(DEFINC)  
LIBS +=$(LIBVAR)
#  
CSRCS = $(wildcard *.c)  
CPPSRCS = $(wildcard *.cpp)  
#  
COBJS := $(CSRCS:.c=.o)  
CPPOBJS := $(CPPSRCS:.cpp=.o)  
#  
CFLAGS += $(INCS)  
CFLAGS += -O2 -Wall -g -fPIE
CPPFLAGS += $(INCS)  
CPPFLAGS += -O2 -Wall -g -fPIE
LDFLAGS += -lm -lrt -lstdc++ -ldl
all:$(BIN)  
$(COBJS) : %.o: %.c  
  $(CC) $(CFLAGS) -c $< -o $@   
$(CPPOBJS) : %.o: %.cpp  
  $(CPP) $(CPPFLAGS) -c $< -o $@ 
  
$(BIN) : $(COBJS) $(CPPOBJS)  
  $(CC) -o $(BIN)    $(COBJS) $(CPPOBJS) $(LDFLAGS) $(LIBS)    
  rm -rf $(COBJS)  
  rm -rf $(CPPOBJS)  
.PHONY:clean cleanall  
   
clean:              
  rm  -rf $(BIN) $(COBJS) $(CPPOBJS)  
#rm *.d  
cleanall:  
  rm $(BIN) $(COBJS) $(CPPOBJS)

拆解分析

BIN = gpio_red_blink
CC = $(CROSS)gcc
CPP = $(CROSS)g++
LD = $(CROSS)ld
  • 定义了变量BIN,表示生成可执行文件名为gpio_red_blink
  • 定义变量CC,表示使用的C编译器为$(CROSS)gcc(其中$(CROSS)是一个可能存在的前缀
  • 定义变量CPP,表示使用的C++编译器为$(CROSS)g++
  • 定义变量LD,表示使用的链接器为$(CROSS)ld
INCS =
LIBS =
SUBDIRS =
  • 定义空变量INCE,LIBS,SUBDIRS
DEFINC = -I ./ \
  • 定义变量DEFINC,指定编译过程中需要包含的头文件路径。这里设置为当前路径
INCS += $(DEFINC)
LIBS +=$(LIBVAR)
  • 将DEFINC添加到INCS中
  • 将未定义变量LIBVAR添加到LIBS中
CSRCS = $(wildcard *.c)
CPPSRCS = $(wildcard *.cpp)
  • 使用通配符,将当前目录所有.c文件加入到CSRCS变量中
  • 使用通配符,将当前目录所有.cpp文件加入到CSRCS变量中
COBJS := $(CSRCS:.c=.o)
CPPOBJS := $(CPPSRCS:.cpp=.o)
  • 将CSRCS中所有.c文件扩展名替换为.o,并且赋值给COBJS
  • 将CPPSRCS中所有,cpp文件扩展名替换为.o,并且赋值给CPPOBJS
CFLAGS += $(INCS)
CFLAGS += -O2 -Wall -g -fPIE
CPPFLAGS += $(INCS)
CPPFLAGS += -O2 -Wall -g -fPIE
LDFLAGS += -lm -lrt -lstdc++ -ldl -lpthread
  • 将INCS分别添加到CFLAGS和CPPFLAGS,指定了编译包含头文件路径
  • 将-O2 -Wall -g -fPIE添加到CFLAGS和CPPFLAGS,表示编译选项
  • 将-lm -lrt -lstdc++ -ldl -lpthread,添加到LDFLAGS中,表示链接选项
all:$(BIN)
  • 定义了一个目标叫做all
  • 依赖于可执行文件$(BIN)
$(COBJS) : %.o: %.c
  $(CC) $(CFLAGS) -c $< -o $@
  • 定义了一个规则模式,将.c文件编译为.o文件
  • %表示通配符,任意字符
  • $<表示第一个依赖的文件,即.c文件
  • $@表示目标文件,即.o文件
$(CPPOBJS) : %.o: %.cpp
  $(CPP) $(CPPFLAGS) -c $< -o $@
  • 定义了一个规则模式,将.cpp文件编译为.o文件
$(BIN) : $(COBJS) $(CPPOBJS)
  $(CC) -o $(BIN)    $(COBJS) $(CPPOBJS) $(LDFLAGS) $(LIBS)
  rm -rf $(COBJS)
  rm -rf $(CPPOBJS)
  • 定义一个规则模式,用于链接目标文件生成可执行文件$(BIN)
  • $(BIN)依赖$(COBJS) $(CPPOBJS)
  • 链接完成后删除中间文件
.PHONY:clean cleanall
clean:
  rm  -rf $(BIN) $(COBJS) $(CPPOBJS)
cleanall:
  rm $(BIN) $(COBJS) $(CPPOBJS)
  • 定义两个伪目标(.PHONY),用于执行清理操作
相关文章
|
6月前
|
编译器 Shell Linux
Makefile(3)进阶
Makefile(3)进阶
51 0
|
6月前
|
Shell Linux C++
Makefile编译实战
Makefile编译实战
83 0
|
6月前
Makefile(1)入门
Makefile(1)入门
44 0
|
6月前
|
编译器 Shell Linux
Makefile(2)原理
Makefile(2)原理
40 0
|
6月前
|
编译器 Shell C语言
Makefile快速入门
Makefile快速入门
47 0
|
11月前
|
Shell
Makefile学习2
Makefile学习2
|
IDE 编译器 程序员
Makefile零基础教学(一)初识makefile
Makefile零基础教学(一)初识makefile
168 1
Makefile零基础教学(一)初识makefile
|
11月前
|
编译器 Shell Linux
Makefile学习1
Makefile学习1
|
Shell
如何使用makefile
如何使用makefile
|
Java Linux 程序员
玩转Makefile | 一文入门Makefile
玩转Makefile | 一文入门Makefile
239 0
玩转Makefile | 一文入门Makefile