现在的位置: 首页 > 综合 > 正文

makefile文件的两种常用书写格式(搜索路径式+递归式)

2013年06月21日 ⁄ 综合 ⁄ 共 2466字 ⁄ 字号 评论关闭

  首先,写一个测试代码,很简单的加减程序:

//path: cacu/main.c

//path: cacu/main.c
#include <stdio.h>
#include "add.h"
#include "sub.h"

int main()
{
    int a=10,b=12;
    float x=1.23456,y=9.87654;

    printf("int a+b IS:%d\n",add_int(a,b));
    printf("int a-b IS:%d\n",sub_int(a,b));
    printf("float x+y IS:%f\n",add_float(x,y));
    printf("float x-y IS:%f\n",sub_float(x,y));
    return 0;
}
//path: cacu/sub/sub.h

//path: cacu/sub/sub.h
#ifndef SUB_H
#define SUB_H
extern float sub_float(float a, float b);
extern int sub_int(int a, int b);
#endif
//path: cacu/sub/sub_float.c

float sub_float(float a, float b)
{
    return a-b;
}
//path: cacu/sub/sub_int.c

//path: cacu/sub/sub_int.c
int sub_int(int a, int b)
{
    return a-b;
}
//path: cacu/add/add.h

//path: cacu/add/add.h
#ifndef ADD_H
#define ADD_H
extern int add_int(int a, int b);
extern float add_float(float a, float b);
#endif
//path: cacu/add/add_float.c

//path: cacu/add/add_float.c
float add_float(float a, float b)
{
    return a+b;
}
//path: cacu/add/add_int.c

//path: cacu/add/add_int.c
int add_int(int a, int b)
{
    return a+b;
}

  接下来看看怎么写makefile文件。

第一种:搜索路径式

  该方法使用了VPATH变量,VPATH的格式如下:

    VPATH=path1:path2:...

  VPATH等号右边的路径名以冒号(:)分割,如

VPATH = add:sub:.

  使用该方法实现前面给出的例子的makefile文件如下:

CFLAGS = -Iadd -Isub -O2
OBJSDIR = .objs
VPATH = add:sub:.
OBJS = add_int.o add_float.o sub_int.o sub_float.o main.o
TARGET = cacu
$(OBJSDIR): mkdir -p ./$@ $(TARGET):$(OBJSDIR) $(OBJS) $(CC) -o $(TARGET) $(OBJSDIR)/*.o $(CFLAGS) $(OBJS):%.o:%.c $(CC) -c $(CFLAGS) $< -o $(OBJSDIR)/$@ clean: -$(RM) $(TARGET) -$(RM) $(OBJSDIR)/*.o

  makdir命令的那一行是建立一个.bojs文件。

  $(OBJS):%.o:%.c
      $(CC) -c $(CFLAGS) $< -o $(OBJSDIR)/$@

  这里也使用了搜索路径。

  其他的$<,$@等介绍请参考:http://baike.baidu.com/view/974566.htm,百度文库把基本用法已经写的很清楚了。

 

第二种:递归式

  为了实现每个目录下的代码具有独立的makefile,且根目录下的makefile可以一次执行子目录下的makefile,就有了递归式的方法来写父目录下的makefile了,该方法的实现是使用的$(MAKE)变量,使用格式如下:

add:
       cd add &&  $(MAKE)

  也可以这样写:

add:
           $(MAKE)  -C add

  这样就可以递归调用子目录add下面make命令来执行add目录下的makefile文件,我们先把add和sub两个子目录下的makefile文件写好来,如下:

OBJS = add_int.o add_float.o
CFLAGS = -O2
all:$(OBJS)
$(OBJS):%.o:%.c
    $(CC) -c $< -o $(OBJSDIR)/$@ $(CFLAGS)
clean:
    $(RM) $(OBJS)
OBJS = sub_int.o sub_float.o
CFLAGS=-O2
all:$(OBJS)
$(OBJS):%.o:%.c
    $(CC) -c $< -o $(OBJSDIR)/$@ $(CFLAGS)
clean:
    $(RM) $(OBJS)

  接下来就是写主目录cacu下面的makefile文件了,使用前面递归调用格式,makefile文件如下:

CC = gcc
CFLAGS = -O2
TARGET = cacu
export OBJSDIR = ${shell pwd}/.objs
$(TARGET):$(OBJSDIR) main.o
    $(MAKE) -C add
    $(MAKE) -C sub
    $(CC) -o $(TARGET) $(OBJSDIR)/*.o
main.o:%.o:%.c
    $(CC) -c $< -o $(OBJSDIR)/$@ $(CFLAGS) -Iadd -Isub
$(OBJSDIR):
    mkdir -p $(OBJSDIR)
clean:
    -$(RM) $(TARGET)
    -$(RM) $(OBJSDIR)/*.o
    
  “$(MAKE) -C add” “$(MAKE) -C sub”这两句实现的就是在执行下面的命令前先执行子目录下的makefile文件。


测试结果:
  搜索路径式的测试结果:

递归式的测试结果:

  这个不算我原创的,借用了书上的,算是学习笔记吧。参考书《Linux网络编程》-宋敬彬,孙海滨。

我就菜鸟一个,欢迎拍砖

抱歉!评论已关闭.