一、基本概念介绍:

   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. Grassfire算法- 运动规划(Motion planning)

     Grassfire算法: 一.概念 这个算法是做图像处理的抽骨架处理,目的是求出图像的骨架,可以想象一片与物体形状相同的草,沿其外围各点同时点火.当火势向内蔓延,向前推进的火线相遇处各点的轨迹就是中 ...

  2. TSN(Temporal Segment Networks)

    一.算法详解 二.代码解析(pytorch版) 训练代码:https://blog.csdn.net/u014380165/article/details/79058147 测试代码:https:// ...

  3. 08 Windows编程——画图

    源码 #include<Windows.h> #include<tchar.h> #include<stdio.h> #define NUM 1000 LRESUL ...

  4. int类型按字节打印输出

      今天在项目编程中,遇到一个问题,u32类型的参数,要赋值给一个u8 array[3],想用memcpy()函数进行赋值,由于类型大小不一致,一时不知道怎么做,经过查找,得以解决.说明如下;   项 ...

  5. 【转】ufw 端口

    1.扫描端口 用ubuntu自带的网络工具中的端口扫描不够强大,扫描结果可能不全,推荐用nmap,黑客常用的端口扫描利器!安装方法:sudo apt-get install nmap ,想扫描端口nm ...

  6. PAT Advanced 1073 Scientific Notation (20 分)

    Scientific notation is the way that scientists easily handle very large numbers or very small number ...

  7. No PostCSS Config found in报错解决

    前情提要]日前本人将本地项目上传GitHub之后,然后再clone到本地,运行是报错:Error: No PostCSS Config found in... 项目在本地打包运行的时候不报错,上传到 ...

  8. 0009SpringBoot静态资源访问路径

    访问静态资源: 静态资源需要放在哪些路径下才能被访问呢: 通过WebMvcAutoConfiguration.java中 addResourceHandlers()方法查找绑定的路径,一个是通过web ...

  9. Nginx防盗链模块ngx_http_referer_module

    ngx_http_referer_module⽤用来阻⽌止Referer⾸首部⽆无有效值的请求访问,可防⽌止盗链指令:12.1 valid_referers定义 referer ⾸首部的合法可⽤用值, ...

  10. JS 日期格式化,留作参考

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...