首页 > 解决方案 > ARM 与旧的 glibc 交叉编译

问题描述

我正在尝试将uGFX库静态构建到我的主二进制文件中。我正在交叉编译。我的构建系统是 Ubuntu Linux,主机是 ARM 环境。构建成功,但是在我的主机上执行二进制文件时,以下消息一直困扰着我:

二进制名称:/lib/libc.so.6:未找到版本“GLIBC_2.17”(二进制名称需要)

这仅在将 uGFX 源包含到我的二进制文件时发生。这就是我的 CMakeLists.txt 在构建时的样子:

cmake_minimum_required(VERSION 3.9.1)
project(MyBinary)

set(CMAKE_C_FLAGS_DEBUG "-nostdinc -fsigned-char -Wstrict-prototypes -Wno-trigraphs -Wimplicit -Wformat")
set(CMAKE_CXX_FLAGS_DEBUG "-nostdinc++ -fsigned-char -Wno-trigraphs -Wimplicit -Wformat")

include_directories(./include
                ./include/ugfx
                ./ExternalProjects/ugfx
                ./ExternalProjects/ugfx/drivers/gdisp/framebuffer
                /usr/gnueabi/lib/gcc/arm-brcm-linux-gnueabi/6.3.0/include
                /usr/arm-linux-gnueabi/include
                /usr/arm-linux-gnueabi/include/linux)
link_directories(/usr/gnueabi/arm-brcm-linux-gnueabi/sysroot/lib)

set(SOURCE_FILES
   ./ExternalProjects/ugfx/src/gfx_mk.c
   ./ExternalProjects/ugfx/drivers/gdisp/framebuffer/gdisp_lld_framebuffer.c
   ./ExternalProjects/ugfx/drivers/ginput/touch/Linux-Event/gmouse_lld_linux_event.c
   MyBinary.c)

add_executable(MyBinary ${SOURCE_FILES})

target_link_libraries(MyBinary curl ssl)

我的工具链 cmake 文件:

include(CMakeForceCompiler)
set(CMAKE_CROSSCOMPILING 1)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_SYSROOT /usr/gnueabi/arm-brcm-linux-gnueabi/sysroot)

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

set(CROSS_COMPILER arm-linux-gnueabi)
set(CMAKE_C_COMPILER "/usr/gnueabi/bin/arm-brcm-linux-gnueabi-gcc")
set(CMAKE_CXX_COMPILER "/usr/gnueabi/bin/arm-brcm-linux-gnueabi-gcc")

使用 objdump 检查我的二进制文件时,我注意到以下内容:

Version References:
  required from libc.so.6:
    0x06969197 0x00 04 GLIBC_2.17
    0x0d696914 0x00 03 GLIBC_2.4
  r equired from libpthread.so.0:
   0x0d696914 0x00 02 GLIBC_2.4

这解释了我收到的信息。甚至进一步检查objdump -T显示以下内容:

...
00000000      DF *UND*  00000000  GLIBC_2.4   abort
00000000      DF *UND*  00000000  GLIBC_2.17  clock_gettime
00000000      DF *UND*  00000000  GLIBC_2.4   system
...

我尝试了链接器选项nodefaultlibsnostdlib。该libc.so.6文件在 sysroot 中可用。我什至尝试find_library(MYLIBC c-2.25 PATHS /usr/gnueabi/arm-brcm-linux-gnueabi/sysroot/lib)在我的 CMakeLists.txt 中使用并将其包含在我target_link_libraries的二进制文件中,但也没有运气。

如何确保工具链 libc 与我的二进制文件链接?

更新 1

先回答问题。是的,我尝试将 libc 静态链接到我的二进制文件。但不知何故,二进制文件变得太大了。好吧,设备崩溃了SIGSEGV。此外,我不希望静态链接 clib,因为最终我也想uGFX动态链接。并且静态地将 libc 链接到一个共享的是不行的。我也可以将所有内容静态链接在一起,但二进制文件会变得很大,将来更新单个库时不会很方便。

在设备上libc.so.6存在。我设法得到了文件系统的转储。它位于/lib主机的目录中。此外,我上传的二进制文件没有uGFX使用GLIBC_2.4并且可以很好地动态链接。

主机系统正在运行以下操作系统:

Linux(无)2.6.32.9 #1 PREEMPT 1 月 16 日星期二 11:00:00 CST 2018 armv6l GNU/Linux

此外,上述cmake文件可能不清楚将其静态链接到二进制文件。示例显示了uGFX添加到二进制文件本身的来源。但我最初尝试使用以下方法:

# Find libc-2.25.so in sysroot (which lives there)
find_library(MYLIBC c-2.25 PATHS /usr/gnueabi/arm-brcm-linux-gnueabi/sysroot/lib)
add_library(gfx STATIC
    ./ExternalProjects/ugfx/src/gfx_mk.c
    ./ExternalProjects/ugfx/drivers/gdisp/framebuffer/gdisp_lld_framebuffer.c
    ./ExternalProjects/ugfx/drivers/ginput/touch/Linux-Event/gmouse_lld_linux_event.c)
target_link_libraries(gfx ${MYLIBC})
target_link_libraries(MyBinary ${MYLIBC} gfx curl ssl)

更新 2

通过将此行添加到库中,我设法摆脱了 GLIB 依赖消息:

asm(".symver clock_gettime,clock_gettime@");

链接问题已经结束,现在它以以下方式终止:

[终止] errorNum = 11 POSIX 信号 11:SIGSEGV

当我静态链接所有内容时,这看起来是一样的。我将对此进行进一步调查。如果有人有任何想法,我想听听他们:)

标签: c++ccmakelinkerglibc

解决方案


找到了问题的解决方案。原来我需要添加以下编译器标志:-lrt。这链接了包含该clock_gettime功能的实时扩展库。所以我不需要asm破解,这不是解决这个问题的方法。

至于SIGSEGV,你需要自己初始化 uGFX 的板子。对于我的帧缓冲区,可以在 board_framebuffer.h 中找到它。该功能static void board_init(GDisplay *g, fbInfo *fbi)需要编辑。在这里,我映射了帧缓冲区 ( /dev/fb0) 并将其分配给fbi->pixels. 后者默认设置为 0,这会导致 SIGSEGV。必须将 board_framebuffer.h 文件复制${ugfx_src}/drivers/gdisp/framebuffer/board_framebuffer_template.h到项目的包含目录并重命名。此外,在这种特殊情况下,您可以使用board_framebuffer.h位于 中的帧缓冲板文件。${ugfx_src}/boards/base/Linux-Framebuffer/board-framebuffer.h


推荐阅读