Ⅹ变量与函数的综合实例

Request

  1. 自动生成target文件夹存放可执行文件。

  2. 自动生成obj文件夹存放编译生成的目标文件.o

  3. 支持调试版本的编译选项

  4. 考虑代码的扩展性

  5. $(wildcard _pattern)

    满足_pattern的文件或目录列表

  6. $(addprefix _prefix,names)

    给名字列表names中的每一个名字曾家前缀_prefix.

Skill

  1. 自动获取当前目录下的源文件列表(函数调用)
SRCS := $(wildcard *.c)
  1. 根据源文件列表生成目标文件列表(变量的值替换)
OBJS := $(SRCS:.c =.o)
#不能有空格
  1. 对每一个目标文件列表加上路径前缀(函数调用)
OBJS := ( addprefix path/ , $(OBJS) )

规则中的模式替换

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

针对于当前工作目录

OBJS := func.o main.o
$(OBJS) : %.c
gcc -o $@ -c $^

针对于变量(OBJS)列表

编译规则中的依赖

				->dirs           (创建文件夹)
all -> targets -> ->objs (生成可执行文件)
->生成可执行文件 (链接)

Summary

  • 目录可以成为目标的依赖,在规则中创建目录。
  • 预定义函数是makefile实战中时不可或缺的部分。
  • 规则中的模式匹配可以直接针对目录中的文件。
  • 可以使用命令行变量便须特殊的目标版本。

工程实例

在工程文件夹下新建立了main.c func.c func.h.(放在同一文件夹下)。

现在已经是第二天。如果.H 文件放在inc文件夹下面会更合适。也会更加符合实际的工程应用。

main.c

#include <stdio.h>
#include "func.h"

int main(){
print("%s\n",);
return 0;
}

func.c

const char* String = "My Densitiy"

func.h

#ifndef __FUNC__
#define __FUNC__

extern cont char* String;
#endif

makefile

CC := gcc
MKDIR := mkdir
RM := rm -fr

DIR_OBJS := objs
DIR_TARGET := target

DIRS := $(DIR_OBJS) $(DIR_TARGET)

TARGET := $(DIR_TARGET)/hello_makefile.out

SRCS := $(wildcard *.c)
#获取源文件列表
#main.c func.c

OBJS := $(SRCS:.c=.o)
#值替换 main.o func.o
#debug TODO:can't use to space in $(SRCS:.c=.o)
#用于生成目录下的列表

OBJS := $(addprefix $(DIR_OBJS)/, $(OBJS))
#添加路径前缀objs/main.o
#objs/mian.o objs/func.o

.PHONY: rebuild clean all

$(TARGET) : $(DIRS) $(OBJS)
@$(CC) -o $@ $(OBJS)
@echo "Target File ==> $@"
@./$(TARGET)

$(DIRS):
@$(MKDIR) $@

$(DIR_OBJS)/%.o : %.c
ifeq ($(DEBUG),true)
@$(CC) -o $@ -g -c $^
else
@$(CC) -o $@ -c $^
endif

rebuild:clean all

all : $(TARGET)

clean:
$(RM) $(DIRS)

Ⅴ预定义变量的使用
预定义变量中存在两类变量,一类是自动变量,一类是特殊变量
  • 自动变量
$@ $^ $<
  • 特殊变量
$(MAKE),$(MAKECMDGOALS),$(MAKEFILE_LIST)
$(MAKE_VERSION),$(CURDIR),$(VARIABLES)
etc...

自动变量的意义

$@

当前规则中触发命令被执行的目标

$^

当前规则中的所有依赖

$<

当前规则中的第一个依赖

自动变量的使用示例

hello : main.o func.o
gcc -o $@ $^

%.o : %.c
gcc -o $@ -c $<

一些特殊变量的意义

$(MAKE)

当前make解释器的文件名

$(MAKECMDGOALS)

命令行中指定的目标名(make的命令行参数)

$(MAKEFILE_LIST)

make所需要的处理的makefile文件列表

当前makefile的文件名总是位于列表的最后

文件名之间以空格进行分割
.PHONY: all out first second third unload

