Makefile学习记录

Make

make是工具,makefile是个文件;

make

make -f md  ;指定make的输入文件
make -v ;输出版本号
make -n ;只输出命令,不执行命令
make -s ;只执行命令 ,不显示具体命令
make -w ;显示执行前执行后的路径
make -C ;指定makefile所在的目录
make -h ;显示帮助

makefile中的变量

系统变量

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

举例:

a.o :a.c
	gcc -c $^ -o $@

自定义变量

TARGET=main ;

注意注意

示例1:

#makefile文件
x=y
x=$(x)1
a:
        echo $(x)

运行结果(报错)

book@100ask:~/make_text$ make -f ma
ma:3: *** Recursive variable 'x' references itself (eventually).  Stop.

示例2:

#makefile文件
x=y
x:=$(x)1
a:
        echo $(x)
#/************运行结果*************/
book@100ask:~/make_text$ make -f ma
echo y1
y1

示例3

x=1
y=$(x)
x=2
a:
        echo $(y)

运行结果:

book@100ask:~/make_text$ make -f ma
echo 2
2

两种变量赋值的方法

=   赋值,但是用终值,就是不管变量调用写在赋值前还是赋值后,调用时都是终值    

:=  也是赋值 ,但是只受当前行及之前代码的影响,而不会受后面赋值的影响

makefile中的伪目标

.PHONY:a b #声明为伪目标后,makefile将不会判断目标是否存在或该目录是否需要更新

模式匹配

