下方makefile的书写针对的是Opencv2.4.9.1版本的动态库调用、OpenCV3.3.0动态库调用和OpenCV3.4.1的静态库调用,别问为啥,感觉都是泪,其实做研发、工程、产线这个当中存在很多问题,例如最简单的就是使用版本不一致的问题,这个很耗时耗力。
举个例子,LZ安装的都是Tensorflow1.14版本,公司写的接口全部是1.13版本的,就会出现LZ训练好了模型,因为tf的版本不一致而可能导致两个问题,1.LZ需要使用tf1.13版本重新训练,2.后端需要开发tf1.14版本对应接口,其实在一开始就沟通好,或者固定好,感觉这样会更加有效一些,对于opencv更是如此,接口与接口的差距还挺大的,版本也有很多,如果研发、后端、产线每个使用的都是不同的版本,在实际应用当中,仅仅是版本冲突不匹配,就会出现各种各样的问题。
好了,下面进入正题,在实际使用的时候,为了保护源代码的安全,经常会将代码封装成动态库.so格式或者静态库.a格式,然后只要直接调用对应接口就行了,LZ也要把自己写的代码封装一下,平时在自己的小笔记本上跑惯了,基本上不需要生成对应的动态库静态库,但现在不一样,所以还是需要生成对应库的。
下面主要是LZ使用的OpenCV是自己文件下的,而不是以前使用的系统环境中的OpenCV,所以还是摸索了一阵。
1. 对OpenCV2.4.9.1版本的动态库链接代码
#获取工程的根目录的全路径
SOURCE_ROOT = $(shell pwd)
SOURCE = main.cpp
OBJS = test.o
TARGET = test
# compile and lib parameter
CC = g++
# 对应需要链接的库
LIBS += -lopencv_core -lopencv_imgproc -lopencv_calib3d -lopencv_videostab -lopencv_ml -lopencv_objdetect
LIBS += -lopencv_features2d -lopencv_flann -lopencv_highgui -lopencv_imgproc
LIBS += -lopencv_photo -lopencv_stitching -lopencv_superres -lopencv_video
LIBS += -ldc1394 -lraw1394 -lm
# 包含对应的文件的路径
LDFLAGS += -L$(SOURCE_ROOT)/lib -L$(SOURCE_ROOT)/lib/opencv
INCLUDE := -I $(SOURCE_ROOT)/include -I $(SOURCE_ROOT)/interface
INCLUDE += -I $(SOURCE_ROOT)/ -I $(SOURCE_ROOT)/inc -I $(SOURCE_ROOT)/inc/opencv
CFLAGS += -Wall -O -fPIC
CXXFLAGS += -std=gnu++11
all: $(TARGET)
# link
$(TARGET):$(OBJS)
$(CC) -o $@ $^ $(LDFLAGS) $(LIBS) $(STATIC_LIBS) $(CFLAGS) $(INCLUDE) $(CXXFLAGS)
#compile
$(OBJS):$(SOURCE)
$(CC) $(CFLAGS) $(INCLUDE) $(CXXFLAGS) -o $@ -c $^
# clean
clean:
rm -fr *.o
rm -fr $(TARGET)
2. 对OpenCV3.3.0版本的动态库链接代码
SOURCE = main.cpp
OBJS = test.o
TARGET = test
OBJS_DEBUG = test_debug.o
TARGET_DEBUG = test_debug
# compile and lib parameter
CC = g++
LIBS += -lopencv_core -lopencv_imgproc -lopencv_calib3d -lopencv_videostab -lopencv_ml -lopencv_objdetect
LIBS += -lopencv_dnn -lopencv_features2d -lopencv_flann -lopencv_highgui -lopencv_imgcodecs
LIBS += -lopencv_photo -lopencv_shape -lopencv_stitching -lopencv_superres -lopencv_video -lopencv_videoio
LIBS += -ldc1394 -lraw1394 -lm -ldl
#STATIC_LIBS =
LDFLAGS += -L./lib -L./lib/opencv
LDFLAGS += -L../boost/stage/lib -pthread
INCLUDE += -I ./ -I ./inc -I ./inc/opencv -I ./
CFLAGS += -Wall -O -fPIC
CXXFLAGS += -std=gnu++11
all: $(TARGET) $(TARGET_DEBUG)
# link
$(TARGET):$(OBJS)
$(CC) -o $@ $^ $(LDFLAGS) $(LIBS) $(STATIC_LIBS) $(CFLAGS) $(INCLUDE) $(CXXFLAGS)
$(TARGET_DEBUG):$(OBJS_DEBUG)
$(CC) -o $@ $^ $(LDFLAGS) $(LIBS) $(STATIC_LIBS) $(CFLAGS) $(INCLUDE) $(CXXFLAGS) -g
#compile
$(OBJS):$(SOURCE)
$(CC) $(CFLAGS) $(INCLUDE) $(CXXFLAGS) -o $@ -c $^
$(OBJS_DEBUG):$(SOURCE)
$(CC) $(CFLAGS) $(INCLUDE) $(CXXFLAGS) -g -o $@ -c $^
# clean
clean:
rm -fr *.o
rm -fr $(TARGET) $(TARGET_DEBUG)
~
3. 对OpenCV3.4.1版本的静态库链接代码
SOURCE = main.cpp
OBJS = test.o
TARGET = test
# compile and lib parameter
CC = g++
LIBS += -lopencv_highgui -lopencv_imgcodecs -lopencv_calib3d -lopencv_imgproc -lopencv_flann -lopencv_core
LIBS += -lcairo -lgtk-3 -lgdk_pixbuf-2.0 -lgobject-2.0 -lzlib
LIBS += -llibjasper -lIlmImf -lippiw -llibjpeg -llibpng -llibtiff -lippicv -llibwebp -littnotify -lz
LIBS += -ldc1394 -lraw1394 -lm -ldl
#STATIC_LIBS =
LDFLAGS += -L./lib -L./lib/opencvLib
LDFLAGS += -L../boost/stage/lib -pthread
INCLUDE += -I ./ -I ./inc -I ./inc/opencv -I ./
CFLAGS += -Wall -O -fPIC
CXXFLAGS += -std=gnu++11
all: $(TARGET) $(TARGET_DEBUG)
# link
$(TARGET):$(OBJS)
$(CC) -o $@ $^ $(LDFLAGS) $(LIBS) $(STATIC_LIBS) $(CFLAGS) $(INCLUDE) $(CXXFLAGS)
#compile
$(OBJS):$(SOURCE)
$(CC) $(CFLAGS) $(INCLUDE) $(CXXFLAGS) -o $@ -c $^
# clean
clean:
rm -fr *.o
rm -fr $(TARGET) $(TARGET_DEBUG)
注意几个问题
- OpenCV3.4.1是业务给我的静态库,结果LZ一直编译不出来,结果发现他少给了LZ一个库,结果LZ各种百度,哭死。。。
OpenCV还会依赖部分第三方库,在编译的时候在opencv3-4.1/build/3rdparty/lib文件夹下,这些静态库都要一起放到opencv的lib下
libippiw.a
libittnotify.a
liblibjasper.a
liblibjpeg.a
liblibprotobuf.a
liblibwebp.a
libzlib.a
下面是LZ折腾了一下午的问题:
./lib/opencvLib/liblibpng.a(pngrutil.c.o): In function `png_inflate_claim':
pngrutil.c:(.text.png_inflate_claim+0x176): undefined reference to `inflateValidate'
./lib/opencvLib/liblibpng.a(pngrutil.c.o): In function `png_decompress_chunk.constprop.4':
pngrutil.c:(.text.png_decompress_chunk.constprop.4+0x267): undefined reference to `inflateValidate'
collect2: error: ld returned 1 exit status
make: *** [test] Error 1
结果各种百度都是无法解决,最后发现业务少给了一个libzlib.a的库,浪费了大半天时间。。。(百度、google大多数给出都是版本不匹配的问题,要重新下载zlib,然后进行编译,LZ总感觉不是这个问题,最后找到缺库的问题)
-
库与库之间是存在先后顺序的,之前出现各种库找不到,undefined reference:之类的就是链接库的顺序不对
-
链接库的时候还要注意权限问题,有些时候链接不上库是没给到权限