Linux locate ldconfig pkg-config ldd 以及 OpenCV C++库的使用

Posted 编号1993

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux locate ldconfig pkg-config ldd 以及 OpenCV C++库的使用相关的知识,希望对你有一定的参考价值。

之前实现了 UbuntuOpenCV2.x 的源码安装 - OpenCV Linux Anaconda 源码安装,并成功在 Anaconda 中应用编译后的 python-opencv

下面实现在 Ubuntu 中完成 OpenCV C/C++ 的使用,并学习使用工具 locate / ldconfig / pkg-config / ldd


主要内容:

  1. locate
  2. ldconfig
  3. pkg-config
  4. 编译,链接,运行 "Hello World"
  5. ldd
  6. 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.cppfootest.cpp

// foo.h
#ifndef FOO_H__
#define FOO_H__

#include <stdio.h>
#include <stdlib.h>

void printHello();

#endif

// foo.cpp
#include "foo.h"

void printHello() 
    printf("Hello World\\n");


// footest.cpp
#include <foo.h>

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 <iostream>
#include <opencv2/opencv.hpp>
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

以上是关于Linux locate ldconfig pkg-config ldd 以及 OpenCV C++库的使用的主要内容,如果未能解决你的问题,请参考以下文章

linux中ldconfig的使用介绍

Linux命令——ldconfig

linux下运行ldconfig命令后,提示“XX不是符号链接“是啥意思

markdown gcc make ldconfig等,linux构建工具

linux ldconfig命令的作用(Linker Configuration 链接器配置)更新动态链接库(共享库)的链接器程序缓存

linux下,一些关于动态库的问题: