一、基本概念介绍:

   Makefile 文件就是告诉make命令需要怎么样的去编译和链接程序。
  编写Makefile的基本规则:
  1.如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。
  2.如果这个工程的某几个C文件被修改,那么我们只编译被修改的C文件,并链接目标程序。
  3.如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C文件,并链接目标程序。

  $@--目标文件,$^--所有的依赖文件,$<--第一个依赖文件。

1 直观方式

 举个例子:一个工程有3个头文件,和8个C文件,根据规则编写Makefile如下:

edit : main.o kbd.o command.o display.o insert.o search.o files.o utils.o
       cc -o edit main.o kbd.o command.o display.o insert.o search.o files.o utils.o main.o : main.c defs.h
       cc -c main.c kbd.o : kbd.c defs.h command.h
       cc -c kbd.c command.o : command.c defs.h command.h
       cc -c command.c display.o : display.c defs.h buffer.h
       cc -c display.c insert.o : insert.c defs.h buffer.h
       cc -c insert.c search.o : search.c defs.h buffer.h
       cc -c search.c files.o : files.c defs.h buffer.h command.h
       cc -c files.c utils.o : utils.c defs.h
       cc -c utils.c
clean :
       rm edit main.o kbd.o command.o display.o insert.o search.o files.o utils.o

  在这个makefile中,目标文件(target)包含:可执行文件 edit 和 中间目标文件(*.o),依赖文件(prerequisites)就是冒号后面的那些 .c 文件和 .h文件。每一个 .o 文件都有一组依赖文件,而这些 .o 文件又是执行文件 edit 的依赖文件。

  输入make指令后的执行内容如下:

  1. make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
  2. 如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“edit”这个文件,并把这个文件作为最终的目标文件。
  3. 如果edit文件不存在,或是edit所依赖的后面的 .o 文件的文件修改时间要比edit这个文件新,那么,他就会执行后面所定义的命令来生成edit这个文件。
  4. 如果edit所依赖的.o文件也存在,那么make会在当前文件中找目标为.o文件的依赖性,如果找到则再根据那一个规则生成.o文件。(这有点像一个堆栈的过程)
  5. 当然,C文件和H文件肯定存在,于是make会生成 .o 文件,然后再用 .o 文件声明make的终极任务,也就是执行文件edit了。

1.1 进阶1:使用变量 

 在上面的例子中,可以看到[.o]文件的字符串被重复了两次,如果工程需要加入一个新的[.o]文件,需要在各个依赖了该[.o]文件的地方添加,如果工程比较复杂会很麻烦,所以为了makefile的易维护,在makefile中可以使用变量。
 比如,声明一个变量叫objects,也就叫 OBJECTS, objs, OBJS, obj, 或是 OBJ,只要能够表示obj文件就行。在makefile一开始就这样定义:

objects = main.o kbd.o command.o display.o insert.o search.o files.o utils.o

 于是,在makefile中以“$(objects)”的方式来使用这个变量了。
 进阶版本1:

objects = main.o kbd.o command.o display.o insert.osearch.o files.o utils.o 
edit : $(objects)
cc -o edit $(objects)
main.o : main.c defs.h
cc -c main.c
kbd.o : kbd.c defs.h command.h
cc -c kbd.c
command.o : command.c defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
insert.o : insert.c defs.h buffer.h
cc -c insert.c
search.o : search.c defs.h buffer.h
cc -c search.c
files.o : files.c defs.h buffer.h command.h
cc -c files.c
utils.o : utils.c defs.h
cc -c utils.c
clean :
rm edit $(objects)

 于是如果有新的 .o 文件加入,只需添加到 objects 变量中即可。

1.2 进阶2:让make自动推导

 GNU的make很强大,它可以自动推导文件以及文件依赖关系后面的命令,于是我们就没必要去在每一个[.o]文件后都写上类似的命令,只要make看到一个[.o]文件,它就会自动的把[.c]文件加在依赖关系中,并且 cc -c xx.c 也会被推导出来。
 进阶版本2:

objects = main.o kbd.o command.o display.o insert.o search.o files.o utils.o

edit : $(objects)
cc -o edit $(objects) main.o : defs.h
kbd.o : defs.h command.h
command.o : defs.h command.h
display.o : defs.h buffer.h
insert.o : defs.h buffer.h
search.o : defs.h buffer.h
files.o : defs.h buffer.h command.h
utils.o : defs.h .PHONY : clean
clean :
rm edit $(objects)

 这种方法,也就是make的“隐晦规则”。上面文件内容中,“.PHONY”表示,clean是个伪目标文件。

