Linux 中 make 命令用法示例

概述:make命令描述源程序间相互关系并自动编译,用于执行makefile文件中的预先设定的命令,诸如编译、运行、删除等等,可大大提高效率。在较大规模的系统中,人们希望对其中某个或者某一些模块的修改不要导致对整个程序的编译,此时makefile可以在这方面带来很大便利。

下面主要分为四个的部分:
1.在单一源文件下的示例
2.在多个源文件下的示例
3.探讨Makefile文件中语句的缺省可能带来的差异
4.部分参数的使用 -B , -f ,-C 等


  • 示例一 单一的源文件

    1. 新建名为“makefile”的文件(不区分大小写)
      这里写图片描述

文件内容如下:

all:hello

hello:hello.c
    gcc -o hello hello.c   
run:hello
    ./hello            
clean:hello
    rm hello

注意:“gcc ”、“./”、“rm”等前方空白区域必须使用tab键生成,不能按空格
代码分析:
all:hello 表示当使用make命令不带参数时,默认执行带hello参数的命令
hello:hello.c 冒号前的hello表示参数名称,是由自己定义的,而冒号后的hello.c,表示需要操作的文件名
gcc -o hello hello.c 表示当使用带hello参数的make命令时,执行当前语句
run 和 clean 的用法与hello 类似
2. hello.c文件
源代码如下:
这里写图片描述
3. 使用示例
hello.c 和 Makefile文件处于同一个目录下
这里写图片描述

执行make hello 命令:可见语句gcc -o hello hello.c 被执行,生成了hello可执行文件
这里写图片描述

执行make run命令: 可见语句./hello被执行,输出hello world
这里写图片描述

执行make clean 命令: 可见语句 rm hello 被执行,hello文件被删除
这里写图片描述

执行make 命令:效果与make hello 命令相同
这里写图片描述


  • 示例二 多个的源文件
    1.首先,编辑具有主函数的文件,实现一个求水仙花数的功能
    文件名: shuixianhua.c
// fileName shuixianhua.c
#include<stdio.h>
#define MIN_NUM 1
#define MAX_NUM 1000
int fun(int i);
int main()
{
    int i;
    for(i=MIN_NUM ;i<MAX_NUM ;++i)
    {
        int res=fun(i);
        if(res)
        {
            printf("%d  ",i);
        }
    }
    printf("\n");
    return 0;
}

2.接着,实现fun函数,是对水仙花数的判断,该函数单独放在fun.c中

//fileName fun.c
int fun(int i)
{
    int sum=0;
    int index=0;
    int cur_num=i;
    while(cur_num!=0)
    {
        int t=cur_num%10;
        sum+=t*t*t;
        cur_num/=10;
    }   
    if (sum==i)
        return 1;
    else return 0;
}

3.创建makefile文件

main:shuixianhua.o fun.o
    gcc -o main shuixianhua.o fun.o
shuixianhua.o:shuixianhua.c
    gcc -c shuixianhua.c
fun.o:fun.c
    gcc -c fun.c

4.查看目录下的文件
这里写图片描述
5.执行make命令
这里写图片描述
可见自动执行了三条指令,多了fun.o , main ,和shuixianhua.o 三个文件
下面分析一下执行的过程:
使用make 命令时,当后面不带参数时,执行的是第一条命令:
这里写图片描述
我们知道,冒号后面的两个文件shuixianhua.o 和fun.o 表示的是执行这条指令需要用到的文件。而我们原先文件中,只有两个.c文件和makefile,并没有以上以及的两个文件,所以程序会自动寻找下面的两个指令,来先编译和生成shuixianhua.o 和fun.o 两个文件
这里写图片描述

6.运行程序
这里写图片描述


  • Makefile文件中语句的缺省可能带来的差异

1.makefile文件不做改动时,如下所示:

main:shuixianhua.o fun.o
    gcc -o main shuixianhua.o fun.o
shuixianhua.o:shuixianhua.c
    gcc -c shuixianhua.c
fun.o:fun.c
    gcc -c fun.c

a. 修改shuixianhua.c文件

