【问题标题】:Linking error when compiling Crypto++ for ARMHF为 ARMHF 编译 Crypto++ 时出现链接错误
【发布时间】:2015-07-29 10:44:36
【问题描述】:

我正在尝试编译 crypto++ 库以运行 armhf 架构。我正在遵循answer 中提供的方法。我调整了setenv-embed.sh 以匹配我的系统配置。运行. ./setenv-embed.sh 的输出是

CPP: /usr/bin/arm-linux-gnueabihf-cpp 
CXX: /usr/bin/arm-linux-gnueabihf-g++
AR: /usr/bin/arm-linux-gnueabihf-ar
LD: /usr/bin/arm-linux-gnueabihf-ld
RANLIB: /usr/bin/arm-linux-gnueabihf-gcc-ranlib-4.8

ARM_EMBEDDED_TOOLCHAIN: /usr/bin
ARM_EMBEDDED_CXX_HEADERS: /usr/arm-linux-gnueabihf/include/c++/4.8.2
ARM_EMBEDDED_FLAGS: -march=armv7-a mfloat-abi=hard -mfpu=neon -I/usr/arm-linux-gnueabihf/include/c++/4.8.2 -I/usr/arm-linux-gnueabihf/include/c++/4.8.2/arm-linux-gnueabihf 
ARM_EMBEDDED_SYSROOT: /usr/arm-linux-gnueabihf

这表明已找到正确的编译器。但是,当我使用 make 构建库时遇到以下错误

/usr/lib/gcc-cross/arm-linux-gnueabihf/4.8/../../../../arm-linux-gnueabihf/bin/‌​ld: cannot find /usr/arm-linux-gnueabihf/lib/libc.so.6 inside /usr/arm-linux-gnueabihf
/usr/lib/gcc-cross/arm-linux-gnueabihf/4.8/../../../../arm-linux-gnueabihf/bin/‌​ld: cannot find /usr/arm-linux-gnueabihf/lib/libc_nonshared.a inside /usr/arm-linux-gnueabihf        
/usr/lib/gcc-cross/arm-linux-gnueabihf/4.8/../../../../arm-linux-gnueabihf/bin/‌​ld: cannot find /usr/arm-linux-gnueabihf/lib/ld-linux-armhf.so.3 inside /usr/arm-linux-gnueabihf

但是当我打开/usr/arm-linux-gnueabihf/lib位置时,我可以找到上面提到的所有三个错误文件,即libc.so.6libc_nonshared.ald-linux-armhf.so.3

我正在尝试为 Beaglebone 编译库,如果有帮助的话。

更新 1:

在做一个新鲜的git pull之后运行make -f GNUmakefile-cross system的结果

