如何写一个makefile
最近因为编译需求,需要更改一些编译条件,顺带看了一些Makefile相关的知识,介绍的很详细,但是例子很少,拆分的比较零碎。初学的话,确实有点压力,我还是喜欢直接在原有的基础上改一些东西,然后遇到问题再进行查找。
GCC := gcc
GXX := g++ SRC_DIR := source
OUT_DIR := build ##依赖的头文件目录
INC_DIR := /usr/include
INC_DIR += ./include ##依赖的库文件目录
LIB_DIR := /usr/lib/debug/linux_x32/lib
LIB_DIR += /usr/lib/debug/linux_x64/lib ##遍历头文件目录中的每一个文件
CFLAGS := $(foreach a, $(INC_DIR), -I$(a)) ##遍历库文件目录中的每一个库
LDFLAGS := $(foreach a, $(LIB_DIR), -L$(a)) ##OBJ(.o)文件名称
OBJS := mcmerge.o ##遍历编译出来的OBJ(.o)文件
FINAL_OBJS := $(foreach obj, $(OBJS), $(OUT_DIR)/$(obj)) ##列举所需要的库文件
LIBS := yuv \
imageunit_linux \
imf \
intlc \
videomanage_linux \
svml ##组装成所需要的LDFALGS
LDFLAGS += $(foreach lib, $(LIBS), -l$(lib)) ##所需要的编译条件
CFLAGS += -DMERGE_MCMERGE -DMCMERGE_DEBUG -fPIC ##目标文件
TARGET := libmerge_x64.so all:$(TARGET) $(TARGET):$(FINAL_OBJS)
$(GXX) -shared -std=c++ -fPIC -m64 -g -D_DEBUG -DNDEBUG -o $@ $^ $(LDFLAGS) $(OUT_DIR)/%.o:$(SRC_DIR)/%.cpp
@test -d $(OUT_DIR) || mkdir -p $(OUT_DIR)
$(GXX) -g -c $< -o $@ $(CFLAGS) -fpermissive $(OUT_DIR)/%.o:$(SRC_DIR)/%.c
@test -d $(OUT_DIR) || mkdir -p $(OUT_DIR)
$(GCC) -g -c $< -o $@ $(CFLAGS) -fpermissive .PHONY:clean
clean:
rm -rf $(OUT_DIR)/*.o $(TARGET)
模板中涉及到的一些东西都添加了注释,需要使用的时候,只需要对地址,库名称进行更改即可,以及一些编译条件的更改。
下面对于一些这两天不太明白的地方进行注解。
1. CFLAGS(cp http://blog.chinaunix.net/uid-31387290-id-5778675.html)
使用gcc编译阶段,最常用的编译选项CFLAGS = -Wall -Werror -g -O0的解释:
-Wall:编译阶段显示所有警告。
-Werror:将所有的警告当成错误进行处理,使出现警告时就停止编译。
常见编译报错:cc1: warnings being treated as errors 。解决方法是:把-Werror去掉,不把warnning当作error处理。
-g:编译器在编译时,产生调试信息,最终产生供gdb调试使用的可执行文件。用了-g选项生成的a.out会比没用-g选项生成的a.out明显大点。
-O0:编译器的优化选项的4个级别
-O0:表示编译时没有优化。
-O1:表示编译时使用默认优化。
-O2:表示编译时使用二级优化。
-O3:表示编译时使用最高级优化。
-Os:相当于-O2.5优化,但又不所见代码尺寸。见:Optimization in GCC
2. .PHONY的作用(cp https://www.cnblogs.com/idorax/p/9306528.html)
伪造的,假的。意思就是:clean是个假target,我不想生成这个target,但是我还想执行下面的语句。白嫖呗~
.PHONY:clean
clean:
rm -rf $(OUT_DIR)/*.o $(TARGET)
3. gcc和g++的区别(cp http://www.cnblogs.com/samewang/p/4774180.html)
什么是gcc / g++
首先说明:gcc 和 GCC 是两个不同的东西
GCC:GNU Compiler Collection(GUN 编译器集合),它可以编译C、C++、JAV、Fortran、Pascal、Object-C、Ada等语言。
gcc是GCC中的GUN C Compiler(C 编译器)
g++是GCC中的GUN C++ Compiler(C++编译器)
一个有趣的事实就是,就本质而言,gcc和g++并不是编译器,也不是编译器的集合,它们只是一种驱动器,根据参数中要编译的文件的类型,调用对应的GUN编译器而已,比如,用gcc编译一个c文件的话,会有以下几个步骤:
Step1:Call a preprocessor, like cpp.
Step2:Call an actual compiler, like cc or cc1.
Step3:Call an assembler, like as.
Step4:Call a linker, like ld
由于编译器是可以更换的,所以gcc不仅仅可以编译C文件
所以,更准确的说法是:gcc调用了C compiler,而g++调用了C++ compiler
gcc和g++的主要区别
①. 对于 *.c和*.cpp文件,gcc分别当做c和cpp文件编译(c和cpp的语法强度是不一样的)
②. 对于 *.c和*.cpp文件,g++则统一当做cpp文件编译
③. 使用g++编译文件时,g++会自动链接标准库STL,而gcc不会自动链接STL
④. gcc在编译C文件时,可使用的预定义宏是比较少的
⑤. gcc在编译cpp文件时/g++在编译c文件和cpp文件时(这时候gcc和g++调用的都是cpp文件的编译器),会加入一些额外的宏
⑥. 在用gcc编译c++文件时,为了能够使用STL,需要加参数 –lstdc++ ,但这并不代表 gcc –lstdc++ 和 g++等价
3. $@,$^,$<的意义
$@--目标文件,$^--所有的依赖文件,$<--第一个依赖文件。
还有各种的编译条件,有待 后续遇到问题之后,根据相关问题进行解决。
如何写一个makefile的更多相关文章
- 从头開始写项目Makefile(五):嵌套运行
[版权声明:转载请保留出处:blog.csdn.net/gentleliu.Mail:shallnew at 163 dot com] 在大一些的项目里面,全部源码不会仅仅放在同一个文件夹,一般各个功 ...
- 一步一步写一个简单通用的makefile(三)
上一篇一步一步写一个简单通用的makefile(二) 里面的makefile 实现对通用的代码进行编译,这一章我将会对上一次的makefile 进行进一步的优化. 优化后的makefile: #Hel ...
- GNU Make 学习系列一:怎样写一个简单的Makefile
编程通常遵循一个相当简单的程序:编辑源文件,编译源代码成可执行的格式,调试结果.尽管将源代码翻译成可执行程序是常规的过程,如果做的不正确,程序员可能会浪费大量的时间去追踪问题.大多数的开发者都经历过这 ...
- “makefile”写法详解,一步一步写一个实用的makefile,详解 sed 's,$∗\.o[ :]*,\1.o $@ : ,g' < $@.
目的:编写一个实用的makefile,能自动编译当前目录下所有.c/.cpp源文件,支持二者混合编译.并且当某个.c/.cpp..h或依赖的源文件被修改后,仅重编涉及到的源文件,未涉及的不编译. 二要 ...
- 学了C语言,如何利用CURL写一个下载程序?—用nmake编译CURL并安装
在这一系列的前一篇文章学了C语言,如何为下载狂人写一个磁盘剩余容量监控程序?中,我们为下载狂人写了一个程序来监视磁盘的剩余容量,防止下载的东西撑爆了硬盘.可是,这两天,他又抱怨他的下载程序不好用,让我 ...
- Linux 我的第一个makefile(Linux指令学习笔记)
我的第一个makefile 最近学到了makefile的文件的编写.makefile是一个能达到方便编译链接生成目标程序的文件, make确实很方便,在写makefile的过程也能更好的理解gcc编译 ...
- 用C写一个web服务器(一) 基础功能
.container { margin-right: auto; margin-left: auto; padding-left: 15px; padding-right: 15px } .conta ...
- 用C写一个web服务器(二) I/O多路复用之epoll
.container { margin-right: auto; margin-left: auto; padding-left: 15px; padding-right: 15px } .conta ...
- 海思的一个 Makefile 解析
Makefile 原文 include ../Makefile.param #ifeq ($(SAMPLE_PARAM_FILE), ) # SAMPLE_PARAM_FILE:=../Makefil ...
随机推荐
- windows常见软件库
1.护卫神软件库 http://soft.huweishen.com/special/1.html 2.护卫神windows资料库 http://v.huweishen.com/ 3.国超软件下载 h ...
- Windows to go 慢,更换 user profile 路径
用 wintousb 安装了 windwos 10 到 u盘 之后, 发觉这个windows 贼慢,卡的不行. 想起以前台式机上用[太阳花]SDD,硬盘满了也是这个感觉的. 就知道 C盘的userpr ...
- 【分布式搜索引擎】初识Elasticsearch
一.Elasticsearch是什么? Elasticsearch是一个基于Apache Lucene(TM)的开源搜索引擎. Elasticsearch是一个实时分布式搜索和分析引擎.它让你以前所未 ...
- 自我学习成长系列之<<FirstHead设计模式>>
第一章 设计模式入门 1.好词好句: 好的设计是可以应付改变. 2.驱动改变的因素:(a)客户需求不清晰,后期会一直变 (b)遇到坑爹的产品,自己不会全扔给程序员 (c)在开发过程中,产生一个新概念, ...
- 『TensorFlow』命令行参数解析
argparse很强大,但是我们未必需要使用这么繁杂的东西,TensorFlow自己封装了一个简化版本的解析方式,实际上是对argparse的封装 脚本化调用tensorflow的标准范式: impo ...
- 常用模块Part(2)
logging模块 hashlib模块 hashlib模块 Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等. # 什么是摘要算法呢?摘要算法又称哈希算法.散列算法.它通过一个 ...
- C# 用 WebClient 的 Post 方法向 WebServer 传输数据
帮朋友做一个通过Web简单传输数据的例子,百度了一下抄了段代码,完成,效果如下: 其中textBox1里面是客户端需要传输过去的数据,textBox2里面是接收到的返回数据. 代码如下: using ...
- Java servlet 实现的简易购物车
首页 2.购买页 3.购物车页 1. 首页代码 发送一个post请求 <!DOCTYPE html><html lang="en"><head> ...
- Java容器解析系列(2) 具体化的第一步——Collection到AbstractCollection
在通向具体化的List,Queue之前,我们需要先了解一下Collection接口和AbstractCollection抽象类,这两个都是处于Collection顶层的存在. Collection接口 ...
- Netty的ByteToMessageDecoder/LengthFieldBasedFrameDecoder
是个inbound handler,channelRead方法里面,用一个bytebuf(cumulation)来把下一个数据包和当前这一个拼在一起,以免同一个请求被拆包.然后callDecode,里 ...