博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Linux-makefile

Posted on 2023-03-14 07:01  乔55  阅读(40)  评论(0编辑  收藏  举报

make的选项

  • make -f mymakefile:make指定的文件

makefile语法规则

目标列表:依赖性列表
<TAB>命令列表
  • 目标:一般指需要编译的目标,也可以是一个动作

    • makefile默认只执行第一个目标
    • 伪目标:它不是一个文件,只是一个标签
  • 依赖:执行当前目标所要依赖的先项

    • 一个目标可以有多个依赖,也可以没有依赖
    • 依赖既可以是其他规则的目标,也可以是某个具体的文件,还可以是某个库
  • 命令:可以没有,也可以是多条,一般,一条命令占据一行

    • 若想当前命令结果作用于下一条命令:cmd1;cmd2
    • 命令出错:并不意味着makefile语法出错,如若目录不存在时cd命令必然出错
    • 当规则中某个命令出错时,make就会终止执行当前规则甚至所有规则
    • 可在命令前添加一个减号,标记为不管命令是否出错,都认为是成功的,这样就不会影响后续命令的执行

makefile自定义变量

// =号:最基本的赋值方式
// ?=号:前边已经对该变量赋值过,则不执行本次赋值,否则执行
// :=号:覆盖式赋值,将当前赋值作为最新变量值
// +=号:追加赋值,旧值保持不变,将新值追加在后边

makefile维护的预定义变量

  • 预定义变量的含义
CC:C编译器的名称,默认为cc
CPP:C预编译器的名称,默认值为$(CC) -E
CXX:C++编译器的名称,默认值为g++
CFLAGS:C编译器的选项,无默认值
CPPFLAGS:C预编译器的选项,无默认值
CXXFLAGS:C++编译器的选项,无默认值
RM:文件删除程序的名称,默认值为rm -f
LDFLAGS:链接器的选项,
  • 预定义变量的用法
  • CC = gcc
  • CFLAGS+=-c -Wall -g
  • CFLAGS += -I /mydir/includ:指定头文件所在目录

makefile内置变量

  • $@:当前目标的名称
  • $<:依赖性列表中的第一个文件
  • $^:用空格分开的所有依赖性列表
  • $?:时间戳比目标文件新的所有依赖文件,以空格分开
  • $* 不包含扩展名的目标文件
  • $+ 所有依赖文件,以空格分开,可能包含重复文件

模式字符串替换函数

$(patsubst <pattern>,<replace>,<text>)

// obj = $(patsubst %.c,%.o,$(src)),将src中所有.c文件替换成.o文件
// 此式子中的%.c就是pattern,%.o就是replace,text就是$(src)
// pattern可包含通配符,pattern中的%表示任意长度的字符串
// replace以包含通配符,replace中的%是pattern中那个%所代表的字符中
$(wildcard <pattern>)


// src = $(wildcard *.c)	
// src = 当前目录下所有.c文件,用空格隔开
$(filter <pattern>,<text>)
// 字符串过滤函数,filter-out反过滤函数
// 1. 对text过滤,保留符合text中符合pattern的单词
// 2. gcc $(filter %.c %.s,$(src)) -o target,保留符合%.c和%.s的


$(sort <list>)
// 排序函数,将list中单词按首字母升序排序


$(dir <names...>)
// $(dir /usr/hello.c)
// 取目录函数:,返回为/usr/


$(notdir /usr/hello.c)
// 取文件名函数,返回值为hello.c


$(suffix /usr/hello.c hello.s)
// 取后缀名函数,返回值为.c .s


$(basename /usr/hello.c)
// 取前缀名函数,返回值为/usr/hello


$(addsuffix .c,hello world)
// 加后缀,返回结果为hello.c world.c

 
$(addprefix /usr/,hello.c)
// 加前缀,返回结果为/usr/hello.c

自定义函数

// 函数基本语法:函数名与函数参数之间用空格隔开,参数之间用逗号隔开
$(<function> <arguments>)

// 自定义函数举例:
define myfunc
	@echo "xxxxxx"
	@echo $(0)	// 第1个参数
	@echo $(1)	// 第2个参数
endef
// 调用:$(call myfunc,1,2)

.c与.o文件的关联

// 1、
src = $(wildcard ./*.c)		// 获取当前目录下所有.c文件
obj = $(patsubst %.c,%.o,$(src))// 获取src中所有.c文件名,替换成.o文件名
%.o:%.c

// 2、
.SUFFIXES:.c.o	// 声明,.c与.o文件是有关系的
src = $(wildcard ./*.c)
obj = $(src:.c=.o)
.c.o:           // 只要依赖是.o文件的,都执行这标号下的把.c编译成.o文件的命令	

makefile-v1

src=$(wildcard *.c)
obj=$(patsubst %.c,%.o,$(src))

# 借助$(target)可删除茂名名称不为mytarget的可执行文件
target=$(patsubst %.c,%,$(src))
exec=mytarget

CC=gcc
CFLAGS+=-c -Wall -g

$(exec):$(obj)
        $(CC) $^ -o $@
        @echo "链接成功"

%.o:%.c
        $(CC) $(CFLAGS) $<
        @echo "编译成功!"

.PHONY:clean
clean:
        $(RM) -rf $(obj)
        $(RM) -rf $(exec)
#       $(RM) -rf $(target)
        @echo "删除成功!"