ARM 与较旧的 glibc 交叉编译
ARM cross compiling with older glibc
我正在尝试将 uGFX 库静态构建到我的主二进制文件中。我正在交叉编译。我的构建系统是 Ubuntu Linux 并且主机是 ARM 环境。
构建成功,但是在我的主机上执行二进制文件时,以下消息一直困扰着我:
binary_name: /lib/libc.so.6: version 'GLIBC_2.17' not found (required by binary_name)
只有在我的二进制文件中包含 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
...
我尝试了 link 其他选项 nodefaultlibs and nostdlib。 libc.so.6
文件在 sysroot 中可用。我什至尝试在我的 CMakeLists.txt 中使用 find_library(MYLIBC c-2.25 PATHS /usr/gnueabi/arm-brcm-linux-gnueabi/sysroot/lib)
并将其包含在我的 target_link_libraries
中用于二进制文件,但也没有运气。
如何确保工具链 libc link针对我的二进制文件进行编辑?
更新 1
先回答问题。是的,我已经尝试静态 link libc 到我的二进制文件。但是不知何故,二进制文件变得太大了。嗯,设备崩溃 SIGSEGV
。此外,我不希望静态 link clib,因为最终我希望 uGFX
也被动态 linked。静态 link libc 到共享的是不行的。我也可以静态 link 将所有东西放在一起,但是二进制文件会变得很大,将来更新单个库时不是很方便。
在设备上 libc.so.6
存在。我设法得到了文件系统的转储。它位于主机的 /lib
目录中。此外,我在没有 uGFX
的情况下上传的二进制文件可以与 GLIBC_2.4
一起使用并且可以动态地正常工作 linked.
宿主系统运行如下OS:
Linux (none) 2.6.32.9 #1 PREEMPT Tue Jan 16 11:00:00 CST 2018 armv6l GNU/Linux
此外,上述 cmake
文件在静态 link 二进制文件方面可能不清楚。这些示例显示了 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@");
linking 的麻烦已经结束,现在它以以下内容结束:
[TERMINATION] errorNum = 11 POSIX signal 11 : SIGSEGV
当我静态地 link 处理所有内容时,这看起来是一样的。我将对此进行进一步调查。如果有人有任何想法,我想听听他们:)
您构建的库需要动态库libc
,但是您的host os没有。请告诉我们您 os 运行 是谁?是否包含动态库libc
.
- 如果它包含
libc
库,请确保正确的 link 库目录
- 如果没有
libc
,是否可以在构建 uGFX
时使用静态库来代替 libc
,或者只是从您的工具链目录中复制 libc.so
(它应该存在)到你的 host os lib path
然后再试一次。
找到问题的解决方法。结果我需要添加以下编译器标志:-lrt。这链接了包含 clock_gettime
函数的实时扩展库。所以我不需要 asm
hack,它不是解决这个问题的方法。
至于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
复制到项目的包含目录并重命名。
此外,在这种特殊情况下,您可以使用位于 ${ugfx_src}/boards/base/Linux-Framebuffer/board-framebuffer.h
中的帧缓冲板文件 board_framebuffer.h
。
我正在尝试将 uGFX 库静态构建到我的主二进制文件中。我正在交叉编译。我的构建系统是 Ubuntu Linux 并且主机是 ARM 环境。 构建成功,但是在我的主机上执行二进制文件时,以下消息一直困扰着我:
binary_name: /lib/libc.so.6: version 'GLIBC_2.17' not found (required by binary_name)
只有在我的二进制文件中包含 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
...
我尝试了 link 其他选项 nodefaultlibs and nostdlib。 libc.so.6
文件在 sysroot 中可用。我什至尝试在我的 CMakeLists.txt 中使用 find_library(MYLIBC c-2.25 PATHS /usr/gnueabi/arm-brcm-linux-gnueabi/sysroot/lib)
并将其包含在我的 target_link_libraries
中用于二进制文件,但也没有运气。
如何确保工具链 libc link针对我的二进制文件进行编辑?
更新 1
先回答问题。是的,我已经尝试静态 link libc 到我的二进制文件。但是不知何故,二进制文件变得太大了。嗯,设备崩溃 SIGSEGV
。此外,我不希望静态 link clib,因为最终我希望 uGFX
也被动态 linked。静态 link libc 到共享的是不行的。我也可以静态 link 将所有东西放在一起,但是二进制文件会变得很大,将来更新单个库时不是很方便。
在设备上 libc.so.6
存在。我设法得到了文件系统的转储。它位于主机的 /lib
目录中。此外,我在没有 uGFX
的情况下上传的二进制文件可以与 GLIBC_2.4
一起使用并且可以动态地正常工作 linked.
宿主系统运行如下OS:
Linux (none) 2.6.32.9 #1 PREEMPT Tue Jan 16 11:00:00 CST 2018 armv6l GNU/Linux
此外,上述 cmake
文件在静态 link 二进制文件方面可能不清楚。这些示例显示了 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@");
linking 的麻烦已经结束,现在它以以下内容结束:
[TERMINATION] errorNum = 11 POSIX signal 11 : SIGSEGV
当我静态地 link 处理所有内容时,这看起来是一样的。我将对此进行进一步调查。如果有人有任何想法,我想听听他们:)
您构建的库需要动态库libc
,但是您的host os没有。请告诉我们您 os 运行 是谁?是否包含动态库libc
.
- 如果它包含
libc
库,请确保正确的 link 库目录 - 如果没有
libc
,是否可以在构建uGFX
时使用静态库来代替libc
,或者只是从您的工具链目录中复制libc.so
(它应该存在)到你的 host oslib path
然后再试一次。
找到问题的解决方法。结果我需要添加以下编译器标志:-lrt。这链接了包含 clock_gettime
函数的实时扩展库。所以我不需要 asm
hack,它不是解决这个问题的方法。
至于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
复制到项目的包含目录并重命名。
此外,在这种特殊情况下,您可以使用位于 ${ugfx_src}/boards/base/Linux-Framebuffer/board-framebuffer.h
中的帧缓冲板文件 board_framebuffer.h
。