即然make可以自动推导命令,那堆[.o]和[.h]的依赖同样可以收拢起来。进阶2.1:

objects = main.o kbd.o command.o display.o insert.o search.o files.o utils.o

edit : $(objects)
cc -o edit $(objects) $(objects) : defs.h
kbd.o command.o files.o : command.h
display.o insert.o search.o files.o : buffer.h .PHONY : clean
clean :
rm edit $(objects)

  上面2.1的版本使makefile变得更简单,但文件依赖关系就显得有点凌乱,鱼和熊掌不可兼得,各取所好。

清空目标文件的规则

 每个Makefile中都应该写一个清空目标文件(.o和执行文件)的规则,这不仅便于重编译,也很利于保持文件的清洁。一般的风格都是:

clean:
  rm edit $(objects)

 更为稳健的做法是:

.PHONY : clean
clean :
-rm edit $(objects)

 前面说过,.PHONY意思表示clean是一个“伪目标”,不声明伪目标的话,如果当前目录有个名为clean的文件,就会认为目标已存在,导致后面规则不执行了。而在rm命令前面加了一个小减号的意思就是,也许某些文件出现问题,但不要管,继续做后面的事。

二、模板:

1、编译动态库

    #############################################################
# Makefile for shared library.
# 编译动态链接库
#############################################################
#set your own environment option
CC = g++
CC_FLAG = -D_NOMNG -D_FILELINE #set your inc and lib
INC =
LIB = -lpthread -L./ -lsvrtool #make target lib and relevant obj
PRG = libsvrtool.so
OBJ = Log.o #all target
all:$(PRG) $(PRG):$(OBJ)
$(CC) -shared -o $@ $(OBJ) $(LIB) .SUFFIXES: .c .o .cpp
.cpp.o:
$(CC) $(CC_FLAG) $(INC) -c $*.cpp -o $*.o .PRONY:clean
clean:
@echo "Removing linked and compiled files......;
rm -f $(OBJ) $(PRG)

2、编译静态库

    #############################################################
# Makefile for static library.
# 编译静态链接库
#############################################################
#set your own environment option
CC = g++
CC_FLAG = -D_NOMNG -D_FILELINE #static library use 'ar' command
AR = ar #set your inc and lib
INC =
LIB = -lpthread -L./ -lsvrtool #make target lib and relevant obj
PRG = libsvrtool.a
OBJ = Log.o #all target
all:$(PRG)
$(PRG):$(OBJ)
${AR} rv ${PRG} $? .SUFFIXES: .c .o .cpp
.cpp.o:
$(CC) $(CC_FLAG) $(INC) -c $*.cpp -o $*.o .PRONY:clean
clean:
@echo "Removing linked and compiled files......"
rm -f $(OBJ) $(PRG)

3、可执行程序

    ###########################################
#Makefile for simple programs
###########################################
INC=
LIB= -lpthread CC=CC
CC_FLAG=-Wall PRG=threadpooltest
OBJ=CThreadManage.o CThreadPool.o CThread.o CWorkerThread.o threadpooltest.o $(PRG):$(OBJ)
$(CC) $(INC) $(LIB) -o $@ $(OBJ) .SUFFIXES: .c .o .cpp
.cpp.o:
$(CC) $(CC_FLAG) $(INC) -c $*.cpp -o $*.o .PRONY:clean
clean:
@echo "Removing linked and compiled files......"
rm -f $(OBJ) $(PRG)

