gpt4 book ai didi

c++ - 嵌入式系统C++编译中的问题

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:05:10 26 4
gpt4 key购买 nike

我有一些关于嵌入式系统编译问题的相关问题。我的问题不仅仅是怎么做,更重要的是为什么,因为我有解决问题的办法(也许还有更好的办法?),但不知道为什么有些东西在某些条件下工作,而在其他条件下不工作。我已经花了一些时间在这件事上,但直到昨天,我还是有点盲目,尝试和错误,不知道我在做什么。是时候停止了!求求你,救命。
脚本
我想在Zedboard上为Xilinx的Zynq ARM处理器开发一个应用程序。该应用程序将涉及多线程、一些音频操作和httpserver。所以我需要pthread、alsa、sndfile和microhttpd库。我和Yocto一起创建了rootfs。在最初的conf.local文件中,我添加/修改了以下行:

BB_NUMBER_THREADS ?= "${@oe.utils.cpu_count()}"
PARALLEL_MAKE ?= "-j ${@oe.utils.cpu_count()}"
MACHINE ?= "zedboard-zynq7"
PACKAGE_CLASSES ?= "package_deb"
EXTRA_IMAGE_FEATURES = "debug-tweaks eclipse-debug"
IMAGE_INSTALL_append = "libgcc alsa-utils mpg123 libstdc++ sthttpd libmicrohttpd libsndfile1"
LICENSE_FLAGS_WHITELIST = "commercial_mpg123"

我还必须在bblayers.conf中添加一些附加层(当然还下载了它们):
meta-xilinx
meta-multimedia (from meta-openembedded)
meta-oe (from meta-openembedded)
meta-webserver (from meta-openembedded)

最后,我用bitbake生成了最小的核心图像。
这与linux内核以及其他单独编译的东西一起,可以很好地引导和工作。
问题
一。使用此rootfs的简单应用程序
它是zynq的应用程序,所以我使用xsdk,它是xilinx的sdk,基于eclipse。我创建了新的应用程序项目。在对话框窗口中,我选择了Linux作为平台,C++作为语言,并且我提供了我的解压缩ROOTFS的路径(很好地是系统通过NFS引导的)。我的rootfs路径是 /home/stas/ZedboardPetalinuxFS(它不是petalinux,我只是使用它,这个文件夹名仍然是相同的)。这为rootfs中的库和头搜索设置了正确的路径。
我从一件非常简单的事情开始:
#include <pthread.h>

int main()
{
int i;
i = 1;
return 0;
}

我还为链接器添加了pthread库(在eclipse设置中)。此时的链接命令:
arm-linux-gnueabihf-g++ -L"/home/stas/ZedboardPetalinuxFS/usr/lib" -L"/home/stas/ZedboardPetalinuxFS/lib" -o "test.elf"  ./src/main.o   -lpthread

在这一点上,它编译。但当我添加sndfile库时它就停止了
#include <sndfile.h>

这是合理的,因为这个rootfs没有所有的头。我需要添加另一个搜索标题的路径。所以我在yocto tmp文件夹中添加了path,它包含构建rootfs所需的所有头文件。添加之后,它再次成功编译。但当我添加sndfile库进行链接时,问题就开始了。下面是链接命令和错误:
arm-linux-gnueabihf-g++ -L"/home/stas/ZedboardPetalinuxFS/usr/lib" -L"/home/stas/ZedboardPetalinuxFS/lib" -o "test.elf"  ./src/main.o   -lpthread -lsndfile
/opt/Xilinx/SDK/2016.4/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/5.2.1/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lsndfile

我找了usr/lib来检查libsndfile.so是否存在,结果只找到libsndfile.so.1和ibsndfile.so.1.27。但pthread也是如此,linker对此并不抱怨。我决定手工创建libsndfile.so(我将其链接到libsndfile.so.1)。链接器不再抱怨它,而是开始抱怨它的依赖性。因此,我还为所有依赖项及其依赖项创建了.so文件,并添加了它们以进行链接。然后成功了。最后,linking命令如下所示:
arm-linux-gnueabihf-g++ -L"/home/stas/ZedboardPetalinuxFS/usr/lib" -L"/home/stas/ZedboardPetalinuxFS/lib" -o "test.elf"  ./src/main.o   -lpthread -lvorbisenc -lvorbis -logg -lFLAC -lsndfile

所以这里有第一个问题——为什么我不需要pthread的.so文件,而需要它来处理所有其他库?或者更一般的-我什么时候需要.so文件,什么时候.so.x文件就足够了?
2.简单应用-另一种方法
经过第一次尝试,我想我应该再做一个形象,这次更适合发展。幸运的是,在yocto中这很容易——我只需要修改一行:
EXTRA_IMAGE_FEATURES = "debug-tweaks eclipse-debug dev-pkgs"

dev pkgs选项为所有已安装的包添加-dev包。
现在我有了rootfs,其中包含所有需要的头,还有指向它们应该指向的位置的.so文件。
在编译之前,我删除了不必要的include路径,只保留rootfs中的include路径,并删除了除pthread和sndfile之外的所有库。但后来我又犯了新的错误:
arm-linux-gnueabihf-g++ -L"/home/stas/ZedboardPetalinuxFS/usr/lib" -L"/home/stas/ZedboardPetalinuxFS/lib" -o "test.elf"  ./src/main.o   -lsndfile -lpthread
/opt/Xilinx/SDK/2016.4/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/5.2.1/../../../../arm-linux-gnueabihf/bin/ld: cannot find /lib/libpthread.so.0
makefile:48: polecenia dla obiektu 'test.elf' nie powiodły się (commands for ‘test.elf’ did not succeed)
/opt/Xilinx/SDK/2016.4/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/5.2.1/../../../../arm-linux-gnueabihf/bin/ld: cannot find /usr/lib/libpthread_nonshared.a

