6. "undefined reference to" 問題彙總及解決方法 ------非常非常好的一篇文章
轉載地址: https://segmentfault.com/a/1190000006049907?utm_source=tuicool&utm_medium=referral
在實際編譯程式碼的過程中,我們經常會遇到"undefined reference to"
的問題,簡單的可以輕易地解決,但有些卻隱藏得很深,需要花費大量的時間去排查。工作中遇到了各色各樣類似的問題,按照以下幾種可能出現的狀況去排查,可有利於理清頭緒,從而迅速解決問題。
連結時缺失了相關目標檔案
首先編寫如下的測試程式碼:
// test.h
#ifndef __TEST_H__
#define __TEST_H__
void test();
#endif
// test.c
#include <string.h>
#include <stdio.h>
void test()
{
printf("just test it\n");
}
// main.c
#include "test.h"
int main(int argc, char **argv)
{
test();
return 0;
}
通過以下的命令,我們將會得到兩個.o
檔案。
$ gcc -c test.c
$ gcc –c main.c
隨後,我們將main.o
這個檔案,編譯成可執行檔案。
$ gcc -o main main.o
Undefined symbols for architecture x86_64:
"_test", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
編譯時報錯了,這是最典型的undefined reference
錯誤,因為在連結時發現找不到某個函式的實現檔案。如果按下面這種方式連結就正確了。
$ gcc -o main main.o test.o
當然,也可以按照如下的命令編譯,這樣就可以一步到位。
$ gcc -o main main.c test.c
連結時缺少相關的庫檔案
我們把第一個示例中的test.c
編譯成靜態庫。
$ gcc -c test.c
$ ar -rc test.a test.o
接著編譯可執行檔案,使用如下命令:
$ gcc -o main main.c
Undefined symbols for architecture x86_64:
"_test", referenced from:
_main in main-6ac26d.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
其根本原因也是找不到test()
函式的實現檔案,由於test()
函式的實現在test.a
這個靜態庫中,故在連結的時候需要在其後加入test.a
這個庫,連結命令修改為如下形式即可。
$ gcc -o main main.c test.a
連結的庫檔案中又使用了另一個庫檔案 (這個例子非常非常好, 我就是犯了這種錯誤!!!)
先更改一下第一個示例中使用到的程式碼,在test()
中呼叫其它的函式,更改的程式碼如下所示。
// func.h
#ifndef __FUNC_H__
#define __FUNC_H__
void func();
#endif
// func.c
#include <stdio.h>
void func()
{
printf("call it\n");
}
// test.h
#ifndef __TEST_H__
#define __TEST_H__
void test();
#endif
// test.c
#include <string.h>
#include <stdio.h>
#include "func.h"
void test()
{
printf("just test it\n");
func();
}
// main.c
#include "test.h"
int main(int argc, char **argv)
{
test();
return 0;
}
我們先對fun.c
和test.c
進行編譯,生成.o
檔案。
$ gcc -c func.c
$ gcc -c test.c
然後,將test.c
和func.c
各自打包成為靜態庫檔案。
$ ar –rc func.a func.o
$ ar –rc test.a test.o
這時將main.c
編譯為可執行程式,由於main.c
中包含了對test()
的呼叫,因此,應該在連結時將test.a
作為我們的庫檔案,連結命令如下。
$ gcc -o main main.c test.a
Undefined symbols for architecture x86_64:
"_func", referenced from:
_test in test.a(test.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
就是說,連結的時候發現test.a
呼叫了func()
函式,找不到對應的實現,我們還需要將test.a
所引用到的庫檔案也加進來才能成功連結,因此命令如下。
$ gcc -o main main.c test.a func.a
同樣,如果我們的庫或者程式中引用了第三方庫(如pthread.a
)則在連結的時候需要給出第三方庫的路徑和庫檔案,否則就會得到undefined reference
的錯誤。
多個庫檔案連結順序問題
這種問題非常隱蔽,不仔細研究,可能會感到非常地莫名其妙。以第三個示例為測試程式碼,把連結庫的順序換一下,如下所示:
$ gcc -o main main.c func.a test.a
test.a(test.o): In function `test':
test.c:(.text+0x13): undefined reference to `func'
collect2: ld returned 1 exit status
因此,在連結命令中給出所依賴的庫時,需要注意庫之間的依賴順序,依賴其他庫的庫一定要放到被依賴庫的前面,這樣才能真正避免undefined reference
的錯誤,完成編譯連結。
備註:在MAC
上可以正常編譯通過。
定義與實現不一致
編寫測試程式碼如下:
// test.h
#ifndef __TEST_H__
#define __TEST_H__
void test(unsigned int c);
#endif
// test.c
#include <string.h>
#include <stdio.h>
void test(int c)
{
printf("just test it\n");
}
// main.c
#include "test.h"
int main(int argc, char **argv)
{
test(5);
return 0;
}
先將test.c
編譯成庫檔案。
$ gcc -c test.c
$ ar -rc test.a test.o
將main.c
編譯成可執行檔案。
$ gcc -o main main.c test.a
ld: warning: ignoring file test.a, file was built for archive which is not the architecture being linked (x86_64): test.a
Undefined symbols for architecture x86_64:
"_test", referenced from:
_main in main-f27cf1.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
連結出錯了,原因很簡單,test()
這個函式的宣告和定義不一致導致,將兩者更改成一樣即可通過編譯。
在c++
程式碼中連結c
語言的庫
程式碼同示例一的程式碼一樣,只是把main.c
更改成了main.cpp
。編譯test.c
,並打包為靜態庫。
$ gcc -c test.c
$ ar -rc test.a test.o
編譯可執行檔案,用如下命令:
$ g++ -o main main.cpp test.a
Undefined symbols for architecture x86_64:
"test()", referenced from:
_main in main-7d7fde.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
原因就是main.cpp
為c++
程式碼,呼叫了c
語言庫的函式,因此連結的時候找不到,解決方法是在相關檔案新增一個extern "C"
的宣告即可,例如修改test.h
檔案。
// test.h
#ifndef __TEST_H__
#define __TEST_H__
#ifdef __cplusplus
extern "C" {
#endif
void test();
#ifdef __cplusplus
}
#endif
#endif
相關推薦
Linux編譯程式報錯 undefined reference to error 的解決方法
對於我這個剛入IT行業不就得新手來說,在linux下連結庫的時候總是會遇到各種各樣奇葩的問題,最多的就是“undefined reference to”和“cannot find”這兩類,層出不窮,總是在我即將完成工作的時候給我當頭一棒,讓我欲罷不能。這不,這幾天編譯linux下一個專案時又遇到難題
gcc "undefined reference to" 問題解決方法(使用庫)
最近在Linux下程式設計發現一個詭異的現象,就是在連結一個靜態庫的時候總是報錯,類似下面這樣的錯誤: (.text+0x13): undefined reference to `func'
關於undefined reference to `inflate'問題解決方法
今天編譯一個程式出現上面的錯誤,在編譯環境中已經加入了連結對應的壓縮庫,後來發現只有在主程式中呼叫一次同壓縮相關的函式即可,但是我實際上在主檔案中並不需要,解決方法為寫一個不被呼叫的函式,裡面內容為: void do_nothing() { ZipArchive zip; m
undefined reference to 錯誤的解決方法總結
在編寫C++時,會遇到一類錯誤的錯。 總結起來為幾類 一、是 Linux環境錯誤 具體沒有深入研究,可以參考http://blog.csdn.net/cserchen/article/details/5503556。 二、使用codeblock這類需要自己配置路徑,要把所
linux 連結庫檔案出現“undefined reference to" 問題的解決方法
最近在Linux下程式設計發現一個詭異的現象,就是在連結一個靜態庫的時候總是報錯,類似下面這樣的錯誤: (.text+0x13): undefined reference to `func' 關於undefined reference這樣的問題,大家其實經常會遇
ubuntu 下沒有pthread庫以及報undefined reference to 'pthread_create'的解決方法
最近在Ubuntu下編譯一個程式,需要使用多執行緒庫pthread,但是編譯時總是提示“undefined reference to 'pthread_create'”的錯誤,如下圖所示: 要解決這
undefined reference to 'function'及解決辦法
在開發演算法過程中,自己寫的函式編譯生成一個動態共享連結庫檔案.so. 然後由其他模組呼叫其中的函式時出現undefined reference to : function(要呼叫的函式)錯誤提示. 反覆檢查函式已經正確編寫,呼叫命令也沒問題. 使用nm命令檢查發現也沒問題,
6. "undefined reference to" 問題彙總及解決方法 ------非常非常好的一篇文章
轉載地址: https://segmentfault.com/a/1190000006049907?utm_source=tuicool&utm_medium=referral在實際編譯程式碼的過程中,我們經常會遇到"undefined reference to"的問
"undefined reference to" 問題彙總及解決方法 ------非常非常好的一篇文章
轉載地址: https://segmentfault.com/a/1190000006049907?utm_source=tuicool&utm_medium=referral 在實際編譯程式碼的過程中,我們經常會遇到"undefined r
Win10+VMware12+ubunt16.04 問題彙總及解決方法
1. 無法安裝成功的方法 $sudo vmware-uninstall-tools.pl 重新作業系統 兩個光碟機,第二個光碟機把系統的安裝程式加入進去 $sudo ./vmware-install.pl 安裝成功 圖片: 重新啟動 2 VMware Wor
undefined reference to `av_register_all' 問題解決
之前一直在eclipse上使用ndk前一陣轉到Android studio上 使用ndk 被這個undefined reference to `av_register_all' 問題困擾了很久,一度認為是路徑沒有配置好後來發現解決方法#include <libavco
undefined reference to `__gnu_mcount_nc'的解決 在編譯核心時出現瞭如下錯誤:
在編譯核心時出現瞭如下錯誤: init/built-in.o: In function `do_one_initcall': calibrate.c:(.text+0x14): undefined reference to `__gnu_mcount_nc' init/built-in.o: In
出現錯誤/ncnn/src/cpu.cpp:426: undefined reference to `stderr'完美解決方案。
前提情況 1。 android studio 編譯器 2。 利用ncnn前向推理框架進行移植caffemodel到android手機端 3。 使用cmake進行編譯,NDK java的c++介面 出現問題 /ncnn/src/cpu.cpp:426: undef
Qt中出現qt : undefined reference to `vtable forXXX解決辦法
我們在Qt中要使用訊號和槽的時候必須要新增Q_OBJECT巨集,否則會報錯。但是有時候我們添加了Q_OBJECT的時候,我們會發現同樣會報錯,報錯如下所示: undefined reference to 'vtable for ***(類) 面對這個報錯
交叉編譯基於ARM架構的linux-3.6核心遇到的問題及解決方法
編譯linux-3.6核心: 安裝交叉編譯工具:arm-linux-gnueabi-gcc 下載並解壓linux-3.6原始碼 清楚原始碼中的無用的編譯檔案:makeclean清除除了config之外的所有編譯出來的文件,makemrproper將配置的config也一併清
undefined reference to `dlopen'錯誤解決
# gcc DBSim.c /tmp/ccEdvduQ.o: In function `main': DBSim.c:(.text+0x38): undefined reference to `dlopen' DBSim.c:(.text+0x55): undefined
C 語言 undefined reference to 'sqrt' 問題解決
題目:一個整數,它加上100後是一個完全平方數,再加上168又是一個完全平方數,請問該數是多少? 1.程式分析:在10萬以內判斷,先將該數加上100後再開方,再將該數加上268後再開方,如果開方後 的結果滿足如下條件,即是結果。請看具體分析: 2.程式原始碼
undefined reference to `log' 問題解決
嘗試gcc 編譯出現問題。如:gcc -o lz77 main.o lz77.o tree.o bitio.obitio.o: In function `bitof':bitio.c:(.text+0xd): undefined reference to `log'bitio
Failed: ambari-server方法彙總及解決方法
假期第二天,適逢北京雨天。原本準備“臥床聽雨眠“,睡衣惺忪之際,突然感覺有什麼事情忘了。屈指一算,發現還欠著部落格的後續文章了。爬起來來辦公室加班整理ing........ 再次補充一點關於物理伺服器搭建準備: 補充1路由篇.在搭建服務時候很多時候能聯網會方便很多。所
C/C++與java網路通訊問題彙總及解決方法
前段時間做了一個簡單的C/S系統, 分別用C++和java開發服務端和客戶端, 並通過tcp通訊. 以前沒有這方面的經驗, 只是知道理論上可行, 實際上還有不少問題要注意. 本文會陸續擴充和修改. 專案1: 校園導航 2006.6平臺: X86, windowsXP+SP2,