今天在編譯一個用到log函數的c檔案時,遇到一個錯誤:
/tmp/ccQuh0ns.o(.text+0x2bb): In function `Compute':
: undefined reference to `log'
到網上查了一下這個問題,原因及解決方案如下:
出現這個錯誤是因為編譯器找不到log的具體實現.雖然我們包括了正確的標頭檔,但是我們在編譯的時候還是要串連確定的庫.在Linux下,為了使用數學函數,我們必須和數學庫串連,為此我們要加入 -lm 選項。
gcc select.c -o select -lm
這樣就搞定了!
全文如下:(http://netsim.bokee.com/4068917.html)
3.程式庫的連結
試著編譯下面這個程式
/* temp.c */
#include
int main(int argc,char **argv)
{
double value;
printf("Value:%f\n",value);
}
這個程式相當簡單,但是當我們用 gcc -o temp temp.c 編譯時間會出現下面所示
的錯誤.
/tmp/cc33Kydu.o: In function `main':
/tmp/cc33Kydu.o(.text+0xe): undefined reference to `log'
collect2: ld returned 1 exit status
出現這個錯誤是因為編譯器找不到log的具體實現.雖然我們包括了正確的頭
檔案,但是我們在編譯的時候還是要串連確定的庫.在Linux下,為了使用數學函數,我
們必須和數學庫串連,為此我們要加入 -lm 選項. gcc -o temp temp.c -lm這樣才能夠
正確的編譯.也許有人要問,前面我們用printf函數的時候怎麼沒有串連庫呢?是這樣
的,對於一些常用的函數的實現,gcc編譯器會自動去串連一些常用庫,這樣我們就沒
有必要自己去指定了. 有時候我們在編譯器的時候還要指定庫的路徑,這個時候
我們要用到編譯器的 -L選項指定路徑.比如說我們有一個庫在 /home/hoyt/mylib下
,這樣我們編譯的時候還要加上 -L/home/hoyt/mylib.對於一些標準庫來說,我們沒
有必要指出路徑.只要它們在起預設庫的路徑下就可以了.系統的預設庫的路徑/lib
/usr/lib /usr/local/lib 在這三個路徑下面的庫,我們可以不指定路徑.
還有一個問題,有時候我們使用了某個函數,但是我們不知道庫的名字,這個時
候怎麼辦呢?很抱歉,對於這個問題我也不知道答案,我只有一個傻辦法.首先,我到
標準庫路徑下面去找看看有沒有和我用的函數相關的庫,我就這樣找到了線程
(thread)函數的庫檔案(libpthread.a). 當然,如果找不到,只有一個笨方法.比如我要找
sin這個函數所在的庫. 就只好用 nm -o /lib/*.so|grep sin>~/sin 命令,然後看~/sin
檔案,到那裡面去找了. 在sin檔案當中,我會找到這樣的一行libm-2.1.2.so:00009fa0
W sin 這樣我就知道了sin在 libm-2.1.2.so庫裡面,我用 -lm選項就可以了(去掉前面
的lib和後面的版本標誌,就剩下m了所以是 -lm).