我发现它在我的根文件夹中查找库。google中的快速搜索(和so:)告诉我应该设置–-sysroot变量。所以我把它添加到eclipse选项(在linker选项的miscelenious卡中)中,如下所示:
--sysroot=/home/stas/ZedboardPetalinuxFS

现在linker命令如下:
arm-linux-gnueabihf-g++ -L"/home/stas/ZedboardPetalinuxFS/usr/lib" -L"/home/stas/ZedboardPetalinuxFS/lib" --sysroot=/home/stas/ZedboardPetalinuxFS -o "test.elf"  ./src/main.o   -lsndfile -lpthread

一切都成功了!我还编写了一个使用pthreads和sndfile的简单示例,它也能工作。但为什么呢?这就引出了第二个问题:
为什么在这种情况下需要--sysroot选项?一般情况下,何时需要使用此选项?为什么这次我不需要将所有依赖项添加到linking命令中?
三。另一个想法
在这一点上,我有一个想法,如果添加 --sysroot选项,让rootfs填充旧的、非开发映像,检查将发生什么。但这给了我新的错误:
arm-linux-gnueabihf-g++ -L"/home/stas/ZedboardPetalinuxFS/usr/lib" -L"/home/stas/ZedboardPetalinuxFS/lib" --sysroot=/home/stas/ZedboardPetalinuxFS -o "test.elf"  ./src/main.o   -lpthread -lvorbisenc -lvorbis -logg -lFLAC -lsndfile
/opt/Xilinx/SDK/2016.4/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/5.2.1/../../../../arm-linux-gnueabihf/bin/ld: cannot find crt1.o: No such file or directory
makefile:48: polecenia dla obiektu 'test.elf' nie powiodły się
/opt/Xilinx/SDK/2016.4/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/5.2.1/../../../../arm-linux-gnueabihf/bin/ld: cannot find crti.o: No such file or directory
/opt/Xilinx/SDK/2016.4/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/5.2.1/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lpthread
/opt/Xilinx/SDK/2016.4/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/5.2.1/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lm

那么第三个问题-这个错误意味着什么?
非常感谢提前!

最佳答案

为什么我不需要pthread的.so文件,而需要其他所有库的文件?
交叉编译器通常带有C运行时(包括pthread),通常位于交叉编译器安装的目录中。
链接器内置了库的搜索路径。这些是关于sysroot的,它默认设置为搜索交叉编译器自己包含的目标c运行时。如果您添加了任何-L选项,它将首先搜索这些选项,然后转到这些预定义的目录。
当您链接到pthread时,它至少会在交叉编译器的库目录中找到libpthread.a
或者更一般的-我什么时候需要.so文件,什么时候.so.x文件就足够了?
Linux中的共享库通常有主版本号和次版本号。库在具有相同主版本的不同次版本之间是ABI兼容的,但在主版本之间不是。有时有三个层次的版本,但主体是相似的。
在安装库时,通常使用全名安装实际文件,例如libmy.so.1.2,然后提供指向libmy.so.1libmy.so的符号链接。
如果链接的应用程序可以使用任何库版本,则只需指定名称,例如-lmy。在这种情况下,您需要从libmy.solibmy.so.1的符号链接。
如果你需要一个特定的版本,你会把-l:libmy.so.1。“:”表示文本文件名。
链接器脚本可能会影响某些内容,甚至在指定短名称时也可能导致选择特定版本。
为什么在这种情况下需要--sysroot选项?我什么时候需要用
一般来说这个选项?
--sysroot所做的是将给定的路径预先放在通常用于搜索include和库的所有搜索目录上。在交叉编译(如您现在所做的)时,它非常有用,可以让编译器和链接器在目标根目录中搜索,而不是在构建主机的根目录中搜索。
如果您已经指定了sysroot,那么您可能不需要通过-I指定include路径,也不需要通过-L指定链接器路径,假设这些文件在目标根目录中的正常位置内。
为什么这次我不需要将所有依赖项添加到linking命令中?
一种可能的情况是,第一次,sndfile表示静态链接,而不是动态链接。如果第一个根映像在lib dir或搜索路径上的其他位置只有sndfile.a,则会发生这种情况。要满足sndfile.a的要求,还需要链接其他lib。
当链接到sndfile.so时,依赖项将通过动态链接过程自动加载。
这只是目前的一个工作理论。
那么第三个问题-这个错误意味着什么?
它们意味着它甚至找不到要链接的C运行库。
如第一个问题所述,它先前在预定义的搜索路径(相对于预定义的sysroot)中找到c运行时,该路径定位了交叉编译器提供的c运行时。
您通过提供自己的sysroot来干扰这一点。它现在只搜索目标根。因为这个目标根文件系统没有安装开发库,所以没有C运行时可供查找。

关于c++ - 嵌入式系统C++编译中的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43491184/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com