怎样写Makefile文件

Makefile 总结
                                        --- 2014.9.17 (miaoguoxiang)

第一部份:makefile应用场合分类及对应目录名称
    1: 基本应用                          basic_make
    2: 自动推导依赖关系应用               auto_make
    3: 变量、函数与通配符的使用应用       variable_make
    4: 文件查找应用                      find_for_make
    5: dos下源文件转UNIX下的混合编程应用  dos_unix_make
    6: 引用其他Makefile应用              refer_make
    7: 静态编译应用                      static_make
    8: 嵌套makefile文件应用              multiple_make

第二部份:基本测试环境
    源文件:main.c  2.c  3.c  
    头文件:a.h  b.h  c.h

    依赖关系:
    /*main.c*/
    #include "a.h"
    /*2.c*/
    #include "a.h"
    #include "b.h"
    /*3.c*/
    #include "b.h"
    #include "c.h"
    
    可执行文件约定名词:myapp

    makefile 中的依赖关系表示为
        myapp:main.o 2.o 3.o
        main.o:main.c a.h
        2.o:2.c a.h b.h
        3.o:3.c b.h c.h
    
第三部份:分组讲解
1: basic_make
说明:处理多文件编译的基本技术,makefile主要分四个基本部份:
    1)定义变量部份:CC=gcc/*指定编译器*/ INSTDIR=/*指定安装位置*/ INCLUDE=/*指定保护三文件位置*/ CFLAGS=/*指定编辑器参数*/
    2)依赖关系部份:基本的依赖关系并引导以tab开头的命令选项
    3)清除中间文件命令部份:clean: 后接shell引导命令
    4)安装位置命令:install:myapp 后接shell安装位置设置命令
主文件如下:
----------------------------------------------------------
    all:myapp    /*指定多个目标需用all,否则,make命令将只创建它在makefile中找到的第一个目标*/
    CC = gcc
    INSTDIR = ~/practice_makefile/basic_make/install_1
    INCLUDE = .
    CFLAGS = -g -Wall -ansi
    
    myapp: main.o 2.o 3.o
        $(CC) -o myapp main.o 2.o 3.o
    main.o: main.c a.h
        $(CC) -I$(INCLUDE) $(CFLAGS) -c main.c
    2.o: 2.c a.h b.h
        $(CC) -I$(INCLUDE) $(CFLAGS) -c 2.c
    3.o: 3.c b.h c.h
        $(CC) -I$(INCLUDE) $(CFLAGS) -c 3.c
    
    clean:
        -rm main.o 2.o 3.o
    install: myapp
        @if [ -d $(INSTDIR) ]; \
            then \
            cp myapp $(INSTDIR);\
            chmod a+x $(INSTDIR)/myapp;\
            chmod og-w $(INSTDIR)/myapp;\
            echo "Installed in $(INSTDIR)";\
        else \
            echo "Sorry, $(INSTDIR) does not exist";\
        fi
---------------------------------------------------------
2: auto_make
说明:这部份的主要作用是简化makefile的编写工作,主要应用于make能够自动推导依赖关系,如将第一部份的makefile文件去除第二部份,改为如下:
-----------------------------------
    myapp: main.o 2.o 3.o
        $(CC) -o myapp main.o 2.o 3.o
    main.o: main.c a.h
    2.o: 2.c a.h b.h
    3.o: 3.c b.h c.h
-----------------------------------
make可以自动的推导出依赖关系,并进行编译
同时,还可以应用单独的make命令进行GCC的编译,如下面的输入文件foo.C文件:
----------------------------------------------------------------
#include <stdio.h>
int main()
{
    printf("This is test only \"make\" to compile.\n");
}
----------------------------------------------------------------
执行命令:$make foo

3: variable_make
说明:这部份主要的作用是简化Makefile文件的编写工作,主要包含宏、通配符、变量、函数四部份
    1)常用的宏如下:
        $? 当前目标所依赖的文件列表中比当前目标文件还要新的文件
        $@ 当前目标的名字
        $< 当前依赖文件的名字
        $* 不包括后缀名的当前依赖文件的名字
        $^ 所有依赖文件的名字
        @ 不要将Make里面的命令回显到标准输出上
    2)常用的通配符如下:
        % 匹配任意个数字符
        * ? ... 与shell一样
        ~ 与shell,当前用户的家目录
        
    3)定义变量的方法与常用的变量:
        定义变量:CFLAGS = -g -Wall -ansi
        /* = 、?=、define 为延时变量
           := 为立即变量*/
        取变量值:$(CFLAGS)
    4)函数的调用格式与常用的函数:
        格式:$(function_name argument)
        常用函数如下:
        字符串函数:subst,patsubst,strip,findstring,filter,filter-out,sort
        文件名函数:dir,notdir,suffix,basename,addsuffix,addprefix
        其他函数:foreach,ifcondition
    这部份对比basic_make文件中的更改为:
