gcc編譯時對’xxxx’未定義的引用問題
在使用gcc
編譯的時候有時候會碰到這樣的問題,編譯為.o
(obj) 文件沒有問題,但是編譯(這一步應該是鏈接)為可執行文件的時候會出現找不到’xxx’的定義的情況。
本文由烏合之眾 lym瞎編,歡迎轉載blog.cnblogs.net/oloroso
本文由烏合之眾 lym瞎編,歡迎轉載 my.oschina.net/oloroso
例如:
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