makefile

目录

  • 1,一个简单的makefile
  • 2,多文件makefile编写
  • 3,引用变量简化makefile
  • 4,gcc编译动态链接库
  • 5,自动推导目标代码配置和伪目标

1,一个简单的makefile

目标:依赖条件
                         (一个tab缩进)命令

案例,
比如我在一个目录下,有一个.cpp文件,
我想编译这个文件的代码,生成可执行文件

first_make:first_make.cpp
	g++ first_make.cpp -o first_make -lpthread

first_make就是要生成的目标文件,也就是可执行文件,
first_make.cpp就是依赖条件,
g++ first_make.cpp -o first_make -lpthread就是命令。
命令前面要有一个 Tab 键的缩进。

编写完成后,在控制台输出 “make” 命令即可

2,多文件makefile编写

上一节中,我们只创建且编译了一个 first_make.cpp 的文件
现在我们创建如下几个文件

xdata.h  
xdata.cpp
first_make.cpp  

其中 first_make.cpp 包含了 xdata.h 头文件,xdata.cpp 也包含了 xdata.h 头文件

first_make:first_make.cpp xdata.cpp
	g++ first_make.cpp xdata.cpp -o first_make -lpthread

gcc常用选项
1, -c
仅对源文件进行编译,不链接生成可执行文件。在对源文件进行查错 时,或只需产生目标文件时可以使用该选项。
2,-g
生成调试信息。
3,-0 [ 0,1,2,3 ]
对生成代码使用优化, 中括号中的部分为优化级别,缺省的情况为2级优化,0为不进行优化。注意,采用更高级的优化并不一定得到效率更高的代码。
4,-Idir
在编译源文件时增加一个搜索库文件的额外目录------dir
即include增加一个搜索的额外目录
5,-Ldir
在编译源文件时增加一个搜索库文件的额外目录------dir
6,-llibrary
在编译链接文件时增加一个额外的库,库名为liblibrary.so
7,-w
禁止所有警告
8,-W
允许产生warning类型的警告。
9,-o
生成二进制编码文件

3,引用变量简化makefile

命令格式 含义
AR 库文件维护程序的名称,默认值为ar
AS 汇编程序的名称,默认值为as
CC C编译器的名称,默认值为cc
CPP C预编译器的名称,默认值为 $(CC)-E
CXX C++编译器的名称,默认值为 g++
FC FORTRAN编译器的名称,默认值为f77
RM 文件删除程序的名称,默认值为rm-f
ARFLAGS 库文件维护程序的选项,无默认值
ASFLAGS 汇编程序的选项,无默认值
CFLAGS C编译器的选项,,无默认值
CPPFLAGS C预编译器的选项,无默认值
CXXFLAGS C编译器的选项,无默认值
FFLAGS FORTRAN编译器的选项,无默认值
命令格式 含义
$* 不包含扩展名的目标文件名称
$+ 所有的依赖文件,以空格分开,并以出现的先后的序,可能包含重复的依赖文件
$< 第一个依赖文件的名称
$? 所有时间戳比目标文件晚的依赖文件,并以空格分开
$@ 目标文件的完整名称
$^ 所有不重复的依赖文件,以空格分开
$% 如果目标是归档成员,则该变量表示目标的归档成员名称

用上述表格中的命令对makefile进行简化

原文件
first_make:first_make.cpp xdata.cpp
	g++ first_make.cpp xdata.cpp -o first_make -lpthread
变量简化
# first_make
# $^ 依赖  不重复
# $@  目标
first_make:first_make.cpp xdata.cpp
	$(CXX)   $^  -o   $@   -lpthread

我们已经用了系统自带的变量进行了简化,接下来我们可以自己定义变量并简化。

自定义变量简化
# first_make
# $^ 依赖  不重复
# $@  目标
# @  不显示执行命令
TARGET=first_make

$(TARGET):first_make.cpp xdata.cpp
	@$(CXX)   $^  -o   $@   -lpthread
	echo  "build  success"

其中,TARGET 为自定义的变量。

4,gcc编译动态链接库

我在当前目录下创建三个文件

test.h
test.cpp
main.cpp

我在test.h/test.cpp中写了一些程序,封装了一些接口,我想制作一个动态库,让main.cpp可以通过引用动态库来调用这些接口。

第一步:生成动态库文件(.so)文件
要注意,动态库的名字必须是以lib为开头,.so为后缀

g++  -shared  -fPIC  test.cpp  -o  libtest.so

第二步:编译main.cpp文件,引入动态库生成可执行文件main。
-ltest 表示引入名为 libtest.so的动态库
-L./ 表示动态库所在的路径为 ./
-o main 表示要生成的可执行文件为 main

g++  main.cpp  -ltest  -L./  -o   main

第三步:添加环境变量, ./为动态库所在的路径

export   LD_LIBRARY_PATH=./

第四步:运行可执行文件

./main

5,自动推导目标代码配置和伪目标

自动推导参数设置 CPPFLAGS
.PHONY clean清理 伪目标

有些依赖文件会由系统自动推导出来,比如 .o 文件
例如,依赖项改为 -o ,系统自动推导,就会自动先生成 .o 文件。

# first_make
# $^ 依赖  不重复
# $@  目标
# @  不显示执行命令
TARGET=first_make

$(TARGET):first_make.o xdata.o
	@$(CXX)   $^  -o   $@   -lpthread
	echo  "build  success"

如上段所示,本目录中存在 first_make.cpp 和 xdata.cpp 文件,并不存在 first_make.o xdata.o 文件,那么我们make运行
makefile_第1张图片
我们看到系统自动推导,自动线生成了连个.o文件。

makefile还有一种功能就是自动清理功能,清理的目标我们称之为伪目标。
当我们改动了代码需要重新编译时,就需要线清理之前生成的一些文件

# first_make
# $^ 依赖  不重复
# $@  目标
TARGET=first_make
CXXFLAGS=-I../test_gcc
OBJS=first_make.o xdata.o

$(TARGET):$(OBJS)
	@$(CXX)   $^  -o   $@   -lpthread
clean:
	$(RM) $(OBJS) $(TARGET)
.PHONY: clean *clean
make  clean

你可能感兴趣的:(linux,linux,运维,服务器)