makefile

1.hello.c

#include <stdio.h>
int main()
{
    printf("Hello World!\n");
    return 0;
}

2.Makefile

hello : hello.o
    cc -o hello hello.o

hello.o : hello.c
    cc -c hello.c

clean : 
    rm hello.o

说明:cc -o hello hello.o前面是一个tab的空格

3.执行make,产生可执行文件hello

输出如下:
cc -c hello.c
cc -o hello hello.o

4.执行make clean,删除产生的中间文件hello.o

输出如下:
rm hello.o


另转:http://hi.baidu.com/s_rlzheng/blog/item/4bc10a06892e217d030881ef.html

  本来早就应该学Makefile了,只是我偷懒,现在才学呵呵^_^makefile的好处叫我说,老实说我也说不出什么之所以然来,但是可以肯定的是它是linux平台的软件工程师都要必备的知识^_^

一、程序的编译及链接

    我们编译程序,无非是想要得到一个可执行文件,而这个过程则是经过这两步:

***.c->编译->***.o->链接->可执行文件。即.c经过编译得到.o文件,.o文件是一个中间文件,再对这些中间文件进行链接最终可得到可执行文件。

二、Makefile的规则

首先,来看一看Makefile的书写规则:

target ... : prerequisites ...

            command

            ...

            ...

    target也就是一个目标文件,可以是.o文件,也可以是执行文件,还可以是一个标签(Label)。

    prerequisites就是,要生成那个target所需要的文件或是目标。

    command也就是make需要执行的命令(任意的Shell命令)。这里要注意的是在命令前面要加上一个tab键,不是空格,是按一个tab键按出来的空格。

     这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。说白一点就是说,prerequisites中如果有一个以上的文件比 target文件要新的话,command所定义的命令就会被执行。这就是Makefile的规则,也就是Makefile中最核心的内容。这是Makefile的主线和核心,但要写好一个Makefile还得继续努力。

三、一个最简单的Makefile例子

如有一个工程,含有3个头文件及四个c文件,那为了生成所需的可执行文件,这时的Makefile可以这样写:

test:main.o t1.o t2.o t3.o

     gcc –o test main.o t1.o t2.o t3.o

main.o:main.c

     gcc –c main.c

t1.o:t1.c t1.h

     gcc –c t1.c

t2.o:t2.c t2.h

     gcc –c t2.c

t3.o:t3.c t3.h

     gcc –c t3.c

clean:

     rm test main.o t1.o t2.o t3.o

到这里一个最简单的makefile就写好了,把它的名字保存为Makefile就可以了,这时你只要在终端敲一下make,它就自动帮你编译链接了^_^如果敲入make clean,它将删掉那些中间文件及可执行文件。

***************************************************************************

工程中的代码分别存放在add/add_int.c、add/add_float.c、add/add.h、sub/sub_int.c、sub/sub_float.c、sub/sub.h、main.c中。

Makefile的一个具体的实例

 

文件main.c

#include <stdio.h>

#include "add.h"            

#include "sub.h"

intmain(void)

{

      int input = 0;

      int a = 10, b = 12;

      float x= 1.23456,y = 9.87654321;

      

      printf("int a+b IS:%d\n",a+b);

      printf("int a-b IS:%d\n",a-b);

      printf("float x+y IS:%f\n",x+y);

      printf("float x-y IS:%f\n",x-y);

 

 

      return 0;      

}

加操作 

#ifdef __ADD_H__

#define __ADD_H__

extern int add_int(int a, int b);

extern float add_float(float a, float b);

#endif  

float add_float(float a, float b)

{

      return a+b;  

}  

intadd_int(int a, int b)

{

      return a+b;  

}

减操作

#ifdef __ADD_H__

#define __ADD_H__

extern float sub_float(float a, float b);

extern int sub_int(int a, int b);

#endif 

float sub_float(float a, float b)

