概述:
上一篇我们已经将onvif需要使用的所有.h和.cpp文件全部放在了ONVIFAPI这个文件夹。即:
1 生成动态库
我们提供两种方法,一种是CMake,另一种是makefile。
1.1 CMake(个人推荐,因为比较简单)。
下面我们将编写CMake对上面文件夹内的所有文件生成动态库。
这是我的,已经成功生成了动态库,具体自己需要改一下对应的资源和openssl路径即可。并且此后使用动态库时无需再链接openssl,因为再生成动态库时可以包含了openssl库。
生成动态库时的CMake文件。
cmake_minimum_required(VERSION 2.6)
project(ONVIF)
#打印
message(STATUS "binary dir: " ${PROJECT_BINARY_DIR})
message(STATUS "source dir: " ${PROJECT_SOURCE_DIR})
# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(./ONVIFAPI/ DIR_SRCS)
set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -g -ggdb -w -Wall -std=c++11 -fPIC -lpthread -lssl -lcrypto -DWITH_OPENSSL -DWITH_NONAMESPACES ")
#OPENSSL
INCLUDE_DIRECTORIES(/home/tyy/mycode/OnvifGetInfo/openssl/include)
LINK_DIRECTORIES(/home/tyy/mycode/OnvifGetInfo/openssl/lib)
# 生成链接库
add_library(Onvif_Client SHARED ${DIR_SRCS})
生成的onvif动态库。
链接项目时的CMake文件,可以看到,针对于上一篇,完全不用再链接openssl库,只需要添加头文件和链接动态库即可。
#1.cmake verson,指定cmake版本
cmake_minimum_required(VERSION 2.8)
#2.project name,指定项目的名称,一般和项目的文件夹名称对应
PROJECT(OnvifGetInfo)
#打印相应变量信息
message(STATUS "PROJECT_BINARY_DIR: ${PROJECT_BINARY_DIR}")
message(STATUS "PROJECT_SOURCE_DIR: ${PROJECT_SOURCE_DIR}")
#设置Cmake的调试类型为Debug,必须设置该行才能gdb调试
#3.工程需要的源文件,可以包含源文件目录下的所有源文件,或者set想要的源文件编译
AUX_SOURCE_DIRECTORY(./src/ SRC_LIST)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_BUILD_TYPE Debug)
#set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -g -ggdb -w -Wall -std=c++11 -fPIC -lssl -lcrypto -DWITH_OPENSSL -DWITH_NONAMESPACES ")
set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -g -ggdb -w -Wall -std=c++11 -fPIC")
message(STATUS "CMAKE_CXX_FLAGS_DEBUG:${CMAKE_CXX_FLAGS_DEBUG}")
#4.包含头文件目录,链接库目录,多个以空格隔开,关键字不区分大小写
#INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/openssl/include)
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/onvif/onvif_client_lib/include)
#LINK_DIRECTORIES(${PROJECT_SOURCE_DIR}/openssl/lib/)
LINK_DIRECTORIES(${PROJECT_SOURCE_DIR}/onvif/onvif_client_lib/lib)
#AUX_SOURCE_DIRECTORY(./FrameSrc/ SRC_LIST)
#AUX_SOURCE_DIRECTORY(./ONVIFAPI/ SRC_LIST)
#5.添加要编译生成的可执行文件
ADD_EXECUTABLE(${PROJECT_NAME} ${SRC_LIST})
#6.添加可执行文件所需要的链接库名,参1为生成的可执行文件名
# TARGET_LINK_LIBRARIES(${PROJECT_NAME} crypto)
# TARGET_LINK_LIBRARIES(${PROJECT_NAME} ssl)
MESSAGE(STATUS "PROJECT_NAME is: ${PROJECT_NAME}")
#onviflib
TARGET_LINK_LIBRARIES(${PROJECT_NAME} Onvif_Client)
MESSAGE(STATUS "PROJECT_NAME is: ${PROJECT_NAME}")
成功编译出项目的可执行文件。整个ONVIF的源代码和动态库框架到此结束,此后我们只需要思考编码的流程即可。
1.2 makefile
这种方法相对CMake比较难,因为比较抽象。
- 1)首先将ONVIFAPI的.h和.cpp(包括wsdd.nsmap)分类,各自新建一个include和src目录把对应的头文件和.cpp文件放进去,再创建一个obj目录。
- 2)编写makefile。注释已经很清楚了。
LIB_NAME = libOnvif_Client.so
COMPOLE_ARGS = -fPIC -DWITH_OPENSSL # 编译参数,DWITH_OPENSSL必须要加,否则链不是openssl
LINK_ARGS = -shared # 链接参数
INCLUDE = ./include ../../../openssl/include/
LIBDIR = ../../../openssl/lib
LIB = -lcrypto -lssl
SRC = $(wildcard ./src/*.cpp) # 此时SRC为./src/add.cpp ...
OBJ = $(patsubst ./src/%.cpp, ./obj/%.o, $(SRC)) # %=add,OBJ=./obj/add
$(info $(SRC)) # 打印变量SRC和OBJ
$(info $(OBJ))
ALL:$(LIB_NAME) # 目标规则。makefile应从最低的规则往上看直至ALL结束。
$(LIB_NAME):$(OBJ) # 注意此规则的命令行(即本行的下一行),输入参数为$(OBJ),即所有的.o文件,而不是$<依次取单个.o文件
g++ $(LINK_ARGS) $(OBJ) -o $@ -L $(LIBDIR) $(LIB)
#每一条规则必须执行完才能执行下一条规则,例如有3个.c文件,必须生成.o才往上执行上面的规则
# $(OBJ):$(SRC),规则必须带%,不能只带变量,否则$<失效,每次的值固定为某个源文件
./obj/%.o:./src/%.cpp
g++ -c $(ARGS) $< -o $@ -I $(INCLUDE)
#删除.o文件
clean:
-rm -rf $(OBJ)
# 防止执行make clean当前目录有clean文件名而不能成功删除
.PHONY:clean ALL
- 3)运行可以看到结果,同样成功生成动态库。我猜应该也不用再链接openssl,因为和上面应该一样,已经测试过了。
对上面makefile稍微优化一下。
LIB_NAME = libOnvif_Client.so
COMPOLE_ARGS = -fPIC -DWITH_OPENSSL # 编译参数,DWITH_OPENSSL必须要加,否则链不是openssl
LINK_ARGS = -shared # 链接参数
COMPOLE_TYPE = g++ # 编译器类型
INCLUDE = ./include ../../../openssl/include/ # 编译时需要的头文件
LIBDIR = ../../../openssl/lib # 链接时需要的库目录
LIB = -lcrypto -lssl # 链接时需要的库
SRC = $(wildcard ./src/*.cpp) # 此时SRC为./src/add.cpp ...
OBJ = $(patsubst ./src/%.cpp, ./obj/%.o, $(SRC)) # %=add,OBJ=./obj/add
ALL:$(LIB_NAME) # 目标规则。makefile应从最低的规则往上看直至ALL结束。
$(LIB_NAME):$(OBJ) # 注意此规则的命令行(即本行的下一行),输入参数为$(OBJ),即所有的.o文件,而不是$<依次取单个.o文件
$(COMPOLE_TYPE) $(LINK_ARGS) $(OBJ) -o $@ -L $(LIBDIR) $(LIB)
#每一条规则必须执行完才能执行下一条规则,例如有3个.c文件,必须生成.o才往上执行上面的规则
# $(OBJ):$(SRC),规则必须带%,不能只带变量,否则$<失效,每次的值固定为某个源文件
./obj/%.o:./src/%.cpp
$(COMPOLE_TYPE) -c $(ARGS) $< -o $@ -I $(INCLUDE)
#删除.o文件
clean:
-rm -rf $(OBJ)
# 防止执行make clean当前目录有clean文件名而不能成功删除
.PHONY:clean ALL
补充:对于arm架构的平台,makefile可能不会太通用,但是CMakeLists是没有问题的。并且需要注意,openssl的版本也是需要arm架构的,若是x86版本的动态库的话,可能就会存在报错。