|
|||||||
Как настроить кросс-компиляцию в 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) |
|||||||
Так же в этом разделе:
|
|||||||
|
|||||||
|