一个应用程序的形成是少不了一下几个步骤的。

1. 预处理    #检查语法错误、包含头文件、展开#if、#define等宏定义

2. 编译     #把.c文件转换为汇编文件.s

3. 汇编     #把.s汇编转换为机器码.o

4. 链接     #和库文件等组合在一起

只有经过了上面几个步骤才能形成一个可执行的应用程序

用gcc -o test test.c这个命令就可以将上面的四个步骤全部完成。加上编译指令-v可以看到详细的编译过程。

介绍一下Makefile中常用的函数。

wildcard 

用法是:

  $(wildcard PATTERN...)

在Makefile中,它被展开为已经存在的、使用空格分开的、匹配此模式的所有文件列表。如果不存在任何符合此模式的文件,函数会忽略模式字符并返回空。

一般我们可以使用“$(wildcard *.c)”来获取工作目录下的所有的.c文件列表。

foreach

$(foreach VAR,LIST,TEXT)

函数功能:

  如果需要(存在变量或者函数的引 用) ,首先展开变量“VAR”和“LIST”的引用;

  而表达式“TEXT”中的变量 引用不展开。执行时把“LIST”中使用空格分割的单词依次取出赋值给变量 “VAR” ,然后执行“TEXT”表达式。

  重复直到“LIST”的最后一个单词(为 空时结束) 。

  “TEXT”中的变量或者函数引用在执行时才被展开,因此如果在 “TEXT”中存在对“VAR”的引用,那么“VAR”的值在每一次展开式将会到 的不同的值。

patsubst

  格式:$(patsubst <pattern>,<replacement>,<text> )

  名称:模式字符串替换函数——patsubst。

  功能:查找<text>中的单词(单词以“空格”、“Tab”或“回车”“换行”分隔)是否符合模式<pattern>,如果匹配的话,则以<replacement>替换。这里,<pattern>可以包括通配符“%”,表示任意长度的字串。如果<replacement>中也包含“%”,那么,<replacement>中的这个“%”将是<pattern>中的那个“%”所代表的字串。(可以用“\”来转义,以“\%”来表示真实含义的“%”字符)

  返回:函数返回被替换过后的字符串。

filter

$(filter PATTERN…,TEXT)

  函数名称:过滤函数—filter。

  函数功能:过滤掉字串“TEXT”中所有不符合模式“PATTERN”的单词,保留所 有符合此模式的单词。可以使用多个模式。模式中一般需要包含模式字 符“%”。存在多个模式时,模式表达式之间使用空格分割。

  返回值:空格分割的“TEXT”字串中所有符合模式“PATTERN”的字串。

   函数说明:“filter”函数可以用来去除一个变量中的某些字符串.

在编译的时候加上-Wp,-MD即可自动生成依赖文件。

如果需要编译子目录下的源文件则在Makefile中加上obj-y += 子目录的名称

在子目录的makef中写上obj-y += 子目录中的源文件.o

示例:

#
# Makefile topdir
#
CROSS_COMPILE := arm-linux-          #指定交叉工具链
AS := $(CROSS_COMPILE)as
LD := $(CROSS_COMPILE)ld
CC := $(CROSS_COMPILE)gcc
CPP := $(CC) -E
AR := $(CROSS_COMPILE)ar
NM := $(CROSS_COMPILE)nm STRIP := $(CROSS_COMPILE)strip
OBJCOPY := $(CROSS_COMPILE)objcopy
OBJDUMP := $(CROSS_COMPILE)objdump export AS LD CC CPP AR NM                #导出变量 用于子目录中的Makefile
export STRIP OBJDUMP OBJCOPY CFLAGS := -Wall -o2
CFLAGS += -I $(shell pwd)/include  
LDFLAGS := -lm -lfreetype      #编译选项 export CFLAGS LDFLAGS TOPDIR := $(shell pwd)
export TOPDIR TARGET := show_file                #生成的目标文件 obj-y += main.o                    #当前目录下的源文件
obj-y += sub/                     #当前目录下的子目录  all:
make -C ./ -f $(TOPDIR)/Makefile.build    
$(CC) $(LDFLAGS) -o $(TARGET) built-in.o     #编译为目标文件 clean:
rm -f $(shell find -name "*.o")
rm -f $(TARGET) distclean:
rm -f $(shell find -name "*.o")
rm -f $(shell find -name "*.d")
rm -f $(shell find -name "*~")
rm -f $(TARGET)
#
# Makefile.build
#
PHONY := __build
__build: obj-y :=
subdir-y := include Makefile          #包含本目录下的Makefile __subdir-y := $(patsubst %/, %, $(filter %/,$(obj-y))) subdir-y += $(__subdir-y) subdir_objs := $(foreach f,$(subdir-y),$(f)/built-in.o) cur_objs := $(filter-out %/, $(obj-y))
dep_files := $(foreach f,$(cur_objs),.$(f).d)
dep_files := $(wildcard $(dep_files)) ifneq ($(dep_files),)
include $(dep_files)
endif PHONY += $(subdir-y) __build:$(subdir-y) built-in.o $(subdir-y) :
make -C $@ -f $(TOPDIR)/Makefile.build built-in.o : $(cur_objs) $(subdir_objs)
$(LD) -r -o $@ $^ %.o : %.c
$(CC) $(CFLAGS) -Wp,-MD,.$@.d -c -o $@ $<
.PHONY : $(PHONY)
#
# Makefile subdir
#
obj-y := test1.o

下面的一个是编译当前目录下所有的.c文件 不包含子目录

#
# Makefile topdir
#
#
TARGET := show_file #生成的目标文件 CROSS_COMPILE := /usr/local/arm/arm-2009q3/bin/arm-none-linux-gnueabi-
AS := $(CROSS_COMPILE)as
LD := $(CROSS_COMPILE)ld
CC := $(CROSS_COMPILE)gcc
CPP := $(CC) -E
AR := $(CROSS_COMPILE)ar
NM := $(CROSS_COMPILE)nm STRIP := $(CROSS_COMPILE)strip
OBJCOPY := $(CROSS_COMPILE)objcopy
OBJDUMP := $(CROSS_COMPILE)objdump export AS LD CC CPP AR NM
export STRIP OBJDUMP OBJCOPY CFLAGS := -Wall -o2
CFLAGS += -I $(shell pwd)/include  
LDFLAGS := -lm -lfreetype export CFLAGS LDFLAGS cur_file = $(wildcard *.c)
cur_objs := $(cur_file:.c=.o) all: $(cur_objs)
$(CC) $(CFLAGS) -o $(TARGET) $^ clean:
rm -f $(shell find -name "*.o")
rm -f $(TARGET) distclean:
rm -f $(shell find -name "*.o")
rm -f $(shell find -name "*~")
rm -f $(TARGET)

sd

编写通用的Makefile的更多相关文章

  1. 第4课.编写通用的Makefile

    1.框架 1. 顶层目录的Makefile 2. 顶层目录的Makefile.build 3. 各级子目录的Makefile 2.概述 1.各级子目录的Makefile: 它最简单,形式如下: obj ...

  2. 编写一个通用的Makefile文件

    1.1在这之前,我们需要了解程序的编译过程 a.预处理:检查语法错误,展开宏,包含头文件等 b.编译:*.c-->*.S c.汇编:*.S-->*.o d.链接:.o +库文件=*.exe ...

  3. Linux C编程学习之开发工具3---多文件项目管理、Makefile、一个通用的Makefile

    GNU Make简介 大型项目的开发过程中,往往会划分出若干个功能模块,这样可以保证软件的易维护性. 作为项目的组成部分,各个模块不可避免的存在各种联系,如果其中某个模块发生改动,那么其他的模块需要相 ...

  4. 通用的 makefile 小工具分享 - Easymake 使用说明

    Easymake 使用说明 介绍 Easymake 是一个在linux系统中 C/C++ 开发的通用 makefile.在一个简单的 C/C++ 程序中使用 easymake,你甚至可以不写一行 ma ...

  5. 如何快速编写大项目的Makefile文件

    在构建C++的后台服务时,经常需要自己来编写makefile文件,而如果没有合适的方法或模板时,编写makefile文件是一件很费时费力的事情.因此,为了帮助程序员高效准确的编写makefile文件, ...

  6. <五>JDBC_利用反射及JDBC元数据编写通用的查询方法

    此类针对javaBean类写了一个通用的查询方法,List<javaBean> 通用查询更新中...:通过学习,深刻体会到学会反射就等于掌握了java基础的半壁江山! 一.使用JDBC驱动 ...

  7. JDBC学习笔记(5)——利用反射及JDBC元数据编写通用的查询方法

    JDBC元数据 1)DatabaseMetaData /** * 了解即可:DatabaseMetaData是描述数据库的元数据对象 * 可以由Connection得到 */ 具体的应用代码: @Te ...

  8. 一步一步写一个简单通用的makefile(三)

    上一篇一步一步写一个简单通用的makefile(二) 里面的makefile 实现对通用的代码进行编译,这一章我将会对上一次的makefile 进行进一步的优化. 优化后的makefile: #Hel ...

  9. 【转】JDBC学习笔记(5)——利用反射及JDBC元数据编写通用的查询方法

    转自:http://www.cnblogs.com/ysw-go/ JDBC元数据 1)DatabaseMetaData /** * 了解即可:DatabaseMetaData是描述数据库的元数据对象 ...