Linux学习:Makefile简介及模板的更多相关文章

  1. Linux学习笔记-Linux系统简介

    Linux学习笔记-Linux系统简介 UNIX与Linux发展史 UNIX是父亲,Linux是儿子. UNIX发行版本 操作系统 公司 硬件平台 AIX IBM PowerPC HP-UX HP P ...

  2. Linux学习笔记之 Btrfs文件系统简介及使用

    Btrfs 也有一个重要的缺点,当 BTree 中某个节点出现错误时,文件系统将失去该节点之下的所有的文件信息.而 ext2/3 却避免了这种被称为”错误扩散”的问题. Btrfs相关介绍: Btrf ...

  3. Linux C++ 开发简介

    主要介绍将Windows程序迁移到Linux系统相关知识 简介 Windows程序迁移到Linux系统可能需要修改很多代码, 既需要了解Linux平台的开发知识, 也需要了解Windows平台代码如何 ...

  4. Linux C++ 开发简介(包括Linux守护线程)

    阅读目录 简介 操作系统 编辑器 编译器 构建系统 调试 IDE 可执行程序.动态库.静态库 服务 Windows服务简介 创建Windows服务 注册Windows服务 管理Windows服务 Li ...

  5. 实验楼 linux 学习

    实验楼 linux 学习     一.Linux 用户管理 1.查看用户 who am i // who mom likes whoami   ====--------====== 输入的第一列表示打 ...

  6. [转] Linux学习之CentOS(十三)--CentOS6.4下Mysql数据库的安装与配置

    from:  http://www.cnblogs.com/xiaoluo501395377/archive/2013/04/07/3003278.html 如果要在Linux上做j2ee开发,首先得 ...

  7. Linux学习之CentOS--CentOS6.4下Mysql数据库的安装与配置【转】

      如果要在Linux上做j2ee开发,首先得搭建好j2ee的开发环境,包括了jdk.tomcat.eclipse的安装(这个在之前的一篇随笔中已经有详细讲解了Linux学习之CentOS(七)--C ...

  8. Makefile简介

    1.源程序的编译在Linux下面,如果要编译一个C语言源程序,我们要使用GNU的gcc编译器. 下面我们以一个实例来说明如何使用gcc编译器.假设我们有下面一个非常简单的源程序(hello.c):in ...

  9. Linux学习之CentOS(十三)--CentOS6.4下Mysql数据库的安装与配置

    原文:http://www.cnblogs.com/xiaoluo501395377/archive/2013/04/07/3003278.html 如果要在Linux上做j2ee开发,首先得搭建好j ...

随机推荐

  1. Oracle insert /*+ APPEND */原理解析

    https://blog.csdn.net/xiaobluesky/article/details/50494101 关于insert /*+ append */我们需要注意以下三点: a.非归档模式 ...

  2. linux环境下composer的安装与使用

    一.下载 Composer(安装前请务必确保已经正确安装了 PHP.打开命令行窗口并执行 php -v 查看是否正确输出版本号.) 1.下载安装脚本 - composer-setup.php - 到当 ...

  3. python2,3区别

      Python2 Python3 default charset ascii(can change) utf-8 print 可不加括号 必须加 range 有xrange()生成器 可转换为ran ...

  4. Subordinates(贪心)

    题目大意: 一共有N个员工,其中最高领导人是编号s的人,每个人都只有一个直接领导,每个人都说出了自己领导的个数,问最少有几个人撒谎了. 思路: 合理的贪心是该把排最后的数变成缺少的数字,然后继续判断. ...

  5. 0003SpringBoot整合SpringDataJPA

    SpringBoot整合SpringDataJpa步骤如下: 1.添加data-jpa起步依赖(pom.xml) 2.添加数据库驱动坐标.添加Junit起步依赖(pom.xml) 3.添加数据库连接信 ...

  6. [ 转载 ] Java基础

    1.String a = “123”; String b = “123”; a==b的结果是什么? 这包含了内存,String存储方式等诸多知识点.ans:同样序列的字符串直接量为一个实例,所以其实引 ...

  7. 5 webpack-dev-server的常用命令参数--open --port 3000 --contentBase src --hot

    --open 自动打开浏览器 --port 3000 指定端口3000 --contentBase src 内容的根路径 --hot 热重载,热更新.打补丁,实现浏览器的无刷新

  8. js重写页面之后后台如何获取重写后的控件值

    需求描述:专业分流系统中,学生在选择志愿时,我想实现在页面按照点击相应专业的顺序来设置选专业的志愿,如首先点击“工商”,则工商专业为第一志愿,接着点击“营销”,则营销专业为第二志愿,以此类推.从而达到 ...

  9. 谈CSRF与JSONP设置header问题

    关于前端发起请求 问题一 JS发起请求的方式 方法一 JS代码中发起请求的方式普遍为AJAX 该技术在 1998 年前后得到了应用.允许客户端脚本发送HTTP请求(XMLHTTP) 方法二 scrip ...

  10. 二进制文件方式安装kubernetes集群

    所有操作全部用root使用者进行,高可用一般建议大于等于3台的奇数,我们使用3台master来做高可用 练习环境说明: 参考GitHub master: kube-apiserver,kube-con ...