关于makefile的使用
什么是makefile?对于Winodws程序员来说可能很陌生,因为windows的IDE已经把所有的工作都做好了,你只需要点击各个按钮就可以了。但是对于一个Unix/Windows程序员来讲makefile则是必须要懂的。结合makefile的大多应用场合我们可以说:会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。
因为,makefile关系到了整个工程的编译规则。一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。
makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。
此处先对makefile的最基本的应用做介绍,以后再继续深入。参考如下
首先准备三个文件file1.cpp、file1.h、file2.cpp,程序代码如下:
//fiel1.h
#ifndef FILE1_H_
#define FILE1_H_#ifdef __cplusplusextern "C"{#endifvoid file1print();#ifdef __cplusplus}#endif
#endif//file1.cpp
#include<iostream>
#include "file1.h"
using namespace std;
void file1print(){cout<<"Print file1......."<<endl;
}//file2.cpp
#include<iostream>
#include "file1.h"
using namespace std;
int main(){cout<<"Print file2....."<<endl;file1print();return 0;
}
一、基本makefile编写
helloworld: file1.o file2.og++ file1.o file2.o -o helloworldfile2.o:file2.cppg++ -c file2.cpp -o file2.ofile1.o:file1.cppg++ -c file1.cpp -o file1.oclean:rm -rf *.o helloworld
解析:makefile文件的编写规则如下。
目标:先决需要
(tab)<command>
(tab)<command>
注:每个命令行前面都必须要有tab符号。
注:“先决需要”中如果有一个以上的文件比“目标”文件要新的话,command所定义的命令就会被执行。这就是Makefile的规则。也就是Makefile中最核心的内容。
上面makefile的目的就是要编译一个helloworld的可执行文件,接下来详细解释:
(1)helloworld依赖file1.o file2.o两个文件。
helloworld: file1.o file2.o
依赖于file.o和file2.o两个目标文件编译出helloworld可执行文件。
g++ file1.o file2.o -o helloworld
(2)file2.o依赖于file2.cpp文件。
file2.o:file2.cpp
依赖于file2.cpp源文件编译出file2.o可执行文件。
(3)file1.o依赖于file1.cpp文件。
file1.o:file1.cpp
依赖于file1.cpp源文件编译出file1.o可执行文件。
(4)最后写入一个clean。当用户输入“make clean”命令时,会删除*.o和helloworld文件。
clean:
rm -rm *.o helloworld
二、makefile中使用变量
其实在makefile文件中使用变量很简单。知道如何设定变量和如何引用变量就ok了。
设定变量:var=value
引用变量:$(var)即可
objs=file1.o file2.o
xx=g++
cflags=-Wall -O -ghelloworld: $(objs)$(xx) $(objs) -o helloworld
file2.o:file2.cpp file1.h$(xx) $(flags) -c file2.cpp -o file2.o
file1.o:file1.cpp file1.h$(xx) $(flags) -c file1.cpp -o file1.o
clean:rm -rf *.o helloworld
三、makefile中使用函数
这个略微复杂一点,看看下面这个吧!
xx=g++
cc=gcc
cflags=-Wall -O -g
target=helloworld%.o:%.c$(cc) $(cflags) -c $< -o $@%.o:%.cpp$(xx) $(cflags) -c $< -o $@source=$(wildcard *.c *.cpp)
objs=$(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(source)))$(target):$(objs)$(xx) $(objs) -o $(target)
clean:rm -rf *.o helloworld
(1)wildcard函数:source = $(wildcard *.c *.cpp)
产生一个所有以.c、.cpp结尾的文件的列表,存入变量source里面。
(2)patsubst函数:用于匹配替换。$(patsubst %.cpp,%.o,$(source))
将$(source)指定的后缀为.cpp的变量符号全部替换成为.o为后缀。
至于$(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(source)))的意思就是将$(source)指定的后缀为.cp或.cpp的变量符号全部替换成为.o为后缀。
(3)有用的内部变量:
1)$@:目标文件
2)$<:第一个依赖文件
3)$^:所有的依赖文件
有了这些后第一个实例的makefile文件就可以写成如下样式了:
helloworld: file1.o file2.og++ -o $@ $^file2.o:file2.cppg++ -c $<file1.o:file1.cppg++ -c $<clean:rm -rf *.o helloworld
关于makefile的使用相关推荐
- 浅显易懂 Makefile 入门 (12)— Makefile 常见的错误信息
1. 常见的错误信息 make 执行过程中所产生错误并不都是致命的,特别是在命令行之前存在 -.或者 make 使用 -k 选项执行时. make 执行过程的致命错误都带有前缀字符串 ***.错误信息 ...
- 浅显易懂 Makefile 入门 (10)— 嵌套执行 make、export 的使用
1. 嵌套执行 make 在一个大的工程文件中,不同的文件按照功能被划分到不同的模块中,每个模块可能都会有自己的编译顺序和规则,如果在一个 Makefile 文件中描述所有模块的编译规则,就会很乱,执 ...
- 浅显易懂 Makefile 入门 (09)— include 文件包含、MAKECMDGOALS
1. include文件包含 当 make 读取到 include 关键字的时候,会暂停读取当前的 Makefile,而是去读 include 包含的文件,读取结束后再继读取当前的 Makefile ...
- 浅显易懂 Makefile 入门 (08)— 默认 shell (/bin/sh)、命令回显、make参数(-n 只显示命令但不执行,-s 禁止所有回显)、单行命令、多行命令、并发执行
1. shell 相关 1.1 默认 shell Makefile 所使用的命令是由 shell 命令行组成,他们是一条一条执行的. 多个命令之间要使用分号隔开,Makefile 中的任何命令都要以 ...
- 浅显易懂 Makefile 入门 (07)— 其它函数(foreach 、if、call、origin )
1. foreach 函数 foreach 函数定义如下: $(foreach <var>,<list>,<text>) 函数的功能是:把参数 <list&g ...
- 浅显易懂 Makefile 入门 (06)— 文件名操作函数(dir、notdir、suffix、basename、addsuffix、addperfix、join、wildcard)
编写 Makefile 的时候,很多情况下需要对文件名进行操作.例如获取文件的路径,去除文件的路径,取出文件前缀或后缀等等. 注意:下面的每个函数的参数字符串都会被当作或是一个系列的文件名来看待. 1 ...
- 浅显易懂 Makefile 入门 (03)— 目标文件搜索(VPATH 和 vpath 的区别和使用)、隐含规则
1. 目标文件搜索(VPATH和vpath) 如果需要的文件是存在于不同的路径下(即源文件与 Makefile 文件不在同一个路径下),在编译的时候就用到了 Makefile 中为我们提供的目录搜索文 ...
- 浅显易懂 Makefile 入门 (02)— 普通变量和自动变量定义、使用($@、$^、$< 作用)、变量覆盖 override、变量的来源 origin
1. 变量的定义 Makefile 文件中定义变量的基本语法如下: 变量的名称=值列表 变量的名称可以由大小写字母.阿拉伯数字和下划线构成.等号左右的空白符没有明确的要求,因为在执行 make 的时候 ...
- 浅显易懂 Makefile 入门 (01)— 什么是Makefile、为什么要用Makefile、Makefile规则、Makefile流程如何实现增量编译
1. 什么是 Makefile Makefile 文件描述了 Linux 系统下 C/C++ 工程的编译规则,它用来自动化编译 C/C++ 项目.一旦写编写好 Makefile 文件,只需要一个 ma ...
- Android 的NDK的Makefile编写
Android.mk 是google根据Linux GNU Makefile精简编译脚本.具体来说:这就是GNU Makefile的一小部分. 举一个简单例子: LOCAL_PATH := $(cal ...
最新文章
- Visual Basic 2005 – 如何播放剪贴簿中的音效数据
- 七、处理机调度概念、层次
- 你的GitHub爆款项目,面试官可能问都不问
- python find函数 和index的区别_【全网最简单Python教程】--10.列表元素的索引和返回索引值(Index函数使用)...
- 图像分割 2020 最新进展
- eclipse git:Transport Error: Cannot get remote repository refs. invalid advertisement of
- Linux跨平台远程控制
- java 抛异常 jvm_邪恶的Java技巧使JVM忘记检查异常
- 面试官,再也别问我的系统如何支持高并发了
- 9篇!悉尼科技大学入选CVPR2021都研究什么?
- java transferto_小六六学Netty系列之Java 零拷贝
- java绘制图形_Java绘制图形
- 犯罪与健康的统计关系
- erp故障处理流程图_(完整版)最新鼎捷易助ERP常见问题故障及解决方案方法FAQ
- 【63测试20161111】【BFS】【DP】【字符串】
- android拦截返回键home键,android屏蔽返回键跟Home键
- UE4中实现鼠标单选空间中的模型、Ctrl键多选、空间打点框选功能。
- matlab在光子晶体,利用平面波展开法在matlab中计算一维光子晶体的带隙结构
- 华为云 ModelArts 应用轻松实现图片识别
- Android:浏览图片,点击放大至全屏效果