LINUX.ORG.RU

Кросс компиляции qt приложения

 , , , ,


0

1

Здравствуйте. Имеется следующий вопрос. Нужно кросс компилировать qt приложение. Хост х86_64 таргет aarch64. Дорожка то известна. Берем сорцы, компилим и библиотеку и тулзы. На выходе кидаем библиотеку и elf по папочкам, смотрим ldd чтобы линканулось все правильно. Почему задаю вопрос, если все известно. Была проблема когда приложение работало нормально, но при магических числах, если выводить на консоль, оно крашилось. Оказалась проблема в glibc, что-то там с тулчейном случилось линаровским. Поэтому было принято решение взять уже готовый дистр бубунту и скачать бинарники всех нужных либ. Вопрос в следующем, чтобы скомпилить qt проект нужны кросс платформенные тулзы 4 штуки. Moc rcc uic и ещё одна. Как мне их получить, собрать проект желательно на cmake. Если сисрут есть и aarch64 gnu компилятор есть. Не хочу брать линаро, ибо может ещё какой приколдес выйдет.

PS Если компилить обычный не qt проект ругается на отсутствие crt1.o, хотя в сисруте он есн.

Дорожка то известна. Берем сорцы, компилим и библиотеку и тулзы. На выходе кидаем библиотеку и elf по папочкам, смотрим ldd чтобы линканулось все правильно.

Плохая дорожка. Потому что Qt загружает некоторые свои либы в рантайме через dlopen, смотреть надо в сторону:

  1. https://github.com/probonopd/linuxdeployqt
  2. https://doc.qt.io/qt-6/linux-deployment.html

PS Если компилить обычный не qt проект ругается на отсутствие crt1.o, хотя в сисруте он есн.

Установи ARM64-компилятор на хост нормально, так чтобы всё компилировалось без Qt и подобного.

qt проект нужны кросс платформенные тулзы 4 штуки. Moc rcc uic и ещё одна

Утилиты moc, uic и rcc генерируют C++-листинги кода, они уже кроссплатформенные априори.

EXL ★★★★★
()

Ну я кросскомпилю так: dnf --installroot /path/to/sysroot install ..., ну или тоже самое с mock. Для убунты по идее можно делать тоже debootstrap’ом. Там тебе нужно устрановить qt5-qtbase-dev, libc-dev и libstdc++-dev.

Чтобы не ругался на отсутствие crt1.o и прочих файлов, нужно правильно указать sysroot. У меня тулчейн получился примерно таким:

# CMake toolchain definitions for buildroot /var/lib/mock/redos-7-aarch64/root

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)

set(CMAKE_SYSROOT "/var/lib/mock/alma+epel-9-aarch64/root")
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})

set(CMAKE_C_COMPILER /usr/bin/aarch64-linux-gnu-gcc)
set(CMAKE_C_COMPILER_TARGET aarch64-linux-gnu)

set(CMAKE_CXX_COMPILER /usr/bin/aarch64-linux-gnu-g++)
set(CMAKE_CXX_COMPILER_TARGET aarch64-linux-gnu)

# cross binutils.
set(CMAKE_AR "/usr/bin/aarch64-linux-gnu-ar")
set(CMAKE_RANLIB "/usr/bin/aarch64-linux-gnu-ranlib")

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(CMAKE_C_STANDARD_INCLUDE_DIRECTORIES SYSTEM "${CMAKE_SYSROOT}/usr/include" "${CMAKE_SYSROOT}/usr/include/aarch64-linux-gnu")
set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES SYSTEM "${CMAKE_SYSROOT}/usr/include/c++/11" "${CMAKE_SYSROOT}/usr/include/c++/11/aarch64-redhat-linux" "${CMAKE_SYSROOT}/usr/include/aarch64-linux-gnu/c++/11" "${CMAKE_SYSROOT}/usr/include" "${CMAKE_SYSROOT}/usr/include/aarch64-linux-gnu")

# PkgConfig.
set(ENV{PKG_CONFIG_DIR} "")
set(ENV{PKG_CONFIG_PATH} "")
set(ENV{PKG_CONFIG_LIBDIR} "${CMAKE_SYSROOT}/usr/lib64/pkgconfig:${CMAKE_SYSROOT}/usr/share/pkgconfig")
set(ENV{PKG_CONFIG_SYSROOT_DIR} "${CMAKE_SYSROOT}")

# Qt utils.
set(AUTOMOC_EXECUTABLE "/usr/lib64/qt5/bin/moc")
set(AUTORCC_EXECUTABLE "/usr/lib64/qt5/bin/rcc")
set(AUTOUIC_EXECUTABLE "/usr/lib64/qt5/bin/uic")

При этом автоматом цеплять moc у меня так и не получилось, поэтому в CMakeLists.txt добавлено такое:

if(AUTOMOC_EXECUTABLE)
    message(STATUS "Используем ${AUTOMOC_EXECUTABLE} в качестве moc.")
    set_target_properties(Qt5::moc PROPERTIES IMPORTED_LOCATION "${AUTOMOC_EXECUTABLE}")
endif()

moc, uic и rcc штатные с хоста, это не проблема.

Я не то, чтобы много qt’шного кросскомпилю, но пока всё работает без проблем.

Ivan_qrt ★★★★★
()
Ответ на: комментарий от Ivan_qrt

Если использовать кросс-компилированный Qt, то все просто работает без плясок с moc/uic/rcc, так как они собираются под хост и автоматически подхватываются. Единственный минус в том, что нужно компилировать.

annulen ★★★★★
()
Ответ на: комментарий от annulen

Ну я компилю под конкретные дистрибутивы, которые будут на железке, а тут самосборный qt не очень хорош, т.к. его придётся таскать с собой. Учитывая, что все проблемы со сборкой в buildroot достаточно просто обходятся, то в моей ситуации компилить qt не имеет большого смысла. Хотя кому-то так возможно лучше.

Ivan_qrt ★★★★★
()
Ответ на: комментарий от Ivan_qrt

Ну я компилю под конкретные дистрибутивы, которые будут на железке, а тут самосборный qt не очень хорош, т.к. его придётся таскать с собой.

Это верно. Можно, конечно, собрать у себя «такой же, только с перламутровыми пуговицами», но можно напортачить с опциями сборки и получить бинарно несовместимый.

annulen ★★★★★
()
Ответ на: комментарий от EXL

Я с этим linuxdeployqt не смог разобраться.

Каким образом он помещает в итоговый каталог бублиотеки, подгружаемые через dlopen()? К ним относятся например плагины поддержки графических форматов типа SVG, PNG...

Единственное что я нашел - это использование опции:

-extra-plugins=iconengines,platformthemes/libqgtk3.so

Таким образом, нужно знать, какие компоненты подгружаются через dlopen(), и перечислять их в вышеуказанной опции. А откуда этот список можно выяснить? И получается что если за этим списком вручную не уследить, то linuxdeployqt сам автоматически не поймет какие библиотеки нужны, и готовая сборка опять таки не будет иметь нужных библиотек.

Xintrea ★★★★★
()