Linux下开源库的使用(共享库文件头文件配置全局搜索)(WSL)
关键词
g++; vscode; c++; pkg-config; include; lib; linux; .pc; tasks.json; launch.json; WSL
前言
需求及手动解决方法
问题
很多时候需要使用别人开源的东西 for C/C++,我们的目标是使用别人的include
和链接库!这俩需求一般都包含在下载下来的文件,这里以下载好的onnxruntime-linux-x64-1.4.0.tgz
为例(这是onnx在linux上的发行版)。
解压之后文件结构如下:
onnxruntime-linux-x64-1.4.0$ tree
.
├── C_API.md
├── GIT_COMMIT_ID
├── LICENSE
├── Privacy.md
├── README.md
├── ThirdPartyNotices.txt
├── VERSION_NUMBER
├── include
│ ├── cpu_provider_factory.h
│ ├── cuda_provider_factory.h
│ ├── onnxruntime_c_api.h
│ ├── onnxruntime_cxx_api.h
│ └── onnxruntime_cxx_inline.h
└── lib├── libonnxruntime.so -> libonnxruntime.so.1.4.0└── libonnxruntime.so.1.4.0
- 其中
lib
问价下存储着我们的lib文件 - 然后
include
下存储着所有头文件
TIPS:C++动态库的使用、C++编译及执行过程
下面是原始的使用方法
pwd
mkdir test && cd test
touch test.cpp && vim ./test.cpp
然后输入
#include <iostream>
#include <onnxruntime_cxx_api.h>int main() {Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "test"); // 测试return 0;
}
用vscode打开会方便一些!
可以看到,此时搜索不到onnxruntime
for CPP
g++编译及vscode配置
设置c_cpp_properties.json
中的includePath
到onnxruntime的include
文件夹。
{"configurations": [{"name": "Linux","includePath": ["${workspaceFolder}/**", "/home/cola/cola/ColaMain/ColaStore/cache/onnxruntime-linux-x64-1.4.0/include"],"defines": [],"compilerPath": "/usr/bin/gcc","cStandard": "gnu17","cppStandard": "gnu++14","intelliSenseMode": "linux-gcc-x64"}],"version": 4
}
编译的时候需要用到链接库文件,所以需要修改tasks.json
来编译!
先用g++
在命令行编译!
g++ test.cpp -o test -I ../include/ -L ../lib/ -lonnxruntime
./test # 输出
./test: error while loading shared libraries: libonnxruntime.so.1.4.0: cannot open shared object file: No such file or directory
- 编译成功了,但是运行的时候失败,因为没有找到动态库
libonnxruntime.so.1.4.0
!
ldd ./testlinux-vdso.so.1 (0x00007ffff7487000)libonnxruntime.so.1.4.0 => not foundlibstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f9cf06c0000)libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f9cf06a0000)libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9cf04a0000)libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f9cf0351000)/lib64/ld-linux-x86-64.so.2 (0x00007f9cf08c2000)
- 直接复制到当前文件夹,即可!
- 好像没起作用
- 重新编译,编译的时候指定动态库搜索路径
g++ test.cpp -o test -I ../include/ -L ../lib/ -lonnxruntime -Wl,-rpath=../lib
./test # 输出成功
cola
然后设置vscode的tasks.json
原始如下:
- 当不包含特殊库且单个文件时,这样是可以的!
{"version": "2.0.0","tasks": [{"type": "cppbuild","label": "C/C++: g++ 生成活动文件","command": "/usr/bin/g++","args": ["-fdiagnostics-color=always","-g","${file}","-o","${fileDirname}/${fileBasenameNoExtension}"],"options": {"cwd": "${fileDirname}"},"problemMatcher": ["$gcc"],"group": {"kind": "build","isDefault": true},"detail": "编译器: /usr/bin/g++"}]
}
修改args
如下
- 可以看到,这和命令行编译时的参数是一一对应的!
"args": ["-fdiagnostics-color=always","-g","test.cpp","-I","../include","-L", "../lib", "-lonnxruntime", "-o","${fileDirname}/${fileBasenameNoExtension}", "-Wl,-rpath=../lib",
],
执行该任务后,可以生成和在命令行一样的输出文件!
至此,我们就明确了要是用别人的一个库,需要怎么做
需求
明确我们要使用的主角仅仅是
include
下的头文件和lib
下的库文件如果我们需要在其他很多地方使用库和头文件,则每次都需要自己写一大段命令行来用g++编译
这样很不方便呀!
需求
- 如何才能让
onnx
这种别人写好的库像标准库那样供我们使用呢!
明确
- Linux环境下的include路径
- Linux环境下的动态库搜索路径
解决方案1:pkg-config
- 特点:专门用于用命令行编译的时候使用!
- 缺点:依然没有设置其能被全局
include
头文件和全局使用lib- 解决方案2可以解决!
类比
编译opencv
时,需要加上pkg-config --cflags --libs opencv4
,这是做啥呢!
echo `pkg-config --cflags --libs opencv4`# 输出
-I/usr/local/include/opencv4 -L/usr/local/lib -lopencv_gapi -lopencv_highgui -lopencv_ml -lopencv_objdetect -lopencv_photo -lopencv_stitching -lopencv_video -lopencv_calib3d -lopencv_features2d -lopencv_dnn -lopencv_flann -lopencv_videoio -lopencv_imgcodecs -lopencv_imgproc -lopencv_core
- 可以看见,这其实就是将我们要在g++后面添加的参数,进行了设置!
所以,类比opencv
的,我们可以自己写一个config
,然后像这样使用!
- (38条消息) pkg-config 详解_newchenxf的专栏-CSDN博客_pkg-config
原理
- 定义一个
xxx.pc
文件,那么pkg-config -xxx
就可以获得全部信息啦! - 注:
pkg-config
是一个命令
pkg-config
的信息来自于两个地方:
- 第一种:取系统的/usr/lib下的所有*.pc文件。
- 第二种:PKG_CONFIG_PATH环境变量所指向的路径下的所有*.pc文件。
添加自己的.pc
文件,两种方式:
把你的pc文件,直接放到
/usr/lib/…
默认路径下。把你的pc文件的路径写到
PKG_CONFIG_PATH
环境变量里。写自己的
.pc
文件
参考opencv
的
# Package Information for pkg-configprefix=/usr/local
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include/opencv4Name: OpenCV
Description: Open Source Computer Vision Library
Version: 4.5.5
Libs: -L${exec_prefix}/lib -lopencv_gapi -lopencv_highgui -lopencv_ml -lopencv_objdetect -lopencv_photo -lopencv_stitching -lopencv_video -lopencv_calib3d -lopencv_features2d -lopencv_dnn -lopencv_flann -lopencv_videoio -lopencv_imgcodecs -lopencv_imgproc -lopencv_core
Libs.private: -ldl -lm -lpthread -lrt
Cflags: -I${includedir}
写onnx的!
# Package Information for pkg-configprefix=/home/cola/cola/ColaMain/ColaStore/cache/onnxruntime-linux-x64-1.4.0/lib
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/includeName: onnxruntime
Description: onnxruntime library made by cola in 2022年2月13日
Version: 1.4.0
Libs: -L${libdir} -lonnxruntime
Cflags: -I${includedir}
添以下到~/.bashrc
,然后再执行source ~/.bashrc
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/home/cola/cola/ColaMain/ColaStore/cache/Cola_pkgconfig
export PKG_CONFIG_PATH
测试
pkg-config onnxruntime --cflags --libs# 输出
-I/home/cola/cola/ColaMain/ColaStore/cache/onnxruntime-linux-x64-1.4.0/lib/include -L/home/cola/cola/ColaMain/ColaStore/cache/onnxruntime-linux-x64-1.4.0/lib/lib -lonnxruntime
编译运行
g++ test.cpp -o test `pkg-config onnxruntime --libs --cflags`
./test # 输出
./test: error while loading shared libraries: libonnxruntime.so.1.4.0: cannot open shared object file: No such file or directory
- 编译成功,但是运行时找不到
将.so
文件复制到当前目录下,然后:
g++ test.cpp -o test `pkg-config onnxruntime --libs --cflags` -Wl,-rpath=./
./test # 输出 前提是 当前路径下有需要的.so文件
cola
附录:pkg-config
的参数
pkg-config onnxruntime --cflags --libs # 头文件信息和库信息
pkg-config --list-all # 所有pkg-config文件
解决方案2: 像标准库一样
想法
对,标准库不就是随地使用么!同时,我也希望onnx
能这样!
提前明确
- Linux环境下的include路径
- Linux环境下链接库路径
todo
- 明确附录中:链接库的搜索路径!
- 完成方案2中对include和lib库搜索的设置!
- vscode中tasks.json到底如何使用
pkg-config
实作
参考:[库搜索路径的全局设置](#include
和lib
的全局搜索路径 by 环境变量)
include
和lib
的全局搜索路径 by 环境变量
注意
- 以下方法都是先明确对应命令所需文件的搜索文件夹路径
- 他们都会对应一个环境变量
- 然后我们修改环境变量
- 所有都是修改的
./bashrc
- 也可以修改
.bash_profile
- 二者区别
- 也可以修改
include路径设置
- https://gcc.gnu.org/onlinedocs/cpp/Environment-Variables.html
路径搜索优先级
CPATH # C/C++的
C_INCLUDE_PATH # C的
CPLUS_INCLUDE_PATH # C++的
OBJC_INCLUDE_PATH # OBJC_INCLUDE_PATH
修改方法
将以下内容加入到~/.bashrc
中
TMP_PATH="/home/cola/cola/ColaMain/ColaStore/cache/onnxruntime-linux-x64-1.4.0/include"
export CPATH=$CPATH:$TMP_PATH
vim ~/.bashrc
source ~/.bashrc
lib路径配置
- https://gcc.gnu.org/onlinedocs/cpp/Environment-Variables.html
原理:设置LIBRARY_PATH
和LD_LIBRARY_PATH
- 之前一直以为是
LD_LIBRARY_PATH
!结果一直出错!凸(艹皿艹 )- 区别在于前者是编译前,后者是编译后!我们需要的是编译前的搜索路径!
添加以下到~/.bashrc
TMP_PATH="/home/cola/cola/ColaMain/ColaStore/cache/onnxruntime-linux-x64-1.4.0/lib"
export LIBRARY_PATH=$LIBRARY_PATH:$TMP_PATH # for compile
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$TMP_PATH # for run time
测试
g++
命令行
g++ test.cpp -lonnxruntime -o test && ./test# 输出
cola
编写vscode::tasks.json
附录
Linux环境下的include路径
- (38条消息) 详解Linux下环境变量C_INCLUDE_PATH、CPLUS_INCLUDE_PATH、CPATH以及常见错误_太阳升起-CSDN博客_c_include_path
查看当前C/C++中include的文件夹
- https://stackoverflow.com/questions/4980819/what-are-the-gcc-default-include-directories
$ cc -xc /dev/null -E -Wp,-v 2>&1 | sed -n 's,^ ,,p'
/usr/lib/gcc/x86_64-linux-gnu/9/include
/usr/local/include
/usr/include/x86_64-linux-gnu
/usr/include$ c++ -xc++ /dev/null -E -Wp
,-v 2>&1 | sed -n 's,^ ,,p'
/usr/include/c++/9
/usr/include/x86_64-linux-gnu/c++/9
/usr/include/c++/9/backward
/usr/lib/gcc/x86_64-linux-gnu/9/include
/usr/local/include
/usr/include/x86_64-linux-gnu
/usr/include
Linux环境下链接库路径
- https://gcc.gnu.org/onlinedocs/cpp/Environment-Variables.html
程序运行时共享库的搜索路径:
环境变量
LD_LIBRARY_PATH
可执行程序的
-rpath
-WL,-rpath=PathToMyLib
系统搜索路径:
/lib
和/usr/lib
程序编译时的搜索路径: LD_LIBRARY_PATH
- https://stackoverflow.com/questions/4250624/ld-library-path-vs-library-path#:~:text=LIBRARY_PATH%20is%20used%20by%20gcc,been%20successfully%20compiled%20and%20linked.
- 可以在编译的时候用
g++ -v
参数查看!
Linux下开源库的使用(共享库文件头文件配置全局搜索)(WSL)相关推荐
- Linux下构建自己的C++共享库并配合pkg-config生成链接选项
Linux下构建自己的C++共享库并配合pkg-config生成链接选项 本文将以C++链表的新建.打印操作为例构建自己的共享库,并在实际调试代码时尝试使用.我们在做数据结构题时经常需要将链表打印出来 ...
- Linux下的LD_PRELOAD环境变量与库打桩
Linux下的LD_PRELOAD环境变量与库打桩 LD_PRELOAD是Linux系统的一个环境变量,它可以影响程序的运行时的链接(Runtime linker),它允许你定义在程序运行前优先加载的 ...
- PHP编译为静态库,Linux下将Tinyxml编译为静态库
转载请注明来源:Linux下将Tinyxml编译为静态库 一个应用需要在linux服务器上运行,不能保证每个服务器都有应用依赖的库,又懒得每个服务器都去安装下,也不太现实,于是就将应用所用到的库全部编 ...
- linux格式化gat分区,Linux 下使用udev永久绑定带库设备方法
Linux 下使用udev永久绑定带库设备方法 在Linux 系统下配置带库设备,传统的方法是当安装完lin_tape驱动后会在/dev/路径下生成IBMtape,IBMchanger 这样的驱动设备 ...
- Linux下开源邮件系统Postfix+Extmail+Extman环境部署
SMTP.POP3.IPMAP三者说明 简单来说:SMTP是邮件发送协议:POP3和IMAP是邮件接收协议.其中: 1)SMTP 全称是"Simple Mail Transfer Proto ...
- Linux下开源打包工具fpm的安装与使用(超详细)
Linux下开源打包工具fpm的安装与使用 一.fpm概述 二.fpm的安装 1.安装ruby环境 2.安装fpm 三.fpm的使用 1.fpm常用参数 2.举例要求 3.准备目录 4.编写脚本文件 ...
- linux 下开源常见监控软件
linux 下开源监控软件有很多,比较常见的有mrtg,cacti,nagios,ganglia等. 名称 优点 缺点 mrtg 是比较早得监控软件,在3年前用的人还是比较多的, 现在少了,他得优点是 ...
- linux 下通过smbclient访问windows共享目录
linux 下通过smbclient访问windows共享目录 sudo apt-get install samba #---------------------------------------- ...
- linux下tar gz bz2 tgz z等众多压缩文件的解压方法
对于刚刚接触Linux的人来说,一定会给Linux下一大堆各式各样的文件名给搞晕.别个不说,单单就压缩文件为例,我们知道在Windows下最常见 的压缩文件就只有两种,一是,zip,另一个是.rar. ...
最新文章
- IIS与ASP.NET管道
- 出于一些原因的考虑,即日起,一步一步SharePoint 2007系列文章将暂停发布
- (09)VHDL例化VHDL
- 《RHEL6.3 FTP服务器虚拟用户的配置(含图)》——如此简单
- 对面象对象概念的理解、解释
- CCS各个版本软件的下载及安装说明(内涵有详细获取安装包以及步骤奥)
- comparison of VLIW and superscaler
- 积分商城系统积分兑换运营开源架构
- Apache RocketMQ源码学习之生产者发送消息
- Linux下硬盘加密
- 基于Springboot的社区志愿者服务管理系统
- 小提琴统计图_【统计图】如何绘制小提琴图?
- Android通过浏览器打开App并传递参数
- 计算机毕业设计-基于微信小程序高校学生课堂扫码考勤签到系统-校园考勤打卡签到小程序
- 笔记本同时内外网双网网卡上网(网线不能连外网,wifi可以连外网)
- Python爬虫 爬取歌曲的评论并写入txt
- 互联网的女性主义思维
- C++第七次作业(函数_递归与非递归_多文件)
- 盛大林:深市不收的“过户费”沪市为何要收?
- java基础—分支结构