交叉编译的应用程序不 运行 on Raspberry Pi
Cross-compiled application does not run on Raspberry Pi
我刚刚开始使用 Buildroot 和 Raspberry Pi (运行ning Raspbian)。但不知何故,我似乎在交叉编译方面做错了什么。该应用程序是用 C 编写的最简单的 Hello World 程序。我是这样做的:
- 已下载并安装 buildroot
make raspberrypi2_defconfig
make toolchain
然后我编写了微型应用程序和以下 Makefile:
CROSS_BIN := /home/me/raspi/buildroot-2016.05/output/host/usr/bin
SYSROOT := /home/me/raspi/buildroot-2016.05/output/host/usr/arm-buildroot-linux-uclibcgnueabihf/sysroot
PATH := $(CROSS_BIN):$(PATH)
CC := arm-linux-gcc
CFLAGS := --sysroot=$(SYSROOT)
app: app.c
$(CC) $(CFLAGS) -o $@ $<
编译应用程序并将其复制到 Raspberry。当我尝试 运行 它时,RPI 抱怨它找不到该文件(尽管它确实存在并且可以执行)。二进制类型对我来说似乎没问题,应该适合 CPU:
pi@raspberrypi:~ $ ./app
-bash: ./app: No such file or directory
pi@raspberrypi:~ $ ls -l app
-rwxr-xr-x 1 pi pi 4916 Jul 10 11:07 app
pi@raspberrypi:~ $ file app
app: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-uClibc.so.0, not stripped
pi@raspberrypi:~ $ lscpu
Architecture: armv7l
Byte Order: Little Endian
CPU(s): 4
On-line CPU(s) list: 0-3
Thread(s) per core: 1
Core(s) per socket: 4
Socket(s): 1
Model name: ARMv7 Processor rev 5 (v7l)
CPU max MHz: 900.0000
CPU min MHz: 600.0000
有人可以告诉我我做错了什么吗?如果我本机编译应用程序并 运行 在开发主机上,它 运行 没有问题。
我的钱在 /lib/ld-uClibc.so.0
上,你的 Rasperry pi 不见了。我说得对吗?
好的,这个库就是你的动态加载器,它负责在运行时加载你的动态库。它会将需要的共享库加载到进程地址space,并对内存设置适当的权限(只读、读写和可执行)。
您的交叉编译器需要一个不存在的加载程序,可能是由于 RPi 上安装的映像与交叉编译环境(您的 sysroot
)不匹配。
有几种方法可以修复它,让我们从检查一个有效的二进制文件开始,在此处尝试 file /bin/ls
和 post 动态加载程序。
例如:
$ file /bin/ls
/bin/ls: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 2.6.32, BuildID[sha1]=5e052e8de057d379ab51d4af510ad9318fe77b46, stripped
When I tried to run it, RPI complains that it can't find the file (though it's there and executable for sure).
shell 抱怨它找不到文件来执行您的程序,而不是它找不到您的文件。
如果已安装,请使用 strace 命令确定找不到哪个文件。
您很可能遇到动态库问题,例如您使用 uClibc 工具链构建,但您的根文件系统具有 glibc。
两种常见的解决方案:
(A) 使用静态链接构建您的程序(这样它就不再依赖于目标系统已安装的库)。
$(CC) $(CFLAGS) -o -static $@ $<
(B) 重建 Buildroot 工具链以匹配已安装在 RPi 上的库。即,构建匹配版本号的 glibc 工具链,而不是 uClibc 工具链。
我刚刚开始使用 Buildroot 和 Raspberry Pi (运行ning Raspbian)。但不知何故,我似乎在交叉编译方面做错了什么。该应用程序是用 C 编写的最简单的 Hello World 程序。我是这样做的:
- 已下载并安装 buildroot
make raspberrypi2_defconfig
make toolchain
然后我编写了微型应用程序和以下 Makefile:
CROSS_BIN := /home/me/raspi/buildroot-2016.05/output/host/usr/bin
SYSROOT := /home/me/raspi/buildroot-2016.05/output/host/usr/arm-buildroot-linux-uclibcgnueabihf/sysroot
PATH := $(CROSS_BIN):$(PATH)
CC := arm-linux-gcc
CFLAGS := --sysroot=$(SYSROOT)
app: app.c
$(CC) $(CFLAGS) -o $@ $<
编译应用程序并将其复制到 Raspberry。当我尝试 运行 它时,RPI 抱怨它找不到该文件(尽管它确实存在并且可以执行)。二进制类型对我来说似乎没问题,应该适合 CPU:
pi@raspberrypi:~ $ ./app
-bash: ./app: No such file or directory
pi@raspberrypi:~ $ ls -l app
-rwxr-xr-x 1 pi pi 4916 Jul 10 11:07 app
pi@raspberrypi:~ $ file app
app: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-uClibc.so.0, not stripped
pi@raspberrypi:~ $ lscpu
Architecture: armv7l
Byte Order: Little Endian
CPU(s): 4
On-line CPU(s) list: 0-3
Thread(s) per core: 1
Core(s) per socket: 4
Socket(s): 1
Model name: ARMv7 Processor rev 5 (v7l)
CPU max MHz: 900.0000
CPU min MHz: 600.0000
有人可以告诉我我做错了什么吗?如果我本机编译应用程序并 运行 在开发主机上,它 运行 没有问题。
我的钱在 /lib/ld-uClibc.so.0
上,你的 Rasperry pi 不见了。我说得对吗?
好的,这个库就是你的动态加载器,它负责在运行时加载你的动态库。它会将需要的共享库加载到进程地址space,并对内存设置适当的权限(只读、读写和可执行)。
您的交叉编译器需要一个不存在的加载程序,可能是由于 RPi 上安装的映像与交叉编译环境(您的 sysroot
)不匹配。
有几种方法可以修复它,让我们从检查一个有效的二进制文件开始,在此处尝试 file /bin/ls
和 post 动态加载程序。
例如:
$ file /bin/ls
/bin/ls: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 2.6.32, BuildID[sha1]=5e052e8de057d379ab51d4af510ad9318fe77b46, stripped
When I tried to run it, RPI complains that it can't find the file (though it's there and executable for sure).
shell 抱怨它找不到文件来执行您的程序,而不是它找不到您的文件。
如果已安装,请使用 strace 命令确定找不到哪个文件。
您很可能遇到动态库问题,例如您使用 uClibc 工具链构建,但您的根文件系统具有 glibc。
两种常见的解决方案:
(A) 使用静态链接构建您的程序(这样它就不再依赖于目标系统已安装的库)。
$(CC) $(CFLAGS) -o -static $@ $<
(B) 重建 Buildroot 工具链以匹配已安装在 RPi 上的库。即,构建匹配版本号的 glibc 工具链,而不是 uClibc 工具链。