I am trying to cross-compile a simple C program with GTK for arm-linux-gnueabi
on Windows 10 x86_64
, using toolchains and sysroots provided by Linaro.
The tools I use in compilation:
- Build suite: Cmake 3.23.2
- Make tool: Ninja 1.10.2
- Build toolchain: Linaro GCC 5.5, as above
- IDE: CLion 2022.2
My cross compile configuration .cmake
file:
# User's variables
set(USER_CROSS_TOOLCHAIN_ROOT "D:/gcc")
set(USER_CROSS_SYSROOT "D:/sysroot")
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_C_COMPILER "${USER_CROSS_TOOLCHAIN_ROOT}/bin/arm-linux-gnueabi-gcc.exe")
set(CMAKE_CXX_COMPILER "${USER_CROSS_TOOLCHAIN_ROOT}/bin/arm-linux-gnueabi-g .exe")
set(CMAKE_FIND_ROOT_PATH "${USER_CROSS_TOOLCHAIN_ROOT}"
"${USER_CROSS_TOOLCHAIN_ROOT}/arm-linux-gnueabi"
)
set(CMAKE_SYSROOT "${USER_CROSS_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)
As you see, CMAKE_SYSROOT
is defined in the file above.
My CMakeLists.txt
:
cmake_minimum_required(VERSION 3.23)
project(gtkHelloWorld C)
set(CMAKE_C_STANDARD 99)
link_directories(lib)
add_executable(${PROJECT_NAME} main.c)
target_link_libraries(${PROJECT_NAME} PRIVATE libgtk-x11-2.0.so libgdk-x11-2.0.so libXrender.so libgdk_pixbuf-2.0.so libpangocairo-1.0.so libXdamage.so libXfixes.so libatk-1.0.so libpng16.so libxcb-shm.so libxcb-render.so libX11.so libgio-2.0.so libpangoft2-1.0.so libfontconfig.so libfreetype.so libz.so libexpat.so libffi.so libgmodule-2.0.so libgthread-2.0.so libglib-2.0.so)
path/to/arm-linux-gnueabi-gcc.exe -{PARAMETERS BELOW...} -print-search-dirs
prints (formatted):
...
Library:
d:/gcc/lib/gcc/arm-linux-gnueabi/5.5.0/
d:/gcc/lib/gcc/arm-linux-gnueabi/
d:/gcc/lib/gcc/
d:/gcc/arm-linux-gnueabi/lib/arm-linux-gnueabi/5.5.0/
d:/gcc/arm-linux-gnueabi/lib/arm-linux-gnueabi/
d:/gcc/arm-linux-gnueabi/lib/
D:/sysroot/lib/arm-linux-gnueabi/5.5.0/
D:/sysroot/lib/arm-linux-gnueabi/
D:/sysroot/lib/
D:/sysroot/usr/lib/arm-linux-gnueabi/5.5.0/
D:/sysroot/usr/lib/arm-linux-gnueabi/
D:/sysroot/usr/lib/
Problem
Everything had been fine until I tried to compile the binary.
I got errors like:
arm-linux-gnueabi/bin/ld.exe: cannot find /lib/libc.so.6
arm-linux-gnueabi/bin/ld.exe: cannot find /usr/lib/libc_nonshared.a
arm-linux-gnueabi/bin/ld.exe: cannot find /lib/ld-linux.so.3
collect2.exe: error: ld returned 1 exit status
The minimal command to reproduce the error:
path/to/arm-linux-gnueabi-gcc.exe \
--sysroot=D:/sysroot \
-g CMakeFiles/gtkHelloWorld.dir/main.c.o \
-LD:/Code/gtkHelloWorld/lib \
-lgtk-x11-2.0 -lgdk-x11-2.0 -lXrender -lgdk_pixbuf-2.0 -lpangocairo-1.0 -lXdamage -lXfixes -latk-1.0 -lpng16 -lxcb-shm -lxcb-render -lX11 -lgio-2.0 -lpangoft2-1.0 -lfontconfig -lfreetype -lz -lexpat -lffi -lgmodule-2.0 -lgthread-2.0 -lglib-2.0
-v
option prints (formatted):
Using built-in specs.
COLLECT_GCC=D:\gcc\bin\arm-linux-gnueabi-gcc.exe
COLLECT_LTO_WRAPPER=d:/gcc/libexec/gcc/arm-linux-gnueabi/5.5.0/lto-wrapper.exe
Target: arm-linux-gnueabi
Configured with: ...
Thread model: posix
gcc version 5.5.0 (Linaro GCC 5.5-2017.10)
COMPILER_PATH=
d:/gcc/libexec/gcc/arm-linux-gnueabi/5.5.0/;
d:/gcc/libexec/gcc/arm-linux-gnueabi/;
d:/gcc/libexec/gcc/;
d:/gcc/arm-linux-gnueabi/bin/
LIBRARY_PATH=
d:/gcc/lib/gcc/arm-linux-gnueabi/5.5.0/;
d:/gcc/lib/gcc/arm-linux-gnueabi/;
d:/gcc/lib/gcc/;
d:/gcc/arm-linux-gnueabi/lib/;
D:/sysroot/lib/;
D:/sysroot/usr/lib/
COLLECT_GCC_OPTIONS='-g' '-LD:/Code/gtkHelloWorld/lib' '-v' '-march=armv7-a' '-mtune=cortex-a9' '-mfloat-abi=soft' '-mthumb' '-mtls-dialect=gnu'
d:/gcc/libexec/gcc/arm-linux-gnueabi/5.5.0/collect2.exe \
-plugin d:/gcc/libexec/gcc/arm-linux-gnueabi/5.5.0/liblto_plugin-0.dll \
-plugin-opt=d:/gcc/libexec/gcc/arm-linux-gnueabi/5.5.0/lto-wrapper.exe \
-plugin-opt=-fresolution=C:\Users\w568w\AppData\Local\Temp\ccWU1Lgv.res \
-plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s \
--sysroot=D:/sysroot \
--build-id --eh-frame-hdr \
-dynamic-linker /lib/ld-linux.so.3 \
-X -m armelf_linux_eabi D:/sysroot/usr/lib/crt1.o D:/sysroot/usr/lib/crti.o d:/gcc/lib/gcc/arm-linux-gnueabi/5.5.0/crtbegin.o \
-LD:/Code/gtkHelloWorld/lib \
-Ld:/gcc/lib/gcc/arm-linux-gnueabi/5.5.0 \
-Ld:/gcc/lib/gcc/arm-linux-gnueabi \
-Ld:/gcc/lib/gcc \
-Ld:/gcc/arm-linux-gnueabi/lib \
-LD:/sysroot/lib \
-LD:/sysroot/usr/lib \
CMakeFiles/gtkHelloWorld.dir/main.c.o \
-rpath D:/Code/gtkHelloWorld/lib \
-lgtk-x11-2.0 -lgdk-x11-2.0 -lXrender -lgdk_pixbuf-2.0 -lpangocairo-1.0 -lXdamage -lXfixes -latk-1.0 -lpng16 -lxcb-shm -lxcb-render -lX11 -lgio-2.0 -lpangoft2-1.0 -lfontconfig -lfreetype -lz -lexpat -lffi -lgmodule-2.0 -lgthread-2.0 -lglib-2.0 -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_ \
--no-as-needed d:/gcc/lib/gcc/arm-linux-gnueabi/5.5.0/crtend.o D:/sysroot/usr/lib/crtn.o
(...A lot of "attempt to open" and "succeeded"...)
opened script file D:/Code/gtkHelloWorld/lib/libc.so
attempt to open /lib/libc.so.6 failed
attempt to open /usr/lib/libc_nonshared.a failed
attempt to open /lib/ld-linux.so.3 failed
d:/gcc/arm-linux-gnueabi/bin/ld.exe: cannot find /lib/libc.so.6
d:/gcc/arm-linux-gnueabi/bin/ld.exe: cannot find /usr/lib/libc_nonshared.a
d:/gcc/arm-linux-gnueabi/bin/ld.exe: cannot find /lib/ld-linux.so.3
collect2.exe: error: ld returned 1 exit status
The file appeared in the output above, D:/Code/gtkHelloWorld/lib/libc.so
is:
/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
OUTPUT_FORMAT(elf32-littlearm)
GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a AS_NEEDED ( /lib/ld-linux.so.3 ) )
What confuses me is that, all answers I could find tell me to add --sysroot=
(or -Wl,--sysroot=
), which I have done from the beginning.
Also, I can confirm that the three .so files exactly exist at {SYS_ROOT}/lib
and {SYS_ROOT}/usr/lib
.
I suppose that the linker does notice the sysroot
, because removing --sysroot=
from the command will produce another error saying cannot find crt1.o
.
The answers I have tried but failed
- cannot find /lib/libc.so.6 even after setting sysroot : Add
-Wl
before--sysroot
- Cannot find /lib/libc.so.6 : Add
--sysroot
- cannot find /lib64/libc.so.6 : Same situation, still no answer
CodePudding user response:
Thanks @n-1-8e9-wheres-my-share-m and @infinitezero for giving advice on how to debug this problem. Now I can answer it by myself.
The crucial point is that ld.exe
does not always follow SYS_ROOT
or see it as a virtual filesystem root.
It services as a shortcut for including a complete set of headers and libraries (usually useful when doing cross compilation). The documentation says:
--sysroot=dir
Use dir as the logical root directory for headers and libraries. For example, if the compiler normally searches for headers in
/usr/include
and libraries in/usr/lib
, it instead searchesdir/usr/include
anddir/usr/lib
.
But the document omits some special rules. As was discussed here,
You misunderstand GNU
ld
's--sysroot
rule, which is applicable in these two cases:
- when a path begins with
=
or$SYSROOT
- (Only) in case a sysroot prefix is configured, and the filename starts with the ‘/’ character, and the script being processed was located inside the sysroot prefix, the filename will be looked for in the sysroot prefix.
Otherwise, ld
will only look at the absolute path defined in the script (/lib/xxx
), instead of {SYS_ROOT}/lib/xxx
.
So a quick fix for my problem is to change the ld script gtkHelloWorld/lib/libc.so
in my project to
/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
OUTPUT_FORMAT(elf32-littlearm)
GROUP ( =/lib/libc.so.6 =/usr/lib/libc_nonshared.a AS_NEEDED ( =/lib/ld-linux.so.3 ) )
Then it compiles normally.
Ref: for those who'd like to explore more about ld script, this is a comprehensive doc.
CodePudding user response:
You can try to add this to your cmake file
find_library(LIB_C "libc" HINTS ${USER_SYSROOT}/lib)
message(STATUS "LIB: ${LIB_C}")
To get an idea if cmake can find it. Then just add ${LIB_C} to target_link_libraries