之前实现了 Ubuntu
下 OpenCV2.x
的源码安装 - OpenCV Linux Anaconda 源码安装,并成功在 Anaconda
中应用编译后的 python-opencv
下面实现在 Ubuntu
中完成 OpenCV C/C++
的使用,并学习使用工具 locate / ldconfig / pkg-config / ldd
主要内容:
locate
ldconfig
pkg-config
"Hello World"
ldd
OpenCV
使用locate
参考:
LOCATE(1)
The locate Command
这是一个查找工具,和 find
类似,不过它是通过查找数据库的方式
优点:查找速度快
缺点:1.不保证数据库中的文件是否存在;2.数据库更新限制,不保证能够查找到最新的数据
如果想要查找最新的数据,可以先手动更新数据库
sudo updatedb
最简单的查找方式,直接在 locate
后跟搜索内容即可
locate name
查找文件名,使用参数 -b
locate name -b
想要限制输出路径的条数,使用参数 -n
// 输出 3 条路径
locate name -n 3
locate
支持正则表达式,使用参数 -r, --regexp REGEXP
。
//搜索路径尾部为 opencv 的文件
locate -r opencv$
// 搜索路径头为 opencv 的文件
locate -r ^opencv
也可以执行多命令组合搜索
// 搜索包含 opencv 文件名,同时包含 samples 字符的路径
locate opencv -b | grep samples
ldconfig
参考:
LDCONFIG(8)
3 UNIX / Linux ldconfig Command Examples
ldconfig
用于动态库的实时绑定(configure dynamic linker run-time bindings
)
默认情况下,它将会搜索 /lib
和 /usr/lib
路径下的动态库(在某些 64
位操作系统中,会有 /lib
和 /lib64
的区分)
in the trusted directories, /lib and /usr/lib
(on some 64-bit architectures such as x86-64, lib and /usr/lib are the trusted directories for 32-bit libraries, while /lib64 and /usr/lib64 are used for 64-bit libraries)
当你创建一个新的动态库后,也可以通过创建 .conf
配置文件让 ldconfig
能够查询到
比如在编译 OpenCV
源码时,发现缺少动态库 libiconv.so.2
,通过工具 locate
查找
locate libiconv.so.2 -n 2
/home/zhujian/software/anaconda/anaconda3/envs/openface/lib/libiconv.so.2
/home/zhujian/software/anaconda/anaconda3/envs/openface/lib/libiconv.so.2.6.0
在 /etc/ld.so.conf.d
路径下新建文件 OpenCV.conf
,并输入该路径,也可以直接输入文件的绝对地址
/home/zhujian/software/anaconda/anaconda3/envs/openface/lib
# 或者
/home/zhujian/software/anaconda/anaconda3/envs/openface/lib/libiconv.so.2
也可以将该路径加入到 /etc/ld.so.conf
文件
$ cat /etc/ld.so.conf
// 原先内容
include /etc/ld.so.conf.d/*.conf
最后还需要刷新缓存
sudo ldconfig
使用参数 -p
可以打印出当前缓存中的动态库链接
ldconfig -p | grep libiconv.so.2
libiconv.so.2 (libc6,x86-64) => /home/zhujian/software/anaconda/anaconda3/envs/openface/lib/libiconv.so.2
pkg-config
pkg-config
用于获取安装库的元信息。默认情况下,它会搜索以下文件夹内的 .pc
文件
/usr/lib/pkgconfig
/usr/share/pkgconfig
/usr/local/lib/pkg-config
/usr/local/share/pkgconfig
也可以自己创建 .pc
文件,格式如下:
# Package Information for pkg-config
prefix=/home/zhujian/opencv/install
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir_old=${prefix}/include/opencv
includedir_new=${prefix}/include
Name: OpenCV
Description: Open Source Computer Vision Library
Version: 2.4.13.7
Libs: -L${exec_prefix}/lib -lopencv_calib3d -lopencv_contrib -lopencv_core -lopencv_features2d -lopencv_flann -lopencv_gpu -lopencv_highgui -lopencv_imgproc -lopencv_legacy -lopencv_ml -lopencv_nonfree -lopencv_objdetect -lopencv_ocl -lopencv_photo -lopencv_stitching -lopencv_superres -lopencv_ts -lopencv_video -lopencv_videostab -lrt -lpthread -lm -ldl
Cflags: -I${includedir_old} -I${includedir_new}
将该配置文件所在路径设置到环境变量 PKG_CONFIG_PATH
中
这样就能够搜索到设置的 头文件 路径和 库文件 路径
$ pkg-config --cflags opencv
-I/home/zhujian/opencv/install/include/opencv -I/home/zhujian/opencv/install/include
$ pkg-config --libs opencv
-L/home/zhujian/opencv/install/lib -lopencv_calib3d -lopencv_contrib -lopencv_core -lopencv_features2d -lopencv_flann -lopencv_gpu -lopencv_highgui -lopencv_imgproc -lopencv_legacy -lopencv_ml -lopencv_nonfree -lopencv_objdetect -lopencv_ocl -lopencv_photo -lopencv_stitching -lopencv_superres -lopencv_ts -lopencv_video -lopencv_videostab -lrt -lpthread -lm -ldl
通常情况下,编译程序可使用如下范式
gcc main.c -o main `pkg-config --cflags --libs opencv`
"Hello World"
参考:
Shared libraries with GCC on Linux
Compiling and Linking: Simple Example with gcc
整个工程目录如下:
.
├── foo.cpp
├── footest
├── footest.cpp
├── include
│ └── foo.h
├── lib
│ ├── libfoo.so
│ └── pkgconfig
│ └── foo.pc
└── makefile
首先编译动态库 libfoo.so
,然后编译测试程序并运行
新建文件 foo.h,foo.cpp
和 footest.cpp
// foo.h
#ifndef FOO_H__
#define FOO_H__
#include
#include
void printHello();
#endif
// foo.cpp
#include "foo.h"
void printHello() {
printf("Hello World\n");
}
// footest.cpp
#include
int main(void) {
printHello();
return 0;
}
创建对应的 foo.pc
文件
prefix=/home/zhujian/pkg_config_test
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: foo
Description: 简单的 pc 文件
Version: 1.0
Libs: -L${libdir} -lfoo
Cflags: -I${includedir}
还需要将 .pc
文件的路径设置在环境变量 PKG_CONFIG_PATH
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/home/zhujian/pkg_config_test/pkgconfig
这样可以使用 pkg-config
进行查找
$ pkg-config --cflags --libs foo
-I/home/zhujian/pkg-config-test/include -L/home/zhujian/pkg-config-test/lib -lfoo
makefile
文件如下
INCLUDE=$(shell pkg-config --cflags foo)
LIB=$(shell pkg-config --libs foo)
SOURCE_TEST=footest.cpp
SOURCE_SHARE=foo.cpp
RES_TEST=footest
RES_SHARE=lib/libfoo.so
$(RES_TEST):$(SOURCE_TEST)
gcc $(SOURCE_TEST) $(INCLUDE) $(LIB) -o $(RES_TEST)
share:$(SOURCE_SHARE)
gcc $(SOURCE_SHARE) -fPIC -shared -Iinclude -o $(RES_SHARE)
clean:
rm $(RES_TEST)
编译动态库:
$ make share
gcc foo.cpp -fPIC -shared -Iinclude -o lib/libfoo.so
编译测试程序:
$ make
gcc footest.cpp -I/home/zhujian/pkg-config-test/include -L/home/zhujian/pkg-config-test/lib -lfoo -o footest
最后还需要使用 ldconfig
配置动态库(或者配置变量 LD_LIBRARY_PATH
),运行测试程序
$ ./footest
Hello World
ldd
参考:LDD(1)
工具 ldd
用于打印出程序的共享库依赖(print shared object dependencies
)
$ ldd footest
linux-vdso.so.1 => (0x00007fffe9fdb000)
libfoo.so => /home/zhujian/pkg-config-test/lib/libfoo.so (0x00007f549f0e5000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f549ed1b000)
/lib64/ld-linux-x86-64.so.2 (0x000056418b8fd000)
OpenCV
使用
之前已完成了 OpenCV Linux Anaconda 源码安装,现在实现一个 C++
的图像显示 demo
OpenCV
源码安装完成后自动会生成一个 opencv.pc
文件
$ locate opencv.pc
/home/zhujian/opencv/build/unix-install/opencv.pc
/home/zhujian/opencv/install/lib/pkgconfig/opencv.pc
将路径加入到环境变量 PKG_CONFIG_PATH
中
测试代码如下:
#include
#include
using namespace std;
using namespace cv;
int main(void) {
Mat img = imread("lena.jpg");
imshow("img", img);
waitKey(0);
return 0;
}
makefile
文件如下:
INCLUDE=$(shell pkg-config --cflags opencv)
LIB=$(shell pkg-config --libs opencv)
SOURCE=img.cpp
RES=img
$(RES):$(SOURCE)
g++ $(SOURCE) $(INCLUDE) $(LIB) -o $(RES)
clean:
rm $(RES)
编译,链接生成可执行程序 img
$ make
g++ img.cpp -I/home/zhujian/opencv/install/include/opencv -I/home/zhujian/opencv/install/include -L/home/zhujian/opencv/install/lib -lopencv_calib3d -lopencv_contrib -lopencv_core -lopencv_features2d -lopencv_flann -lopencv_gpu -lopencv_highgui -lopencv_imgproc -lopencv_legacy -lopencv_ml -lopencv_nonfree -lopencv_objdetect -lopencv_ocl -lopencv_photo -lopencv_stitching -lopencv_superres -lopencv_ts -lopencv_video -lopencv_videostab -lrt -lpthread -lm -ldl -o img
/usr/bin/ld: warning: libpcre.so.1, needed by //home/zhujian/software/anaconda/anaconda3/lib/libglib-2.0.so.0, not found (try using -rpath or -rpath-link)
问题
anaconda3/lib/libstdc++.so.6: error adding symbols: DSO missing from command line
参考:libstdc++: DSO missing from command line
使用 g++ 代替 gcc