2015-06-14 37 views
1

我的環境是Ubuntu 14 32bits。
我寫了三個分別稱爲main.c,foo.c和bar.c的c文件。
代碼非常簡單。
第一個源代碼是main.c中
我無法運行ELF格式的程序。shell告訴我沒有這樣的文件或目錄

#include<stdio.h> 
extern void foo(); 
int main(){ 
foo(); 
return 0; 
} 

第二源代碼的foo.c

#include<stdio.h> 
void foo(){ 
printf("Hi,I am foo."); 
bar(); 
} 

最後一個是bar.c

#include<stdio.h> 
void bar(){ 
printf("Hi,I am bar."); 
} 

所有上面的文件將被放入同一個名爲test的文件夾中。
(其絕對路徑爲/ home /插孔/桌面/測試)
然後我發出命令:

$ gcc -fPIC -shared -Wl,-soname,libbar.so.1 -o libbar.so.1.0.0 bar.c 
$ ln -s libbar.so.1.0.0 libbar.so 
$ gcc -fPIC -shared -Wl,-soname,libfoo.so.1 -o libfoo.so.1.0.0 foo.c -lbar -L. 
$ ln -s libfoo.so.1.0.0 libfoo.so 
$ gcc -c main.c 
$ ld -rpath /home/jack/Desktop/test -e main -o main main.o -L. -lfoo -lbar 

然後我跑稱爲主可執行文件。

$./main 

但外殼下面返回

bash的字符串:./main:沒有這樣的文件或目錄。

但是主文件確實存在於當前目錄中。

爲什麼?

+0

@SantoshA'gcc -c main.c'不會生成'a.out'。它根本不會生成任何可執行文件。它只編譯源文件'main.c'並生成目標文件'main.o'。 – axiac

+0

您需要鏈接'crt0.o'和其他東西。 'gcc'正在爲你做這件事。使用'gcc -v'來理解正在發生的事情。 –

+0

@newbie:請**編輯您的問題**以激勵它。 **爲什麼你這樣做**,爲什麼不使用'gcc'來編譯和鏈接你的程序? –

回答

5

通常情況下,您不應直接調用ld。相反,你應該使用gcc做鏈接。 gcc將一些特殊選項傳遞給鏈接器。

如果我修改腳本以使用正確的sonames並使用gcc進行鏈接,它就可以工作。我這樣做:

gcc -fPIC -shared -Wl,-soname,libbar.so.1.0.0 -o libbar.so.1.0.0 bar.c 
ln -s libbar.so.1.0.0 libbar.so 
gcc -fPIC -shared -Wl,-soname,libfoo.so.1.0.0 -o libfoo.so.1.0.0 foo.c -lbar -L. 
ln -s libfoo.so.1.0.0 libfoo.so 
gcc -c main.c 
gcc -Wl,-rpath,$(pwd) -o main main.o -L$(pwd) -lfoo -lbar 

直接使用ld是針對異常情況。不要這樣做。這就是說,我不知道你的方法有什麼問題。我認爲-e在這裏是錯誤的 - 你不想直接調用main,_start做一些其他的事情。查看ldd的輸出顯示了兩種方法之間的一些重要差異。使用gcc -v調用鏈接會向你展示幕後發生的一些事情,以防你想了解更多。

+0

嗨,@ Tom Tromey,修改參數-Wl,-soname,libbar.so.1到-Wl,-soname,libbar.so.1.0.0可能不合適。我記得soname通常只包含主版本數量。感謝您的幫助。 – newbie

2
bash: ./main: no such file or directory. 

但主要的文件確實存在在當前目錄。

爲什麼?

可執行文件需要合適的程序解釋器才能執行動態鏈接。打印no such file or directory消息是因爲找不到默認解釋器,這是錯誤的。

將其設置爲ld選項-dynamic-linker /lib/ld-linux.so.2(對於32位)。

64位動態鏈接器是/lib64/ld-linux-x86-64.so.2

由於您的輸入是直接main您必須致電exit(0)main的末尾。它不能從主體返回,因爲沒有人叫它。內核將指令指針直接設置爲main的地址。從main返回可能會導致段錯誤,並且由於您沒有向printf添加\n,所以無法看到消息。

+0

嗨,你完全解決我的問題。當我添加ld選項-dynamic-linker /lib/ld-linux.so.2時,程序主要工作,但正如你所說,發生段故障是因爲我忘記調用exit謝謝你的幫助。謝謝。 – newbie

相關問題