Makefile和Make Rules

多模块软件、依赖树和Make

默认规则

Make使用程序对简单变量的支持

内建变量

虚目标

特殊目标

一般性语法错误及其纠正措施

命令行的使用和调试


Makefile中常用规则总结


make常用选项

-d    显示调试信息

-f     指定从哪个文件中读取依赖关系信息。默认文件是“Makefile”或“makefile” ,"-"表示从标准输入

-h    显示所有的Makefile的help信息

-n    打印所有Makefile执行命令,但不执行这些命令

-s    运行时不显示任何信息

注释

#   

连接符

\

关联列表和命令列表中使用shell通配符

?    

*

默认模式规则

%.o:%.c:

  $(CC) $(CFLAGS) -c $<

%.o:%.s:

  $(AS) $(ASFLAGS) -o $@ $<

简单变量

定义:变量名:=文本

添加:变量名+=文本

变量引用

$(变量名)

${变量名}

$单字符变量

C := gcc
$C
CC := gcc
OPTIONS := -O3
OBJECTS :=main.o
OBJECTS := input.o compute.o
SOURCE :=main.c input.c compute.c
HEADERS := main.h input.h compute.h
power: $(OBJECTS)
$(CC) $(OPTIONS) $(OBJECTS) -o power -lm
main.o: main.h input.h compute.h     #包含隐含规则
input.o: input.h
compute.o: compute.h
tar: Makefile $(HEADERS) $(SOURCES)   #伪目标tar用于打包Makefile和源文件头文件
tar -cvf power.tar Makefile $(HEADERS) $(SOURCES)
clean:
rm *.o

内置变量

$@  当前目标的名称

$?   比当前目标更加新的已修改的依赖性列表

$<    比当前目标更新的已修改的当前依赖性名称

$^    用空格分开的所有依赖性列表

@echo "Build complete"
power: $(OBJECTS)
$(CC) $(OPTIONS) -O $@ $^ -lm
@echo "The executable is in the power file."
main.o: main.h input.h compute.h
compute.o: compute.h
input.o: input.h
power.tar: Makefile $(HEADERS) $(SOURCES)
tar -cvf $@ $^
.PHONY:clean
clean:
rm -f *.o power

虚目标 

允许强制执行某些在正常规则中不会发生的事件。

比如:可以通过设置一个虚目标生成多个可执行文件,若不使用虚目标,make就只能建立第一个目标。

.PHONY: rebuild-all
rebuild-all:prog1 prog2 prog3
prog1: prog1.o utils.o
cc -o prog1 prog1.o utils.o
prog2: prog2.o
cc -o $@ $^
prog3: prog3.o sort.o utils.o
cc -o $@ $^

常见虚目标列表

all    生成工程中所有可以执行者,通常是Makefile的第一个生成目标

     $make all  #使目标全部被执行

clean   删除make all生成的所有文件

install    在系统目录中安装工程项目生成的可执行文件和文档

uninstall  删除make install 安装的所有文件

$cat Makefile

INSTALLDIR=/home/embedclub/bin
install: client server
cp -f $^ $(INSTALLDIR)
rm -f *.o $^
cd $(INSTALLDIR); chmod 755 $^
uninstall:
cd $(INSTALLDIR); rm client server
client: client.o miscc.o rcopyc.o
gcc client.o miscc.o rcopyc.o -lnsl -o client \
client.o: client.c netc.h rcopy.h rcopy.h
gcc -c client.c

$make install

$make uninstall

一般性语法错误

1 缺少Tab键,可使用cat -t Makefile查看tab键位置

2 在连接符和换行符之间插入了空格,可使用cat -e Makefile查看换行符位置

 显示Makefile中不正确的行 grep '\\[]$' Makefile

使用非标准的Makefile名称文件

$make -f prog1.makefile

从标准输入读取

$make -f -

显示Makefile中所执行命令的顺序

$make -n

制作工程文件的Makefile

一般的工程文件proc组成:

src:main.c fun1.c fun2.c

include:fun1.h fun2.h

Makefile

$cat Makefile

VPATH = src:include
all:test4 tar
.PHONY:all
test4:main.o fun1.o fun2.o
gcc main.o fun1.o fun2.o -o test4
main.o:main.c
gcc -c -linclude -o $@ $^
fun1.o:
fun2.o:
tar:
tar cvf test4.tar src include Makefile
.PHONY:clean
clean:
rm *.o test4

  

Makefile编写规则详解 


Make命令与Makefile