// fileName shuixianhua.c
#include<stdio.h>
#define MIN_NUM 1
#define MAX_NUM 1000
int fun(int i);
int main()
{
    printf("hello \n");  //这一行新增,其他未做修改
    int i;
    for(i=MIN_NUM ;i<MAX_NUM ;++i)
    {
        int res=fun(i);
        if(res)
        {
            printf("%d  ",i);
        }
    }
    printf("\n");
    return 0;
}

b. 使用make命令进行编译,出现如下结果:
这里写图片描述
可见有两条语句执行了

c.查看运行结果
这里写图片描述

2.makefile文件做改动时,对部分参数进行省略,如下所示:

main:shuixianhua.o fun.o
    gcc -o main shuixianhua.o fun.o
shuixianhua.o:  
    gcc -c shuixianhua.c
fun.o:
    gcc -c fun.c

我们可以看到,后面两条语句中,引号后面的内容被省略。在默认的情况下,.o 缺省情况下依赖于相应的 .c 文件

a.在前者的基础上继续修改shuixianhua.c 文件

// fileName shuixianhua.c
#include<stdio.h>
#define MIN_NUM 1
#define MAX_NUM 1000
int fun(int i);
int main()
{
    printf("hello \n");  //之前增加的一行
    int i;
    for(i=MIN_NUM ;i<MAX_NUM ;++i)
    {
        int res=fun(i);
        if(res)
        {
            printf("%d  ",i);
        }
    }
    printf("\n");
    printf("good bye\n");  //这次增加的
    return 0;
}

b.接着,使用make命令进行编译,出现如下结果:
这里写图片描述
可见,没有语句被执行

接下来继续运行,发现与修改前的运行结果一样:
这里写图片描述

为什么会这样呢?我们猜想,在语句缺省的情况下,因为经过之前的编译后,生成了shuixianhua.o 文件,所以再次执行make命令时,系统发现文件夹中有shuixianhua.o文件和fun.o文件。所以不会执行第一条编译命令,所以也不会去执行下面的两条命令,也就是说不会去重新生成shuixianhua.o文件和fun.o文件,只有当第一条指令参数中的.o文件不存在时,才会执行命令生成新的main文件,才会去生成编译生成.o文件来满足生成main文件的需求

接下来验证我们的猜想:
删除文件夹中的shuixianhua.o文件,然后再执行make命令
这里写图片描述
可见系统自动地执行了两条命令。
我们再看运行结果:
这里写图片描述
很明显,有good bye语句输出,验证了我们的猜想

对比:不缺省的情况下,当程序涉及到的源文件发生变化时,执行编译命令时会根据新的源文件生成新的目标文件;而在缺省的情况下,当.o程序已经存在时,系统就不会去重新判断生成.o文件的.c文件是否发生了改变,因而在.c文件改变的情况下也不会做更新。因此,还是建议少使用缺省的方法。


  • 参数的使用

1. -B 全部目标重新建立连接
使用 make -B 指令时,无论基于以上哪种情况,无论文件是否存在,都会重新建立连接,生成新的文件(可解决以上出现的不更新的问题,但是可能带来效率方面的问题)

2. -d 打印调试信息
这样我们可以很清楚地知道执行的具体步骤 (| more 表示采用管道的方式,实现分页浏览)
这里写图片描述

3.使用 -C 选项改变目录
你可以为 make 命令提供不同的目录路径,在寻找 Makefile 之前会切换目录的。
这是一个目录,假设你就在当前目录下:

$ ls 
file file2 frnd frnd1.cpp log1.txt log3.txt log5.txt
file1 file name with spaces frnd1 frnd.cpp log2.txt log4.txt

但是你想运行的 make 命令的 Makefile 文件保存在 ../make-dir/ 目录下,你可以这样做:

$ make -C ../make-dir/ 
make: Entering directory `/home/himanshu/practice/make-dir’ 
make: Nothing to be done for `all’. 
make: Leaving directory `/home/himanshu/practice/make-dir

你能看到 make 命令首先切到特定的目录下,在那执行,然后再切换回来。

4.通过 -f 选项将其它文件看作 Makefile
如果你想将重命名 Makefile 文件,比如取名为 my_makefile 或者其它的名字,我们想让 make 将它也当成 Makefile,可以使用 -f 选项。

make -f my_makefile

通过这种方法,make 命令会选择扫描 my_makefile 来代替 Makefile。

部分资料参考自:http://www.cnblogs.com/hazir/p/linux_make_examples.html

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值