关键词

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

实作

参考:[库搜索路径的全局设置](#includelib的全局搜索路径 by 环境变量)

includelib的全局搜索路径 by 环境变量

注意

  1. 以下方法都是先明确对应命令所需文件的搜索文件夹路径

    • 他们都会对应一个环境变量
    • 然后我们修改环境变量
  2. 所有都是修改的./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_PATHLD_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)相关推荐

  1. Linux下构建自己的C++共享库并配合pkg-config生成链接选项

    Linux下构建自己的C++共享库并配合pkg-config生成链接选项 本文将以C++链表的新建.打印操作为例构建自己的共享库,并在实际调试代码时尝试使用.我们在做数据结构题时经常需要将链表打印出来 ...

  2. Linux下的LD_PRELOAD环境变量与库打桩

    Linux下的LD_PRELOAD环境变量与库打桩 LD_PRELOAD是Linux系统的一个环境变量,它可以影响程序的运行时的链接(Runtime linker),它允许你定义在程序运行前优先加载的 ...

  3. PHP编译为静态库,Linux下将Tinyxml编译为静态库

    转载请注明来源:Linux下将Tinyxml编译为静态库 一个应用需要在linux服务器上运行,不能保证每个服务器都有应用依赖的库,又懒得每个服务器都去安装下,也不太现实,于是就将应用所用到的库全部编 ...

  4. linux格式化gat分区,Linux 下使用udev永久绑定带库设备方法

    Linux 下使用udev永久绑定带库设备方法 在Linux 系统下配置带库设备,传统的方法是当安装完lin_tape驱动后会在/dev/路径下生成IBMtape,IBMchanger 这样的驱动设备 ...

  5. Linux下开源邮件系统Postfix+Extmail+Extman环境部署

    SMTP.POP3.IPMAP三者说明 简单来说:SMTP是邮件发送协议:POP3和IMAP是邮件接收协议.其中: 1)SMTP 全称是"Simple Mail Transfer Proto ...

  6. Linux下开源打包工具fpm的安装与使用(超详细)

    Linux下开源打包工具fpm的安装与使用 一.fpm概述 二.fpm的安装 1.安装ruby环境 2.安装fpm 三.fpm的使用 1.fpm常用参数 2.举例要求 3.准备目录 4.编写脚本文件 ...

  7. linux 下开源常见监控软件

    linux 下开源监控软件有很多,比较常见的有mrtg,cacti,nagios,ganglia等. 名称 优点 缺点 mrtg 是比较早得监控软件,在3年前用的人还是比较多的, 现在少了,他得优点是 ...

  8. linux 下通过smbclient访问windows共享目录

    linux 下通过smbclient访问windows共享目录 sudo apt-get install samba #---------------------------------------- ...

  9. linux下tar gz bz2 tgz z等众多压缩文件的解压方法

    对于刚刚接触Linux的人来说,一定会给Linux下一大堆各式各样的文件名给搞晕.别个不说,单单就压缩文件为例,我们知道在Windows下最常见 的压缩文件就只有两种,一是,zip,另一个是.rar. ...

最新文章

  1. IIS与ASP.NET管道
  2. 出于一些原因的考虑,即日起,一步一步SharePoint 2007系列文章将暂停发布
  3. (09)VHDL例化VHDL
  4. 《RHEL6.3 FTP服务器虚拟用户的配置(含图)》——如此简单
  5. 对面象对象概念的理解、解释
  6. CCS各个版本软件的下载及安装说明(内涵有详细获取安装包以及步骤奥)
  7. comparison of VLIW and superscaler
  8. 积分商城系统积分兑换运营开源架构
  9. Apache RocketMQ源码学习之生产者发送消息
  10. Linux下硬盘加密
  11. 基于Springboot的社区志愿者服务管理系统
  12. 小提琴统计图_【统计图】如何绘制小提琴图?
  13. Android通过浏览器打开App并传递参数
  14. 计算机毕业设计-基于微信小程序高校学生课堂扫码考勤签到系统-校园考勤打卡签到小程序
  15. 笔记本同时内外网双网网卡上网(网线不能连外网,wifi可以连外网)
  16. Python爬虫 爬取歌曲的评论并写入txt
  17. 互联网的女性主义思维
  18. C++第七次作业(函数_递归与非递归_多文件)
  19. 盛大林:深市不收的“过户费”沪市为何要收?
  20. java基础—分支结构

热门文章

  1. 最强大的截图软件share X 添加英文文字识别
  2. 第五模块:WEB开发基础-第8章 Jquery开发BootStrap
  3. 【增强版短视频去水印源码】去水印微信小程序+去水印软件源码
  4. 小甲鱼课后作业_教学常规聚养料,润物无声花更艳 ——记长小教师一日教学常规点滴工作...
  5. No module named _bz2
  6. Java获取当前时间的前几分钟的时间
  7. 国土空间总体规划编制之基期数据转换工具(免费)
  8. day02-HTML的基本标签
  9. 【理财】《穷爸爸富爸爸》读后感
  10. 三种实现Android主界面Tab的方式