歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> 關於Linux

AIX上使用庫文件和編寫庫文件

一直以來,被動態鏈接庫,靜態庫,靜態鏈接,動態鏈接,最近又聽到運行時鏈接弄得一塌糊塗。天下文章一大抄,知道的大家都知道,靜態鏈接是編譯時鏈接,生成的文件大,動態鏈接是運行時鏈接,生成的文件小。不知道的大家都不知道,或者大家都以為自己知道...有時windows,有時linux,有時Aix,有時gcc,有時g++,有時cc,有時xlc,有時.so,有時.a,有時.dll有時.lib有時.o,太多不一致,太多麻煩。
還有,因為工作的原因,經常在以Aix為工作環境,有的說.so是動態鏈接庫,.a是靜態鏈接庫,但在Aix上咋看咋不像。
這周末,我花了兩天時間研究Aix上的這些問題,用的是vac的xlc和ccs的ld,不能說現在有多了解,但至少不像以前那麼糊塗了。現在做做總結。

一,鏈接文件和鏈接方式。
其實沒有將動態鏈接和動態鏈接方式仔細地想一想,是導致我原來混亂的主要原因。之所以想到這個問題,是在工作中要編寫一個庫a,那我要編譯a,然後要寫另一個庫b,b依賴於a,我又要編譯b,在這個過程中,我開始思考,我當初編譯a的時候是用的什麼鏈接方式,我現在要用a了,那a又是什麼?
於是我開始區分鏈接文件和鏈接方式,開始了以下實驗
1,使用庫文件libc.a,靜態鏈接成可執行程序
hello.c

C代碼 復制代碼
#include <stdio.h>
int main() {
printf("Hello, world!\n");
}
#include <stdio.h>int main() {printf("Hello, world!\n");}
運行
# xlc -o hello.o -c hello.c
生成目標文件hello.o
運行
ld -o hello_s -bstatic hello.o -lc
想靜態鏈接hello.o和libc.a,並生成可執行文件hello_s。我這裡沒有直接使用xlc來生成可執行文件,是想把其中每一步弄清楚,結果求知的代價就是大量的時間和無盡的搜索。-bnso是告訴ld靜態鏈接。(你還可以用xlc的-E和-S參數看hello.c的預處理文件和匯編文件,再用as來編譯匯編文件生成對象文件)
結果
ld: 0711-327 WARNING: Entry point not found: __start
ld: 0711-244 ERROR: No csects or exported symbols have been saved.
這裡說沒有找到__start,這個__start看起來很像系統的一個子歷程。出現這個錯的原因是因為我們沒有在鏈接時加入這樣一個庫/usr/lib/crt0.o,如果你用xlc直接靜態鏈接,那麼這個庫應該是xlc自己幫你加的(這個庫好像是線程初始化相關),你可以通過nm命令查看這個目標文件相關的symbol,裡面是包含有__start的。於是我們再運行
ld -o hello_s -bstatic hello.o -lc /usr/lib/crt0.o
結果報錯說一大堆符號找不到,
ld: 0711-224 WARNING: Duplicate symbol: .is_posix_tz
ld: 0711-224 WARNING: Duplicate symbol: .__icuinit
ld: 0711-345 Use the -bloadmap or -bnoquiet option to obtain more information.
ld: 0711-317 ERROR: Undefined symbol: __loadx
ld: 0711-317 ERROR: Undefined symbol: _system_TB_config
ld: 0711-317 ERROR: Undefined symbol: errno
ld: 0711-317 ERROR: Undefined symbol: .___bzero
ld: 0711-317 ERROR: Undefined symbol: smcr_timebase
ld: 0711-317 ERROR: Undefined symbol: .___memmove
ld: 0711-317 ERROR: Undefined symbol: .___memset
ld: 0711-317 ERROR: Undefined symbol: _system_configuration
ld: 0711-317 ERROR: Undefined symbol: disclaim
ld: 0711-317 ERROR: Undefined symbol: kwritev
ld: 0711-317 ERROR: Undefined symbol: kpwritev
ld: 0711-317 ERROR: Undefined symbol: kpwrite
ld: 0711-317 ERROR: Undefined symbol: kwrite
ld: 0711-317 ERROR: Undefined symbol: kopenx
...
ld提示可以用-bloadmap來查看具體的出錯信息,於是我運行
ld -o hello_s -bstatic hello.o -lc /usr/lib/crt0.o -bloadmap:out.txt
並查看輸出文件,得到
...
ld: 0711-318 ERROR: Undefined symbols were found.
The following symbols are in error:
Symbol Inpndx TY CL Source-File(Object-File) OR Import-File{Shared-object}
RLD: Address Section Rld-type Referencing Symbol
----------------------------------------------------------------------------------------------
__loadx [262] ER DS (/usr/lib/libc.a[shr.o])
0006919c .data R_POS [1658] <__loadx>
_system_TB_config [792] ER UA (/usr/lib/libc.a[shr.o])
000691a8 .data R_POS [1664] <_system_TB_config>
errno [8] ER UA (/usr/lib/libc.a[shr.o])
00068e3c .data R_POS [1226]
...
這說明是libc.a中的shr.o中的定義的一些符號找不到,於是我們將這個shr.o解出來,運行
ar -x /usr/lib/libc.a shr.o
得到shr.o,然後
ldd shr.o
得到輸出
shr.o needs:
/unix
/usr/lib/libcrypt.a(shr.o)
/usr/lib/libc.a(shr.o)
這個shr.o需要以上三個庫,libc.a我們已經包括了,那麼哪裡去找/unix這個庫?相比現在所找不到的符號應該都是系統調用吧。查看ld的手冊得知我們需要導入系統調用的符號表/lib/syscalls.exp
於是我們再運行
# ld -o hello_s -bstatic hello.o -lc /usr/lib/crt0.o -bI:/lib/syscalls.exp
結果還是報錯
# ld -o hello_s -bstatic hello.o -lc /usr/lib/crt0.o -bI:/lib/syscalls.exp
ld: 0711-224 WARNING: Duplicate symbol: .open
ld: 0711-224 WARNING: Duplicate symbol: .openx
ld: 0711-224 WARNING: Duplicate symbol: .is_posix_tz
ld: 0711-224 WARNING: Duplicate symbol: .__icuinit
ld: 0711-224 WARNING: Duplicate symbol: .send
ld: 0711-224 WARNING: Duplicate symbol: .nrecvmsg

Copyright © Linux教程網 All Rights Reserved