all out:
@echo "\$$(MAKE)=> $(MAKE)"
@echo "\$$MAKECMDGOALS=> $(MAKECMDGOALS)"
@echo "\$$(MAKEFILE_LIST)=> $(MAKEFILE_LIST)"

first:
@echo "\$$MAKECMDGOALS=> $(MAKECMDGOALS)"
@echo "first"
second:
@echo "\$$MAKECMDGOALS=> $(MAKECMDGOALS)"
@echo "second"
third:
@echo "\$$MAKECMDGOALS=> $(MAKECMDGOALS)"
@echo "third"

test:
@$(MAKE) first
@$(MAKE) second
@$(MAKE) third
##文末这种调用方式,适用于大型工程多个makefile的调用##
##但不能实现多文件的调用##

image-20210411175744920

$(MAKE_VERSION)

当前make解释器的版本

$(CURDIR)

当前make解释器的工作目录

$(.VARIABLES)

所有已经定义的变量名列表(预定义变量和自定义变量)
.PHONY: test1 test2

ZHC := Aron
test1:
@echo "\$$(MAKE_VERSION) => $(MAKE_VERSION)"
@echo "\$$(CURDIR) => $(CURDIR)"
@echo "\$$(。VARIABLES) => $(.VARIABLES)"

##我们可以通过(.VARIABLES)去查看该版本下的预定义的特殊变量,具体的解释需要到gnu官网去查看##

image-20210411175525011

小结

makefile提供了预定义变量供开发者使用

预定义变量的使用能够使得 makefile的开发更高效

自动变量是makefile中最常见的元素

使用$(.VARIABLES)能够获取所有的特殊变量


小问题

makefile中能否实现 类似C语言 中多文件调用的情况?


Ⅳ变量和不同的赋值方式
  • makefile中支持程序设计语言中变量的概念

  • makefile中的变量只代表文本数据( 字符串 )

  • makefile中的变量名规则

-变量名可以包含字符,数字,下划线.
-不能包含":" , "#" ,"=" 或 " "
-变量名大小写敏感

变量的定义和使用

CC := gcc
TARGET := hello.out

$(TARGET) : func.o main.o
$(CC) -o $(TARGET) fun.o main.o

##开始的两行表示 变量的定义##
##使用的时候 需要加上 $() ,变量名填入其中##

makefile中变量的赋值方式

-简单赋值 ( := )
-递归赋值 ( = )
-条件赋值 ( ?= )
-追加赋值 ( += )

简单赋值( := )

  • 程序设计语言中的通用的赋值方法
  • 只针对当前语句的变量有效
x := foo
y := $(x)b
x := new

.PHONY: test
test:
@echo "x=> $(x)"
@echo "y=> $(y)"

输出结果:

x=> foo
y=> foob

递归赋值( = )

  • 赋值操作可能影响多个其他变量.
  • 所有与目标变量相关的其他变量都将受到其影响.
x := foo
y := $(x)b
x = new

.PHONY : test
test:
@echo "x=> $(x)"
@echo "y=> $(y)"

输出结果:

x=> new
y=> newb

条件赋值( ?= )

  • 如果变量未定义,使用赋值符号中的值定义变量
  • 如果变量已经定义,赋值无效
x := foo
y := $(x)b
x ?= new
c ?= WHL

.PHONY : test
test:
@echo "x=> $(x)"
@echo "y=> $(y)"
@echo "c=> $(c)"

输出结果:

x=> foo
y=> foob
c=> WHL

追加赋值( += )

  • 原变量之后加上一个新值
  • 原变量值与新值之间有空格隔开
x := foo
y := $(x)b
x += y

.PHONY : test
test:
@echo "x=> $(x)"
@echo "y=> $(y)"

输出结果:

x=> foo foob
y=> foob

构造函数

ControlTheory Ⅰ

C8051F380初级教程(1)

​ 首先说说我做这个的目的,首先是为了整理知识,另外为了分享出来,让自己实现一些个人价值。

​ 另外这个教程会写多久?预计在2021年6月1日写完。目前制作这个教程的计划,还没有明确规划,但是先划一个Death Line

Read more
自我介绍

欢迎来到Aron Blog,这是第一次自己成功搭建的博客,是我很喜欢的蓝色。欢迎大家提出意见。

Read more