利用Makfile给多文件、多目录C源码建立工程

2023-03-30 12:19:34     来源:面包芯语

有粉丝留言,想知道如何使用Makefile给多个文件和多级目录建立一个工程,必须安排!

关于Makefile的入门参考文章,初学者可以先看看这篇文章:


(资料图片)

@echo--compilingmodule----;//屏幕输出--compilingmodule----echo--compilingmodule----;//没有@屏幕输出echo--compilingmodule----

通常删除,创建文件如果碰到文件不存在或者已经创建,那么希望忽略掉这个错误,继续执行,就可以在命令前面添加 -,

-rm dir;-mkdir aaadir;

[1] wildcard

说明:列出当前目录下所有符合模式“ PATTERN”格式的文件名,并且以空格分开。“ PATTERN”使用shell可识别的通配符,包括“ ?”(单字符)、“ *”(多字符)等。示例:

$(wildcard*.c)

返回值为当前目录下所有.c 源文件列表。

[2] patsubst

说明:把字串“ x.c.c bar.c”中以.c 结尾的单词替换成以.o 结尾的字符。示例:

$(patsubst%.c,%.o,x.c.cbar.c)

函数的返回结果 是:

x.c.obar.o

[3] notdir

说明:去除文件名中的路径信息 示例:

SRC=(notdir./src/a.c)

去除文件a . c 的路径信息 , 使用 (notdir ./src/a.c) 去除文件a.c的路径信息,使用 (notdir./src/a.c)去除文件a.c的路径信息,使用(SRC)得到的是不带路径的文件名称,即a.c。

[4] 包含头文件路径

使用-I+头文件路径的方式可以指定编译器的头文件的路径 示例:

INCLUDES=-I./inc
$(CC)-c$(INCLUDES)$(SRC)

[5] addsuffix

函数名称:加后缀函数—addsuffix。语法:

$(addsuffixSUFFIX,NAMES…)

函数功能:为“NAMES…”中的每一个文件名添加后缀“SUFFIX”。参数“NAMES…”为空格分割的文件名序列,将“SUFFIX”追加到此序列的每一个文件名的末尾。返回值:以单空格分割的添加了后缀“SUFFIX”的文件名序列。函数说明:示例:

$(addsuffix.c,foobar)

返回值为:

foo.cbar.c

[6] 包含另外一个文件:include

在Makefile使用include关键字可以把别的Makefile包含进来,这很像C语言的#include,被包含的文件会原模原样的放在当前文件的包含位置。比如命令:

includefile.dep

即把file.dep文件在当前Makefile文件中展开,亦即把file.dep文件的内容包含进当前Makefile文件。

在 include前面可以有一些空字符,但是绝不能是[Tab]键开始。

[7] foreach

foreach函数和别的函数非常的不一样。因为这个函数是用来做循环用的语法是:

$(foreach,,)

这个函数的意思是,把参数中的单词逐一取出放到参数所指定的变量中,然后再执行所包含的表达式。

每一次会返回一个字符串,循环过程中,的所返回的每个字符串会以空格分隔,最后当整个循环结束时,所返回的每个字符串所组成的整个字符串(以空格分隔)将会是foreach函数的返回值。

所以,最好是一个变量名,可以是一个表达式,而中一般会使用这个参数来依次枚举中的单词。

举例:

names:=abcdfiles:=$(foreachn,$(names),$(n).o)

上面的例子中,$(name)中的单词会被挨个取出,并存到变量“n”中,“$(n).o”每次根据“$(n)”计算出一个值,这些值以空格分隔,最后作为foreach函数的返回,所以,$(files)的值是“a.o b.o c.o d.o”。

注意,foreach中的参数是一个临时的局部变量,foreach函数执行完后,参数的变量将不在作用,其作用域只在foreach函数当中。

[8] call

“ call”函数是唯一一个可以创建定制化参数函数的引用函数。使用这个函数可以实现对用户自己定义函数引用。我们可以将一个变量定义为一个复杂的表达式,用“ call”函数根据不同的参数对它进行展开来获得不同的结果。

函数语法:

$(callvariable,param1,param2,...)

函数功能:在执行时,将它的参数“param”依次赋值给临时变量“ $(1)”、“ $(2)” call 函数对参数的数目没有限制,也可以没有参数值,没有参数值的“ call”没有任何实际存在的意义。

执行时变量“variable”被展开为在函数上下文有效的临时变量,变量定义中的“ $(1)”作为第一个参数,并将函数参数值中的第一个参数赋值给它;变量中的“ $(2)”一样被赋值为函数的第二个参数值;依此类推(变量**$(0)**代表变量“ variable”本身)。之后对变量“ variable” 表达式的计算值。

返回值:参数值“ param”依次替换“ $(1)”、“ $(2)”…… 之后变量“ variable”定义的表达式的计算值。

函数说明:

函数示例:

reverse=$(2)$(1)foo=$(callreverse,a,b)all:@echo"foo=$(foo)"

执行结果:

foo=ba

即a替代了(2)

三、编译详细说明

我们在根目录下执行make命令后,详细步骤如下:

@$(foreachn,$(Modules),$(callmodules_make,$(n)))

Modules是所有的目录名字集合,foreach 会遍历字符串$(Modules)中每个词语,每个词语会赋值给n,同时执行语句:

callmodules_make,$(n)

$(MAKE)有默认的名字make-C:进入子目录执行make$(1):是步骤4中$(n),即每一个目录名字

最终步骤4的语句就是进入到每一个目录下,执行每一个目录下的Makefile

Objs:=$(patsubst%.c,%.o,$(Source))

patsubst 把字串$ource中以.c 结尾的单词替换成以.o 结尾的字符而

Source:=$(wildcard./*.c)

wildcard 会列举出当前目录下所有的.c文件,所以第6步最终就是将子目录下的所有的.c文件,编译生成对应文件名的.o文件。

$(CC)$(CFLAGS)-o$(Target)$(AllObjs)$(Libs)

这几个变量都在文件scripts/Makefile中定义$(CC):替换成gcc,制定编译器$(CFLAGS):替换成-Wall -O3,即编译时的优化等级-o $(Target):生成可执行程序phone$(AllObjs)

AllObjs:=$(addsuffix/*.o,$(Modules))

addsuffix 会将 /*.o追加到$(Modules)中所有的词语后面,也就是我们之前在子目录下编译生成的所有的.o文件$(Libs):替换为-lpthread,即所需要的动态库

关键词:

明星

电影