hassan@hassan-Inspiron-7537:~/cryptopp-armhf$ make -f GNUmakefile-cross system
CXX: /usr/bin/arm-linux-gnueabihf-g++
CXXFLAGS: -DNDEBUG -g2 -Os -Wall -Wextra -DCRYPTOPP_DISABLE_ASM -march=armv7-a -mfloat-abi=hard -mfpu=neon -mthumb -I/usr/arm-linux-gnueabihf/include/c++/4.8.2 -I/usr/arm-linux-gnueabihf/include/c++/4.8.2/arm-linux-gnueabihf --sysroot=/usr/arm-linux-gnueabihf -Wno-type-limits -Wno-unknown-pragmas
LDLIBS: 
GCC_COMPILER: 1
CLANG_COMPILER: 0
INTEL_COMPILER: 0
UNALIGNED_ACCESS: 
UNAME: Linux hassan-Inspiron-7537 3.13.0-35-generic #62-Ubuntu SMP Fri Aug 15 01:58:42 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
MACHINE: 
SYSTEM: 
RELEASE: 
make: Nothing to be done for `system'.

【问题讨论】:

  • 嵌入式标签将在正确的专家的雷达上得到问题。有一些非常敏锐的人遵循嵌入式标签。抱歉,我无法提供帮助。
  • "/usr/bin/ ..." "找不到 /usr/arm-linux-gnueabihf/ ..." PATH 不匹配?
  • 我不这么认为。第一个usr/bin/ 指向编译器可执行文件的路径。奇怪的是它声称找不到的文件存在于目录中
  • 这通常是因为地址宽度不匹配导致链接器拒绝它们。您是否尝试使用 ARMv8 64 位库进行 ARMv7 32 位编译?尝试在库上运行 objdump,它会告诉你它们的编译目的。
  • @user3079474 - "当我使用 make 进行库时..." 这引起了我的注意...你只是在运行 make;或者你正在运行make -f GNUmakefile-cross

标签: c++ linker arm embedded crypto++


【解决方案1】:

问题很简单。它位于--sysroot 选项中。此选项的值为/usr/arm-linux-gnueabihf/,它被链接器使用,生成的库文件夹变为 /usr/arm-linux-gnueabihf/usr/arm-linux-gnueabihf/lib/

我从文件 GNUmakefile-cross 的第 68 行删除了 --sysroot 选项,所有编译和链接都正常。

但是,由于某些共享库版本不匹配,我无法在 BeagleBone Black 上运行该示例。但这对我来说不是一个真正的问题,因为在我的应用程序中,我静态链接 crypto++,而不是动态链接。

【讨论】:

  • ...我无法在我的 BeagleBone Black 上运行该示例..." - 您可以通过 SSH 连接到设备并在设备上构建。我有一个 BBB ,并且我在测试库时也这样做。“...一些共享库版本不匹配” - 是的,我可以看到 Ubuntu 交叉编译器和德州仪器 (TI) 映像的位置这样做。也许你需要使用 TI 交叉编译器。为了享受开发空间(4GB emmc 没有太多空间),你应该使用来自Beagleboard:BeagleBoneBlack Debian的控制台映像
  • @jww:我没有过多调查共享库版本不匹配的问题,因为它与我的应用程序无关。
  • @jww(继续我之前的评论):对于 BeagleBone 应用程序的交叉开发,我使用 Eclipse 和桌面 Ubuntu(在 Virtual Box 中运行)。它与crypto++配合得很好。好吧,我不得不花一些时间弄清楚如何配置 Eclipse 以远程调试 BeagleBone 应用程序。
  • 你知道include目录是不是也搞砸了吗?即,是 $SYSROOT/include,还是 $SYSROOT/$SYSROOT/include(如 $SYSROOT/$SYSROOT/lib 如上所示)?
  • 编译器使用包含目录。我可以在存在 --sysroot 选项的情况下编译示例代码。链接器使用库目录。在我看来,编译器不使用 --sysroot 并且链接器确实使用它。在我看来,链接器以 sysroot 目录作为库目录的前缀。结果是 $SYSROOT/$LIBDIR。它与$SYSROOT/$SYSROOT/lib 相同,但我认为$SYSROOT/$LIBDIR 是更好的解释。但是,我既不是 Linux 专家,也不是 gcc 专家——我有时只是使用它们。这可能是链接器中的错误。
【解决方案2】:

根据 Crosswalking 的研究,我想我可以解释发生了什么。我认为我不同意评估“问题很简单。它在 --sysroot 选项中”,因为 Crypto++ 环境脚本和 makefile 正在按预期工作。

我认为 Crosswalking 的答案可能是如何解决它;但请参阅下面的开放式问题。以下来自Crypto++ Issue 134: setenv-embedded.sh and GNUmakefile-cross

我认为这是另一个发行版问题,类似于g++-arm-linux-gnueabi cannot compile a C++ program with --sysroot。 可能是 Ubuntu 问题或 Debian 问题,如果它来自 上游。

当交叉编译时,我们期望如下(使用 ARMHF):

  • SYSROOT/usr/arm-linux-gnueabihf
  • INCLUDEDIR/usr/arm-linux-gnueabihf/include
  • LIBDIR/usr/arm-linux-gnueabihf/lib
  • BINDIR/usr/arm-linux-gnueabihf/bin

LIBDIR 如何变成 /usr/arm-linux-gnueabihf/usr/arm-linux-gnueabihf/lib/(即, $SYSROOT/$SYSROOT/lib) 是个谜。但平心而论,建筑 GCC 不是一项简单的任务。

您可能应该向 Debian 或 Ubuntu(或 提供工具链的人)。


对我来说,悬而未决的问题是,既然 $SYSROOT/lib 搞砸了,那么 $SYSROOT/include 也搞砸了吗?

如果包含目录也乱了,那么交叉编译使用的是主机的包含文件,而不是目标包含文件。这将在以后产生难以诊断的问题。

如果 $SYSROOT/include$SYSROOT/lib 都搞砸了,那么仅仅删除 --sysroot 是不够的。实际上,这是必须要做的:

# Exported by setenv-embedded
export=ARM_EMBEDDED_SYSROOT=/usr/arm-linux-gnueabihf

# Used by the makefile
-I $ARM_EMBEDDED_SYSROOT/$ARM_EMBEDDED_SYSROOT/include
-L $ARM_EMBEDDED_SYSROOT/$ARM_EMBEDDED_SYSROOT/lib

这意味着我们应该能够做到以下几点:

# Exported by setenv-embedded
export=ARM_EMBEDDED_SYSROOT=/usr/arm-linux-gnueabihf/usr/arm-linux-gnueabihf

# Used by the makefile
--sysroot="$ARM_EMBEDDED_SYSROOT"

最后,这看起来很像 Ubuntu 的 Bug 1375071: g++-arm-linux-gnueabi cannot compile a C++ program with --sysroot。错误报告特别指出...内置路径使用额外的“/usr/arm-linux-gnueabi”

我们需要路径:

A) /usr/arm-linux-gnueabi/include/c++/4.7.3
B) /usr/arm-linux-gnueabi/include/c++/4.7.3/arm-linux-gnueabi

但内置路径尝试使用:

C) /usr/arm-linux-gnueabi/usr/arm-linux-gnueabi/include/c++/4.7.3
D) /usr/arm-linux-gnueabi/usr/arm-linux-gnueabi/include/c++/4.7.3/arm-linux-gnueabi/sf E) /usr/arm-linux-gnueabi/usr/arm-linux-gnueabi/include/c++/4.7.3/backward

注意内置路径使用了额外的“/usr/arm-linux-gnueabi”

【讨论】:

    猜你喜欢
    • 2021-10-25
    • 2020-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-11
    相关资源
    最近更新 更多