【问题标题】:cross compiling gstreamer fails: x86-64 -> ARMv6 32-bit交叉编译 gstreamer 失败:x86-64 -> ARMv6 32-bit
【发布时间】:2016-08-17 18:46:41
【问题描述】:

我正在尝试在 x86_64 (linux) 系统上为 RPi 1 构建一个项目。我有一个工作工具链 - 我已经构建了一个小程序并在 RPi(“Hello World”)上运行它。

我正在尝试构建的项目是 gstreamer .

配置脚本中,我添加了相应的--host=,它会找到所有正确的工具并成功完成。但是,当我做这个项目时, 我收到以下错误:

    In file included from gsttracerutils.h:30:0,
                 from gst_private.h:68,
                 from gst.c:96:
../gst/gstutils.h: In function '__gst_slow_read64_be':
../gst/gstutils.h:111:61: error: left shift count >= width of type [-Werror=shift-count-overflow]
     (((guint##__size) (((const guint8 *) (__data))[__idx])) << (__shift))
                                                             ^
../gst/gstutils.h:164:36: note: in expansion of macro '_GST_GET'
 #define _GST_READ_UINT64_BE(data) (_GST_GET (data, 0, 64, 56) | \
                                    ^
../gst/gstutils.h:184:10: note: in expansion of macro '_GST_READ_UINT64_BE'
   return _GST_READ_UINT64_BE (data);
          ^

似乎(至少在我看来)编译器在抱怨 32 位 cpu 上的 64 位类型(这是正确的)。

这是工具链编译器的问题吗?还是别的什么?

我最初(成功地)在 rpi 本身上构建了 gstreamer。但由于这需要很长时间,而且我需要能够重新制作应用程序,所以我想在一个快速的系统上构建它。

为了澄清: 我使用的构建工具链是 crosstool-ng。 我将配置命令运行为:

./configure --disable-gtk-doc --disable-examples --disable-benchmarks --disable-gtk-doc-html --host=armv6-rpi-linux-gnueabihf

并从配置日志(config.log):

## ----------- ##
## Core tests. ##
## ----------- ##

configure:3217: checking build system type
configure:3231: result: x86_64-unknown-linux-gnu
configure:3251: checking host system type
configure:3264: result: armv6-rpi-linux-gnueabihf
configure:3284: checking target system type
configure:3297: result: armv6-rpi-linux-gnueabihf
configure:3343: checking for a BSD-compatible install
configure:3411: result: /usr/bin/install -c
configure:3422: checking whether build environment is sane
configure:3477: result: yes
configure:3536: checking for armv6-rpi-linux-gnueabihf-strip
configure:3552: found /nas/temp/build/rpi/tc/x-tools/armv6-rpi-linux-gnueabihf/bin/armv6-rpi-linux-gnueabihf-strip
configure:3563: result: armv6-rpi-linux-gnueabihf-strip

这表明构建系统是 x86_64,主机和目标是 armv6(...)。

如上所示,错误与处理 64 位数据的宏有关。

我可以使用这个相同的项目树,运行 autogen.sh、configure.sh,然后在 rpi-1 上进行制作(使用 gcc 工具的 pignus 版本 - pignus 是专门针对 rpi-1 的 fedora 23 spin) ,并且它完全构建成功。我还在 x86_64 系统上构建了这个项目,并为它构建了这个项目,这也很成功。

而且,如开头所述,我使用相同的工具链构建了一个简单的程序——“Hello World”程序——它在 x86_64 系统上编译和链接成功,然后在 rpi 上成功运行。

所以,我的问题是:这可能是交叉编译器工具链的问题/错误,还是项目源代码中的问题?关于在哪里寻找或尝试什么的任何建议?

TIA

【问题讨论】:

  • 你设置ARCHCROSS_COMPILE了吗?
  • 是的,两者都已设置。此外,这适用于 armv6 处理器 (rpi-1),而不是 v7 (rpi-2/3)。
  • 在 configure.sh 脚本中:“--host=" 设置架构和交叉编译标志 (FWIW: --host=armv6-rpi-linux-gnueabihf")。如前所述,这些值有效 - 例如,编译了一个工作应用程序。抱歉,我以为人们知道该配置选项的用途。
  • ARMv7 的事情有点糟糕,因为我没有注意到“Rpi-1”的事情(我不认为它们是“模型 1”,我只是认为它们是 A/B/ +/0,或 ARMv6 版本)——但解释上下文的相关细节并没有什么坏处,显然交叉编译器在这里很重要(我认为 v7 是 linux 发行版自带的原因,而使用 ct-ng等是超越)。
  • ..无论如何,宏看起来很纠结。显然你不想费心去改变任何东西,但有可能它实际上是 gstreamer 中的一个极端案例错误。 您可以尝试在他们的 -devel 邮件列表中很好地征求意见gstreamer.freedesktop.org/lists 实际上看起来就像一个答案刚刚放在 \O/

标签: linux arm cross-compiling gstreamer


【解决方案1】:

从取消选择those macros 开始,编译器特别抱怨的是,将guint64 类型的值左移56 位会溢出类型,因此是未定义的。

现在,这对我说的是,您正在获取 主机的 glibconfig.h,其中 guint64 必须是 unsigned long 的 typedef,即 64 位类型那台机器,但是一旦你将它输入 32 位 ARM 编译器,它就会变成 32 位。在 Pi 本身上,您可能有一个适当配置的 glibconfig.h,其中 guint64unsigned long long 的 typedef,因此可以本地构建。

您需要将构建指向 Pi 的 GLib 头文件和库,而不是主机的(当交叉链接器找到 x86 库并拒绝它们时,这个编译错误几乎肯定会延迟最终链接失败)。我自己没有使用 GStreamer 的经验,所以我不能确切地说出该怎么做,但是根据 this mailing list post 我发现,正确的方法似乎涉及覆盖 PKG_CONFIG_PATH。

【讨论】:

  • 是的,我就是这么想的。宏是 64 位的。至于 glib,我似乎在我的工具链(crosstool-ng)中的任何地方都找不到它。从您的邮件列表链接中,看起来我需要先交叉构建 glib。听起来对吗?至于 PKG_CONFIG_PATH,在工具链中,有 .pc 文件,所以我想我可以将该路径添加到 PKG_CONFIG_PATH 中。
  • 您不需要自己交叉构建 GLib,尤其是因为这可能会导致版本不匹配。只需将 Pi 的文件系统挂载/复制到主机上并指向它 - 然后您将针对将要运行的完全相同的东西进行构建(并且您知道它已经存在,因为本机构建很好)。
  • 嘿!好主意啊!。我遇到的问题正是 - 让交叉编译器查看目标环境而不是构建环境。从未想过使用实际的文件系统。而且,对于 rpi,它位于 SD 上,只需将其弹出到构建机器中,说几句神奇的安装词,瞧!但是我仍然遇到一个问题,即制作过程想要使用构建的路径(/usr/include 等),而忽略已配置的内容。会试试这个,让你知道。谢谢,@Notlikethat。
  • 试过这个。我仍然遇到的主要问题是编译器选择了构建系统的包含文件,而不是目标文件。我已经明确使用了 --with-sysroot=, --includedir=/usr/include (和其他)。但是编译器会先用完构建系统的路径,然后再尝试这些显式路径。我可以让make 改变它吗?
  • 是的,--sysroot= 是避免许多麻烦的好习惯,但它只会更改默认搜索路径,因此不会优先于任何明确提供的内容。表现良好的项目倾向于让您控制外部依赖项,例如configure --with-libwidget=/path...make LIBDOODAH=/path... 等等。另一方面,有些项目只是交叉编译的混蛋。有趣的是,就在今天,我在 makefile 上花费了更长的时间来试图说服交叉构建工作,而不是最终启动开发板、将东西克隆到上面并在本地构建它。
【解决方案2】:

我遇到的问题正是 - 让交叉编译器查看目标环境而不是构建环境。

在子目录中安装 Rpi 也是我过去几天的工作,我找到了对 OsX 主机的描述,但由于我只有 Windows 计算机,我做了一些变通办法让 RPi1 在 NFS 上启动- 共享 Trusty 虚拟机而不是 SD 卡: https://github.com/rmast/rpi-build-and-boot

【讨论】:

  • 我的下一个实验将使用 pi-1 中的 distcc 将 cc 命令分发到 Ubuntu 虚拟机。这样我希望不要依赖于编写良好的交叉编译代码。这个项目带给我的不仅仅是使用来自 git 的一些 gstreamer.sh 进行本地构建,但我也在学习,确实有一个更快的构建方法会很好。
猜你喜欢
  • 1970-01-01
  • 2011-09-03
  • 1970-01-01
  • 1970-01-01
  • 2020-07-05
  • 2018-08-08
  • 2013-01-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多