Linux下C/C++程序编译链接加载过程中的常见问题及解决方法

Linux下C/C++程序编译链接加载过程中的常见问题及解决方法

1 头文件包含的问题

报错信息

该错误通常发生在编译时,常见报错信息如下:

run.cpp:2:10: fatal error: dlpack/dlpack.h: No such file or directory#include <dlpack/dlpack.h>^~~~~~~~~~~~~~~~~
compilation terminated.

头文件包含的问题是新手常常会遇到的问题,在这里,我们要先搞懂 gcc 关于头文件搜索的相关过程、参数选项和环境变量,之后头文件包含的相关问题就迎刃而解了。

头文件的搜索顺序

我们先来看一下头文件的搜索顺序,我们知道,在 C/C++ 源文件中,包含头文件有两种形式,即分别是尖括号和双引号来包含:#inlcude <xxx>#include "xxx"

<>

对于尖括号包含的头文件,通常搜索顺序为:

  1. 搜索 -I 指定的目录
  2. 搜索 gcc 环境变量 C_INCLUDE_PATH(如果是C++程序,则为 CPLUS_INCLUDE_PATH) 中指定的目录
  3. 搜索 gcc 的默认目录:
    • /usr/include
    • /usr/local/include
    • /usr/lib/gcc/x86_64-linux-gnu/7.5.0/include

“”

而对于双引号包含的头文件,我们很清楚,主要是为了当前工作目录下去搜索,这种情况的详细搜索顺序是这样的:

  1. 搜索当前目录
  2. 搜索 -I 参数指定的目录
  3. 搜索 gcc 环境变量 C_INCLUDE_PATH(如果是C++程序,则为 CPLUS_INCLUDE_PATH) 中指定的目录
  4. 搜索 gcc 的默认目录:
    • /usr/include
    • /usr/local/include
    • /usr/lib/gcc/x86_64-linux-gnu/7.5.0/include

可以看到,相对于 <> 的包含方式,"" 就是先多搜索了当前目录。

另外,要指出,编译器会按照上述顺序搜索头文件,一旦找到了就不会就绪往下进行了,也就是说,如果有同名的头文件,顺序靠后的搜索目录中的头文件会被靠前的屏蔽掉。

解决方法:编译参数选项和环境变量

通过上面介绍的与包含头文件相关的编译参数选项和环境变量我们也不难发现,当面对找不到头文件的错误时,有两种方式可以告诉编译器去找所需的头文件的目录:即 通过编译参数选项或环境变量

  • 编译参数选项 -I 参数指定编译器会去搜索的头文件包含目录。
  • 环境变量 C_INCLUDE_PATHCPLUS_INCULDE_PATH 分别指定C代码和C++代码需要去搜索的头文件包含目录。

注意这里不是由 PATH 环境变量指定的,PATH 目录下都是一些可执行文件,他不是用来指定头文件的搜索目录的,

这里要说下 include 的默认目录,它也不是由 $ATH 环境变量指定的(也就是说在所有头文件包含的行为中,和 PATH 环境变量一毛钱关系没有),而是由g++的配置prefix指定的,可以通过 gcc -v 来查看:

Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.5.0-3ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)

2 编译连接时的未定义引用的问题

报错信息

常见报错信息如下:

/tmp/ccWYumCZ.o: In function `main':
run.cpp:(.text+0x8f): undefined reference to `tvm::runtime::Module::LoadFromFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
collect2: error: ld returned 1 exit status

编译链接时库搜索顺序

首先还是要明确在编译连接时的库的搜索顺序:

  1. 搜索 -L + -l 参数指定的
  2. 搜索环境变量 LIBRARY_PATH + 参数-l指定的
  3. 搜索默认目录中的
    • /lib
    • /usr/lib
    • /usr/local/lib

解决方法:编译参数选项和环境变量

与上面头文件包含问题类似,解决方法还是靠添加编译参数选项和环境变量。这里需要注意的是:-L 参数选项和 LIBRARY_PATH 环境变量都可以负责指定库的搜索目录,而 -l 参数选项是来指定搜索目录下的具体的库文件的名字。也就是说, -LLIBRARY_PATH 二选一,再加上 -l 参数,才行。

比如我们在 /home/song/tvm/build/ 目录下,有两个库文件 libtvm.solibtvm_runtime.so,我们要用它们,有以下两种方法:

  • 方法一:

    export LIBRARY_PATH=/home/song/tvm/build/:$LIBRARY_PATH
    gcc main.cpp -ltvm -ltvm_runtime
    
  • 方法二:

    gcc main.cpp -L/home/song/tvm/build/ -ltvm -ltvm_runtime
    

可参考:gcc参数 -i, -L, -l, -include

3 运行时链接库的问题

报错信息

该问题发生在运行时,即我们已经得到可执行文件 a.out 了,但是在运行时却报错类似:

./a.out: error while loading shared libraries: libtvm.so: cannot open shared object file: No such file or directory

