libwiringPi.so:undefined reference to ‘fcntl@GLIBC_2.28‘
wiringpi动态库移植到ubuntu下arm-linux-gnueabihf-gcc 交叉编译树莓派 或者Qt Creator 构建linux设备(一键调试)用到wiringpi.so 情况下出现以下错误!!!都是同样的问题!!!!!!!!!!!1.2.问题原因都是虚拟机ubuntu下1.glibc版本不一致2.arm-linux-gnueabihf 版本不一致 树莓派的版本在8以上解决办法参
wiringpi动态库移植到ubuntu下
arm-linux-gnueabihf-gcc 交叉编译树莓派 或者
Qt Creator 构建linux设备(一键调试)用到wiringpi.so 情况下出现以下错误!!!
都是同样的问题!!!!!!!!!!!
1.
2.
问题原因都是虚拟机ubuntu下
1.glibc版本不一致
2.arm-linux-gnueabihf 版本不一致 树莓派的版本在8以上
解决办法参考如下
构建 GCC 作为 Raspberry Pi 的交叉编译器
在本文中,我将向您展示如何构建GCC 10作为Raspberry Pi的交叉编译器。交叉编译器是在操作系统上运行并为另一个操作系统生成可执行文件的编译器。当您想使用强大的计算机为 Raspberry Pi 构建库或其他大型代码时,这非常有用。作为一个实际例子,在文章的最后,我将向您展示如何使用交叉编译器将 GCC 本身构建为原生 Raspberry Pi 应用程序。
本文中介绍的方法的一个优点是您可以使用交叉编译器来构建 RPi 零和更高版本的可执行文件。使用来自Debian的官方crossbuild-essential-armhf,您只能构建 Raspberry Pi 2 和更高版本的二进制文件。
本文的一部分是我在阅读其他人的帖子时学到的知识的汇编。以下是我使用过的资源列表:
- http://preshing.com/20141119/how-to-build-a-gcc-cross-compiler/
- https://www.raspberrypi.org/documentation/linux/kernel/building.md
- https://wiki.osdev.org/Why_do_I_need_a_Cross_Compiler%3F
- https://wiki.osdev.org/GCC_Cross-Compiler
- https://wiki.osdev.org/Building_GCC
- http://www.ifp.illinois.edu/~nakazato/tips/xgcc.html
从上面的列表中,第一篇文章是最完整的,如果你遵循它,你最终会得到一个部分工作的交叉编译器。公平地说,这篇文章不是为 Raspberry Pi 写的。如果您想更深入地了解该过程的某些步骤,我建议您阅读它。
为了构建和托管交叉编译器,我使用了Debian 10,但类似的过程应该适用于其他 Linux 发行版。
首先,确保您的系统已更新并安装所需的先决条件:
1 sudo apt update
2 sudo apt upgrade
3 sudo apt install build-essential gawk git texinfo bison file wget
在撰写本文时,Raspbian 附带GCC 8.3.0、Binutils 2.31和Glibc 2.28。使用与Raspbian相同的Glibc版本构建我们的交叉编译器非常重要。这将使我们能够很好地与操作系统集成。如果您来自未来并阅读本文,您可以使用以下命令检查上述软件的版本:
1 gcc --version
2 ld -v
3 ldd --version
这是我在 Raspberry Pi 上看到的:
1 pi@raspberrypi:~ $ gcc --version
2 gcc (Raspbian 8.3.0-6+rpi1) 8.3.0
3 Copyright (C) 2018 Free Software Foundation, Inc.
4 This is free software; see the source for copying conditions. There is NO
5 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
6
7 pi@raspberrypi:~ $ ld -v
8 GNU ld (GNU Binutils for Raspbian) 2.31.1
9 pi@raspberrypi:~ $ ldd --version
10 ldd (Debian GLIBC 2.28-10+rpi1) 2.28
11 Copyright (C) 2018 Free Software Foundation, Inc.
12 This is free software; see the source for copying conditions. There is NO
13 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 Written by Roland McGrath and Ulrich Drepper.
15 pi@raspberrypi:~ $
如果您尝试使用更现代的GCC构建Glibc 2.28,例如 9.x 或 10.x,您会遇到很多错误。最简单的方法是使用GCC 8.3.0构建Glibc,然后将其与最新最好的GCC 一起使用,此时是 10.1。
在接下来的说明中,我将假设您在一个单独的文件夹中执行所有步骤,并保持相同的终端会话打开,直到一切都完成。例如,您可以在您的家中创建一个工作文件夹:
1 cd ~
2 mkdir gcc_all && cd gcc_all
让我们下载用于构建交叉编译器的软件:
1 wget https://ftpmirror.gnu.org/binutils/binutils-2.31.tar.bz2
2 wget https://ftpmirror.gnu.org/glibc/glibc-2.28.tar.bz2
3 wget https://ftpmirror.gnu.org/gcc/gcc-8.3.0/gcc-8.3.0.tar.gz
4 wget https://ftpmirror.gnu.org/gcc/gcc-10.1.0/gcc-10.1.0.tar.gz
5 git clone --depth=1 https://github.com/raspberrypi/linux
接下来,提取档案并删除它们:
1 tar xf binutils-2.31.tar.bz2
2 tar xf glibc-2.28.tar.bz2
3 tar xf gcc-8.3.0.tar.gz
4 tar xf gcc-10.1.0.tar.gz
5 rm *.tar.*
GCC还需要一些先决条件,我们可以在源文件夹中下载这些先决条件:
1 cd gcc-8.3.0
2 contrib/download_prerequisites
3 rm *.tar.*
4 cd ..
5 cd gcc-10.1.0
6 contrib/download_prerequisites
7 rm *.tar.*
8 cd ..
接下来,创建一个文件夹,我们将在其中放置交叉编译器并将其添加到路径中:
1 cd ~/gcc_all
2 sudo mkdir -p /opt/cross-pi-gcc
3 sudo chown $USER /opt/cross-pi-gcc
4 export PATH=/opt/cross-pi-gcc/bin:$PATH
复制上述文件夹中的内核头文件,有关内核的更多信息,请参阅 Raspbian文档:
1 cd ~/gcc_all
2 cd linux
3 KERNEL=kernel7
4 make ARCH=arm INSTALL_HDR_PATH=/opt/cross-pi-gcc/arm-linux-gnueabihf headers_install
接下来,让我们构建Binutils:
1 cd ~/gcc_all
2 mkdir build-binutils && cd build-binutils
3 ../binutils-2.31/configure --prefix=/opt/cross-pi-gcc --target=arm-linux-gnueabihf --with-arch=armv6 --with-fpu=vfp --with-float=hard --disable-multilib
4 make -j 8
5 make install
GCC和Glibc是相互依赖的,没有另一个你不能完全构建一个,所以我们将进行GCC的部分构建,Glibc的部分构建,最后构建GCC和Glibc。您可以在Preshing 的文章中阅读有关此内容的更多信息。
1 cd ~/gcc_all
2 mkdir build-gcc && cd build-gcc
3 ../gcc-8.3.0/configure --prefix=/opt/cross-pi-gcc --target=arm-linux-gnueabihf --enable-languages=c,c++,fortran --with-arch=armv6 --with-fpu=vfp --with-float=hard --disable-multilib
4 make -j8 all-gcc
5 make install-gcc
现在,让我们部分构建Glibc:
1 cd ~/gcc_all
2 mkdir build-glibc && cd build-glibc
3 ../glibc-2.28/configure --prefix=/opt/cross-pi-gcc/arm-linux-gnueabihf --build=$MACHTYPE --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf --with-arch=armv6 --with-fpu=vfp --with-float=hard --with-headers=/opt/cross-pi-gcc/arm-linux-gnueabihf/include --disable-multilib libc_cv_forced_unwind=yes
4 make install-bootstrap-headers=yes install-headers
5 make -j8 csu/subdir_lib
6 install csu/crt1.o csu/crti.o csu/crtn.o /opt/cross-pi-gcc/arm-linux-gnueabihf/lib
7 arm-linux-gnueabihf-gcc -nostdlib -nostartfiles -shared -x c /dev/null -o /opt/cross-pi-gcc/arm-linux-gnueabihf/lib/libc.so
8 touch /opt/cross-pi-gcc/arm-linux-gnueabihf/include/gnu/stubs.h
回到海湾合作委员会:
1 cd ..
2 cd build-gcc
3 make -j8 all-target-libgcc
4 make install-target-libgcc
完成构建Glibc:
1 cd ..
2 cd build-glibc
3 make -j8
4 make install
完成构建GCC 8.3.0:
1 cd ..
2 cd build-gcc
3 make -j8
4 make install
5 cd ..
或者,编写一个小的 C 或 C++ 测试程序,您可以使用以下命令构建代码:
1 arm-linux-gnueabihf-g++ test.cpp -o test
上面生成的可执行文件test是使用我们的第一个交叉编译器构建的,将在您的 Pi 上运行。您可以使用file命令检查:
1 $ file test
2 test: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, not stripped
一个更好的测试是将上面创建的二进制文件传输到您的 RPi 并查看您是否可以运行它。
此时,您拥有了一个完整的带有 GCC 8.3.0 的交叉编译器工具链。在继续下一步之前进行备份,以防出现问题:
1 sudo cp -r /opt/cross-pi-gcc /opt/cross-pi-gcc-8.3.0
1 cd ~/gcc_all
编辑gcc-10.1.0/libsanitizer/asan/asan_linux.cpp。如果未定义,则需要定义PATH_MAX。在第 66 行之后添加下一段代码:
1 #ifndef PATH_MAX
2 #define PATH_MAX 4096
3 #endif
保存并关闭文件。
接下来,我们将使用上面构建的Glibc来构建一个更现代的交叉编译器,它将覆盖GCC 8.3:
1 cd ~/gcc_all
2 mkdir build-gcc10 && cd build-gcc10
3 ../gcc-10.1.0/configure --prefix=/opt/cross-pi-gcc --target=arm-linux-gnueabihf --enable-languages=c,c++,fortran --with-arch=armv6 --with-fpu=vfp --with-float=hard --disable-multilib
4 make -j8
5 make install
此时,您可以使用GCC 10.1为您的 Raspberry Pi 交叉编译任何 C、C++ 或 Fortran 代码。您可以使用前缀调用任何交叉编译器:
1 arm-linux-gnueabihf-
示例:arm-linux-gnueabihf-gcc、arm-linux-gnueabihf-g++、arm-linux-gnueabihf-gfortran。
为了对我们的交叉编译器进行压力测试,让我们使用它为 Pi 交叉编译自身:
1 sudo mkdir -p /opt/gcc-10.1.0
2 sudo chown $USER /opt/gcc-10.1.0
3
4 cd ~/gcc_all
5 mkdir build-native-gcc10 && cd build-native-gcc10
6 ../gcc-10.1.0/configure --prefix=/opt/gcc-10.1.0 --build=$MACHTYPE --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf --enable-languages=c,c++,fortran --with-arch=armv6 --with-fpu=vfp --with-float=hard --disable-multilib --program-suffix=-10.1
7 make -j 8
8 make install-strip
你应该在你的/opt/gcc-10.1.0文件夹中得到一个原生的 ARM GCC 。
附带说明一下,在 Debian 10 x86-64 机器上使用上述交叉编译器构建GCC 10.1大约需要 30 分钟。将此与我过去在我的 Pi 3 上直接构建GCC 8.1所需的 5 个小时进行比较,您将看到在您的主机上安装交叉编译器的优势。有人告诉我,在 Raspberry Pi Zero 上编译GCC 7大约需要 5 天!
如果您想将交叉编译器永久添加到您的路径中,请使用以下内容:
1 echo 'export PATH=/opt/cross-pi-gcc/bin:$PATH' >> ~/.bashrc
2 source ~/.bashrc
您现在可以选择安全地擦除构建文件夹。假设您遵循了我的建议,从您的主文件夹使用下一个命令:
1 cd ~
2 rm -rf gcc_all
让我们将原生GCC ARM编译器存档并将其保存到我们的主文件夹中:
1 cd /opt
2 tar -cjvf ~/gcc-10.1.0-armhf-raspbian.tar.bz2 gcc-10.1.0
3 cd ~
将gcc-10.1.0-armhf-raspbian.tar.bz2 复制到您的 RPi。对于本文的其余部分,我将假设您使用的是 RPi,并且上述存档位于您的主文件夹中:
1 cd ~
2 tar xvf gcc-10.1.0-armhf-raspbian.tar.bz2
3 rm gcc-10.1.0-armhf-raspbian.tar.bz2
4 sudo mv gcc-10.1.0 /opt
接下来,我们要将新的编译器添加到路径中并创建一些符号链接:
1 echo 'export PATH=/opt/gcc-10.1.0/bin:$PATH' >> ~/.bashrc
2 echo 'export LD_LIBRARY_PATH=/opt/gcc-10.1.0/lib:$LD_LIBRARY_PATH' >> ~/.bashrc
3 source ~/.bashrc
4 sudo ln -s /usr/include/arm-linux-gnueabihf/sys /usr/include/sys
5 sudo ln -s /usr/include/arm-linux-gnueabihf/bits /usr/include/bits
6 sudo ln -s /usr/include/arm-linux-gnueabihf/gnu /usr/include/gnu
7 sudo ln -s /usr/include/arm-linux-gnueabihf/asm /usr/include/asm
8 sudo ln -s /usr/lib/arm-linux-gnueabihf/crti.o /usr/lib/crti.o
9 sudo ln -s /usr/lib/arm-linux-gnueabihf/crt1.o /usr/lib/crt1.o
10 sudo ln -s /usr/lib/arm-linux-gnueabihf/crtn.o /usr/lib/crtn.o
此时,您应该能够使用gcc-10.1、g++-10.1或gfortran-10.1调用编译器。
让我们尝试编译并运行一个 C++17 代码,它使用带有 init 语句的 if 块(这个例子有点傻,但它会告诉你如何编译 C++17 程序):
1 #include <iostream>
2
3 int main() {
4 // if block with init-statement:
5 if(int a = 5; a < 8) {
6 std::cout << "Local variable a is < 8\n";
7 } else {
8 std::cout << "Local variable a is >= 8\n";
9 }
10 return 0;
11 }
将上述代码保存在名为if_test.cpp的文件中,并使用以下命令编译它:
1 g++-10.1 -std=c++17 -Wall -pedantic if_test.cpp -o if_test
这是我在 RPi 上看到的:
1 pi@raspberrypi:~ $ g++-10.1 -std=c++17 -Wall -pedantic if_test.cpp -o if_test
2 pi@raspberrypi:~ $ ./if_test
3 Local variable a is < 8
4 pi@raspberrypi:~ $
让我们也尝试使用 C++17文件系统:
1 #include <iostream>
2 #include <filesystem>
3
4 int main() {
5 for(auto &file : std::filesystem::recursive_directory_iterator("./")) {
6 std::cout << file.path() << '\n';
7 }
8 }
将上述代码保存在名为fs_test.cpp的文件中,并使用以下命令编译它:
1 g++-10.1 -std=c++17 -Wall -pedantic fs_test.cpp -o fs_test
这是我在我的 RPi 上看到的(如果您有很多文件,请不要在主文件夹中运行下一个代码,因为它会递归打印所有文件,例如,您可以将其移动到具有较少数量的文件夹中)文件):
1 pi@raspberrypi:~ $ g++-10.1 -std=c++17 -Wall -pedantic fs_test.cpp -o fs_test
2 pi@raspberrypi:~ $ ./fs_test
3 "./.nano"
4 "./.profile"
5 "./.bash_logout"
6 "./fs_test.cpp"
7 "./.bashrc"
8 "./if_test.cpp"
9 "./if_test"
10 "./fs_test"
11 "./.bash_history"
12 pi@raspberrypi:~ $
ok 解决办法参考国外网站
更多推荐
所有评论(0)