随机推荐

  1. LeetCode 038 Count and Say

    题目要求:Count and Say The count-and-say sequence is the sequence of integers beginning as follows:1, 11 ...

  2. 基于FPGA的VGA显示实验设计

    基于FPGA的VGA显示实验设计 成果展示(优酷视频): 视频: 基于FPGA的VGA显示技术(手机控制) http://v.youku.com/v_show/id_XNjk4ODE3ODUy.htm ...

  3. 我与PHP,ULM和Vue.js不得不说的故事(一个放荡不羁与一个神神秘秘一个似曾相识,从入门到放弃记录第二章)

    ·关于UML(git) 究竟是命运在茫茫语言之中遇到了你,还是我的魅力让你向我奔涌而来.好吧都不是,我俩就像古代包办婚姻,被专业牢牢的绑在一起了,既然都是一条绳上的蚂蚱.我我们应该能体谅彼此的不容易, ...

  4. CentOS7.X 挂载磁盘 与Mysql 自动备份

    1.前言 搞了好几天终于弄了出来,简单记录一下.注意以下教程是在测试服务器基础上编写 如数据盘含有数据切勿使用此教程,如对命令行不熟悉的 不建议搞哈 .本文中的磁盘/dev/sdb为笔者测试服务器上的 ...

  5. 排序--QuickSort 快排

    Quick の implementation 快排,就像它的名字一定,风一样的快.基本上算是最快的排序算法了.快排的基本思想是选择一个切分的元素.把这个元素排序了.所有这个元素左边的元素都小于这个元素 ...

  6. Jdk源码-集合类主要原理和解析

    写在前面 熟悉Jdk原理的重要性不言而喻,作为Java开发者或者面试者,了解其实现原理也显得更为装逼,在Java读书计划我写到了,它是面试中最基础的一部分,所以单独拿出来做个总结,为了更好滴理解和学习 ...

  7. 第6.3节 Python动态执行之动态编译的compile函数

    Python支持动态代码主要三个函数,分别是compile.eval和exec.本节介绍compile函数的语法和相关使用.compile函数用来编译一段字符串的源码,将其编译为字节码或者AST(抽像 ...

  8. 第七章、PyQt图形界面应用程序的事件捕获方法

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一. 概述 PyQt的图形界面应用中,事件处理类似于Windows系统的消息处理.一个带图形界面的应 ...

  9. Xpath基础学习

    方法 获取文本 a/text() 获取a标签下的文本 a//text() 获取a标签下所有标签的文本 a[text()='xxx']获取文本为xxx的a标签 @符号 a/@href 获取a标签的hre ...

  10. Hadoop 中HDFS、MapReduce体系结构

    在网络环境方面,作为分布式系统,Hadoop基于TCP/IP进行节点间的通信和传输. 在数据传输方面,广泛应用HTTP实现. 在监控.通知方面,Hadoop等分布式大数据软件则广泛使用异步消息队列等机 ...