我们还可以借助工具 ldd 来查看 a.out 需要运行时链接的库是否都可用:

ldd a.out
# 输出:linux-vdso.so.1 (0x00007ffc0ebca000)libtvm.so => not foundlibstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f1b829b7000)libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f1b8279f000)libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1b823ae000)libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f1b82010000)/lib64/ld-linux-x86-64.so.2 (0x00007f1b82f45000)

可以看到,确实如同报错信息提示的那样,libtvm.so 它是找不到的。

运行时链接库的搜索顺序

我们还是先来看一下运行时链接库的搜索顺序:

  1. 编译目标代码时指定的动态库搜索路径

  2. 环境变量 LD_LIBRARY_PATH 指定的动态库搜索路径

  3. 配置文件 /etc/ld.so.conf 中指定的动态库搜索路径

  4. 默认的动态库搜索路径

    • /lib

    • /lib64

    • /usr/lib

应注意动态库搜寻路径并不包括当前文件夹,所以当即使可执行文件和其所需的so文件在同一文件夹,也会出现找不到so的问题,就像 #include <xxxx> 也不搜索当前目录

解决方法:编译选项参数、环境变量、配置文件、软链接

这里编译选项参数和环境变量的方法与上面类似,这里就不再赘述了,说说配置文件和软链接的方法:

修改/etc/ld.so.conf文件

/etc/ld.so.conf 文件中添加运行时库的路径。然后执行 ldconfig 命令。

或者在 /etc/ld.so.conf.d 目录下添加一个新建的 .conf 新文件,然后在文件中输入新的路径,然后再执行ldconfig 命令:

vim /etc/ld.so.conf.d/MyLibrary.conf		# 加上自己需要的搜索路径
sudo ldconfig

添加运行时库的软链接

可以用 ln 命令来创建运行时库的软链接,并把软链接放在系统默认路径下,然后程序链接时只需链接动态库的软链接就行。这样做的好处是当动态库升级时,只需替换掉原来的老软链接就行,无需修改编译命令。其实上面的问题2 也可以考虑用这种方法。

Ref:

http://blog.sina.com.cn/s/blog_7195909a0100zi7i.html

https://blog.csdn.net/Damocles_shi/article/details/104085803

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/532607.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DVWA Command Injection 练习总结

low: 首先查看源码没有对字符进行任何过滤 target参数为将要ping的ip地址&#xff0c;比如在输入框输入127.0.0.1后&#xff0c;对于windows系统&#xff0c;会发出ping 127.0.0.1操作。 这里可以引入命令行的几种操作方式&#xff1a; A && B&#xff1a; 先执行A…

在vimrc中设置record

在vimrc中设置record Vim的record功能在大量重复操作的场景下非常实用&#xff0c;但是&#xff0c;一般我们都要每次进入Vim时重新录制record。而对于一些非常常用的record&#xff0c;我们想让它永久地保持&#xff0c;我们知道这种需求需要借助Vim的配置文件vimrc。但是具体…

DVWA sql注入 WP

sql注入基本思路&#xff1a; 1.源码 2.判断数字型和字符型 3.猜测字段数 4.查询数据库中的字段 5.查询表中的字段 6.查询user表中的字段 7.拿字段中数据 low: 1.源码&#xff1a; <?phpif( isset( $_REQUEST[ Submit ] ) ) {// Get input$id $_REQUEST[ id ];// Check…

cmake find_package路径详解

cmake find_package路径详解 转自&#xff1a;https://zhuanlan.zhihu.com/p/50829542 经常在Linux下面写C程序&#xff0c;尤其是需要集成各种第三方库的工程&#xff0c;肯定对find_package指令不陌生。 这是条很强大的指令。可以直接帮我们解决整个工程的依赖问题&#x…

DVWA File Inclusion——Writeup

文件包含&#xff1a; 即File Inclusion&#xff0c;意思是文件包含&#xff08;漏洞&#xff09;&#xff0c;是指当服务器开启allow_url_include选项时&#xff0c;就可以通过php的某些特性函数&#xff08;include()&#xff0c;require()和include_once()&#xff0c;requi…

PyTorch JIT与TorchScript

PyTorch JIT与TorchScript 转自&#xff1a;https://zhuanlan.zhihu.com/p/370455320 如果搜索 PyTorch JIT&#xff0c;找到的将会是「TorchScript」的文档&#xff0c;那么什么是 JIT 呢&#xff1f;JIT 和 TorchScript 又有什么联系&#xff1f; 文章只会关注概念的部分&a…

DVWA Cross Site Request Forgery (CSRF) -------WP

CSRF: 介绍 CSRF跨站点请求伪造(Cross—Site Request Forgery)&#xff0c;跟XSS攻击一样&#xff0c;存在巨大的危害性&#xff0c;你可以这样来理解&#xff1a; 攻击者盗用了你的身份&#xff0c;以你的名义发送恶意请求&#xff0c;对服务器来说这个请求是完全合法的&…

