gcc 編譯器對‘sqrt’未定義的引用與對‘pow’未定義的引用
linuxidc@linuxidc:~/linuxidc.com$ gcc linuxidc.c -o linuxidc.com
在使用gcc編譯c時提示
/tmp/cchJksha.o:在函式‘prime’中:
linuxidc.c:(.text+0x11):對‘sqrt’未定義的引用
/tmp/cchJksha.o:在函式‘main’中:
linuxidc.c:(.text+0x9f):對‘pow’未定義的引用
collect2: error: ld returned 1 exit status
gcc編譯的時候也要在指令後面加 -lm:
linuxidc@linuxidc:~/linuxidc.com$ gcc linuxidc.c -o linuxidc.com -lm
即可編譯成功。
原因:缺少某個庫,用 -l 引數將庫加入。Linux的庫命名是一致的, 一般為 libxxx.so, 或 libxxx.a, libxxx.la, 要連結某個庫就用 -lxxx,去掉頭 lib 及 "." 後面的 so, la, a 等即可。
常見的庫連結方法為:數學庫 -lm; posix 執行緒 -lpthread
gcc編譯時對’xxxx’未定義的引用問題
在使用gcc編譯的時候有時候會碰到這樣的問題,編譯為.o(obj) 檔案沒有問題,但是編譯(這一步應該是連結)為可執行檔案的時候會出現找不到’xxx’的定義的情況。
例如:
g++ -o spider -rdynamic -lpthread -levent -lcrypt -ldl bloomfilter.o confparser.o crc32.o dso.o hashs.o md5.o qstring.o sha1.o socket.o spider.o threads.o url.o
...
dso.o:在函式‘dso_load(char const*, char const*)’中:
dso.cpp:(.text+0x3c):對‘dlopen’未定義的引用
dso.cpp:(.text+0x4c):對‘dlsym’未定義的引用
dso.cpp:(.text+0xb5):對‘dlerror’未定義的引用
dso.cpp:(.text+0x13e):對‘dlclose’未定義的引用
原因
出現這種情況的原因,主要是C/C++編譯為obj檔案的時候並不需要函式的具體實現,只要有函式的原型即可。但是在連結為可執行檔案的時候就必須要具體的實現了。如果錯誤是未宣告的引用,那就是找不到函式的原型,解決辦法這裡就不細緻說了,通常是相關的標頭檔案未包含。
解決辦法
指定原因就好辦了,既然知道是缺少了函式的具體實現,那麼就給它這個函式的實現就好了。比如上面的例子,是因為缺失了dlopen、dlsym、dlerror、dlclose這些函式的實現,這幾個函式是用於載入動態連結庫的,編譯的時候需要新增-ldl來使用dl庫(這是靜態庫,在系統目錄下/usr/lib/i386-linux-gnu/libdl.a、/usr/lib/x86_64-linux-gnu/libdl.a)。
但是看上面編譯的時候是有新增-ldl選項的,那麼為什麼不行呢?
gcc 依賴順序問題
這個主要的原因是gcc編譯的時候,各個檔案依賴順序的問題。
在gcc編譯的時候,如果檔案a依賴於檔案b,那麼編譯的時候必須把a放前面,b放後面。
例如:在main.c中使用了pthread庫相關函式,那麼編譯的時候必須是main.c在前,-lpthread在後。 gcc main.c -lpthread -o a.out 。
上面出現問題的原因就是引入庫的順序在前面了,將其放置在後面即可了。
g++ -o spider bloomfilter.o confparser.o crc32.o dso.o hashs.o md5.o qstring.o sha1.o socket.o spider.o threads.o url.o -rdynamic -lpthread -levent -lcrypt -ldl
Linux公社的RSS地址 : ofollow,noindex" target="_blank">https://www.linuxidc.com/rssFeed.aspx
本文永久更新連結地址: https://www.linuxidc.com/Linux/2018-11/155614.htm