【个人体会】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编程的更多相关文章

  1. GCC、Makefile编程学习

    相关学习资料 http://gcc.gnu.org/ https://gcc.gnu.org/onlinedocs/ http://zh.wikipedia.org/zh/GCC http://blo ...

  2. 【 MAKEFILE 编程基础之四】详解MAKEFILE 函数的语法与使用!

    本站文章均为 李华明Himi 原创,转载务必在明显处注明: 转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/gcc-makefile/771.html   ...

  3. MAKEFILE 编程基础之一【转】

    本文转载自:http://www.himigame.com/gcc-makefile/766.html 概述: 什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Wind ...

  4. (六)makefile编程

    最简单的makefile: all: gcc server.c -o ser gcc client.c  -o cli clear: rm ser cli *.o -rf  #rm -rf表示删除文件 ...

  5. 【 MAKEFILE 编程基础之三】详解 MAKEFILE 变量的定义规则使用!

    本站文章均为 李华明Himi 原创,转载务必在明显处注明: 转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/gcc-makefile/770.html   ...

  6. 【 MAKEFILE 编程基础之二】MAKEFILE 书写规划以及语法规则!

    本站文章均为 李华明Himi 原创,转载务必在明显处注明: 转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/gcc-makefile/768.html   ...

  7. 掌握简单的Makefile文件编程

    Makefile描述整个程序的编译.链接规则 其中还包括了工程中用到的那些源文件及需要产生的目标文件 1)Makefile编程规则 目标(唯一):依赖(可多个) 命令... 伪目标 .PHONY:cl ...

  8. Makefile研究(三) —— 实际应用

    转自:http://blog.csdn.net/jundic/article/details/17886637 前面讲了Makefile 的简单语法和简单的应用模板,但在实际项目应用中比这个肯定复杂很 ...

  9. 第2课 - 初识makefile的结构

    第2课 - 初识makefile的结构 1. makefile 的意义 (1)makefile 用于定义源文件之间的依赖关系 (在阅读开源软件源码时,可通过Makefile掌握源码中各个文件之间的关系 ...

随机推荐

  1. Hibernate 缓存机制二(转)

    感谢:http://www.cnblogs.com/wean/archive/2012/05/16/2502724.html 一.why(为什么要用Hibernate缓存?) Hibernate是一个 ...

  2. C++: std::string 与 Unicode 如何结合?

    关键字:std::string Unicode 转自:http://www.vckbase.com/document/viewdoc/?id=1293 一旦知道 TCHAR 和_T 是如何工作的,那么 ...

  3. hdu 4658 Integer Partition

    五角数定理!!可以参考这个http://www.cnblogs.com/xin-hua/p/3242428.html  代码如下: #include<iostream> #include& ...

  4. BZOJ 3997 TJOI2015 组合数学

    分析一下样例就可以知道,求的实际上是从左下角到右上角的最长路 因为对于任意不在这个最长路的上的点,都可以通过经过最长路上的点的路径将这个点的价值减光 (可以用反证法证明) 之后就是一个非常NOIP的D ...

  5. [itint5]环形最大连续子段和

    http://www.itint5.com/oj/#9 一开始有了个n*n的算法,就是把原来的数组*2,由环形的展开成数组.然后调用n次最大子段和的方法.超时. 后来看到个O(n)的算法,就是如果不跨 ...

  6. Android Spannable

    ApiDemo 源码至 com.example.android.apis.text.Link 类. 首先,看一下其运行效果: 要给 TextView 加上效果,方式主要有几种: 第一种,自动应用效果, ...

  7. 24点C++程序实现 编程之美1.16

    解法1,对于任意输入的四个数字,给出一个24点的解法,若无解,则没有输出. 原理参照下图(编程之美原书) 代码如下,仅供参考 // 1.16.cpp : Defines the entry point ...

  8. android开发无障碍app

    最近做一些为盲人提供服务的APP,还是挺有感触的,感谢手机和互联网的普及,他们的生活比以前丰富了很多. 通过读屏软件,盲人可以操作手机,上网浏览信息.读屏软件的工作原理很简单,就是读出屏幕上按钮.文本 ...

  9. How does it work in C#? - Part 3 (C# LINQ in detail)

    http://www.codeproject.com/Articles/383749/How-does-it-work-in-Csharp-Part-Csharp-LINQ-in-d

  10. Android开发之自定义组合控件

    自定义组合控件的步骤1.自定义一个View,继承ViewGroup,比如RelativeLayout2.编写组合控件的布局文件,在自定义的view中加载(使用View.inflate())3.自定义属 ...