一个专业拧螺丝的打工人Linux打怪升级之路-Make工程管理器

linux升级之路-Make工程管理器

 首先输入命令:vim Makefile(make命令的执行需要一个Makefile文件) 编辑目标;如:

hello: hello.c hellofunction.c
	gcc -o hell hello.c hellofunction.c -I.		#-I.表示告诉编译器可以在“.”即当前目录下去寻找头文件
clean:
	rm -f *.o hello

一、依赖规则:

二、Mkaefile 假目标

 采用.PHONY关键字定义假目标,目的是为了防止定义的目标与以存在的文件名或者指令集重名,用.PHONY关键字定义的目标不予关联,每次make name该目标都会执行
 用法:
  .PHONY: name
  name:
  rm file

三、Makefile 使用变量

 1、自定义:li= test.o (“=”在这里相当于 C语言里的define )
  使用方法如:

.PHONY:cl

li = test.o		#自定义变量,=相当于C中的define

e: $(li)
	gcc -o e $(li)	#$在此处代表引用自定义变量

$(li): test.c
	gcc -c test.c
cl:
	rm e $(li)

 2、一些特殊符号的意义及用法
  $# $@ $0 $* $$ $? 的意义和用法:

echo "$#"			#传给shell的参数的个数
echo "$@"			#此处表示所有参数列表(用“”符号括起来的形式,另外不用“”括起来的表示目标文件)
echo "文件名:$0"	#表示shell本身文件名
echo "传给sehll的第一个参数:$1"
echo "传给shell的第二个参数:$2"
echo "$*"			#所有参数列表,连续输出,$@是分别输出
echo "IP = $$"		#sehll 本身的PID(Process ID)
echo "$?"			#最后运行的命令结束代码(返回值),另外#!表示最后运行后台的IP

$@ $^ $< $% 的意义和用法

   $@ 表示目标文件
   $^ 表示所有的依赖文件,重复的只保留一份
   $< 表示第一个依赖文件
   $%与 $@相似,但 $%仅匹配“库”类型的目标文件

ARCH ?= x86
TARGET = hello
#CC = gcc
CFLAGS = -I .
DEPS = file.h
OBJS = main.o file.o
ifeq ($(ARCH),x86)
	CC = gcc
else
	CC = arm-linux-gnueabihf-gcc
endif
$(TARGET) : $(OBJS)
	$(CC) -o $@ $^ $(CFLAGS)
%.o : %.c $(DEPS)
	$(CC) -c -o $@ $< $(CFLAGS)
.PHONY: clean
clean:
	rm -rf *.o test

四、Makefile 三要素: 目标、依赖、命令

五、使用函数

 1、patsubst: 模式字符串替换

$(patsubst %.c, %.o, x.c y.c)		#输出“x.o y.o”

 2、notdir: 用于去除文件路径中的目录部分

$(notdir work_dir/usr test.txt)		#输出“usr test.txt”

 3、wildcard: 获取文件列表,并使用空格分隔开

$(wildcard *.c)		#列出当前目录下所有.c结尾的文件

 4、foreach: 循环函数,类似shell中的for语句

.PHONY: all
dirs := a b c d
# 使用foreach 遍历找出目录下的所有文件
files := $(foreach dir,$(dirs),$(wildcard $(dir)/*))
all:
	@echo "$(files)"	# 列出所有目录下的文件

六、多级结构工程

ARCH ?= x86
TARGET = hello
# 存放中间文件的路径
BUILD_DIR = build_$(ARCH)
# 存放源文件的文件夹
SRC_DIR = sources
# 存放头文件的文件夹
INC_DIR = include
# 源文件
SRCS = $(wildcard $(SRC_DIR)/*.c)
# 目标文件
OBJS = $(patsubst %.c, $(BUILD_DIR)/%.o, $(notdir $(SRCS)))
# 头文件
DEPS = $(wildcard $(INC_DIR)/*.h)
# 指定头文件路径
CFLAGS = $(patsubst %, -I%, $(INC_DIR))
ifeq ($(ARCH), x86)
	CC = gcc
else
	CC = arm-linux-gnueabihf-gcc
endif
$(BUILD_DIR)/$(TARGET): $(OBJS)
	$(CC) -o $@ $^ $(CFLAGS)
$(BUILD_DIR)/%.o : $(SRC_DIR)/%.c $(DEPS)
	@mkdir -p $(BUILD_DIR)
	$(CC) -c -o $@ $< $(CFLAGS)
.PHONY: clean cleanall
clean:
	rm -rf $(BUILD_DIR)
cleanall:
	rm -rf build_x86 build_arm

你可能感兴趣的:(学习笔记,linux)