Я пишу код на C ++ 17 для Digilent Zybo Zynq-7000 (ARMv7 Cortex-A9).Я использую arm-linux-gnueabihf GCC 8.3 toolchain .Я скачал компилятор и системный корень.
Я могу скомпилировать и запустить проект, используя флаг компоновщика -static
, но это приводит к огромным двоичным файлам, и я сталкиваюсь с внутренними ошибками компилятора, если я включаю LTO.
Когда я пытаюсь скомпилировать его с использованием общих библиотек, я не могу запустить его на целевом устройстве, даже после копирования всех файлов .so
в папках sysroot-glibc-8.3-2019.03-x86_64-arm-linux-gnueabi/lib
и usr/lib
.
Важная часть моего Dockerfile со средой сборки:
RUN wget https://developer.arm.com/-/media/Files/downloads/gnu-a/8.3-2019.03/binrel/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf.tar.xz
RUN tar xf gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf.tar.xz && \
rm gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf.tar.xz
ENV PATH="${PATH}:/home/develop/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin"
RUN wget https://developer.arm.com/-/media/Files/downloads/gnu-a/8.3-2019.03/binrel/sysroot/sysroot-glibc-8.3-2019.03-x86_64-arm-linux-gnueabi.tar.xz
RUN mkdir /home/develop/sysroot-glibc-8.3-2019.03-x86_64-arm-linux-gnueabi
WORKDIR /home/develop/sysroot-glibc-8.3-2019.03-x86_64-arm-linux-gnueabi
RUN tar xf ../sysroot-glibc-8.3-2019.03-x86_64-arm-linux-gnueabi.tar.xz && \
rm ../sysroot-glibc-8.3-2019.03-x86_64-arm-linux-gnueabi.tar.xz
( Полная версия на GitHub )
Файл моего набора инструментов CMake:
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_VERSION 1)
# Specify the cross compiler
SET(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
SET(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
# Where is the target environment
SET(CMAKE_FIND_ROOT_PATH /home/develop/sysroot-glibc-8.3-2019.03-x86_64-arm-linux-gnueabi)
# Search for programs in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \
-mcpu=cortex-a9 \
-mfpu=neon -mfloat-abi=hard -ftree-vectorize -mvectorize-with-neon-quad"
CACHE STRING "" FORCE)
# Link all libraries statically
# SET(CMAKE_EXE_LINKER_FLAGS " -static"
# CACHE STRING "" FORCE)
Общие библиотеки, необходимые моему исполняемому файлу:
$ arm-linux-gnueabihf-readelf -d bin/test-crypto
Dynamic section at offset 0x5cef0 contains 29 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libpthread.so.0]
0x00000001 (NEEDED) Shared library: [libstdc++.so.6]
0x00000001 (NEEDED) Shared library: [libm.so.6]
0x00000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x00000001 (NEEDED) Shared library: [libc.so.6]
Когда я пытаюсь запустить исполняемый файл на цели, я получаю следующую ошибку, поскольку он не может найти необходимые библиотеки:
$ /media/test-crypto
/bin/sh: /media/test-crypto: not found
$ ldd /media/test-crypto
checking sub-depends for 'not found'
checking sub-depends for '/usr/lib/libstdc++.so.6'
checking sub-depends for 'not found'
checking sub-depends for '/lib/libgcc_s.so.1'
checking sub-depends for 'not found'
checking sub-depends for '/lib/libm.so.1'
libc.so.1 => /lib/libc.so.1 (0xb6ea7000)
ld-uClibc.so.1 => /lib/ld-uClibc.so.1 (0xb6f06000)
checking sub-depends for '/lib/libc.so.1'
ld-uClibc.so.1 => /lib/ld-uClibc.so.1 (0xb6f88000)
libpthread.so.0 => not found (0x00000000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00000000)
libm.so.6 => not found (0x00000000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00000000)
libc.so.6 => not found (0x00000000)
libm.so.1 => /lib/libm.so.1 (0x00000000)
libc.so.1 => /lib/libc.so.1 (0x00000000)
/lib/ld-uClibc.so.1 => /lib/ld-uClibc.so.1 (0x00000000)
/lib/ld-uClibc.so.1 => /lib/ld-uClibc.so.1 (0x00000000)
Я проверил папки / lib и / usr / lib на цели, и /usr/lib/libstdc++.so.6
и /lib/libgcc_s.so.1
есть, остальные три нет.
Когда я копирую все библиотеки из папки sysroot GCC на SD-карту и добавляю их в LD_LIBRARY_PATH
, вывод ldd
изменяется, и кажется, что он находит все библиотеки, но когда я пытаюсь запустить исполняемый файл, я все ещеполучаю ту же ошибку:
$ LD_LIBRARY_PATH=/media/lib ldd /media/test-crypto
checking sub-depends for '/media/lib/libpthread.so.0'
checking sub-depends for '/media/lib/libstdc++.so.6'
checking sub-depends for '/media/lib/libm.so.6'
checking sub-depends for '/media/lib/libgcc_s.so.1'
checking sub-depends for '/media/lib/libc.so.6'
libpthread.so.0 => /media/lib/libpthread.so.0 (0x00000000)
libstdc++.so.6 => /media/lib/libstdc++.so.6 (0x00000000)
libm.so.6 => /media/lib/libm.so.6 (0x00000000)
libgcc_s.so.1 => /media/lib/libgcc_s.so.1 (0x00000000)
libc.so.6 => /media/lib/libc.so.6 (0x00000000)
/lib/ld-linux.so.3 => /lib/ld-linux.so.3 (0x00000000)
/lib/ld-linux.so.3 => /lib/ld-linux.so.3 (0x00000000)
$ LD_LIBRARY_PATH=/media/lib /media/test-crypto
/bin/sh: /media/test-crypto: not found
Я пытался создать символические ссылки избиблиотеки в /lib
и /usr/lib
с использованием ln -s /media/lib/* /lib
, но это не сработало.
Я не могу добавить системный корень GCC в архив rootfs.cpio образа Linux, который нам дали, потому что он слишкомбольшой, и он больше не загружается, когда я добавляю слишком много файлов.Файловая система SD-карты FAT32 не поддерживает символические ссылки, и многие из разделяемых библиотек являются символическими ссылками, так что, возможно, это проблема.Я попытался использовать ext2 и ext4 вместо FAT, но это не поддерживается платой разработки, оно просто не загружается, если я пробую что-то еще, кроме FAT.Добавление второго раздела только для библиотек тоже не сработало.
Каков наилучший способ установки необходимых библиотек на SD-карту, чтобы я мог запускать свои программы на C / C ++?