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.pswp.cn/news/532607.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/532607.shtml
英文地址,請注明出處:http://en.pswp.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;…