一、动态库makefile编写
TARGET = libD_lib.so
OBJS = Test_d_lib.o
LDFLAGS = -shared
CXXFLAGS = -fPIC
$(TARGET):$(OBJS)
$(CXX) $(LDFLAGS) $^ -o $@
clean:
$(RM) $(TARGET) $(OBJS)
.PHONY: clean
(1)动态链接库命名规范
TARGET 是 目标文件,我这里的命名是libTest_d_lib.so
注意:动态链接库的目标文件有自己的命名规范,一定要以lib开头,再在结尾加上.so(Linux环境下,window环境下dll后缀表示动态库),说明是动态链接库文件
(2)依赖项
OBJS依赖项是自己前面写好的文件,这里是.o文件是因为Makefile 会自动推断出要生成main.o文件,并且知道需要使用 C ++编译器(通常是g++)将main.cpp编译成main.o。
如果这里的依赖项是.cpp会报错噢!!!!因为库是在最后一步链接的时候链接进源文件,所以依赖项得是.o文件
(3)设置链接器选项
LDFLAGS 是用于设置链接器选项的环境变量
-shared说明需要链接器将目标文件链接成一个动态库
CXXFLAGS 是用于设置c++编译器选项的环境变量
-fPIC 说明将生成位置无关代码
这个-fPIC对共享库的创建非常重要!!!!
位置无关代码可以在内存中的任意位置正确执行,当创建共享库时,使用位置无关代码可以使库在不同的地址空间被加载和使用,增加了代码的可移植性和灵活性。
然后是代码区,$^和$@已经在上一篇中讲过,这里就不再啰嗦啦
(4)clean伪目标
clean是几乎每一个makefile都需要的重要的部分,用于在每次make之前清除上一次的文件,在make之前用一次make clean就可以做到不用再一步步去手动清除
这里的RM默认值为 rm 后面跟TAGRGET和OBJS即可以删除所有目标项和依赖项
注意:因为这里的依赖项是.o, 是由.cpp自动推导出来的,所以可以删除依赖项,大家注意别在写的时候不小心把.cpp项也删掉了!!
最下面那个.PHONY用于声明一个伪目标
伪目标并不是真正的文件名,只是一个标签。它的主要作用是避免与同名的文件冲突,并且无论同名文件是否存在,指定的伪目标会被当成命令来执行
二、静态库makefile编写
TARGET = libTest_s_lib.a
OBJS = Test_s_lib.o
TARGET := $(TARGET)
$(TARGET):$(OBJS)
$(AR) -cvr $@ $^
clean:
$(RM) $(TARGET) $(OBJS)
.PHONY: clean
(1)静态库命名规范
我这里的目标项是libTest_s_lib
和动态库一样,静态库也要在前面加上lib,并以.a为后缀(在window环境下,静态库的后缀是.lib)
(2)AR变量和参数
AR是一个预定义变量,默认值是ar,
ar:是 Unix/Linux 系统中的归档工具,用于创建和维护静态库。
后面跟的参数-cvr的意思:
-c:创建一个新的归档文件。如果指定的归档文件已存在,它将被覆盖。
-v:显示详细信息,即在执行命令时输出处理的文件名等信息。
-r:向归档文件中添加文件。如果要添加的文件已经存在于归档中,新的文件将替换旧的文件。
三、调用静态库和动态库
随便写个.cpp来调用前面写的库
(1)main.cpp的makefile编写
TARGET = Test_lib
OBJS = Test_lib.o
CXXFLAGS = -I../Test_d_lib -I../Test_s_lib
LDFLAGS = -L../Test_d_lib -L../Test_s_lib
LIBS = -lD_lib -lpthread -lTest_s_lib
$(TARGET):$(OBJS)
$(CXX) $^ -o $@ $(LDFLAGS) $(LIBS)
clean:
$(RM) $(TARGET) $(OBJS)
.PHONY: clean
(2)设置链接器选项
跟前面一样,
CXXFLAGS 是用于设置c++编译器选项的环境变量
这里跟的 -I (大写的i)表示头文件的搜索路径
LDFLAGS 是一个用于指定链接器选项的变量
后面的 -L 用于指定链接库的搜索路径
(3)链接库
LISB是自己定义的变量 ,用于指定链接库。
-l(小写的L)用于链接库文件的选项。链接库时直接在-l(小写L)后面跟自己的库,
注意:这时候要去掉库名字前面的lib!!!
比如我这里的就是-lTest_s_lib,而不是-llibTest_s_lib