----------------------------
    src = $(shell ls *.c)  /*用shell命令选取所有C源文件*/
    objs = $(patsubst %.c, %.o, $(src)) /*将src选取的源文件的后缀名由.c改为.o*/
    
    myapp: $(objs)   
        $(CC) -o $@  $^
---------------------------

4: find_for_make
说明:这个的应用比较具有实用价值,工程中将.c文件与.h文件分别放在两个目录中。make将会自动去往两个子目录进行文件查找,需要应用的到的两个变量(或关系)名如下:
    1)VPATH = src:../headers
    2)vpath %.h ../headers
    /*需要注意依赖命令编译时要将*.c改为$<*/
本测试程序的目录结构如下:
    find_for_make
      |-main.c
      |-Makefile
      |-directory_c
         |-2.c
         |-2.c
      |-directory_h
         |-a.h
         |-b.h
         |-c.h
本测试程序的makefile主内容如下:
------------------------------------
    vpath %.c ./directory_c
    vpath %.h ./directory_h
------------------------------------

5: dos下源文件转UNIX值下的混合编程应用dos_unix_make
说明:dos下的C或者C++源文件常常不是以.c结尾的。可能会是以.cpp结尾的。其实dos下的源文件可以直接拿到unix下与unix源文件进行一起编译。
    格式如下:
    .cpp.o:        或者    %.cpp: %o    /*意思是遇到所有.cpp文件均将其转为.o的文件*/
本测试程序的2.cpp和3.cpp是从windows7中转过来的。如下是makefile主要内容:
--------------------------------------------------------
    myapp: main.o 2.o 3.o
        $(CC) -o myapp main.o 2.o 3.o
    main.o: main.c a.h
        $(CC) -xc++ -I$(INCLUDE) $(CFLAGS) -c main.c
    2.o: 2.cpp a.h b.h
    %.cpp: %o
        $(CC) -xc++ -I$(INCLUDE) $(CFLAGS) -c $<
    3.o: 3.cpp b.h c.h
    %.cpp: %o
        $(CC) -xc++ -I$(INCLUDE) $(CFLAGS) -c $<
--------------------------------------------------------

6: refer_make
说明:这个部份主要应用于借助已有的makefile文件,来为当前要创建的makefile文件来省掉一些工作。有点类似于C或C++里面的包含文件。格式如下:
    include filename
本测试部份将makefile分为两个文件,Makefile和Makefile_refer,将Makefile_refer作为被引用的文件。在Makefile中的引用语句如下:
    include ./Makefile_refer

7: static_make
说明:适用于有很多的.o和.c文件的大编译项目,总的思想是用通配符与宏运用静态编译的规则将.c文件转为.o文件。规则如下:
    <targets...>:<target-pattern>:<prereq-patterns...>
        <commands>
    ...
本测试部份主要部份如下:
---------------------------------------------------
    #This is static compiler test
    objects = 2.o 3.o
    
    myapp: main.o 2.o 3.o
        $(CC) -o myapp main.o 2.o 3.o
    main.o: main.c a.h
        $(CC) -I$(INCLUDE) $(CFLAGS) -c main.c
    $(objects):%.o:%.c
        $(CC)  -c $(CFLAGS) -I$(INCLUDE) $< -o $@
---------------------------------------------------
8: multiple_make
说明:个人认为嵌套的makefile文件是最有用的。当安装文件时什么“正在进入的目录...”,“正在离开目录...”的云云提示,就是嵌套文件的工作反馈。嵌套make文件也可以叫宏控制makefile文件。我们可以把不同模块或者不同功能的源文件放在一个目录中,并为其编写makefile文件,然后在父目录进行makefile的总控。
规则如下:
    subsystem:
        cd subdir && $(MAKE)
本测试部份的目录结构如下:
    multiple_make
      |-Makefile
      |-subdir1
         |-main.c 2.c 3.c a.h b.h c.h Makefile
      |-subdir2
         |-main.c 2.c 3.c a.h b.h c.h Makefile
本测试部份的各子目录的Makefile的内容基本不做变化,总控Makefile内容如下:
-----------------------------------------------------------------------
    DIRS = subdir1 subdir2
    
    all:
        for i in $(DIRS); do \
            (cd $$i && echo "making $$i" && $(MAKE) ) || exit 1; \
        done
    
    clean:
        for i in $(DIRS); do \
            (cd $$i && echo "cleaning $$i" && $(MAKE) clean) || exit 1; \
        done
----------------------------------------------------------------------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值