5makefile
makefile编译多个可执行文件
1: 多个 C 文件编译成不同的目标文件
2: 多个 C 文件编译成 一个目标文件
注意:makefile的文件名的三种形式(优先级排序)
makefile>Makefile>GNUMakefile
简单说,makefile类似快捷键。
如:创建主函数文件mian.c 函数文件func.c
编译二进制:
gcc -g -Wall -c main.c -o mian.o
gcc -g -Wall -c func.c -o func.o
链接并生成可执行文件:
gcc -Wall main.o func.o -o main
此时可以看到只用两个文件都如此麻烦,一旦许多文件呢?或对mian.c进行修改后,还要再一次编译
解决方式:
创建一个makefile的文件:
main:main.o func.o
gcc -g -Wall mainn.o func.o -o main
main.o:main.c
gcc -g -Wall -c mainn.c func.o -o main.o
func.o:func.c
gcc -g -Wall -c func.c func.o -o func.o
执行:make
解析:
main依赖于main.o func.o,一定要就此句在第一个。因此makefile只编译第一个语句。main.o,func.o将会向下寻找。即使重新修改文件内容,只需再一次make就自动编译
如果:
main.o:main.c
gcc -g -Wall -c mainn.c func.o -o main.o
main:main.o func.o
gcc -g -Wall mainn.o func.o -o main
func.o:func.c
gcc -g -Wall -c func.c func.o -o func.o
此时,只编译
main.o:main.c
gcc -g -Wall -c mainn.c func.o -o main.o
后面两个不进行编译。
make工具
自动完成编译工作
1:修改某个文件后,只重新编译修改的文件
2:修改某个头文件后,重新编译所有包含该头文件的文件
makefile 描述了整个工程编译,链接的规则
make工具通过makefile文件来完成、维护编译工作
makefile基本规则
Target ... : dependencies ...
[ Tab ] command
...
Target: 程序生成的文件,或者要指向的动作,如clean
dependencies:目标文件依赖的文件
command:make执行的动作(以 TAB字符开始!!!)
dependencies 中文件更新时候,执行command
例子:
main:main.o add.o sub.o
gcc -Wall -g main.o sub.o add.o -o main
main.o:main.c
gcc -Wall -g -c main.c -o main.o
add.o:add.c add.h
gcc -Wall -g -c add.c -o add.o
sub.o:sub.c sub.h
gcc -Wall -g -c sub.c -o sub.o
clean:
rm -f main main.o add.o sub.o
make ==》按需生成文件
make ==》修改时间未改变,则不会重新编译
make ... 生成某个目标(或者伪目标clean),不加则默认生成第一个模板
显式指定伪目标
上面的makefile文件,如果目录下存在clean文件
结果: make clean失效
解决办法:需要显示指定 clean 是伪目标, 文件开头加上:.PHONY:clean
.PHONY: 表示这是一个伪目标
定义变量
makefile自动化变量
$@: 规则的目标文件名
$< : 规则的第一个依赖文件名
$^ : 规则的所有依赖文件列表
举例 add.o:add.c add.h
$@ 为 add.o
$< 为 add.c
$^ 为 add.c add.h
自定义变量
var=....... ? 使用变量 $(var)
使用变量的例子:
.PHONY:clean
OBJ=main.o add.o sub.o
main:$(OBJ)
gcc -Wall -g $^ -o $@
main.o:main.c
gcc -Wall -g -c $< -o $@
add.o:add.c add.h
gcc -Wall -g -c $< -o $@
sub.o:sub.c sub.h
gcc -Wall -g -c $< -o $@
clean:
rm -rf $(OBJ)
改进:
.PHONY:clean
BIN=main
CC=gcc
CFLAGS=-Wall -g
OBJ=main.o add.o sub.o
$(BIN):$(OBJ)
$(CC) $(CFLAGS) $^ -o $@
main.o:main.c
$(CC) $(CFLAGS) -c $< -o $@
add.o:add.c add.h
$(CC) $(CFLAGS)-c $< -o $@
sub.o:sub.c sub.h
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -rf *.o $(BIN)
自定义的变量一般使用大写。
注意:通过 –f 参数,指定需要用到的makefile文件make –f makefile.1 自定义使用的makefile文件
自动推导
编译器会自动推导,
同名的 .c 文件生成同名目标文件
默认使用隐含方式生成,不想使用自动推导则自行添加生成方式
cc –c –o xxx.o xxx.c
模式匹配
规则 1:
%.o:%.c
gcc -Wall -g -c $< -o $@
规则2:
.c.o:
gcc -Wall -g -c $< -o $@
规则2注意 .c.o之间不能由空格
编译目录下所有.c 文件
$(BIN):%:%.o
所有的 $(BIN) 文件生成规则:
$(BIN)中没有扩展名的文件依赖于对应扩展名为.o 的文件
编译多个可执行文件
makefile 默认生成第一个对象
要生成对个对象的话,可以使用自定义变量
.PHONY:clean all
OBJ=test1 test2
all:$(OBJ)
...
这里: all 是一个伪目标,makefile 要生成 all, 也就是 test1, test2
make常用内嵌函数
函数调用
$(function arguments)
$(wildcard 模式)
当前目录下匹配模式的文件:
获取所有.c文件
src = $(wildcard *.c)
把src的 .c替换为.o
$(src :%.c=%.o)
obj = $(src:%.c=%.o)
shell函数
执行shell命令: $(shell ls –d */) 获取所有子目录
例子改进:
.PHONY:clean all
SRC=$(wildcard *.c)
OBJ=$(SRC:%.c=%.o)
BIN=$(SRC:$.c=%)
CC=gcc
CFLAGS=-Wall -g
all:$(BIN)
%.o:%.c
$(CC) $(SFLAGS) $^ -o %@
clean:
rm -f $(BIN) $(OBJ)
多级目录makefile
SUBDIRS=test1 test2
.PHONY:default all clean $(SUBDIRS)
default:all #无参数,则生成all
all clean: #all 和 clean都依赖下面语句
$(MAKE) $(SUBDIRS) TARGET=$@ #make test1 test2 ;赋值 TARGET=all
$(SBUDIRS):
$(MAKE) -C $@ $(TARGET)
#make –C test1 all: 调用test1中make,并以all为入参。 make test1/makefile all
注意-C大写
C语言版
makefile万能模板:
.PHONY:clean all
SRC=$(wildcard *.c)
BIN=$(SRC:%.c=%)
CC=gcc
CFLAGS=-g -Wall
all:$(BIN)
clean:
rm -rf $(BIN)
~
C++版
.PHONY:all clean
SRC=$(wildcard *.c)
BIN=$(SRC:%.c=%)
CPPSRC=$(wildcard *.cpp)
CPPBIN=$(CPPSRC:%.cpp=%)
CC=gcc
CXX=g++
CFLAGS=-g -Wall
CXXFLAGS=-g -Wall -std=c++11
all:$(BIN) //$(CPPBIN)
clean:
rm -rf $(BIN) //$(CPPBIN)
5makefile的更多相关文章
- 【Makefile】5-Makefile变量的基础
目录 前言 概念 Chapter 5:变量的基础 5.1 变量的基础 * 空格的定义 ** 一些赋值 一些特殊的符号 5.2 变量中的变量 * 5.3 变量高级用法 变量值替换 把变量的值再当成变量 ...
- 嵌入式Linux-GNU Make 使用手册(中译版)
GNU Make 使用手册(中译版) 翻译:于凤昌 译者注:本人在阅读Linux源代码过程中发现如果要全面了解Linux的结构.理解Linux的编程总体设计及思想必须首先全部读通Linux源代码中各级 ...
- PostgreSQL杂记页
磨砺技术珠矶,践行数据之道,追求卓越价值 luckyjackgao@gmail.com 返回顶级页:PostgreSQL索引页 此页,记录其他数据库,linux以及各种点滴事项 1--数据库设计 1 ...
随机推荐
- python2.0_day22_web聊天室二
上节内容已经实现了客户端使用长轮询的方式获取消息的功能.但是还没有展现到前端.本节内容将实现1.展现消息到前端窗口.2.客户端之间发送图片和文件.3.文件上传时显示进度条 下面我们来实现上面3个功能. ...
- B-J UI框架(前端异步框架)
B-JUI 客户端框架 http://xiangzhanyou.com/B-JUI
- linux 统计命令执行后的行数或者统计目录下文件数目
ls |wc 是统计你这个目录下的文件数目.ls |wc -l是输出第一个结果即31即文件的数目.
- ORA-20000的解决过程
今天在用impdp导数据时出现卡住的现象,开始我以为是数据量过大导致的,过了两个小时还是卡住,看警告日志得到下面的错误信息: GATHER_STATS_JOB encountered errors. ...
- 如何设置SOLR的高亮 (highlight)?
打开SOLR的核心配置文件: solrconfig.xml 找到 standard request handler 写入以下XML配置代码: <requestHandler name=" ...
- C++的virtual详解
类的多态特性是支持面向对象的语言最主要的特性,有过非面向对象语言开发经历的人,通常对这一章节的内容会觉得不习惯,因为很多人错误的认为,支持类的封装的语言就是支持面向对象的,其实不然,Visual BA ...
- 《C++ Primer Plus》第9章 内存模型和名称空间 学习笔记
C++鼓励程序员在开发程序时使用多个文件.一种有效的组织策略是,使用头文件来定义用户类型,为操纵用户类型的函数提供函数原型,并将函数定义放在一个独立的源代码文件中.头文件和源代码文件一起定义和实现了用 ...
- poj_1151 线段树
题目大意 在平面上给定n个矩形,可以相互覆盖全部或者部分,求出矩形占据的总面积. 题目分析 将矩形按照x方向的进行分割之后,将平面沿着y方向划分一系列单元(不定高度),每个矩形在y方向上占据若干连续的 ...
- MyBatis——Java API
Java API 既然你已经知道如何配置 MyBatis 和创建映射文件,你就已经准备好来提升技能了. MyBatis 的 Java API 就是你收获你所做的努力的地方.正如你即将看到的,和 JDB ...
- 浅析HTTPS与SSL原理
版权声明:本文由盛旷 原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/134 来源:腾云阁 https://www.qclo ...