%.o:%.c #采用通配符%
wildcard   #$(wildcard ./*.c) 获取当前目录下所有的.c文件
patsubst   #$(patsubst %.cpp,%.o, ./*.^cpp)将对应的cpp文件名替换成.o文件名
.PHONY :clean
BY=gcc
TARGET=main
OBJ=$(patsubst %.c,%.o,$(wildcard ./*.c))

$(TARGET):$(OBJ)
        $(BY) $^ -o $@
%.o:%.c
        $(BY) -c $^ -o $@
clean:
        rm -rf $(OBJ)

运行结果

book@100ask:~/make_text$ make clean
rm -rf ./a.o ./c.o ./main.o ./b.o
book@100ask:~/make_text$ make
gcc -c a.c -o a.o
gcc -c c.c -o c.o
gcc -c main.c -o main.o
gcc -c b.c -o b.o
gcc a.o c.o main.o b.o -o main
book@100ask:~/make_text$ ./main
funa()
funb()
func()

公共头文件

include /home/book/Makefile   #调用公共makefile

举例

公共Makefile

ifndef TARGET
        TARGET:=main
endif
.PHONY :clean
BY=gcc
OBJ=$(patsubst %.c,%.o,$(wildcard ./*.c))
OBJ:=$(OBJ)

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

clean:
        rm -rf $(OBJ)

私有makefile

TARGET=main
include ../Makefile

运行结果

book@100ask:~/make_text$ make clean
rm -rf ./a.o ./c.o ./main.o ./b.o
book@100ask:~/make_text$ make
cc    -c -o a.o a.c
cc    -c -o c.o c.c
cc    -c -o main.o main.c
\cc    -c -o b.o b.c
gcc a.o c.o main.o b.o -o main
book@100ask:~/make_text$ ./main
funa()
funb()
func()

Makefile中调用shell命令

x=$(shell pwd)
y=1
z=$x
a:
        echo $(x)
        echo $z
        if [ 1 -eq $y ];then echo eq;fi;

运行结果

book@100ask:~/make_text$ make -f ma
echo /home/book/make_text
/home/book/make_text
echo /home/book/make_text
/home/book/make_text
if [ 1 -eq 1 ];then echo eq;fi;
eq

makefile 中的嵌套调用

001和002文件夹内容

book@100ask:~$ cat 001/makefile
a:
        echo a

book@100ask:~$ cat 002/makefile
b:
        echo b

另一个文件夹中的makefile:

DIR=001 002
.PHONY : all $(DIR)
all:$(DIR)
        echo done
$(DIR):
        make -C $@
clean:
        make -C $(DIR)

运行结果:

book@100ask:~$ make -f ma
make -C 001
make[1]: Entering directory '/home/book/001'
echo a
a
make[1]: Leaving directory '/home/book/001'
make -C 002
make[1]: Entering directory '/home/book/002'
echo b
b
make[1]: Leaving directory '/home/book/002'
echo done

条件判断

ifdef ;判断变量是否存在
ifndef ;判断变量是否不存在
ifeq ;判断是否相等
ifneq ;判断是否不相等
x=1
ifneq ($(x),1)
        a=1
else
        a=0
        ifneq ($(x),2)
                c=1
        else
                c=0
        endif
endif

ifndef x
        b=1
else
        b=0
endif

a:
        echo $(b)
        echo $(a)
        echo $(c)

运行结果:

book@100ask:~/make_text$ make -f ma
echo 0
0
echo 0
0
echo 1
1

注意 ifeq 没有elif搭配

循环

DIR=001 002 003
a:
        echo $(foreach v,$(DIR),$(v))

运行结果:

book@100ask:~/make_text$ make -f ma
echo 001 002 003
001 002 003

除了这种循环方式,还可以使用shell命令循环

函数

#自定义函数,不是真正的函数,本质上是多行命令,放在外面
#没有返回值
#$(0)指的是函数名,$(1)指的是传进第一个参数  
define FUNC1
	echo $(1) $(2) $(3)
	echo func1
endef
all:
	$(call FUNC1,abc,def)

make install

001_text.c 文件

#include "stdio.h"

int main()
{
	int i=0;
	for(;i<10;++i){
		printf("001_run%d\n",i);
	}
	return 0;
}

makefile文件

TARGET:=001_text
SOURCE:=$(wildcard ./*.c)
OBJ:=$(patsubst %.c,%.o,$(SOURCE))

bin:=/usr/local/bin/
path:=/home/book/make_text/002

START:=start
STOP:=stop
LOG:=$(path)/log.txt
.PHONY: clean install clean_log

$(TARGET):$(OBJ)
	gcc $^ -o $@
%.o: %.c
	gcc -c $^ -o $@

install:$(TARGET)
	if [ -d $(path) ]; \
		then echo $(path) exist; \
	else \
		echo $(path) not exist; \
		mkdir $(path); \
	fi; \
	touch $(LOG); \
	chmod a+rwx $(LOG);\
	echo "$(TARGET)>$(LOG) & " > $(path)/$(START); \
	echo "killall $(TARGET)" > $(path)/$(STOP);\
	chmod +x $(path)/$(STOP);\
	chmod +x $(path)/$(START);\
	cp $(TARGET) $(path)/$(TARGET); \
	sudo ln -sv $(path)/$(START) $(bin); \
	sudo ln -sv $(path)/$(STOP) $(bin); \
	sudo ln -sv $(path)/$(TARGET) $(bin); \


clean:
	sudo rm -rf $(TARGET) $(OBJ) $(bin)/$(TARGET) $(path)/$(TARGET) $(path)/$(START) $(path)/$(STOP) $(bin)/$(START)  $(bin)/$(STOP)
clean_log:
	rm -f $(LOG)

运行结果:

book@100ask:~/make_text/001$ ls /usr/local/bin
001_text  start  stop
book@100ask:~/make_text/001$ start
book@100ask:~/make_text/001$ cat ../002/log.txt
001_run0
001_run1
001_run2
001_run3
001_run4
001_run5
001_run6
001_run7
001_run8
001_run9

-rf $(TARGET) $(OBJ) ( b i n ) / (bin)/ (bin)/(TARGET) ( p a t h ) / (path)/ (path)/(TARGET) ( p a t h ) / (path)/ (path)/(START) ( p a t h ) / (path)/ (path)/(STOP) ( b i n ) / (bin)/ (bin)/(START) ( b i n ) / (bin)/ (bin)/(STOP)
clean_log:
rm -f $(LOG)


运行结果:

```shell
book@100ask:~/make_text/001$ ls /usr/local/bin
001_text  start  stop
book@100ask:~/make_text/001$ start
book@100ask:~/make_text/001$ cat ../002/log.txt
001_run0
001_run1
001_run2
001_run3
001_run4
001_run5
001_run6
001_run7
001_run8
001_run9
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值