makefile实操准备
  0eGysyk4Lrwg 2023年11月02日 32 0

(目录)


一、系统变量

系统变量 描述
$* 不包括扩展名的目标文件名称
$+ 所有的依赖文件,以空格分隔
$< 表示规则中的第一个依赖项
$? 所有时间戳比目标文件晚的依赖文件,以空格分隔
$@ 目标Target的完整名称
$^ 所有不重复的依赖文件,以空格分隔
$% 如果目标是归档成员,则该变量表示目标的归档成员名称

二、系统常量

可用 make -p 查看

系统常量 描述 默认值
AS 汇编程序的名称 默认值为 as
CC C编译器名称 默认值为 cc
CPP C预编译器名称 默认值为 cc -E
CXX C++编译器名称 默认值为 g++
RM 文件删除程序别名 默认值为 rm -f

注意:#为注释。

三、自定义变量

定义:VAR_NAME = VALUE 使用:$(VAR_NAME) 或 ${VAR_NAME}

注意:makefile中的变量是大小写敏感的。

四、伪目标和模式匹配

makefile默认先处理第一个目标。

1. 伪目标

.PHONY:clean

声明目标为伪目标之后,makefile将不会判断目标是否存在或该目标是否需要更新。

2. 模式匹配

符号 说明 备注
%.o:%.cpp .o依赖于对应的.cpp文件 通配符
wildcard $(wildcard ./*.cpp) 获取当前目录下所有的.cpp文件名 空格分隔
patsubst $(patsubst %.cpp, %.o, ./*.cpp) 将xxx.cpp文件名替换成对应的xxx.o文件名

五、基本使用

c++提示版如下:

# 目标: 依赖
# $@ 目标;$< 第一个依赖;$^ 所有依赖

# 通过include指令可以包含其他makefile文件
# include ../makefile

# 不使用默认值cc
#CC=gcc

# 注意:hello后边#之前的空格也会作为赋值字符串的一部分
TARGET=hello # := 可以阻止递归展开的效果,即只展开一次再赋值(从上到下逐步展开)
# 当前目录下的所有.cpp文件名都放到SRC变量里
SRC=$(wildcard *.cpp)
# path路径替换:把变量SRC中的文件名(.cpp)替换为.o结尾并赋值给OBJ变量
OBJ=$(patsubst %.cpp, %.o, $(SRC))

CXXFLAGES=-c -Wall -g

$(TARGET): $(OBJ)
    $(CXX) -o $@ $^

%.o: %.cpp
    $(CXX) $(CXXFLAGES) $< -o $@

.PHONY: clean
clean:
    $(RM) $(OBJ) $(TARGET)

c语言简用版如下

TARGET=testbed
PRJ_ROOT = $(dir $(abspath $(lastword $(MAKEFILE_LIST))))src
SRC=$(wildcard $(PRJ_ROOT)/*.c)
OBJ=$(patsubst %.c, %.o, $(SRC))
CFLAGS=-c -Wall -g
CC=gcc

$(TARGET):	$(OBJ)
	$(CC) -o $@ $^

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

.PHONY:	clean
clean:
	$(RM) $(OBJ) $(TARGET)

在包含多文件的情况下可以采用如下方法避免重复赋值带来的递归展开问题

ifndef TARGET
	TARGET:=hello 
endif

六、调用shell

PWD:=$(shell pwd)

七、嵌套调用

# -C 指定目录,调用其中的Makefile。或者使用-f 指明文件名。
all:
	$(MAKE) -C ./dir1
	$(MAKE) -C ./dir2
	$(MAKE) -C ./dir3 -f makefile03
clean:
	make -C ./dir1 clean
	make -C ./dir2 clean
	make -C ./dir3 -f makefile03 clean

或者优化为

DIR=dir1 dir2 dir3
.PHONY:$(DIR) clean

all:$(DIR)
$(DIR):
	make -C $@
clean:
	@echo $(shell for dir in $(DIR); do make -C $$dir clean; done)

八、makefile中的条件判断

判断指令 描述 返回值
ifeq 判断是否相等 相等返回true,不相等返回false
ifneq 判断是否不相等 相等返回true,不相等返回false
ifdef 判断变量是否存在 存在返回true,不存在返回false
ifndef 判断变量是否不存在 不存在返回true,存在返回false

ifeq,ifneq与条件之间要有空格,否则报错。 没有elseif的用法,如果要实现,则必须使用嵌套。

ifeq ($(A), 123)
	RET1:=yes
else
	ifneq ($(B), balabala)
		RET1:=p1
	else
		RET1:=p2
	endif
	RET1:=no
endif

ifdef C
        C:=123
else
        C=123
endif

ifndef PARAM_NAME
	PARAM_NAME=mufasa
endif

注意:make可以通过命令行参数PARAM_NAME=VALUE向makefile中的PARAM_NAME自定义变量传参。 make PARAM_NAME=VALUE

九、makefile中的循环

.PHONY:show

VAR=a b c d
FILE=$(foreach V, $(VAR), $V.txt)
ATTR=$(wildcard *.c)

show:
        @echo $(FILE)
        @for A in $(ATTR); do ls -l $$A; done;

显然使用shell命令的方式灵活性更强。

十、自定义函数

.PHONY:show

define func
        @echo func
        @echo $(1) $(2)
endef

show:
        $(call func, 123, abc)

函数没有返回值。

十一、install的实现

.PHONY:install
install:
	install -o bee -g bee -m 666 --suffix=.old hello.asm ./dir/hello.asm

以上命令的解释如下:

  • -o bee:将目标文件所有者设置为bee用户。
  • -g bee:将目标文件属组设置为bee。
  • -m 666:将目标文件的权限设置为rw-rw-rw-。
  • hello.asm:源文件的名称。
  • ./dir/hello.asm:目标文件的路径名。
  • --suffix=.old:如果目标文件已经存在,则将目标文件备份为hello.asm.old,并将新的源文件复制为hello.asm。
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  0eGysyk4Lrwg   2023年11月02日   33   0   0 makemakefile
0eGysyk4Lrwg