设为首页 加入收藏

TOP

简介make命令和makefile文件(一)
2019-09-03 00:26:00 】 浏览:42
Tags:简介 make 命令 makefile 文件

一、为什么要用到 make 命令和 makefile 文件

  在 Linux 下编写一个程序,每次编译都需要在命令行一行一行的敲命令。如果是一个很小的程序还好说,命令不怎的复杂,编译速度也挺快,但是对于大型程序来说,这样无疑很麻烦,且不说可能会敲错命令,有时候仅仅改动了一个小地方,却需要将整个程序全部重新编译一遍,显然很浪费时间。Linux 提供了 make 命令来解决上述问题,它会在必要时重新编译所有受改动影响的源文件。同时,还提供了一个 makefile 文件,它告诉 make 命令如何构建应用程序。这里用一个简单的例子提前演示一下:

/* hello.c */
#include <unistd.h> #include <stdio.h> #include <stdlib.h> int main() { printf("hello world!\n"); exit(0); }
/* Makefile */
hello: hello.c gcc
-o hello.s -S hello.c gcc -o hello.o -c hello.s gcc -o hello hello.o clean: -rm hello hello.s hello.o

  这里提供了两段代码,第一段代码是一个简单的 HelloWorld 程序,第二段代码是为这个程序编写的一个 makefile 文件。此时,只需要在命令行输入 make 命令,就可以对源文件 hello.c 进行编译,如下:

  执行 make 命令时,make 命令会读取 makefile 文件,并按照 makefile 文件中给出的命令来创建文件,同时会在执行时将命令打印到标准输出。执行完 make 命令后,源文件所在目录下多了三个文件:hello、hello.o 和 hello.s,其中 hello 是可执行文件,使用命令 ./hello 即可查看程序的输出结果。这和直接在命令行使用 gcc 命令所得到的结果是一样的,而且,当你修改了源文件时,也只需要再次使用 make 命令即可重新编译,十分方便。 

 

二、make 命令

  make 命令用于从一个名为 makefile 的文件中获得构建一个程序的依赖关系。make 命令会根据 makefile 文件来确定目标文件的创建顺序以及正确的规则调用顺序。

make 命令的一些常用参数

1)-k 参数:

  使用 -k 参数可以让 make 命令在发现错误时仍然继续执行,而不是在检测到第一个错误时就停下来。利用这个选项可以在一次操作中发现所有未编译成功的源文件;

2)-n 参数:

   使用 -n 参数,让 make 命令输出将要执行的操作步骤,而不是真正执行这些操作;

3)-f 参数:

  使用 -f 参数,后面可以接一个文件名,用于指定一个文件作为 makefile 文件。如果没有使用 -f 选项,则 make 命令会在当前目录下查找名为 makefile 的文件,如果该文件不存在,则查找名为 Makefile 的文件。 

 

三、makefile 文件

  makefile 文件由一组依赖关系规则构成。每个依赖关系都由一个目标(即将要创建的文件)和一个该目标所依赖的源文件组成;规则描述了如何通过这些依赖文件创建目标。简单的来说,makefile 文件的写法如下:

target: prerequisites
    command1
    command2
    ...

  其中,target 是即将要创建的目标(通常是一个可执行文件),target 后面紧跟一个冒号,prerequisite 是生成该目标所需要的源文件(依赖),一个目标所依赖的文件可以有多个,依赖文件与目标之间以及各依赖文件之间用空格或制表符 Tab 隔开,这些元素组成了一个依赖关系。随后的命令 command 就是规则,也就是 make 需要执行的命令,它可以是任意的 shell 命令。另外,makefile 文件中,注释以 # 号开头,一直延续到该行的结束

3.1 依赖关系

  依赖关系定义了最终应用程序里的每个文件与源文件之间的关系。一个依赖关系列表由目标和该目标的零个或多个依赖组成,语法是:先写目标,然后接一个冒号,再用一个空格或制表符隔开,最后是用空格或制表符隔开的依赖文件列表,如下:

target: prerequisite1 prerequisite2 prerequisite3 ...

  依赖关系表明了这样一件事:目标文件 target 依赖于文件 prerequisite1、prerequisite2、prerequisite3 ...,即,要生成 target,需要有这几个依赖文件的存在,而且,若其中一个依赖文件发生了改变,则需要重新生成 target。目标所依赖的文件可以有一个或多个,也可以没有依赖文件 —— 该目标总被认为是过时的,在执行 make 命令时,若指定了该目标,则该目标所对应的规则将总被执行(如目标 clean)。

  makefile 文件中可以有很多个目标,每个目标都有自己对应的规则。make 命令默认创建的是 makefile 文件中的第一个目标。也可以自己指定一个目标让 make 命令去创建,只需要将该目标的名字作为参数放到 make 命令之后即可(如常用的 make clean)。实际上,更好的做法是,将 makefile 文件中的第一个目标定义为 all,然后再 all 后面列出其他从属目标,这将告诉 make 命令,在未指定特定目标时,默认情况下将创建哪个目标。此外,使用目标 all ,还可以使 make 命令一次性创建多个文件,这取决于 all 后面所接的从属目标的个数。

  举个例子说明一下文件与文件之间的依赖关系:

/* sum.c */
#include <stdio.h>
#include <stdlib.h>

extern int add(int i,int j);

int main()
{
  printf("%d\n",add(1,2));
  exit(0);
}

/* add.c */
#include <stdio.h>

int add(int i,int j)
{
  int k;
  k = i + j;
  return k;
}

  这是一个简单的加法程序,包含两个文件:sum.c 和 add.c,其中,sum.c 中的 main 函数调用了 add.c 中的 add 函数。这个程序的依赖关系表如下:

sum: sum.o add.o
sum.o: sum.c stdio.h stdlib.h
add.o: add.c stdio.h

  其中,最终所需要的目标文件是 sum,sum.o 和 add.o 是依赖 —— 要生成目标文件 sum ,需要先生成 sum.o 和 add.o。同样的,作为目标的 sum.o 依赖于 sum.c、stdio.h 和 stdlib.h;add.o 依赖于 add.c 和 stdio.h。这组依赖关系形成了一个层次结构,它显示了源文件之间的关系。

  可以看出来,如果 add.c 发生了改变,那么就需要重新编译 add.o,而由于 add.o 发生了改变,目标文件 sum 也需要被重新创建,同时,由于 add.c 的改变并没有影响到 sum.o(sum.o 不依赖于 add.c),因此,sum.o 并不需要被重新编译。也就是说,通过使用 makefile 文件和 make 命令

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇【Linux】【Java】CentOS7安装最.. 下一篇linux 取消笔记本触摸键

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目