PyTorch C++ API libtorch 简介

PyTorch C API libtorch 简介 翻译自 PyTorch 官方文档&#xff1a;https://pytorch.org/cppdocs/index.html#acknowledgements 整体划分 根据 PyTorch 官方文档 的介绍&#xff0c;PyTorch的C API可以粗略分为以下五个部分&#xff1a; ATen&#xff1a;基础的张量和数学计…

DVWA upload

LOW medium high impossible

安装 PyTorch C++ API libtorch 及一个最小例子

安装 PyTorch C API libtorch 及一个最小例子 翻译自&#xff1a;https://pytorch.org/cppdocs/installing.html 我们提供依赖 PyTorch 所需的所有头文件、库和 CMake 配置文件的二进制分发版。我们将此发行版称为 LibTorch&#xff0c;您可以在我们的网站上下载包含最新 Lib…

ImageNet 1K 类别名与索引的对应关系

ImageNet 1K 类别名与索引的对应关系 转自&#xff1a;http://befree2008.github.io/2018/10/05/20181005_ImageNet1000%E5%88%86%E7%B1%BB%E5%90%8D%E7%A7%B0%E5%92%8C%E7%BC%96%E5%8F%B7/ ImageNet 2012 1000个类名称和编号。ILSVRC2012_img_train.tar 这个文件解压出来都是…

sqlilab--writeup (5~6) 布尔盲注

1.# 和 – &#xff08;有个空格&#xff09;表示注释&#xff0c;可以使它们后面的语句不被执行。在url中&#xff0c;如果是get请求**(记住是get请求&#xff0c;也就是我们在浏览器中输入的url)** &#xff0c;解释执行的时候&#xff0c;url中#号是用来指导浏览器动作的&am…

PyTorch导出JIT模型并用C++ API libtorch调用

PyTorch导出JIT模型并用C API libtorch调用 本文将介绍如何将一个 PyTorch 模型导出为 JIT 模型并用 PyTorch 的 CAPI libtorch运行这个模型。 Step1&#xff1a;导出模型 首先我们进行第一步&#xff0c;用 Python API 来导出模型&#xff0c;由于本文的重点是在后面的部署…

sqli-lab--writeup(7~10)文件输出,时间布尔盲注

前置知识点&#xff1a; 1、outfile是将检索到的数据&#xff0c;保存到服务器的文件内&#xff1a; 格式&#xff1a;select * into outfile “文件地址” 示例&#xff1a; mysql> select * into outfile ‘f:/mysql/test/one’ from teacher_class; 2、文件是自动创建…

树莓派4B (aarch64) 安装PyTorch 1.8 的可行方案

树莓派4B (aarch64) 安装PyTorch 1.8 的可行方案 最终可行方案 试了一堆方案&#xff08;源码编译、Fast.ai的安装文件等&#xff09;之后&#xff0c;终于找到一个可行的方案。是在 PyTorch 官方讨论社区的一个帖子中找到的&#xff0c;在回复中一个大佬给出了自己在2021年1…

sqli-lab———writeup(11~17)

less11 用户名提交单引号显示sql语法错误&#xff0c;故存在sql注入 根据单引号报错&#xff0c;在用户名和密码任意行输入 万能密码&#xff1a;‘ or 11# 输入后username语句为&#xff1a;SELECT username, password FROM users WHERE username or 11; 双引号 password语…

深入理解Python中的全局解释锁GIL

深入理解Python中的全局解释锁GIL 转自&#xff1a;https://zhuanlan.zhihu.com/p/75780308 注&#xff1a;本文为蜗牛学院资深讲师卿淳俊老师原创&#xff0c;首发自公众号https://mp.weixin.qq.com/s/TBiqbSCsjIbNIk8ATky-tg&#xff0c;如需转载请私聊我处获得授权并注明出处…

sqli-lab————Writeup(18~20)各种头部注入

less18 基于错误的用户代理&#xff0c;头部POST注入 admin admin 登入成功&#xff08;进不去重置数据库&#xff09; 显示如下 有user agent参数&#xff0c;可能存在注入点 显示版本号&#xff1a; 爆库&#xff1a;User-Agent:and extractvalue(1,concat(0x7e,(select …

Python GIL

转自&#xff1a;https://blog.csdn.net/weixin_41594007/article/details/79485847 Python GIL 在进行GIL讲解之前&#xff0c;我们可以先回顾一下并行和并发的区别&#xff1a; 并行&#xff1a;多个CPU同时执行多个任务&#xff0c;就好像有两个程序&#xff0c;这两个程序…

sqli-lab——Writeup21~38(各种过滤绕过WAF和)

Less-21 Cookie Injection- Error Based- complex - string ( 基于错误的复杂的字符型Cookie注入) base64编码&#xff0c;单引号&#xff0c;报错型&#xff0c;cookie型注入。 本关和less-20相似&#xff0c;只是cookie的uname值经过base64编码了。 登录后页面&#xff1a;…