{

      return a-b;   

intsub_int(int a, int b)

{

      return a-b;   

}

命令行编译程序:

#gcc-c add/add_int.c -o add/add_int.o     #生成add_int.o目标函数

#gcc-c add/add_float.c -o add/add_float.o  #生成add_float.o目标函数

#gcc-c sub/sub_int.c -o sub/sub_int.o      #生成sub_int.o目标函数

#gcc-c sub/sub_float.c -o sub/sub_float.o    #生成sub_float.o目标函数

#gcc-c main.c -o main.o                 #生成main.o目标函数

#gcc-o casu add/add_int.o add/add_float.o sub/sub_int.o sub/sub_float.omain.o

#链接生成cacu

多文件的makefile:

#生成casu,“;”右边为目标

casu:add_int.o add_float.o sub_int.o sub_float.omain.o

      gcc -o casu add/add_int.o add/add_float.o \          #\为连接符

                    sub/sub_int.o sub/sub_float.o main.o    

#生成add_int.o的规则,将add_int.c编译生成目标文件add_int.o

add_int.o:add/add_int.c add/add.h

      gcc -c -o add/add_int.o add/add_int.c

#生成add_float.o的规则

add_float.o:add/add_float.c add/add.h

      gcc -c -o add/add_float.o add/add_float.c

#生成sub_int.o的规则

sub_int.o:sub/sub_int.c sub/sub.h

      gcc -c -o sub/sub_int.o sub/sub_int.c

#生成sub_float.o的规则

sub_float.o:sub/sub_float.c sub/sub.h

      gcc -c -o sub/sub_float.o sub/sub_float.c

#生成main.o的规则

main.o:main.c add/add.h sub/sub.h

      gcc -c -o main.o main.c -Iadd -Isub

      

#清理规则

clean:

      rm -f casu add/add_int.o add/add_float.o \

           sub/sub_int.o sub/sub_float.o main.o

使用自定义变量的makefile文件:

CC = gcc                                #CC定义成gcc

CFLAGES =   -Iadd -Isub -O2   #加入头文件搜索路径subaddO2为优化#目标文件

OBJS = add/add_int.o add/add_float.o \

             sub/sub_int.o sub/sub_float.o main.o

TARGET = casu                          #生成的可执行文件

RM = rm -f                              #删除的命令

$(TARGET):$(OBJS)                      #TARGET目标,需要先生成OBJS目标

      $(CC) -o $(TARGET) $(OBJS) $(CFLAGES)   #生成可执行文件

$(OBJS):%.o:%.c         #OBJS中所有扩展名为.o的文件替换成扩展名为.c的文件

      $(CC) -c $(CFLAGES) $< -o $@       #采用CFLAGS指定的选项编译生成目标文件

clean:                              #清理

      -$(RM) $(TARGET) $(OBJS)          #删除所有的目标文件和可执行文件

使用预定义变量的makefile文件:

CFLAGES =   -Iadd -Isub -O2              #编译选项

OBJS= add/add_int.o add/add_float.o \

               sub/sub_int.osub/sub_float.o main.o

TARGET = casu                         #生成的可执行文件

$(TARGET):$(OBJS)                      #TARGET目标,需要先生成OBJS目标

      $(CC) -o $(TARGET) $(OBJS)$(CFLAGES)  #生成可执行文件

$(OBJS):%.o:%.c         #OBJS中所有扩展名为.o的文件替换成扩展名为.c的文件

      $(CC) -c $(CFLAGES)$< -o $@       #采用CFLAGS指定的选项编译生成目标文件

clean:                              #清理

      -$(RM) $(TARGET)$(OBJS)          #删除所有的目标文件和可执行文件

使用自动变量的makefile文件:

CFLAGES =   -Iadd -Isub -O2              #编译选项

OBJS= add/add_int.o add/add_float.o \

               sub/sub_int.osub/sub_float.o main.o

TARGET = casu                          #生成的可执行文件

$(TARGET):$(OBJS)                      #TARGET目标,需要先生成OBJS目标

      $(CC) -o  $@  $^$(CFLAGES)         #生成可执行文件

$(OBJS):%.o:%.c         #OBJS中所有扩展名为.o的文件替换成扩展名为.c的文件

      $(CC) -c $<  $(CFLAGES) -o$@     #采用CFLAGS指定的选项编译生成目标文件

clean:                              #清理

      -$(RM) $(TARGET) $(OBJS)          #删除所有的目标文件和可执行文件

使用搜索路径的makefile文件:

CFLAGES =   -Iadd -Isub -O2  

OBJSDIR = .objs

VPATH = add:sub:.        

OBJS= add_int.o add_float.o sub_int.o sub_float.o main.o

TARGET = casu                          

$(TARGET):$(OBJSDIR) $(OBJS)     #先检测OBJSDIROBJS依赖项是否存在                

      $(CC) -o $(TARGET) $(OBJSDIR)/*.o $(CFLAGES)

 #OBJSDIR目录中所有的.o文件链接成casu          

$(OBJS):%.o:%.c         

      $(CC) -c $< $(CFLAGES) -o $(OBJSDIR)/$@ #生成目标文件,存放在OBJSDIR目录中

$(OBJSDIR):

      mkdir -p ./$@           #建立目录,-p选项可以忽略父目录不存在的错误

clean:                                

      -$(RM) $(TARGET)       #删除casu

      -$(RM) $(OBJSDIR)/*.o   #删除OBJSDIR目录下的所有.o文件

使用自动推导规则的makefile:

CFLAGS = -Iadd -Isub -O2        # 用户自定义变量

VPATH=add:sub               #搜索路径

OBJS= add_int.o add_float.o sub_int.o sub_float.o main.o

TARGET = cacu

$(TARGET):$(OBJS)            #OBJS依赖项的规则自动生成

      $(CC) -o $(TARGET) $(OBJS) $(CFLAGS)   #链接文件

clean:

      -$(RM) $(TARGET)        #-”表示当前操作失败时不报错,命令继续执行

      -$(RM) $(OBJS)

使用函数的makefile文件:

CC =gcc                              #CC定义成gcc

VPATH =add:sub

CFLAGES =   -Iadd -Isub -O2    #加入头文件搜索路径subaddO2为优化#目标文件

TARGET = casu                        #生成的可执行文件

DIRS= sub add .                    #DIRS字符串的值为目录addsub和当前目录

FILES = $(foreach dir, $(DIRS),$(wildcard$(dir)/*.c))  #查找所用目录下的.c文件

OBJS = $(patsubst %.c,%.o,$(FILES))          #.c替换成.o

$(TARGET):$(OBJS)                       #TARGET目标,需要先生成OBJS目标

      $(CC) -o $(TARGET) $(OBJS) $(CFLAGES)  #生成可执行文件

clean:                                 #清理

      -$(RM) $(TARGET) $(OBJS)             #删除所有的目标文件和可执行文件



阅读更多
个人分类: Linux
想对作者说点什么? 我来说一句

跟我一起写 Makefile.htm

2010年08月17日 1.02MB 下载

Make和makefile

2011年08月29日 71KB 下载

Makefile进阶 Makefile进阶

2011年05月06日 224KB 下载

makefile教程makefile教程

2010年08月23日 2.44MB 下载

makefile相关资料

2011年06月08日 328KB 下载

Makefile概述 Makefile概述

2009年04月10日 16KB 下载

makefile 教程 教学

2010年08月16日 199KB 下载

Makefile 跟我一起写Makefile

2018年03月17日 293KB 下载

没有更多推荐了,返回首页

不良信息举报

makefile

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