交叉编译时如何链接共享对象库(.so)

4

我正在尝试使用ARM交叉编译器arm-linux-gnueabi-gcc将我的c程序链接到一个共享对象库(libfoo.so)。我在Ubuntu系统上进行编译,并希望在Android设备上运行该程序。编译工作正常,但当我尝试在我的Android设备上运行程序时,出现了错误。

我创建了一个包含以下文件的简单测试程序:

foo.c:

#include <stdio.h>
void foo(void){ puts("Hello, I am a shared library"); }

foo.h:

#ifndef foo_h__
#define foo_h__
extern void foo(void);
#endif

main.c:

#include <stdio.h>
#include "foo.h"
int main(void)
{
    puts("This is a shared library test...");
    foo();
    return 0;
}

我使用以下命令创建共享对象库:
arm-linux-gnueabi-gcc -c -fPIC foo.c
arm-linux-gnueabi-gcc -shared -o libfoo.so foo.o
然后我使用以下命令编译我的程序:
arm-linux-gnueabi-gcc -L/home/foo -o test main.c -lfoo 将test程序上传到Android设备中后,我无法运行它。相反,我会收到错误消息:
/system/bin/sh: ./test: No such file or directory
我在正确的目录下,并且test文件存在,因此我认为无法找到共享库。我已经尝试将libfoo.so上传到Android设备中(上传的路径与编译时指定的路径相同),但仍无法运行程序。
使用静态库(foo.o)可以正常工作:arm-linux-gnueabi-gcc -static -o test main.c foo.o,但无法使用共享库。
如何在交叉编译时正确链接共享库,以确保程序可以在Android设备上运行?

我尝试使用-fPIC而不是-fpic。仍然无法运行./test。我将更新问题以避免混淆。 - Pineapple
请务必尝试以下命令:file testldd test以获取更多详细信息(其中test是您编译的可执行文件)。 - Yeti
1个回答

0

链接器无法动态链接到库。

定义LD_LIBRARY_PATH环境变量以包含该库:

export LD_LIBRARY_PATH=/home/foo

我在Ubuntu系统和Android系统上都尝试了这个操作,但仍然出现相同的错误。 - Pineapple
你确定你的库文件位置是正确的吗?尝试将它移动到当前工作目录,并导出LD_LIBRARY_PATH=./ - MrBens
是的,我确定路径是正确的。我尝试将库移动到当前工作目录并导出新的LD_LIBRARY_PATH,但仍然没有运气。我还尝试将库放在/vendor/lib位置,那里有一堆其他的.so文件。 也许错误“./test: No such file or directory”指的是其他东西……?我只是看不到它如何找不到共享库,除非它完全忽略了LD_LIBRARY_PATH的设置。 - Pineapple
尝试使用不同的顺序进行编译:arm-linux-gnueabi-gcc main.c -o test -L/home/foo -lfoo - MrBens
我终于也尝试了一下,结果遇到了同样的问题!这太奇怪了。你有办法解决吗?当我在我的树莓派上编译库时,它可以正常工作。相同的可执行文件、相同的格式、相同的大小... - MrBens
确实是这样,非常奇怪。我无法让它工作,所以最终我转而使用ndk-build。 - Pineapple

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接