关闭

makefile

269人阅读 评论(0) 收藏 举报
分类:

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)             #删除所有的目标文件和可执行文件



0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:88720次
    • 积分:1365
    • 等级:
    • 排名:千里之外
    • 原创:4篇
    • 转载:288篇
    • 译文:0篇
    • 评论:6条
    最新评论