Makefile基础复习

206 阅读1分钟

前言

这周使用cmake构建了一个新工程代码,目录结构参照GmSSL3.0进行了划分,新增的代码和测试代码都编译测试运行OK,也增加了相应的README说明。在我看来,初步版本已经是完整的了。使用cmake可以使得构建中间文件跟源代码分离,而且cmake还提供了安装、打包的功能,已经相当的完善了。初期的工作是完成了。

复习复习Makefile的基础吧。

Makefile

Makefile最主要的就是变量和函数了。

变量

变量的赋值跟shell类似,var=value

取值是(变量名)或者(变量名)或者{变量名}

Makefile还提供了一些默认的变量名:

CC=gcc
CFLAGS # 编译选项 如 -g -Wall
LDFLAGS #链接选项

# 命令中使用的自动变量
$@ # 表示规则的目标
$< # 表示规则中的第一个条件
$^: # 表示规则中的所有条件,空格分隔


模式规则

%.o:%.c
    $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@

模式规则用来说明依赖文件是如何生成目标文件的,一般就是%号加上后缀,上面的例子表示.c文件如何生成.o文件。

函数

最常用的函数是wildcard, 和patsubst:

  • wildcard 用于获取以某个后缀结尾的所有函数。
  • patsubst 把指定后缀替换为新的后缀,如.c --> .o
SRC=$(wildcard *.c) # 获取所有.c结尾的文件
OBJS=$(patsubst %.c, %.o, $(SRC)) # SRC中.c替换为.o
TARGET=main
$(TARGET):$(OBJS)
	$(CC) $(OBJS) -o $(TARGET)
%.o:%.c
	$(CC) -c $< -o $@ # 依赖条件第一个$< 编译成目标文件 $@

伪目标

经常使用make clean或者make all命令来清理或者编译目标,这里的clean和all一般都是伪目标,即不是实际存在的文件, 需要使用.PHONY声明。


SRC=$(wildcard *.c)
OBJS=$(patsubst %.c,%.o,$(SRC))
TARGET=main

.PHONY: all


all: $(TARGET)
    @echo "make all"

$(TARGET):$(OBJS)
	$(CC) $(OBJS) -o $(TARGET)
%.o:%.c
	$(CC) -c $< -o $@
.PHONY:clean
clean:
	rm -rf $(OBJS) $(TARGET)

Makefile嵌套

Makefile的嵌套,一种是最外层的Makefile需要包含更深层的Makefile内容,才能编译完成。这种需要使用include关键字包含深层次的Makefile,类似于C语言的include,被include的Makefile内容会展开到对应的外层Makefile。

另外一种是,更深层的Makefile本身就可以独立编译,最外层的Makefile可以调用到内层的Makefile完成功能。最外层可以通过make -C path/to/subdir的命令调用深层次的Makefile编译。

更多的是第三种最外层的Makefile直接包含了所有内层目录的源文件,整个工程就一个Makefile。

如果需要在Makefile间传递变量, 可以使用export关键字,这样深层次的Makefile可以获取到对应的变量值。 在深层次Makefile注意使用?=方式给对应的变量设置默认值。

第一种可以参考linux kernel 生成的Makefile。

第二种参考https://gitee.com/mirrors/intel-ipsec-mb 代码的Makefile:

.PHONY: all clean style install uninstall help TAGS

all:
	$(MAKE) -C lib
	$(MAKE) -C test
	$(MAKE) -C perf

clean:
	$(MAKE) -C lib clean
	$(MAKE) -C test clean
	$(MAKE) -C perf clean

style:
	$(MAKE) -C lib style
	$(MAKE) -C test style
	$(MAKE) -C perf style

install:
	$(MAKE) -C lib install

uninstall:
	$(MAKE) -C lib uninstall

help:
	$(MAKE) -C lib help

doxy:
	$(MAKE) -C lib doxy

README: README.md
	pandoc -f markdown -t plain $< -o $@

... # 省略后续内容


第三种参考 git@gitee.com:kunpengcompute/KAE.git代码的Makefile

# ...

# Src
SRCDIRS   := ${WORK_PATH}/
SRCDIRS   += ${WORK_PATH}/alg/pkey
SRCDIRS   += ${WORK_PATH}/alg/dh
SRCDIRS   += ${WORK_PATH}/alg/ciphers
SRCDIRS   += ${WORK_PATH}/alg/digests
SRCDIRS   += ${WORK_PATH}/async
SRCDIRS   += ${WORK_PATH}/wdmngr
SRCDIRS   += ${WORK_PATH}/utils

SRCEXTS   := .c # C program


# ...

SOURCES = $(foreach d,$(SRCDIRS),$(wildcard $(addprefix $(d)/*,$(SRCEXTS))))

OBJS    = $(foreach x,$(SRCEXTS), \
      $(patsubst %$(x), %.o, $(filter %$(x),$(SOURCES))))

更多

Makefile的基础知识差不多是这些,更多的还可以命令调用不同的shell命令执行想要的操作。最基础的就是使用rm命令清理编译文件了。

在码云gitee上面,基本上都有github上众多知名开源库的镜像库,可以提升我们的下载速度。毕竟很多时候github总是连接不上,如果单纯是下载代码学习的话,推荐直接使用gitee查找开源库代码来下载。

不论是在生活,学习还是工作中,你不可能总是得到你想要的。那么就多学习一些知识,提高自身应对需求的能力吧。

近期长沙开启了降温模式,已然进入了秋天,周末早起带我妈去橘子洲景区走了一圈,让她也在长沙旅游一下。我妈从老家来长沙帮忙带娃,平常一个人在陌生的环境中也不容易,周末有时间带她多走走逛逛了!

2.jpg

行动,才不会被动!

欢迎关注个人公众号 微信 -> 搜索 -> fishmwei,沟通交流。

博客地址: fishmwei.github.io

掘金主页: juejin.cn/user/208432…