2015-06-14 24 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

相关问题