Makefile文件内容
        显示规则:说明了如何生成一个或多个目标文件(包括要生成的文件/文件的依赖文件/生成的命令)。
        隐式规则
        变量定义:一般是字符串,Makefile被执行时,其中变量都会拓展到相应的引用位。
        文件指示:    1 在一个Makefile文件中引用另一个Makefile文件 (类似include)
                    2 根据某些情况指定makefile文件中的有效部分 (类似预编译#if)
                    3 定义一个多行的命令
        注释:     注释符#(Makefile文件中需要用到#,可以使用\#转义)
    注意:
        makefile文件的文件名可以是其他名称,但要使用-f或--file指定
    
    make工作执行步骤
        1 读入所有makefile文件
        2 读入被include包括的其他makefile文件
        3 初始化文件中的变量
        4 推导隐式规则,并分析所有规则
        5 为所有目标文件创建依赖关系链
        6 根据依赖关系,决定哪些目标要重新生成
        7 执行生成命令

make参数                    例子                        作用
        -f --file            make -f makelinux        指定特定的makefile文件
        -I --include-dir                            在指定目录下寻找makefile文件
        -n --just-print                              只是显示->命令不执行命令
        -s --silent                                 禁止命令的输出显示

makefile关键子                    例子                            作用
        include                     include ../Make.defines        将别的makefile文件包含进来
                                    include foo.make *.mk $(bar)
        -include                                                  不理会无法找到的文件
        wildcard                     objects:= $(wildcard *.o)     让通配符在变量中展开,即让objects的值成为所有.o的文件名的集合
        vpath <pattern> <directory>    vpath %.h ../headers        为符合模式<pattern>的文件指定搜素目录

vpath %.c foo:bar
                                    vpath       blish                这两句一起用的话,表示.c结尾的文件先在foo,然后在bar,最后在blish中寻找
        vpath <patterh>                                            清除符合模式<pattern>的文件的搜索目录
        vpath                                                     清除所有已设置好的文件搜索目录

定义环境变量            例子                        作用
        MAKEFILES                                把此变量的值(其他makefile,多个文件用空格分隔)作为一个类似于include的动作
        VPATH            VPATH = src:../headers  让make根据路径寻找目标依赖文件,多个路径用:隔开
    
    自动变量
        $@     目标集
        $<  所有的依赖目标集

Makefile书写规则(里面的命令其实是shell命令)
        通配符(定义一系列比较类似的文件)
            *            objects=*.o             所有的.o文件的集合
            ?
            []
            ~             ~/test                     表示宿主主目录下test文件
        
        文件搜寻
            VPATH
            vpath 关键字

伪目标
            .PHONY        .PHONY: clean            伪目标可以直接放在make后面像操作文件一样操作
                        make clean

多目标

静态模式
            目标集合            目标集模式             目标集的二次定义
            <targets ...>: <target-pattern>: <prereq-pattern>
                <commands>
                ...
        
        makefile文件的函数
            filter

自动生成依赖关系
            gcc -MM main.c         //查找main.c文件包含的头文件,并生成依赖关系
            .d文件的应用
    使用命令
        显示命令 @ehco (@避免输出命令,只输出命令执行结果)
        
        执行命令
            exec:
                cd /home/hchen; pwd        第二条命令执行建立在第一条命令结果上

#伪目标同样可以存在依赖关系
.PHONY: cleanall cleanobj cleandiff
cleanall: cleanobj cleandiff
rm program
cleanobj:
rm *.o
cleaniff:
rm *.diff
#静态模式
objects=foo.o bar.o
all: $(objects)
$(objects): %.o: %.c
$(gcc) -c $(CFLAGS) $< -o $@ #展开后等价于
foo.o:foo.c
$(gcc) -c $(CFLAGS) foo.c -o foo.o
bar.o: bar.c
$(gcc) -c $(CFLAGS) bar.c -o bar.o

学习积累


源文件:ChessBoard.h ChessBoard.cpp Player.h Player.cpp main.cpp

依赖关系:

ChessBoard.cpp 包含ChessBoard.h

Player.cpp 包含 Player.h

main.cpp 包含ChessBoard.h 和 Player.h

Makefile:

 gomoku: ChessBoard.o Player.o main.o
g++ -o gomoku ChessBoard.o Player.o main.o
#main.o: main.cpp Player.h ChessBoard.h
# g++ -c $^
#ChessBoard.o: ChessBoard.cpp ChessBoard.h
# g++ -c $^
#Player.o: Player.cpp Player.h
# g++ -c $^ #通过下面方法编译器可以自动推导
main.o: Player.h ChessBoard.h
ChessBoard.o: ChessBoard.h
Player.o: Player.h .PHONY: clean allclean
clean:
rm *.o *.gch
allclean:
rm *.o *.gch gomoku

Make和Makefile编写(详见GCC手册)的更多相关文章

  1. Yocto开发笔记之《Makefile编写》(QQ交流群:519230208)

    开了一个交流群,欢迎爱好者和开发者一起交流,转载请注明出处. QQ群:519230208,为避免广告骚扰,申请时请注明 “开发者” 字样 =============================== ...

  2. linux 下C语言编程库文件处理与Makefile编写

    做开发快3年了,在linux下编译安装软件算是家常便饭了.就拿gcc来说,都有不下10次了,可基本每次都会碰到些奇奇怪怪的问题.看来还是像vs.codeblocks这样的ide把人弄蠢了.便下定决心一 ...

  3. 单目录下多文件 makefile编写

    makefile很久就接触过了,但是一直没怎么深入的去学习和总结:在项目中我也只是看看makefile或者修改部分语句,全部自己动手写的话还真没有:知识在于沉淀,这句说的非常好,所以现在把自己理解的东 ...

  4. 多目录下多文件 makefile编写

    前面已经分享了单目录项下多文件的makefile的编写,现在来看看多目录下多文件makefile的编写: 在做项目时,一般文件都会分几个目录来存放:基本的是  include/  bin/ src/ ...

  5. linux --> Makefile编写

    Makefile编写 单目录 测试程序在同一个文件中,共有func.h.func.c.main.c三个文件,Makefile写法如下所示: CC = gcc CFLAGS = -g -Wall mai ...

  6. Linux——makefile编写

    以前对makefile的编写,限于刚开始接触,我都比较局限一些死板的格式,有时候就会显得有些繁琐.在进一步了解一些系统编译和链接的知识后,对makefile编写流程有了一些新的认识,所以来此梳理梳理, ...

  7. 如何将多个C文件链接在一起----Makefile编写及make指令

    需使用GCC编译器,关于MinGW的安装指南:https://people.eng.unimelb.edu.au/ammoffat/teaching/20005/Install-MinGW.pdf 单 ...

  8. [动态库]动态库生成和使用以及Makefile编写

    转自:https://www.cnblogs.com/ljtknowns/p/5647793.html 文件目录结构如下 1 dynamiclibapp.c 2 Makefile 3 comm/inc ...

  9. Makefile编写 一 *****

    编译:把高级语言书写的代码转换为机器可识别的机器指令.编译高级语言后生成的指令虽然可被机器识别,但是还不能被执行.编译时,编译器检查高级语言的语法.函数与变量的声明是否正确.只有所有的语法正确.相关变 ...

随机推荐

  1. [Java]Java简介

    Java版本历史 1995年5月23日,Java语言诞生 1996年1月,第一个JDK1.0诞生 1996年4月,10个最主要的操作系统供应商申明将在其产品中嵌入JAVA技术 1996年9月,约8.3 ...

  2. hbase基本概念和hbase shell常用命令用法

    1. 简介 HBase是一个分布式的.面向列的开源数据库,源于google的一篇论文<bigtable:一个结构化数据的分布式存储系统>.HBase是Google Bigtable的开源实 ...

  3. Python File I/O

    File is a named location on disk to store related information. It is used to permanently store data ...

  4. 更改layout的布局

    创建了一个layout,缺省都是LinearLayout,原来都在xml把他改成其他布局,习惯了拖放的方式觉得挺麻烦. 其实vs2013有这个功能,就是在设计界面单机右键可以删除布局,然后拖一个布局进 ...

  5. AFNetworking vs ASIHTTPRequest vs MKNetworkKit

    AFNetworking vs ASIHTTPRequest vs MKNetworkKit

  6. C++数据结构之Linked Stack(链式栈)

    上一节用连续的方式实现栈,这种方法用一个确定大小的数组存储栈元素,因为当存储达到数组上限时会遇到麻烦. 连续实现的栈与链式实现的栈的最大不同在于,前者使用一个确定大小的数组存储每一个栈元素,后者使用带 ...

  7. SVG 2D入门8 - 文档结构

    前面介绍了很多的基本元素,包括结构相关的组合和重用元素,这里先对SVG的文档结构中剩下的相关元素简单总结一下,然后继续向前领略SVG的其他特性. SVG文档的元素基本可以分为以下几类: 动画元素:an ...

  8. python global vs nonlocal (2)

    上一篇中简述了这两个关键字的基本用法: global用于在局部作用于修改或重定义全局变量 nonlocal用于在内部作用域修改或重定义外部变量(全局变量除外) 这只是很浅的理解方式 注意python的 ...

  9. 数据结构 《5》----二叉搜索树 ( Binary Search Tree )

    二叉树的一个重要应用就是查找. 二叉搜索树 满足如下的性质: 左子树的关键字 < 节点的关键字 < 右子树的关键字 1. Find(x) 有了上述的性质后,我们就可以像二分查找那样查找给定 ...

  10. Palindrome Number ---- LeetCode 009

    Determine whether an integer is a palindrome. Do this without extra space. Some hints: Could negativ ...