选项说明:
-Wall 选项 :可以打印出编译时所有的错误或者警告信息。变量没有初始化,类型不匹配,没有使用的变量或者类型转换错误等警告提示。
-fPIC 选项:适用于动态连接,作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code), 则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意 位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。
-fpermissive选项:用这个选项,可以兼容一些老的语法,但是一些语法错误也会被忽略。该选项需慎重使用,因为会降低对于代码检查的严格性。
-DDEBUG :相当于定义了宏DEBUG,代码中可以用#ifdef DEBUG来控制调试输出信息等。可以用-D加名字定义一些用到的宏定义。
-I 选项:(i的大写)编译选项(准确的是说是预处理选项CFLAGS或者CPPFLAGS中指定),用来指定预处理时查找头文件的范围的。
-L选项 :链接选项(LDFLAGS中指定),用来告诉链接器到哪个路径下面去找动态链接库。
-l 选项: (L的小写)链接选项(LDFLAGS中指定),用来指定链接额外的库(譬如我们用到了uuid,就用-luuid,链接器就会去链接libuuid.so)
-shared :创建动态链接库使用的选项。
自定变量:
$@:表示规则中的目标文件集。在模式规则中,如果有多个目标,那么, $@ 就是匹配于目标中模式定义的集合。
$% :仅当目标是函数库文件时,表示规则中的目标成员名。例如,如果一个目标是 foo.a(bar.o),那么, $% 就是 bar.o , $@ 就是 foo.a 。如果目标不是函数库文件(Unix 下是 .a , Windows下是 .lib ),那么,其值为空
$< :依赖目标中的第一个目标名字。如果依赖目标是以模式(即 % )定义的,那么 $< 将是符合模式的一系列的文件集。注意,其是一个一个取出来的。
$? :所有比目标新的依赖目标的集合。以空格分隔。
$^ :所有的依赖目标的集合。以空格分隔。如果在依赖目标中有多个重复的,那个这个变量会去除重复的依赖目标,只保留一份。
$+ :所有依赖目标的集合,不去除重复的依赖目标。
# flags
CC = gcc
CXX = g++
CXXFLAGS = -Wall -fPIC -std=c++11 -fpermissive
LDFLAGS = -shared
# args
RELEASE = 0 #控制release还是debug版本 0代表debug版本 ,1代表release版本
BITS = 64 #64还是32位
# [args] 程序位数. 32代表32位程序, 64代表64位程序, 其他默认. make BITS=32.
ifeq ($(BITS),32)
CXXFLAGS += -m32
#需用到的一些第三方库的路径
LIB_PATH = ../lib
DVR_LIB_PATH = ../../../DeviceSdk/ViskingNVR/netsdk/
else
CXXFLAGS += -m64
#需用到的一些第三方库的路径
LIB_PATH = ../lib/x64
DVR_LIB_PATH = ../../../DeviceSdk/ViskingNVR/linux_NetSdk_x64/NetSdk/lib/
endif
OUTPUT = $(LIB_PATH)/libVisking.so #最终生成的动态库
# [args] 生成模式. 1代表debug模式, 0代表release模式. make RELEASE=0.
#-O0: 不做任何优化,这是默认的编译选项
#-O2: O2优化增加了编译时间的基础上,提高了生成代码的执行效率。
#-O3:包含了O2所有的优化的基础上,增加了更多的优化。
#-ggdb 为GDB 生成专用的更为丰富的调试信息,但是,此时就不能用其他的调试器来进行调试了
#-DNDEBUG 定义NDEBUG宏定义
ifeq ($(RELEASE),0)
# release
CXXFLAGS += -ggdb -O0 -gdwarf-2
else
# debug
CXXFLAGS += -O3 -DNDEBUG
endif
# files 用的一些头文件的路径
INCLUDES = -I./
INCLUDES += -I./../../
INCLUDES += -I../../../include
ifeq ($(BITS),32)
INCLUDES += -I../../../DeviceSdk/ViskingNVR/netsdk/
else
INCLUDES += -I../../../DeviceSdk/ViskingNVR/linux_NetSdk_x64/NetSdk/
endif
ifeq ($(RELEASE),0)
# release
LIB_DIR = -L$(LIB_PATH)
LIB_DIR += -L$(DVR_LIB_PATH)
LIBS += -lvsksdk #链接用到的动态库libvsksdk.so
else
# debug
LIB_DIR = -L$(LIB_PATH)
LIB_DIR += -L$(DVR_LIB_PATH)
LIBS += -lvsksdk #链接用到的动态库libvsksdk.so
endif
#SRCS := $(wildcard *.cpp) 表示获取当前目录下的c文件集,放在变量SRCS中
#OBJS := $(SRCS:%.cpp=%.o) 表示将对应的c文件名转为o文件后放在下面的OBJS变量中
SRCS = $(wildcard ./*.cpp)
OBJS := $(SRCS:%.cpp=%.o)
#例如 用到h264的第三方库
H264SRCS := $(wildcard ../../../thirdparty/H264BSAnalysis/*.cpp)
H264OBJS := $(H264SRCS:%.cpp=%.o)
.phony : all $(OUTPUT) $(OBJS)
all: $(OUTPUT)
@echo "========end"
$(OUTPUT) : $(OBJS) $(H264OBJS)
$(CXX) $(CXXFLAGS) $(LDFLAGS) $(LIB_DIR) $(LIBS) $(OBJS) $(H264OBJS) -o $(OUTPUT)
$(OBJS):%.o:%.cpp
@echo "=================VISKING"
$(CXX) $(CXXFLAGS) -c $< -o $@ $(INCLUDES)
$(H264OBJS):%.o:%.cpp
@echo "=================H264"
$(CXX) $(CXXFLAGS) -c $< -o $@ $(INCLUDES)
clean :
rm -rf $(OBJS) $(OUTPUT)
linux终端输入make,最终生成libVisking.so动态库文件。