Makefile第十课:Makefile编译
Posted 爱听歌的周童鞋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Makefile第十课:Makefile编译相关的知识,希望对你有一定的参考价值。
目录
Makefile编译
前言
学习杜老师推荐的Makefile教程视频,链接。记录下个人学习笔记,仅供自己参考。
之前有转载过杜老师的从零Makefile落地算法大项目文章,感兴趣的可以看看。
本课程主要讲解Makefile编译完整的带头文件的程序。
1.编译过程
1.1 预处理
示例如下:
cpp_srcs := $(shell find src -name *.cpp)
cpp_i := $(patsubst src/%.cpp,src/%.i,$(cpp_srcs))
src/%.i : src/%.cpp
@g++ -E $< -o $@
preprocess : $(cpp_i)
debug :
@echo $(cpp_i)
clean :
@rm -rf src/*.i
.PHONY : debug preprocess
1.2 编译成汇编语言
示例如下:
cpp_srcs := $(shell find src -name *.cpp)
cpp_s := $(patsubst src/%.cpp,src/%.s,$(cpp_srcs))
src/%.s : src/%.cpp
@g++ -S $< -o $@
assemble : $(cpp_s)
debug :
@echo $(cpp_s)
clean :
@rm -rf src/*.s
.PHONY : debug assemble
1.3 编译成目标文件
示例如下:
cpp_srcs := $(shell find src -name *.cpp)
cpp_objs := $(patsubst src/%.cpp,objs/%.o,$(cpp_srcs))
objs/%.o : src/%.cpp
@mkdir -p $(dir $@)
@g++ -c $< -o $@
objects : $(cpp_objs)
debug :
@echo $(cpp_objs)
clean :
@rm -rf objs
.PHONY : debug clean objects
1.4 链接可执行文件
示例如下:
cpp_srcs := $(shell find src -name *.cpp)
cpp_objs := $(patsubst src/%.cpp,objs/%.o,$(cpp_srcs))
objs/%.o : src/%.cpp
@mkdir -p $(dir $@)
@g++ -c $< -o $@
workspace/pro : $(cpp_objs)
@mkdir -p $(dir $@)
@g++ $^ -o $@
run : workspace/pro
@./$<
debug :
@echo $(cpp_objs)
clean :
@rm -rf objs
.PHONY : debug clean
2.CC++编译选项
编译选项
-m64
:指定编译为 64 位应用程序(x86_64架构)-std=
:指定编译标准,例如:-std=c++11、-std=c++14-g
:包含调试信息-w
:不显示警告-O
:优化等级,通常使用:-O3-I
:加在头文件路径前fPIC
:(Position-Independent Code),产生的没有绝对地址,全部使用相对地址,代码可以被加载到内存的任意位置,且可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的
链接选项
-l
:加在库名前面-L
:加在库路径前面-Wl,<选项>
:将逗号分隔的 <选项> 传递给链接器-rpath=
:运行的时候去寻找的目录。运行的时候,要找 .so 文件,会从这个选项里指定的地方去找
3.Implicit Rules
大家约定俗成常用的一些变量名
- CC: Program for compiling C programs; default cc
- CXX: Program for compiling C++ programs; default g++
- CFLAGS: Extra flags to give to the C compiler
- CXXFLAGS: Extra flags to give to the C++ compiler
- CPPFLAGS: Extra flags to give to the C preprocessor
- LDFLAGS: Extra flags to give to compilers when they are supposed to invoke the linker
4.编译带头文件的程序
add.hpp
#ifndef ADD_HPP
#define ADD_HPP
int add(int a, int b);
#endif // ADD_HPP
add.cpp
int add(int a, int b)
return a+b;
main.cpp
#include <stdio.h>
#include "add.hpp"
int main()
int a=10; int b=5;
int res = add(a, b);
printf("a + b = %d\\n", res);
return 0;
Makefile
cpp_srcs := $(shell find src -name *.cpp)
cpp_objs := $(patsubst src/%.cpp,objs/%.o,$(cpp_srcs))
include_paths := include
I_flags := $(include_paths:%=-I%)
compile_options := -g -O3 -w $(I_flags)
objs/%.o : src/%.cpp
@mkdir -p $(dir $@)
@g++ -c $^ -o $@ $(compile_options)
workspace/pro : $(cpp_objs)
@mkdir -p $(dir $@)
@g++ $^ -o $@
run : workspace/pro
@./$<
debug :
@echo $(compile_options)
@echo $(cpp_objs)
clean :
@rm -rf objs workspace/pro
.PHONY : debug clean run
总结
本次课程学习了Makefile的编译和链接选项以及完整的带头文件程序的Makefile编译。
Makefile 第十二章 Makefile里有什么?
Makefile里主要包含了五个东西:显式规则、隐晦规则、变量定义、文件指示和注释。
- 显式规则。显式规则说明了,如何生成一个或多的的目标文件。这是由Makefile的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。
- 隐晦规则。由于我们的make有自动推导的功能,所以隐晦的规则可以让我们比较简略地书写Makefile,这是由make所支持的。
- 变量的定义。在Makefile中我们要定义一系列的变量,变量一般都是字符串,这个有点像你C语言中的宏,当Makefile被执行时,其中的变量都会被扩展到相应的引用位置上。
- 文件指示。其包括了三个部分,一个是在一个Makefile中引用另一个Makefile,就像C语言中的include一样;另一个是指根据某些情况指定Makefile中的有效部分,就像C语言中的预编译#if一样;还有就是定义一个多行的命令。有关这一部分的内容,我会在后续的部分中讲述。
- 注释。Makefile中只有行注释,和UNIX的Shell脚本一样,其注释是用“#”字符,这个就像C/C++中的“//”一样。如果你要在你的Makefile中使用“#”字符,可以用反斜框进行转义,如:“#”。
最后,还值得一提的是,在Makefile中的命令,必须要以[Tab]键开始。
以上是关于Makefile第十课:Makefile编译的主要内容,如果未能解决你的问题,请参考以下文章
Makefile 第十一章 makefile清空目标文件的规则
从另一个makefile在Makefile中追加/替换字符串