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的更多相关文章

  1. 【Makefile】5-Makefile变量的基础

    目录 前言 概念 Chapter 5:变量的基础 5.1 变量的基础 * 空格的定义 ** 一些赋值 一些特殊的符号 5.2 变量中的变量 * 5.3 变量高级用法 变量值替换 把变量的值再当成变量 ...

  2. 嵌入式Linux-GNU Make 使用手册(中译版)

    GNU Make 使用手册(中译版) 翻译:于凤昌 译者注:本人在阅读Linux源代码过程中发现如果要全面了解Linux的结构.理解Linux的编程总体设计及思想必须首先全部读通Linux源代码中各级 ...

  3. PostgreSQL杂记页

    磨砺技术珠矶,践行数据之道,追求卓越价值  luckyjackgao@gmail.com 返回顶级页:PostgreSQL索引页 此页,记录其他数据库,linux以及各种点滴事项 1--数据库设计 1 ...

随机推荐

  1. GIS-012-ArcGIS JS API 绘图

    Name Description ARROW Draws an arrow. CIRCLE Draws a circle. DOWN_ARROW Draws an arrow that points ...

  2. 下载SpringJar包

    方法一: 地址:http://repo.spring.io/release/org/springframework/spring/ 此方法简单. 方法二: 安装TortoiseSVN后,在电脑的任意空 ...

  3. 编写一个读写倾斜测量数据.s3c文件格式的OSG插件osgdb_s3c

    VS新建一个空的DLL工程 ReaderWriterS3C.cpp源文件 #include <osg/Notify> #include <osgDB/FileNameUtils> ...

  4. linux 提示符>怎样退出

    在linux(Red Hat)字符界面下,不小心输入了上漂号 ’ ,结果命令提示符变成了>,然后在q.exit.ctrl+c.ctrl+z都回不去了,不知道怎么回到#的命令提示符?   表示ct ...

  5. C++中的inline关键字

    from here 1. 引入inline关键字的原因 在c/c++中,为了解决一些频繁调用的小函数大量消耗栈空间(栈内存)的问题,特别的引入了inline修饰符,表示为内联函数. 栈空间就是指放置程 ...

  6. String() 函数把对象的值转换为字符串。

    var test1 = new Boolean(1);var test2 = new Boolean(0);var test3 = new Boolean(true);var test4 = new ...

  7. TweenLite简单运用

    参考:TweenLite说明 1 ease TweenLite.to(nextLevelTip, 1.5, { x:0, ease:Bounce.easeOut } ); 2 delayCall 语法 ...

  8. python 10分钟入门pandas

    本文是对pandas官方网站上<10 Minutes to pandas>的一个简单的翻译,原文在这里.这篇文章是对pandas的一个简单的介绍,详细的介绍请参考:Cookbook .习惯 ...

  9. SQL SERVER大话存储结构(5)_SQL SERVER 事务日志解析

          本系列上一篇博文链接:SQL SERVER大话存储结构(4)_复合索引与包含索引    1 基本介绍 每个数据库都具有事务日志,用于记录所有事物以及每个事物对数据库所作的操作. 日志的记录 ...

  10. Error:(12, 64) java: 未报告的异常错误java.io.IOException; 必须对其进行捕获或声明以便抛出

    Error:(12, 64) java: 未报告的异常错误java.io.IOException; 必须对其进行捕获或声明以便抛出 package com.test; import org.apach ...