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 ...
随机推荐
- div位置设置
div居中显示 margin:0 auto div中的内容居中显示 text-algin:center div靠右显示 float:right 设置div元素的右外边距 margin-right:10 ...
- MySQL只有information_schema,test两个数据库
一.现象 1.今天登上数据库,用 mysql -uroot -proot 登录(本人密码是root),出现: 2.然后尝试 无密码登录,竟然登录成功: 3.查看mysql中的数据库,发现只有两个系统表 ...
- Linux tmux 工具
基础术语: sessions :会话,一个用户登录到主机,那么就建立了一个 session,如下图1,详细参考:https://my.oschina.net/u/158589/blog/360862t ...
- Unity中Oculus分屏相机和普通相机一键切换
Unity中Oculus分屏相机和普通相机一键切换 一.OCulus 分屏相机介绍 在VR开发工程中,总会觉得OC分屏的处理太慢,严重浪费时间啊! 但是不使用有不好调试,来回切换相机就成为了一个必须. ...
- scss语法
SCSS其实就是SASS新语法, 增强了对CSS3语法的支持 1.变量(Variables) /*声明变明*/ $color: #333; $bgcolor:#f36; /*引用变量*/ body { ...
- [UML]UML 教程 - 第二部分
UML作为软件开发典型的开发过程 业务过程模型创建 业务过程模型被用来定义发生在企业或组织内部的高级业务活动和业务过程,并且是建立用例模型的基础.一般来说业务过程模型比一个软件系统所能实现的更多(比如 ...
- java如何重命名文件?
/** * 修改文件名 * @param oldFilePath 原文件路径 * @param newFileName 新文件名称 * @param overriding 判断标志(如果存在相同名的文 ...
- log buffer space事件(转)
看了这篇文章: Oracle常见的等待事件说明http://database.ctocio.com.cn/tips/38/6669538.shtml 对于Log Buffer Space-日志缓冲空间 ...
- python-social-auth with Django: ImportError: No module named 'social_django' 解决方法
To use Django with python social auth, you need to install the Django app as well. You can specify t ...
- 利用Linux系统生成随机密码的8种方法
Linux操作系统的一大优点是对于同样一件事情,你可以使用高达数百种方法来实现它.例如,你可以通过数十种方法来生成随机密码.本文将介绍生成随机密码的十种方法. 1. 使用SHA算法来加密日期,并输出结 ...