makefile2

一、make执行解析与实例操作

如图:整体是递归过程

1、#make 后没有指定,只执行第一个定义。优先执行依赖,依赖没有就依次查找依赖,找到后执行依赖生成文件,在继续执行。

      makefile书写都是tab键,不是空格形式

make -s #不打印输出命令

例1:
OBJ=name.o sk.o jk.o #定义变量
name.o: OBJ #定义make执行的函数。(Nj为依赖函数,优先执行。)
@echo "run command"
gcc -c NJ -o NJ.o
NJ:
@echo "dependency function"

例1.1:
$^ 所有不重复依赖
OBJ=name.o sk.o jk.o #定义变量
%.o: OBJ #定义make执行的函数(Nj为依赖函数,优先执行。 ),%.o自动匹配上面的name.o sk.o jk.o
@echo "run command"           #echo前加@可以不打印执行的命令行,只输出打印结果,相当于make -s
gcc -c $^ -o $@ #-o 指向生成文件,$^不重复依赖,指向上面的依赖.$@目标文件的完整名称
OBJ:
@echo "dependency function"

-rm -rf test           #“-”表示次命名执行失败后不影响后面的命令执行,相当于Python的 “ignore”

@# echo "jim"     #“@#”表示注释
2.变量
变量名=变量值
使用:$(变量)/$(变量)

2.1 自动变量

2.2 定义变量

TARGET=first_make

CFLAGS:  g++ 编译时自动调用参数

传参: make -f Makefile flag=345 #flag为参数定义
3.伪目标: 声明为伪目标,makefile将不会判断目标是否存在或该目标是否需要更新,(根据指定的命令直接执行这个文件,并打印结果)与make直接调用makefile文件命令无关
.PHONY: all clean

4.模式匹配:%目标:%依赖

%.o%.cpp .o依赖对应的.cpp #配皮文中所有*.o的文件,目标和依赖相同部分可以匹配.重复依赖不再执行

wildcard $(wildcard ./*.cpp) #获取当前目录下的所有.cpp文件
patsubst $(patsubst %.cpp,%.o,%*.cpp)          #将所有对应的cpp文件名替换成.o文件

例:

OBJS=$(patsubst %.cpp,%,(wildcard   *.cpp))          #创建规则,所.cpp文件替换成无.cpp后缀的文件名

all:$(OBJS)             #遍历所有可编译文件,                         

5.动态链接库:.dll .so 库文件(运行时才加载)
libtest.so #库名书写规则前要有个lib**.so

void func(); #定义函数
virtual void func(); #虚函数

6.静态库: .a 库文件

7.通用部分用include

8.公共头文件
8.1 = 赋值,但是取得是最后一个赋值命令赋的值(只能赋予固定值)
例1:
A=123
B=${A}
echo $A $B 输出值为456 456
A=456
B=${B} #${B}不能直接应用。会报错

8.2 := #可以直接应用上面赋值命令,取上面第一个赋予的值,而不是最终值
例2:
A=123
B=${A}
echo $A $B 输出值为123 123
A=456
B:=${B} #${B}可以递归应用

9.shell命令
A:=$(shell ls)
B:=$(shell pwd)
c:=$(shell if [ ! f abc ];then touch abc; fi)

10.-C 指定工作目录
make -C ../
make -C ../ clean

make -C $@   #读取指定目录下的makefile文件

export CC OBJ BIN BIN_DIR    #让子makefile可以找到并使用这些变量

11.条件判断,没有elseif或elseifdef,只能用嵌套形式

ifeq 判断是否相等,相等返回ture,不相等返回false
ifneq 判断是否不相等,不相等返回ture,相等返回false
ifdef 判断是否存在
ifndef 判断是否不存在

例:
a:= 123
name:=
ifeq ($(a),123)
name=yes
else
ifeq ($(a),321)
name=no
else
name=yes
endif
endif

12.循环:makefile中只有一个循环foreach,只支持GUN Make。
其他平台make可以用shell的循环实现
TARGET= A B C
all:
echo $(TARGET)
echo $(foreach v,$(TARGET),$v)
touch $(foreach v,$(TARGET),$v.text) #可创建A.text B.text C.text
clean:
$(RM) -rf $(TARGET) *text

13,调用函数:call
例:
define FUNC
echo $0 #$0为函数自己的名称。输出FUNC
echo func1
echo $1 $2
endef

all:
$(call FUNC) #调用函数
$(call FUNC,abd,nak) #abd,nak传参,传参给$1,$2


例:
.cpp文件需要g++进行编译,生成*.out文件(可直接运行)

 g++  testmake.cpp

 

#vim makefile
TARGET=firstmake
$(TARGET): first_make.cpp
    $(CXX) $^ -lpthread -std=c++11 -o $@
    @echo "first success"
clean: cleanone
    rm -rf firstmake 
.PHONY: clean $(TARGET)

add: add.c
    gcc $^ -o $@
cleanone:
    $(RM) add *.o *.s *.i
CC = gcc
OBJ = main
OBJS = main.o add.o sub.o 
$(OBJ):$(OBJS)
    $(CC) $(OBJS) -o $(OBJ)
$*.o:$%.c
    gcc -c $^ -o $@
#main.o:main.c
#    gcc -c $^ -o $@
#add.o:add.c
#    gcc -c $^ -o $@
#sub.o:sub.c
#    gcc -c $^ -o $@

#vim add.c
int add(int a,int b)
{
    return a + b;
}

#vim sub.c
int sub(int a,int b)
{
    return a * b;
}

vim main.c
#include <stdio.h>
extern int add(int ,int);
extern int sub(int ,int);
int main(int argc, const char *argv[])
{
    int a = 1;
    int b = 2;
    printf("a + b = %d\na * b = %d\n",add(a,b),sub(a,b));
    return 0;
}

#make clean
#make main

  

posted @ 2022-09-28 15:28  JASON_yul  阅读(135)  评论(0)    收藏  举报