某日,網友不會飛的駱駝問了我一個問題。在嵌入式Linux系統中執行./a.out時,提示找不到,信息以下:linux
$ ./a.out
-sh: ./a.out: not found
1
2
找了點資料,幫解決了。c++
問題重現
我在板子上重現了問題。的確如上所述。
使用file命令查看a.out屬性,信息以下:ubuntu
file ./a.out
./a.out: 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]=89b9b01541d4f84bfba73ce649cdd2982bb3840e, stripped
1
2
從信息上看,a.out是32位ARM系統程序,動態連接,解析器爲/lib/ld-linux-armhf.so.3。可是,在板子上查看該文件:bash
$ ls /lib/ld-linux*
/lib/ld-linux.so.3
1
2
能夠看到只有ld-linux.so.3,找不到前面提到的ld-linux-armhf.so.3,因此執行程序時提示not found。
形成這個問題的緣由是:板子上的系統所用的連接器版本,與編譯程序的交叉編譯器的連接器版本不一致。先試試將交叉編譯器的連接器拷貝到板子系統中,再次執行:ui
$ ./a.out
./a.out: /lib/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by ./a.out)
1
2
提示信息變化了,但仍是出錯,是由於c++庫的版本號不對應。即a.out使用的版本是GLIBCXX_3.4.21,但系統上的c++動態庫沒有這個版本號。在板子上查找這個庫,信息以下:es5
$ ll /lib/libstdc\+\+.so.6*
lrwxrwxrwx 1 root root 19 Jan 21 2017 /lib/libstdc++.so.6 -> libstdc++.so.6.0.16
-rwxr-xr-x 1 root root 1044441 Oct 15 09:57 /lib/libstdc++.so.6.0.16
1
2
3
從中獲得,c++庫版本爲6.0.16(姑且這麼認爲)。
再在交叉編譯器目錄中查找,已精簡的信息以下:.net
$ ll ./sysroots/usr/lib/libstdc++*
./sysroots/usr/lib/libstdc++.so -> libstdc++.so.6.0.21*
lrwxrwxrwx 1 latelee latelee 19 Jan 14 08:23 ./sysroots/usr/lib/libstdc++.so.6 -> libstdc++.so.6.0.21*
-rwxr-xr-x 1 latelee latelee 1240644 Jun 20 2018 ./sysroots/usr/lib/libstdc++.so.6.0.21*
1
2
3
4
能夠看到,c++庫的版本爲6.0.21。這樣,更能印證版本不匹配的問題了。blog
解決辦法
確認清楚板子系統使用哪一個版本的編譯器,再使用這個版本編譯程序源碼便可。在實踐中,u-boot、kernel、busybox以及應用層,必須統一使用一套相同的編譯器,不然,會出現各類問題。
(注:也不必定要必須,可是,統一一個版本的話,將減小不少沒必要要的麻煩)ip
其它擴展
以前曾經也遇到過此類問題,寫在此,做爲一個擴展知識點。查看交叉編譯器版本,提示信息以下:get
latelee@ubuntu:~$ arm-linux-gcc --version
-bash: /home/latelee/bin/gcc-4.6.2-glibc-2.13-linaro-multilib-2011.12/fsl-linaro-toolchain/bin/arm-linux-gcc: No such file or directory
1
2
用file命令查看文件屬性以下:
/home/latelee/bin/gcc-4.6.2-glibc-2.13-linaro-multilib-2011.12/fsl-linaro-toolchain/bin/arm-fsl-linux-gnueabi-gcc: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.0, stripped
1
能夠看到解析器爲/lib/ld-linux.so.2,但這個文件並不存在,因此沒法找到。
這個問題很典型,是由於在64位系統中執行32位程序形成的(除交叉編譯器外,其它程序亦然)。如何解決?安裝32位庫便可,命令以下:
sudo apt-get install -y lib32ncurses5 lib32z1 1 安裝完畢後,系統上有/lib/ld-linux.so.2文件。從新執行前面的命令便可顯示正常的版本號。 ———————————————— 版權聲明:本文爲CSDN博主「李遲」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處連接及本聲明。 原文連接:https://blog.csdn.net/subfate/article/details/86490887