LIBTOOL= libtool
//指定采用libtool编译器,LIBTOOL为标识符
*1. 编译为一个object文件:Object的描述文件为 .lo文件
CC = $(LIBTOOL) --mode=compile --tag=CXX g++
//CC为标识符,代表=号后面的东西
//–mode:表示此次动作是 compile(编译)
//–tag: 如果是交叉编译器,则需要用–tag指定编译器。
//C CC
//C++ CXX
//Java GCJ
//Fortran 77 F77
//Windows Resource RC
// g++:编译器–一般C++用g++;C用gcc
2. 将Object文件编译成可执行文件:libtool只与lo,la文件打交道,所以需要编译成可执行文件
LINK = $(LIBTOOL) --mode=link --tag=CXX g++ -Wl,-rpath,./lib
//–mode:表示此次动作是 link:编译可执行文件
//–tag: 如果是交叉编译器,则需要用–tag指定编译器。
// g++:编译器–一般C++用g++;C用gcc
//-Wl,-rpath=./lib或者-Wl,-rpath,./lib;程序链接时指定链接库的位置,就是使用-wl,-rpath=<link_path>参数
3. 链接用到的第三方库的include文件
INCS = -I../include/ -I/usr/local/openmpi-3.1.2/include
//LIBS:告诉链接器要链接哪些库文件
//-I…/在上级目录中寻找
-l 用于指定程序要链接的库,-l后面紧接着(没有空格)就是库名xxxx(去掉lib和.so)
4. 链接用到的第三方库的lib文件
LIBS = -L./lib -lgdal -lproj -L/usr/local/openmpi-3.1.2/lib -lmpi
//LIBS:告诉链接器要链接哪些链接下的库文件
假设libxxxx.so所在目录为/aa/bb/cc,那么使用格式如下:-L/aa/bb/cc –lxxxx
CFLAGS = -Wall -g -O2 -std=c++11 -fPIC -Wl,-rpath,./lib
//-Wall:选项可以打印出编译时所有的错误或者警告信息
//-O0: 表示编译时没有优化。
//-O1: 表示编译时使用默认优化。
//-O2: 表示编译时使用二级优化。
//-O3: 表示编译时使用最高级优化。
//-Os:相当于-O2.5优化,但又不所见代码尺寸
//-fPIC创建共享库时需要添加的编译选项
//-fPIC; Generate position-independent code if possible (large mode)
//-fpic; Generate position-independent code if possible (small mode)
//编译共享库时使用;
//-fPIE; Generate position-independent code for executables if possible (large mode)
//-fpie; Generate position-independent code for executables if possible (small mode)
//编译可执行程序时使用
//还需要在ld时增加-pie选项才能产生这种代码。即gcc -fpie -pie来编译程序。单独使用哪一//个都无法达到效果。
6. 源文件目录
CPPS = $(wildcard ../src/*.cpp)
//通配符用法$(wildcard PATTERN…) ,将目录下的所有cpp展开
//1、wildcard : 扩展通配符
//2、notdir : 去除路径
//3、patsubst :替换通配符
OBJS = $(patsubst %.cpp,%.lo,$(CPPS))
//patsubst把$(CPPS)中的变量符合后缀是.cpp的全部替换成.lo
BIN = ./LayerStacking
all: $(BIN)
“$”调用定义好的变量
$(OBJS): %.lo: %.cpp
$(CC) -o $@ $(CFLAGS) $(INCS) -c $<
$(BIN): $(OBJS)
$(LINK) -o $@ $(CFLAGS) $^ $(LIBS)
目标列表:目标模式:依赖模式
命令行
目标列表包含了这个规则的全部目标,注意不能包含不适用此条规则的其他目标。
目标模式:是一个包含%的模式字符串。%匹配任意的字符。
依赖模式:也是一个包含%的模式字符串。依赖中的%的具体值等于目标中的%的值。
objects := foo.o bar.o
all:$(objects)
$(objects):%.o:%.c
$(CC) –c $(CFLAGS) $< -o $@
对于foo.o来说,%的值为foo,那么他的依赖中的%的值也为foo,那么依赖为foo.c
如果需要使用%的值可以使用$*,$*在这种模式下代表%的值。
常见自动化变量的说明如下:
$@ 代表目标的依赖文件。
$% 当规则的目标是一个静态库文件的时候,代表静态库的一个成员
$< 代表第一个依赖文件
$? 所有比目标更新的依赖文件
$^ 代表所有依赖文件,当依赖文件重复时,去掉重复文件
$+ 与$^相同,但是保留重复的依赖文件
$* 在模式规则和静态模式规则中,代表%的值。
在老版本的makefile中,还可以通过组合D或者F来,表示目录和文件名,如下:
$(@D) 代表依赖文件的目录部分
$(@F) 代表依赖文件的文件名(除去目录部分)
- 伪目标
clean:
$(LIBTOOL) --mode=clean --tag=CXX rm -f $(OBJS) $(BIN)
clean:
rm -rf *.o
伪目标不代表一个真正的文件。系统不会主动执行伪目标,只有手动指定伪目标之后,才进行相应的操作
./ 当前目录。
../ 父级目录。
/ 基准所在的最顶级目录即根目录,根目录是相对于其他子目录来说的
AR 函数库打包程序,可创建静态库.a文档。默认是“ar” 。
AS 汇编程序。默认是“as” 。
CC C编译程序。默认是“cc” 。
CXX C++编译程序。默认是“g++” 。
CO 从 RCS中提取文件的程序。默认是“co” 。
CPP C程序的预处理器(输出是标准输出设备) 。默认是“$(CC) –E” 。
FC 编译器和预处理Fortran 和 Ratfor 源文件的编译器。默认是“f77” 。
GET 从SCCS中提取文件程序。默认是“get” 。
LEX 将 Lex 语言转变为 C 或 Ratfo 的程序。默认是“lex” 。
PC Pascal语言编译器。默认是“pc” 。
YACC Yacc文法分析器(针对于C程序) 。默认命令是“yacc” 。
YACCR Yacc文法分析器(针对于Ratfor程序) 。默认是“yacc –r” 。
MAKEINFO 转换Texinfo源文件(.texi)到Info文件程序。默认是“makeinfo” 。
TEX 从TeX源文件创建TeX DVI文件的程序。默认是“tex” 。
TEXI2DVI 从Texinfo源文件创建TeX DVI 文件的程序。默认是“texi2dvi” 。
WEAVE 转换Web到TeX的程序。默认是“weave” 。
CWEAVE 转换C Web 到 TeX的程序。默认是“cweave” 。
TANGLE 转换Web到Pascal语言的程序。默认是“tangle” 。
CTANGLE 转换C Web 到 C。默认是“ctangle” 。
RM 删除命令。默认是“rm –f” 。
ARFLAGS 执行“AR”命令的命令行参数。默认值是“rv” 。
ASFLAGS 执行汇编语器“AS”的命令行参数(明确指定“.s”或“.S”文件时) 。
CFLAGS 执行“CC”编译器的命令行参数(编译.c源文件的选项) 。
CXXFLAGS 执行“g++”编译器的命令行参数(编译.cc源文件的选项) 。
COFLAGS 执行“co”的命令行参数(在RCS中提取文件的选项) 。
CPPFLAGS 执行C预处理器“cc -E”的命令行参数(C 和 Fortran 编译器会用到) 。
FFLAGS Fortran语言编译器“f77”执行的命令行参数(编译Fortran源文件的选项) 。
GFLAGS SCCS “get”程序参数。
LDFLAGS 链接器参数。 (如: “ld” )
LFLAGS Lex文法分析器参数。
PFLAGS Pascal语言编译器参数。
RFLAGS Ratfor 程序的Fortran 编译器参数。
YFLAGS Yacc文法分析器参数。
https://blog.csdn.net/xiaowanbiao123/article/details/74644540