MyTetra Share
Делитесь знаниями!
Как настроить кросс-компиляцию в Qt5/Qt6 с использованием CMake
Время создания: 05.09.2023 11:55
Текстовые метки: linux, qt5, qt6, кросс-компиляция, toolchain, тулчейн, инструменты, настройка, параметры, пути, компилятор, cmake
Раздел: Компьютер - Программирование - Язык C++ (Си++) - Библиотека Qt - Инсталляция Qt и сборка проектов
Запись: xintrea/mytetra_syncro/master/base/1693904118qw7hzc3ysd/text.html на raw.github.com

Сразу надо сказать, что под андроид сборку не делал, только под другую платформу. Кросскомпиляция в этом случае выглядит так:



cmake -S /path/to/project -B /tmp/build -DCMAKE_TOOLCHAIN_FILE=/path/to/sysroot/usr/share/cmake/toolchain.cmake -DCMAKE_BUILD_TYPE=Release



Но вообще, под Андроид настройка ровно та же самая - файл тулчейна там идет в комплекте с NDK, плюс нужно указать пару опций вроде ANDROID_ABI, про которые рассказывается в доке https://developer.android.com/ndk/guides/cmake#command-line .


Файл toolchain.cmake содержит такие опции:



set(CMAKE_SYSTEM_NAME Linux)

set(CMAKE_SYSTEM_PROCESSOR aarch64)


set(CMAKE_SYSROOT /path/to/sysroot)

set(CMAKE_FIND_ROOT_PATH /path/to/sysroot)


set(CMAKE_C_COMPILER /path/to/sysroot/bin/sysroot-gcc)

set(CMAKE_C_COMPILER_TARGET aarch64-linux-gnu)


set(CMAKE_CXX_COMPILER /path/to/sysroot/bin/sysroot-g++)

set(CMAKE_CXX_COMPILER_TARGET aarch64-linux-gnu)


set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH)

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_CXX_STANDARD_INCLUDE_DIRECTORIES SYSTEM /path/to/sysroot/usr/include/c++/10

/path/to/sysroot/usr/include/aarch64-linux-gnu/c++/10

/path/to/sysroot/usr/include

/path/to/sysroot/usr/include/aarch64-linux-gnu)


set(CMAKE_C_STANDARD_INCLUDE_DIRECTORIES SYSTEM /path/to/sysroot/usr/include/c++/10

/path/to/sysroot/usr/include/aarch64-linux-gnu/c++/10

/path/to/sysroot/usr/include

/path/to/sysroot/usr/include/aarch64-linux-gnu)



Файлы sysroot-gcc и sysroot-g++ - это просто обёртка над компилятором с указанием дополнительных опций. Она не обязательна, но так обычно удобнее работать:



#!/bin/bash


/usr/bin/aarch64-linux-gnu-gcc -isystem /path/to/sysroot/usr/include/c++/10 -isystem /path/to/sysroot/usr/include/aarch64-linux-gnu/c++/10 -isystem /path/to/sysroot/usr/include

-isystem /path/to/sysroot/usr/include/aarch64-linux-gnu --sysroot=/path/to/sysroot $@



В общем случае, чтобы что-то кросскомпилить, нужно указать компилятор, которым необходимо производить сборку, и указать компилятору, чтобы он использовал инклюды и библиотеки из конкретного buildroot. Ну и указать специфичные опции, если они нужны. В остальном файл cmake точно такой же как и в дефолной конфигурации.


Для qt ещё и утилиты в sysroot можно менять на хостовые и конфиги. Но это для qt5. Впрочем для qt6 отличий должно быть не много. Наверняка есть более изящное решение, но можно не запариваться с этим и просто использовать следующий Python скрипт:



def conf_qt5(root: str, wrapped_cc: str, wrapped_cxx: str):

"""Создаёт qmake, указывающий на qt5 из root, задаёт компиляторы для кросс-компиляции."""

with pushd(root):

# Заменяем собранные по args.arch утилиты на собранные под x86_64, т.к. их надо запускать на хосте.

for tool in ['qmake', 'moc', 'rcc', 'uic', 'lrelease']:

host_path = f'/usr/bin/{tool}-qt5'

if exists(host_path):

cmd('ln -svf {} {}', host_path, f'{root}/usr/lib64/qt5/bin/{tool}')


qtconf = f'{root}/usr/lib64/qt5/qt.conf'

with open(qtconf, 'w') as cfg:

cfg.write(f"""[Paths]

Prefix={root}/usr

ArchData=lib64/qt5

Binaries=lib64/qt5/bin

Data=share/qt5

Documentation=share/qt5/doc

Examples=lib64/qt5/examples

Headers=include/qt5

HostBinaries=lib64/qt5/bin

HostData=lib64/qt5

HostLibraries=lib64

Imports=lib64/qt5/imports

Libraries=lib64

LibraryExecutables=lib64/qt5/libexec

Plugins=lib64/qt5/plugins

Qml2Imports=lib64/qt5/qml

Settings=/etc/xdg

Translations=share/qt5/translations

""")


qmake_file = f'{root}/bin/qmake'

with open(qmake_file, 'w') as qmake:

qmake.write(f"""#!/bin/bash\n\n{root}/usr/lib64/qt5/bin/qmake $@ -qtconf {qtconf}\n""")

chmod(qmake_file, 0o755)

qmake_spec = f'{root}/usr/lib64/qt5/mkspecs/common/g++-base.conf'

if exists(qmake_spec):

cmd("sed -i 's|$${{CROSS_COMPILE}}gcc|{}|g' {}", wrapped_cc, qmake_spec)

cmd("sed -i 's|$${{CROSS_COMPILE}}g++|{}|g' {}", wrapped_cxx, qmake_spec)



Так же в этом разделе:
 
MyTetra Share v.0.65
Яндекс индекс цитирования