Makefile编程
【个人体会】0.1 项目文件要合理分隔,功能模块分开放,分别设置Makefile自动编译,
0.2 源码和头文件分开放,一个或多个头文件对应一个源码文件。
0.3 头文件中不要定义变量。
1. 默认变量与注释
# 表示注释
@ 取消回显
$^ 表示所有依赖文件
$@ 表示目标
$< 表示第一个依赖文件
2. 伪目标(伪目标重建时,并不影响其他的,所以很方便的添加和描述非预设的动作)
.PHONY:clean 声明clean为伪目标(作用?)
clean:
rm -f hello main.o
【注】作用:因为没有依赖文件,所以目标文件一定是最新的,所以即使用户明确命令 make clean 重新产生它,也不会有任何事情发生。解决方法是标明所有的伪目标(用 .PHONY),这就告诉 make 不用检查它们是否存在于磁碟上,也不用查找任何隐含规则,直接假设指定的目标需要被更新。
3. 基本语法
3.1 基本格式
targets:prerequistes
【tab】command
eg:
main.o:main.c
gcc -c main.c
3.2 =和:=区别
eg:
A = foo
B = $(A)
# 现在 B 是 $(A) ,而 $(A) 是 'foo' 。
A = bar
# 现在 B 仍然是 $(A) ,但它的值已随着变成 'bar' 了。
B := $(A)
# 现在 B 的值是 'bar' 。
A = foo # B 的值仍然是 'bar' 。
4. 时间戳的作用
eg:
myprog : foo.o bar.o
gcc foo.o bar.o -o myprog
foo.o : foo.c foo.h bar.h
gcc -c foo.c -o foo.o
bar.o : bar.c bar.h
gcc -c bar.c -o bar.o
【注】make 从最上面开始,把第一个目标myprog做为主要目标。只要文件myprog比文件foo.o或bar.o中的任何一个旧,下一行的命令将会被执行。但是,在检查文件 foo.o 和 bar.o 的时间戳之前,它会往下查找那些把 foo.o 或 bar.o 做为目标文件的规则。它找到的关于 foo.o 的规则,该文件的依靠文件是 foo.c, foo.h 和 bar.h 。 它从下面再找不到生成这些依靠文件的规则,它就开始检查磁碟 上这些依靠文件的时间戳。如果这些文件中任何一个的时间戳比 foo.o 的新,命令 'gcc -o foo.o foo.c' 将会执行,从而更新 文件 foo.o 。 接下来对文件 bar.o 做类似的检查,依靠文件在这里是文件 bar.c 和 bar.h 。
5. 使用变量
eg:
OBJS = foo.o bar.o
CC = gcc
CFLAGS = -Wall -O -g
myprog : $(OBJS)
$(CC) $(OBJS) -o myprog
foo.o : foo.c foo.h bar.h
$(CC) $(CFLAGS) -c foo.c -o foo.o
bar.o : bar.c bar.h
$(CC) $(CFLAGS) -c bar.c -o bar.o
编译的指令可以写为: #(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
CC 编译器
CFLAGS 给c编译器传递变量,c++用CXXFLAGS
CPPFLAGS c预处理器旗标
TARGET_ARCH
6. 函数
SOURCES=$(wildcard *.c) 使用函数wildcard,产生一列.c结尾的文件
列表,空格分隔,存到SOURCES中。
OBJS=$(patsubst %.c,%.o,$(SOURCES)) SOUCES中以.c结尾的都用.o代替.c。
其中%匹配一个和多个字符。
eg:
SOURCES = $(wildcard *.c *.cc)
OBJS = $(patsubst %.c,%.o,$(patsubst %.cc,%.o,$(SOURCES)))
myprog : $(OBJS)
gcc -o myprog $(OBJS)
depends : $(SOURCES)
gcc -M $(SOURCES) > depends
7. 一个完整的Makefile
######################################
# Generic makefile
#
# by AUTHOR
#
# Copyright (c)
# All rights reserved.
######################################
# 用户设定
#
# 如果需要,调整下面的东西。 EXECUTABLE 是目标的可执行文件名, LIBS
# 是一个需要连接的程序包列表(例如 alleg, stdcx, iostr 等等)。当然你
# 可以在 make 的命令行覆盖它们,你愿意就没问题。
#
# 现在来改变任何你想改动的隐含规则中的变量。
CFLAGS := -g -Wall -O3 -m486
CXXFLAGS := $(CFLAGS)
# 下面先检查你的 djgpp 命令目录下有没有 rm 命令,如果没有,我们使用
# del 命令来代替,但有可能给我们 'File not found' 这个错误信息,这没
# 什么大碍。如果你不是用 DOS ,把它设定成一个删文件而不废话的命令。
# (其实这一步在 UNIX 类的系统上是多余的,只是方便 DOS 用户。 UNIX
# 用户可以删除这5行命令。)
ifneq ($(wildcard $(DJDIR)/bin/rm.exe),) #【注】ifneq与ifeq用法相反
RM-F := rm -f
else
RM-F := del
endif
# 从这里开始,你应该不需要改动任何东西。(我是不太相信,太NB了!)
SOURCE := $(wildcard *.c) $(wildcard *.cc)
OBJS := $(patsubst %.c,%.o,$(patsubst %.cc,%.o,$(SOURCE)))
DEPS := $(patsubst %.o,%.d,$(OBJS))
MISSING_DEPS := $(filter-out $(wildcard $(DEPS)),$(DEPS))
#【注】filter-out函数使用两个空格分开的列表,把第二列表中所有的存在于第一列表中的项目删除。
MISSING_DEPS_SOURCES := $(wildcard $(patsubst %.d,%.c,$(MISSING_DEPS)) \
$(patsubst %.d,%.cc,$(MISSING_DEPS)))
CPPFLAGS += -MD
.PHONY : everything deps objs clean veryclean rebuild
everything : $(EXECUTABLE)
deps : $(DEPS)
objs : $(OBJS)
clean : #【注】删除所有中介/依赖文件(*.d 和 *.o )
@$(RM-F) *.o
@$(RM-F) *.d
veryclean: clean
@$(RM-F) $(EXECUTABLE)
rebuild: veryclean everything
ifneq ($(MISSING_DEPS),)
$(MISSING_DEPS) : @$(RM-F) $(patsubst %.d,%.o,$@)
endif
-include $(DEPS)
$(EXECUTABLE) : $(OBJS)
gcc -o $(EXECUTABLE) $(OBJS) $(addprefix -l,$(LIBS))
#【注】addprefix函数把第二个参数列表每一项前缀上第一个参数值。
# everything:(预设) 更新主要的可执行程序,并且为每一个源码文件
# 生成或更新一个 '.d' 文件和一个 '.o' 文件。
# deps: 只是为每一个源码程序产生或更新一个 '.d' 文件。
# objs: 为每一个源码程序生成或更新 '.d' 文件和目标文件。
# veryclean: 做 `clean' 和删除可执行文件。
# rebuild: 先做 `veryclean' 然后 `everything' ;既完全重建。
# 除了预设的 everything 以外,这里头只有 clean,veryclean,和 rebuild 对用户是有意义的。
#
#
Makefile编程的更多相关文章
- GCC、Makefile编程学习
相关学习资料 http://gcc.gnu.org/ https://gcc.gnu.org/onlinedocs/ http://zh.wikipedia.org/zh/GCC http://blo ...
- 【 MAKEFILE 编程基础之四】详解MAKEFILE 函数的语法与使用!
本站文章均为 李华明Himi 原创,转载务必在明显处注明: 转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/gcc-makefile/771.html ...
- MAKEFILE 编程基础之一【转】
本文转载自:http://www.himigame.com/gcc-makefile/766.html 概述: 什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Wind ...
- (六)makefile编程
最简单的makefile: all: gcc server.c -o ser gcc client.c -o cli clear: rm ser cli *.o -rf #rm -rf表示删除文件 ...
- 【 MAKEFILE 编程基础之三】详解 MAKEFILE 变量的定义规则使用!
本站文章均为 李华明Himi 原创,转载务必在明显处注明: 转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/gcc-makefile/770.html ...
- 【 MAKEFILE 编程基础之二】MAKEFILE 书写规划以及语法规则!
本站文章均为 李华明Himi 原创,转载务必在明显处注明: 转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/gcc-makefile/768.html ...
- 掌握简单的Makefile文件编程
Makefile描述整个程序的编译.链接规则 其中还包括了工程中用到的那些源文件及需要产生的目标文件 1)Makefile编程规则 目标(唯一):依赖(可多个) 命令... 伪目标 .PHONY:cl ...
- Makefile研究(三) —— 实际应用
转自:http://blog.csdn.net/jundic/article/details/17886637 前面讲了Makefile 的简单语法和简单的应用模板,但在实际项目应用中比这个肯定复杂很 ...
- 第2课 - 初识makefile的结构
第2课 - 初识makefile的结构 1. makefile 的意义 (1)makefile 用于定义源文件之间的依赖关系 (在阅读开源软件源码时,可通过Makefile掌握源码中各个文件之间的关系 ...
随机推荐
- poj 1094 Sorting It All Out (拓扑排序)
http://poj.org/problem?id=1094 Sorting It All Out Time Limit: 1000MS Memory Limit: 10000K Total Su ...
- Buffer
Buffer 我们用原有 IO 读写文件应该不会陌生了,顺带回顾一下,大致两种: 1. 在 InputStream 或 OutputStream 上读写字节或字节数组,读 InputStream 时用 ...
- springMVC+MyBatis+Spring+maven 整合(1)
1.首先第一步.部署mybatis ; 1.1 下载myBatis MyBits前身是iBitis,相对于Hibernate而言,它是半自动化ORM框架.由于老板对性能要求的比较苛刻,不得不放弃我亲爱 ...
- 如何循环遍历document.querySelectorAll()方法返回的结果
使用JavaScript的forEach方法,我们可以轻松的循环一个数组,但如果你认为document.querySelectorAll()方法返回的应该是个数组,而使用forEach循环它: /* ...
- 一周一话题之四(JavaScript、Dom、jQuery全面复习总结<Dom篇>)
-->目录导航 一. 初探Dom 1. Dom介绍 二. Dom基础 1. window顶级对象 2. body.document对象事件 3. 通用的HTML元素的事件 4. 冒泡事件 5. ...
- Discuz模版与插件 安装时提示“对不起,您安装的不是正版应用...”解决方法
关于出现“对不起,您安装的不是正版应用..”的解决办法 有些插件和风格在安装时出现不能安装的现象,出现以下提示: 对不起,您安装的不是正版应用,安装程序无法继续执行 点击这里安 ...
- sed找到重复的行
sed之仅打印相邻重复的行 cat file aaa bbb bbb ccc ddd eee eee fff 只显示重复的行: bbb bbb eee eee sed -n ':a;N;/\ ...
- jQgrid问题总结
最近一段时间一直在使用jqgrid这个免费的插件,网上的资料也比较多.比较全,但是这里还是整理几个自己在开发过程中遇到的小问题. 1.自动换行 一行数据过多需要自动根据内容换行时,如果遇到在表格中的汉 ...
- 基于邻接矩阵的深度优先搜索(DFS)
题目:http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=2107&cid=1186 #include<stdio.h> #incl ...
- freemarker跳出循环
break语句跳出当前循环,如下: <#list table.columns as c> <#if c.isPK> &l ...