首页 > 代码库 > Makefile使用,Makefile的优化全过程

Makefile使用,Makefile的优化全过程

以一组简单的.c文件为例。从编译命令到Makefile的学习过程。

gcc参数不做过多叙述,如下这几个文件及内容:


add.c

int add(int a int b)
{
    return a+b;
}


sub.c

int sub(int a ,int b)
{
    return a-b;
}

cal.h

#ifndef __CAL_H_
#define __CAL_H_
int add(int,int);
int sub(int,int);
#endif


main.c

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

int main (void)
{
    printf("%d\n",add(33,55));
    printf("%d\n",sub(88,55));
    return 0;
}
<p>
</p>

共有3个源文件,一个头文件,那么现在编译的话需要如下命令

gcc main.c add.c sub.c -o app

假设当前文件夹内没有其他的.c文件了

但是每次编译也需要敲这个命令。这是一个多么让人蛋疼的事情啊。

所以应该有一种办法来搞定这个让人非常蛋疼的事情,没错,它就是Makefile

现在,我们写一个第一版本的Makefile,Makefile文件名固定,第一个字母必须大写。

如下:

app:main.c add.c sub.c
     gcc main.c add.c sub.c -o app
app是目标 ‘:’冒号后面是这个目标的依赖项,下面的命令是要执行的命令,需要加tab 缩进


那么现在 我们直接在终端输入make 就可以执行刚才的命令了。

只是,现在问题来了。我可能修改的时候只改动来一个.c文件,这样做不是每个都要重新再编译一遍吗。C CPP的编译是多么浪费时间呀

所以下一个版本就又诞生了

   app:main.o add.o sub.o
       gcc main.o add.o sub.o -o app
   main.o:main.c
      gcc -c main.c
   add.o:add.c
       gcc -c add.c
   sub.o:sub.c
       gcc -c sub.c
这个文件表示:最终目标是编译出一个可执行文件,依赖三个预处理文件.o文件,各个.o文件又依赖与.c文件。Makefile 内部机制会检测依赖的.c 和.o文件是否在时间上匹配,如果.c文件较新,则需要重新编译成.o文件。所以,当我们只修改了一个源文件的时候,再make编译也不会全部都编译一遍了,只会编译修改过的文件。

嗯,不错,貌似感觉已经很好了。

不过,我现在又增加了一个mul.c文件,需要一起编译,我了个去,貌似需要改的地方很多呀,要增加app依赖的.o  要修改gcc命令,还要增加新文件的.o目标依赖。

干,这样还是不够智能啊。怎么办呢。   哈哈 ,偷偷告诉你们,Makefile的默认配置已经做好了.o文件依赖.c文件的关联,文件前缀相同即可。

所以,还可以这样写,也没有问题

 app:main.o add.o sub.o
       gcc main.o add.o sub.o -o app


这样写跟上面的效果是相同的。但是这样还是达不到我们想要的效果,Dont do yourself

所以我们继续优化Makefile 下面我们使用Makefile的函数来获取需要的文件,

src=http://www.mamicode.com/$(wildcard *.c)>

这样,我们先获取当前目录下的所有的.c文件,保存在变量src中,然后再将所有的.c替换成.o 保存在变量obj中.下面的$(obj)只是取变量的值。所以,我们在当前目录增加多少个.c文件也不需要修改这个文件了。仅限当前单目录编译哦。

但是,又但是了,我都烦了,但是真的得再但是一下,优化是作为程序猿一直要做的事情。所以,继续优化Makefile,比如我想在编译的时候很方便的指定各项参数,输出的可执行文件名字,甚至,我想换个编译器。能行吗 ? 好吧,确实可以这么干。但是还得看下面的:

CFLAGS= -g -Wall
LDFLAGS=
CPPFLAGS=-I.
CC=gcc
#CC=clang
target=app
src=http://www.mamicode.com/$(wildcard *.c)>
OK 最终版单目录无干扰c文件的通用编译Makefile 就写好了。这个文件可以指定 编译选项,预处理选项,和库文件选项,

可以更换编译器,也可以修改输出文件名,而且都是只需要修改文件最前方的几个变量就可以了。







Makefile使用,Makefile的优化全过程