Makefile学习

流过昼夜 提交于 2019-12-10 06:08:16
  1. makefile工程管理

1.1 makefile概述

  linux 环境下的程序员如果不会使用GNU make来构建和管理自己的工程,应该不能算是一个合格的专业程序员,至少不能称得上是unix程序员。在linux环境下使用GNU的make工具能够比较容易的构建一个属于你自己的工程,整个工程的编译只需要一个命令就可以完成编译,链接以至于最后的执行 ,不过这需要我们投入一些时间去完成一个或者多个称为makefile文件的编写,次文件正是make正常工作的基础。所要完成的makefile文件描述了整个工程的编译,链接等规则。

Make是一个命令工具它解释makefile中的指令(应该说是规则)makefile文件中描述了整个工程所有文件的编译顺序、编译规则Makfile有自己的书写格式。像c语言有自己的格式、关键字和函数一样。而且在makefile中可以使用系统shell所提供的任何命令来完成想要的工作。

    首先我们需要明确一些基本概念:

 编译:把高级语言书写的代码转换为机器语言可识别的机器码。编译高级语言后生成的指令虽然可被机器识别,但是还不能被执行。编译时,编译器检查高级语言的 语法,函数与变量的声明是否正确。只有所有的语法正确、相关变量定义正确编译器就可以编译出中间目标文件。通常,一个高级语言的源文件都可对应一个目标文件。目标文件在linux中默认后缀为“.o”(如“foo.c”的目标文件为“foo.o”)

链接:将多个.o 文件,或者.o文件和库文件链接成为可被操作系统执行的可执行程序(linux环境下,可执行文件的格式“ELF”格式),连接器不检查函数所在的源文件,只检查所有.o文件中定义的符号。将.o文件中使用的函数和其他.o或者库文件中的相关符号进行合并,对所有文件中符号进行重新安排(重定位),并连接系统相关文件(程序启动文件等)最终生成可执行文件。连接过程使用GNU的“ld”工具。

  1. makefile 规则的介绍:

make  需要开发者 自己构建 创建 。创建文件的名称:  Makefile   makefile 。

模型:

    Target……….  : prerequisites………..

         (tab键) Command………….

目标文件 (a.out  可执行文件):依赖文件(xxx.c)

(以tab键开始)依赖文件生成目标文件的 指令

执行一个makfile文件需要 输入 make   指令 ,make指令能够寻找当前路径下面的makefile文件。

案例1:

a:main.c menu.c book.c

gcc -o a main.c menu.c book.c

通过版本1:得出版本2:

aa:main.o menu.o book.o

gcc -o a main.o menu.o book.o

main.o:main.c

gcc -c main.c

menu.o:menu.c   

gcc -c menu.c

book.o:book.c

gcc -c book.c

.PHONLY:clean   # 伪目标   

clean:

rm -rf *.o

rm -rf aa

总结:  1. 整个makefile 文件  通过 在依赖关系上面做文章 。

        2. 当在终端输入一个make 指令之后会寻找相应的makefile 文件,会将makefie当中第一个目标文件当作最终的可执行文件,如果目标文件不存在,会找相应的依赖文件。如果依赖文件不存在,会继续向下寻找以依赖文件为目标文件的依赖文件,如果依赖文件存在,则执行  将依赖文件转化成 目标文件。然后最终的目标文件的 依赖文件都产生,再将依赖文件转换成最终的 目标文件。

       3. 依赖文件可以当作目标文件来对待。

       4. clean :  不是真正的目标文件 是伪目标 文件: 简单 :  当作声明来理解.对应的指令是 make  clean

   展开后的写法:

      .PHONLY:clean   # 伪目标   

clean:

rm -rf *.o

rm -rf aa

     5. makefile  文件中的注释 用  #  

  1. Makefile中使用变量

在makefile中 经常会使用变量,一般用obj  object   ……….等等 。

变量的赋值   =     :  直接赋值

             +=    :  以追加的形式赋值

             ?=    :  如果变量没有赋值,则将右值赋给变量,如果变量有赋值,以变量的赋值为标准。

             :=    :  覆盖之前的赋值。

案例:

@ : 取消提示指令符

all  :  所有的目标文件    后面可以没有依赖文件

变量的取值: $( 变量名 )

obj=123

 

 

all:

@echo "$(obj)"

运行结果:

[root@localhost val]# make

echo "123"                // 没有加@ 标志

123

[root@localhost val]# make

123

[root@localhost val]#

案例2 :  已追加的形式赋值

obj=123

obj+=456

all:

@echo "$(obj)"

运行结果:

[root@localhost val]# make

123 456

案例:?=

#obj=main.c

obj ?=obj.c

 

all:

@echo "$(obj)"

运行结果:

[root@localhost val]# make

obj.c

[root@localhost val]#

案例:

obj=main.c

obj :=obj.c

all:

@echo "$(obj)"

 

% : 在makefile当中  匹配任意的字符串

%.c  :  匹配任意的xxxx.c 文件

%_config  :  匹配的是任意的 xxxx_config  配置文件

案例:

val=main.c  hello.c book.c  kkkk.c

 

val2=$(val:%.c=%.s)

all:

@echo "$(val2)"

@echo "$(val)"

运行结果:

[root@localhost val]# make

main.s hello.s book.s kkkk.s

main.c  hello.c book.c  kkkk.c

[root@localhost val]#

练习:  将hello替换world

val=hello

 

val2=$(val:%hello=%world)

 

all:

@echo "$(val2)"

 

 

 注意:  遇到.c 文件下面要写makefile  文件。

  1. Make的命令行选项如下:

-C    (大写) dir 读入指定目录下的makefile  (切换路径)

-f file     读入当前目录下的file文件作为makefile

-i         忽略所有的命令行错误

-I     (大写i)指定被包含得makfile 所在目录   找头文件

-w        如果make在执行过程中改变目录,则打印当前目录名

-s        在执行命令时不显示命令

-p        显示make 变量数据库和隐含规则。

 

  1. Makflie常用的自动变量:

$@: 全部的目标文件

$^: 全部的依赖文件

$<:  第一个依赖文件

练习:

 

menu:

 

第二个makefile

obj=main.o

obj+=menu.o book.o

CC=gcc

DEST=ss

$(DEST):$(obj)

$(CC) -o $(DEST) $(obj)

main.o:main.c

$(CC) -c $^ -I include

menu.o:

make -C menu

book.o:book.c

$(CC) -c $^

clean:

rm -rf *.o

rm -rf aa

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!