Время на прочтение
14 мин
Количество просмотров 77K
Библиотека Qt позволяет делать действительно кроссплатформенные приложения. Единожды написанный код можно откомпилировать под многие операционные системы. Но проблема именно в слове «компилировать», т.к. подразумевается, что необходимо перезагрузиться под целевую систему, иметь в ней настроенную среду разработки, установленный и настроенный зоопарк библиотек. Спасает кросс-компиляция — компиляция, производящая исполняемый код для платформы, отличной от той, на которой исполняется.
Кросс-компиляция для Windows 64
Обычно одной из наиболее востребованных проблем является сборка Windows-версии своего приложения, изначально разрабатывающегося под Linux. Пример решения этой проблемы можно увидеть тут или на русском. Необходимо создать mkspecs-конфигурацию, положить файлы Qt в соответствующие директории и всё. Компилировать Qt в таком случае не обязательно, можно скачать бинарники с официального сайта.
У такого подхода есть несколько минусов: 1) QtCreator об установленной таким образом библиотеке ничего не знает; 2) Официальной сборки Qt для Windows x64 не существует. И если с первой проблемой ещё как-то можно бороться, то против второй поможет только компиляция…
Перед кросс-компиляцией не забудьте поставить непосредственно сам кросс-компилятор (ищется в пакетом менеджере по названию «mingw»). И скачать исходники qt-everywhere с официального сайта. В директории mkspecs распакованного архива копируем папку win32-g++ в win64-x-g++ и корректируем содержимое файла qmake.conf. У меня получилось следующее:
Скрытый текст
#
# qmake configuration for win64-x-g++
#
# Written for MinGW
#
# Cross compile example for i686-w64-mingw32-g++:
# configure -xplatform win32-g++ -device-option CROSS_COMPILE=i686-w64-mingw32-
#
MAKEFILE_GENERATOR = MINGW
load(device_config)
equals(QMAKE_HOST.os, Windows): EXE_SUFFIX = .exe
TEMPLATE = app
CONFIG += qt warn_on release link_prl copy_dir_files debug_and_release debug_and_release_target precompile_header
QT += core gui
DEFINES += UNICODE
#QT_LARGEFILE_SUPPORT
QMAKE_COMPILER_DEFINES += __GNUC__ WIN WIN32 WIN64
QMAKE_EXT_OBJ = .o
QMAKE_EXT_RES = _res.o
QMAKE_CC = $${CROSS_COMPILE}gcc
QMAKE_LEX = flex
QMAKE_LEXFLAGS =
QMAKE_YACC = byacc
QMAKE_YACCFLAGS = -d
QMAKE_CFLAGS = -pipe -m64
QMAKE_CFLAGS_DEPS = -M
QMAKE_CFLAGS_WARN_ON = -Wall -Wextra
QMAKE_CFLAGS_WARN_OFF = -w
QMAKE_CFLAGS_RELEASE = -O2
QMAKE_CFLAGS_DEBUG = -g
QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
QMAKE_CXX = $${CROSS_COMPILE}g++
QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
QMAKE_CXXFLAGS_RTTI_ON = -frtti
QMAKE_CXXFLAGS_RTTI_OFF = -fno-rtti
QMAKE_CXXFLAGS_EXCEPTIONS_ON = -fexceptions -mthreads
QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -fno-exceptions
QMAKE_INCDIR = /usr/x86_64-w64-mingw32/include
QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
QMAKE_RUN_CC = $(CC) -c $(CFLAGS) $(INCPATH) -o $obj $src
QMAKE_RUN_CC_IMP = $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
QMAKE_RUN_CXX = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $obj $src
QMAKE_RUN_CXX_IMP = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
QMAKE_LINK = $${CROSS_COMPILE}g++
QMAKE_LINK_C = $${CROSS_COMPILE}gcc
#QMAKE_LFLAGS = -m64
QMAKE_LFLAGS = -m64 -mthreads -static-libgcc -static -Wl,-enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc -mwindows
QMAKE_LFLAGS_EXCEPTIONS_ON = -mthreads
QMAKE_LFLAGS_EXCEPTIONS_OFF =
QMAKE_LFLAGS_RELEASE = -Wl,-s
QMAKE_LFLAGS_DEBUG =
QMAKE_LFLAGS_CONSOLE = -Wl,-subsystem,console
QMAKE_LFLAGS_WINDOWS = -Wl,-subsystem,windows
QMAKE_LFLAGS_DLL = -shared
QMAKE_LINK_OBJECT_MAX = 10
QMAKE_LINK_OBJECT_SCRIPT= object_script
QMAKE_PREFIX_STATICLIB = lib
QMAKE_EXTENSION_STATICLIB = a
QMAKE_LIBS =
QMAKE_LIBS_CORE = -lole32 -luuid -lws2_32 -ladvapi32 -lshell32 -luser32 -lkernel32
QMAKE_LIBS_GUI = -lgdi32 -lcomdlg32 -loleaut32 -limm32 -lwinmm -lwinspool -lws2_32 -lole32 -luuid -luser32 -ladvapi32
QMAKE_LIBS_NETWORK = -lws2_32
QMAKE_LIBS_OPENGL = -lglu32 -lopengl32 -lgdi32 -luser32
QMAKE_LIBS_COMPAT = -ladvapi32 -lshell32 -lcomdlg32 -luser32 -lgdi32 -lws2_32
QMAKE_LIBS_QT_ENTRY = -lmingw32 -lqtmain
!isEmpty(QMAKE_SH) {
MINGW_IN_SHELL = 1
QMAKE_DIR_SEP = /
QMAKE_QMAKE ~= s,\\\\,/,
QMAKE_COPY = cp
QMAKE_COPY_DIR = cp -r
QMAKE_MOVE = mv
QMAKE_DEL_FILE = rm
QMAKE_MKDIR = mkdir -p
QMAKE_DEL_DIR = rmdir
QMAKE_CHK_DIR_EXISTS = test -d
} else {
QMAKE_COPY = copy /y
QMAKE_COPY_DIR = xcopy /s /q /y /i
QMAKE_MOVE = move
QMAKE_DEL_FILE = del
QMAKE_MKDIR = mkdir
QMAKE_DEL_DIR = rmdir
QMAKE_CHK_DIR_EXISTS = if not exist
}
QMAKE_MOC = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}moc$${EXE_SUFFIX}
QMAKE_UIC = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}uic$${EXE_SUFFIX}
QMAKE_IDC = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}idc$${EXE_SUFFIX}
QMAKE_IDL = midl
QMAKE_LIB = $${CROSS_COMPILE}ar -ru
QMAKE_RC = $${CROSS_COMPILE}windres
QMAKE_ZIP = zip -r -9
QMAKE_STRIP = $${CROSS_COMPILE}strip
QMAKE_STRIPFLAGS_LIB += --strip-unneeded
load(qt_config)
По сути в файле спецификации были заменены только пути.
Я выполнял configure со следующими параметрами:
./configure -xplatform win64-x-g++ CROSS_COMPILE=x86_64-w64-mingw32- -prefix /usr/local/qt4win64 -no-webkit -no-phonon -no-phonon-backend -no-script -no-scripttools -no-multimedia -no-qt3support -fast -nomake demos -nomake examples -nomake tools -device-option -little-endian -qt-zlib -qt-libpng -qt-libjpeg -openssl-linked -no-fontconfig -no-3dnow -no-ssse3 -continue
Здесь собираю минимальную версию Qt без webkit, phonon, multimedia и т.п. Полный список опций можно посмотреть по команде ./configure —help
Соответственно, для такой сборки должен быть установлен пакет g++-mingw-w64-x86-64, содержащий в себе x86_64-w64-mingw32-g++ (в убунту пакет надо ставить отдельно).
Далее make && sudo make install. На первом этапе компиляции используется родной системный компилятор, он собирает необходимые утилиты для linux, которые будут использоваться для сборки уже windows-бинарников.
После установки у меня в /usr/local/qt4win64/bin лежат PE32+ DLL и несколько ELF 64-bit LSB executable, в том числе: qmake, uic, moc, rcc. Вот они то и пригодятся для QtCreator!
После установки не удаляйте распакованную директорию — она используется.
Кросс-компиляция для Windows 32
Аналогична компиляции для Win64. За исключением того, что есть официальная сборка, и саму библиотеку компилировать не нужно! Достаточно собрать qmake, uic, moc, rcc.
configure:
Скрытый текст
./configure -xplatform win32-x-g++ -prefix /usr/local/qt4win32 CROSS_COMPILE=i686-w64-mingw32- -no-webkit -no-phonon -no-phonon-backend -no-script -no-scripttools -no-multimedia -no-qt3support -fast -nomake demos -nomake examples -nomake tools -device-option -little-endian -qt-zlib -qt-libpng -qt-libjpeg -openssl-linked -no-fontconfig -no-3dnow -no-ssse3 -continue
qmake.conf
Скрытый текст
#
# qmake configuration for win32-x-g++
#
# Written for MinGW
#
# Cross compile example for i686-w64-mingw32-g++:
# configure -xplatform win32-g++ -device-option CROSS_COMPILE=i686-w64-mingw32-
#
MAKEFILE_GENERATOR = MINGW
load(device_config)
equals(QMAKE_HOST.os, Windows): EXE_SUFFIX = .exe
TEMPLATE = app
CONFIG += qt warn_on release link_prl copy_dir_files debug_and_release debug_and_release_target precompile_header
QT += core gui
DEFINES += UNICODE
#QT_LARGEFILE_SUPPORT
QMAKE_COMPILER_DEFINES += __GNUC__ WIN WIN32
QMAKE_EXT_OBJ = .o
QMAKE_EXT_RES = _res.o
QMAKE_CC = $${CROSS_COMPILE}gcc
QMAKE_LEX = flex
QMAKE_LEXFLAGS =
QMAKE_YACC = byacc
QMAKE_YACCFLAGS = -d
QMAKE_CFLAGS = -pipe -m32
QMAKE_CFLAGS_DEPS = -M
QMAKE_CFLAGS_WARN_ON = -Wall -Wextra
QMAKE_CFLAGS_WARN_OFF = -w
QMAKE_CFLAGS_RELEASE = -O2
QMAKE_CFLAGS_DEBUG = -g
QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
QMAKE_CXX = $${CROSS_COMPILE}g++
QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
QMAKE_CXXFLAGS_RTTI_ON = -frtti
QMAKE_CXXFLAGS_RTTI_OFF = -fno-rtti
QMAKE_CXXFLAGS_EXCEPTIONS_ON = -fexceptions -mthreads
QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -fno-exceptions
QMAKE_INCDIR = /usr/i686-w64-mingw32/include
QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
QMAKE_RUN_CC = $(CC) -c $(CFLAGS) $(INCPATH) -o $obj $src
QMAKE_RUN_CC_IMP = $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
QMAKE_RUN_CXX = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $obj $src
QMAKE_RUN_CXX_IMP = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
QMAKE_LINK = $${CROSS_COMPILE}g++
QMAKE_LINK_C = $${CROSS_COMPILE}gcc
QMAKE_LFLAGS = -m32 -mthreads -static-libgcc -static -Wl,-enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc -mwindows
QMAKE_LFLAGS_EXCEPTIONS_ON = -mthreads
QMAKE_LFLAGS_EXCEPTIONS_OFF =
QMAKE_LFLAGS_RELEASE = -Wl,-s
QMAKE_LFLAGS_DEBUG =
QMAKE_LFLAGS_CONSOLE = -Wl,-subsystem,console
QMAKE_LFLAGS_WINDOWS = -Wl,-subsystem,windows
QMAKE_LFLAGS_DLL = -shared
QMAKE_LINK_OBJECT_MAX = 10
QMAKE_LINK_OBJECT_SCRIPT= object_script
QMAKE_PREFIX_STATICLIB = lib
QMAKE_EXTENSION_STATICLIB = a
QMAKE_LIBS =
QMAKE_LIBS_CORE = -lole32 -luuid -lws2_32 -ladvapi32 -lshell32 -luser32 -lkernel32
QMAKE_LIBS_GUI = -lgdi32 -lcomdlg32 -loleaut32 -limm32 -lwinmm -lwinspool -lws2_32 -lole32 -luuid -luser32 -ladvapi32
QMAKE_LIBS_NETWORK = -lws2_32
QMAKE_LIBS_OPENGL = -lglu32 -lopengl32 -lgdi32 -luser32
QMAKE_LIBS_COMPAT = -ladvapi32 -lshell32 -lcomdlg32 -luser32 -lgdi32 -lws2_32
QMAKE_LIBS_QT_ENTRY = -lmingw32 -lqtmain
!isEmpty(QMAKE_SH) {
MINGW_IN_SHELL = 1
QMAKE_DIR_SEP = /
QMAKE_QMAKE ~= s,\\\\,/,
QMAKE_COPY = cp
QMAKE_COPY_DIR = cp -r
QMAKE_MOVE = mv
QMAKE_DEL_FILE = rm
QMAKE_MKDIR = mkdir -p
QMAKE_DEL_DIR = rmdir
QMAKE_CHK_DIR_EXISTS = test -d
} else {
QMAKE_COPY = copy /y
QMAKE_COPY_DIR = xcopy /s /q /y /i
QMAKE_MOVE = move
QMAKE_DEL_FILE = del
QMAKE_MKDIR = mkdir
QMAKE_DEL_DIR = rmdir
QMAKE_CHK_DIR_EXISTS = if not exist
}
QMAKE_MOC = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}moc$${EXE_SUFFIX}
QMAKE_UIC = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}uic$${EXE_SUFFIX}
QMAKE_IDC = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}idc$${EXE_SUFFIX}
QMAKE_IDL = midl
QMAKE_LIB = $${CROSS_COMPILE}ar -ru
QMAKE_RC = $${CROSS_COMPILE}windres
QMAKE_ZIP = zip -r -9
QMAKE_STRIP = $${CROSS_COMPILE}strip
QMAKE_STRIPFLAGS_LIB += --strip-unneeded
load(qt_config)
Кросс-компиляция для Mac OS X
Кросс-компиляция для мака тоже очень похожа, за исключением того, что надо будет собрать и компилятор. Я собирал по этой инструкции. Это отняло полный день времени и кучу нервов. В процессе будет нужна рабочая Mac OS X (как минимум на виртуальной машине) с установленным XCode, чтобы взять оттуда необходимые файлы. При компилировании своих Qt-приложений запущенная Mac OS X не нужна.
configure:
Скрытый текст
./configure -xplatform macx-x-g++ -prefix /usr/x86_64-apple-darwin11/usr/Qt CROSS_COMPILE=/usr/x86_64-apple-darwin11/usr/bin/x86_64-apple-darwin11- -no-webkit -no-phonon -no-phonon-backend -no-script -no-scripttools -no-multimedia -no-qt3support -fast -nomake demos -nomake examples -nomake tools -device-option -little-endian -qt-zlib -qt-libpng -qt-libjpeg -openssl-linked -no-fontconfig -no-3dnow -no-ssse3 -continue
qmake.conf:
Скрытый текст
#macx-x-g++ (different from g++.conf)
#
# qmake configuration for macx-g++
#
# Mac OS X + command-line compiler
#
MAKEFILE_GENERATOR = UNIX
TARGET_PLATFORM = macx
TEMPLATE = app
CONFIG += qt warn_on release app_bundle incremental global_init_link_order lib_version_first plugin_no_soname link_prl
QT += core gui
QMAKE_INCREMENTAL_STYLE = sublib
#include(../common/mac.conf)
#
# qmake configuration for common Mac OS X
#
#QMAKE_RESOURCE = /Developer/Tools/Rez
QMAKE_EXTENSION_SHLIB = dylib
QMAKE_INCDIR = /usr/x86_64-apple-darwin11/usr/include
QMAKE_LIBDIR =
QMAKE_INCDIR_QT = /usr/x86_64-apple-darwin11/usr/Qt/include
QMAKE_LIBDIR_QT = /usr/x86_64-apple-darwin11/usr/Qt/lib
QMAKE_INCDIR_OPENGL = /System/Library/Frameworks/OpenGL.framework/Headers \
/System/Library/Frameworks/AGL.framework/Headers/
QMAKE_FRAMEWORKDIR_QT= /usr/x86_64-apple-darwin11/usr/QtFrameworks
QMAKE_FIX_RPATH = install_name_tool -id
QMAKE_LFLAGS_RPATH =
QMAKE_LIBS_DYNLOAD =
QMAKE_LIBS_OPENGL = -framework OpenGL -framework AGL
QMAKE_LIBS_OPENGL_QT = $$QMAKE_LIBS_OPENGL
QMAKE_LIBS_THREAD =
QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
QMAKE_AR = /usr/x86_64-apple-darwin11/usr/bin/x86_64-apple-darwin11-ar cq
QMAKE_RANLIB = /usr/x86_64-apple-darwin11/usr/bin/x86_64-apple-darwin11-ranlib -s
QMAKE_TAR = tar -cf
QMAKE_GZIP = gzip -9f
QMAKE_COPY = cp -f
QMAKE_COPY_FILE = $$QMAKE_COPY
QMAKE_COPY_DIR = $$QMAKE_COPY -R
QMAKE_MOVE = mv -f
QMAKE_DEL_FILE = rm -f
QMAKE_DEL_DIR = rmdir
QMAKE_CHK_DIR_EXISTS = test -d
QMAKE_MKDIR = mkdir -p
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.5 # overridden to 10.5 for Cocoa on the compiler command line
#
# qmake configuration for common unix
#
QMAKE_LEX = flex
QMAKE_LEXFLAGS +=
QMAKE_YACC = yacc
QMAKE_YACCFLAGS += -d
QMAKE_YACCFLAGS_MANGLE += -p $base -b $base
QMAKE_YACC_HEADER = $base.tab.h
QMAKE_YACC_SOURCE = $base.tab.c
QMAKE_PREFIX_SHLIB = lib
QMAKE_PREFIX_STATICLIB = lib
QMAKE_EXTENSION_STATICLIB = a
#include(../common/gcc-base-macx.conf)
#
# This file is used as a basis for the following compilers:
#
# - The QNX qcc compiler
#
# The only difference between this and gcc-base.conf is that -pipe is removed
# as it's on by default in qcc (and has an analogous -nopipe option)
#
QMAKE_CFLAGS +=
QMAKE_CFLAGS_DEPS += -M
QMAKE_CFLAGS_WARN_ON += -Wall -W
QMAKE_CFLAGS_WARN_OFF += -w
QMAKE_CFLAGS_RELEASE += -O2
QMAKE_CFLAGS_DEBUG += -g
QMAKE_CFLAGS_SHLIB += -fPIC
QMAKE_CFLAGS_STATIC_LIB += -fPIC
QMAKE_CFLAGS_YACC += -Wno-unused -Wno-parentheses
QMAKE_CFLAGS_HIDESYMS += -fvisibility=hidden
QMAKE_CXXFLAGS += $$QMAKE_CFLAGS
QMAKE_CXXFLAGS_DEPS += $$QMAKE_CFLAGS_DEPS
QMAKE_CXXFLAGS_WARN_ON += $$QMAKE_CFLAGS_WARN_ON
QMAKE_CXXFLAGS_WARN_OFF += $$QMAKE_CFLAGS_WARN_OFF
QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_RELEASE
QMAKE_CXXFLAGS_DEBUG += $$QMAKE_CFLAGS_DEBUG
QMAKE_CXXFLAGS_SHLIB += $$QMAKE_CFLAGS_SHLIB
QMAKE_CXXFLAGS_STATIC_LIB += $$QMAKE_CFLAGS_STATIC_LIB
QMAKE_CXXFLAGS_YACC += $$QMAKE_CFLAGS_YACC
QMAKE_CXXFLAGS_HIDESYMS += $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden
QMAKE_LFLAGS +=
QMAKE_LFLAGS_DEBUG +=
QMAKE_LFLAGS_APP +=
QMAKE_LFLAGS_RELEASE +=
#
# Base qmake configuration for GCC on Mac OS X
#
# Before making changes to this file, please read the comment in
# gcc-base.conf, to make sure the change goes in the right place.
#
# To verify that your change has the desired effect on the final configuration
# you can use the manual test in tests/manual/mkspecs.
#
QMAKE_COMPILER_DEFINES += __APPLE__ __GNUC__
QMAKE_CFLAGS_X86 += -arch i386
QMAKE_CFLAGS_X86_64 += -arch x86_64
QMAKE_CFLAGS_PPC += -arch ppc
QMAKE_CFLAGS_PPC_64 += -arch ppc64
QMAKE_CFLAGS_DWARF2 += -gdwarf-2
QMAKE_CXXFLAGS_X86 += $$QMAKE_CFLAGS_X86
QMAKE_CXXFLAGS_X86_64 += $$QMAKE_CFLAGS_X86_64
QMAKE_CXXFLAGS_PPC += $$QMAKE_CFLAGS_PPC
QMAKE_CXXFLAGS_PPC_64 += $$QMAKE_CFLAGS_PPC_64
QMAKE_CXXFLAGS_DWARF2 += $$QMAKE_CFLAGS_DWARF2
QMAKE_OBJECTIVE_CFLAGS = $$QMAKE_CFLAGS
QMAKE_OBJECTIVE_CFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
QMAKE_OBJECTIVE_CFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
QMAKE_OBJECTIVE_CFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
QMAKE_OBJECTIVE_CFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
QMAKE_OBJECTIVE_CFLAGS_HIDESYMS = $$QMAKE_CXXFLAGS_HIDESYMS
QMAKE_OBJECTIVE_CFLAGS_X86 = $$QMAKE_CFLAGS_X86
QMAKE_OBJECTIVE_CFLAGS_X86_64 = $$QMAKE_CFLAGS_X86_64
QMAKE_OBJECTIVE_CFLAGS_PPC = $$QMAKE_CFLAGS_PPC
QMAKE_OBJECTIVE_CFLAGS_PPC_64 = $$QMAKE_CFLAGS_PPC_64
QMAKE_LFLAGS_X86 += $$QMAKE_CFLAGS_X86
QMAKE_LFLAGS_X86_64 += $$QMAKE_CFLAGS_X86_64
QMAKE_LFLAGS_PPC += $$QMAKE_CFLAGS_PPC
QMAKE_LFLAGS_PPC_64 += $$QMAKE_CFLAGS_PPC_64
QMAKE_LFLAGS += -headerpad_max_install_names
QMAKE_LFLAGS_SHLIB += -single_module -dynamiclib
QMAKE_LFLAGS_PLUGIN += $$QMAKE_LFLAGS_SHLIB
QMAKE_LFLAGS_INCREMENTAL += -undefined suppress -flat_namespace
QMAKE_LFLAGS_SONAME += -install_name$${LITERAL_WHITESPACE}
QMAKE_LFLAGS_VERSION += -current_version$${LITERAL_WHITESPACE}
QMAKE_LFLAGS_COMPAT_VERSION += -compatibility_version$${LITERAL_WHITESPACE}
#
# Qmake configuration for the GNU C++ compiler
#
# Before making changes to this file, please read the comment in
# gcc-base.conf, to make sure the change goes in the right place.
#
# To verify that your change has the desired effect on the final configuration
# you can use the manual test in tests/manual/mkspecs.
#
QMAKE_CC = /usr/x86_64-apple-darwin11/usr/bin/x86_64-apple-darwin11-g++
QMAKE_LINK_C = $$QMAKE_CC -F/usr/x86_64-apple-darwin11/usr/Frameworks
QMAKE_LINK_C_SHLIB = $$QMAKE_CC -F/usr/x86_64-apple-darwin11/usr/Frameworks
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -O2 -g
QMAKE_CXX = /usr/x86_64-apple-darwin11/usr/bin/x86_64-apple-darwin11-g++
QMAKE_LINK = /usr/x86_64-apple-darwin11/usr/bin/x86_64-apple-darwin11-g++ -F/usr/x86_64-apple-darwin11/usr/Frameworks
QMAKE_LINK_SHLIB = $$QMAKE_CXX -F/usr/x86_64-apple-darwin11/usr/Frameworks
QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
QMAKE_PCH_OUTPUT_EXT = .gch
QMAKE_CFLAGS_PRECOMPILE = -x c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
QMAKE_CFLAGS_USE_PRECOMPILE = -include ${QMAKE_PCH_OUTPUT_BASE}
QMAKE_CXXFLAGS_PRECOMPILE = -x c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE
#include(../common/g++-macx.conf)
#
# Qmake configuration for the GNU C++ compiler on Mac OS X
#
# Before making changes to this file, please read the comment in
# gcc-base.conf, to make sure the change goes in the right place.
#
# To verify that your change has the desired effect on the final configuration
# you can use the manual test in tests/manual/mkspecs.
#
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_DWARF2
QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_DWARF2
QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO += -g $$QMAKE_CFLAGS_DWARF2
QMAKE_LFLAGS_STATIC_LIB += -all_load
QMAKE_CFLAGS_X86_64 += -Xarch_x86_64 -mmacosx-version-min=10.5
QMAKE_CFLAGS_PPC_64 += -Xarch_ppc64 -mmacosx-version-min=10.5
QMAKE_CXXFLAGS_X86_64 = $$QMAKE_CFLAGS_X86_64
QMAKE_CXXFLAGS_PPC_64 = $$QMAKE_CFLAGS_PPC_64
QMAKE_OBJECTIVE_CFLAGS_X86_64 = $$QMAKE_CFLAGS_X86_64
QMAKE_OBJECTIVE_CFLAGS_PPC_64 = $$QMAKE_CFLAGS_PPC_64
QMAKE_LFLAGS_X86_64 = $$QMAKE_CFLAGS_X86_64
QMAKE_LFLAGS_PPC_64 = $$QMAKE_CFLAGS_PPC_64
QMAKE_OBJCFLAGS_PRECOMPILE = -x objective-c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
QMAKE_OBJCFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE
QMAKE_OBJCXXFLAGS_PRECOMPILE = -x objective-c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
QMAKE_OBJCXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE
load(qt_config)
Помните, в Mac OS X для линковки с библиотекой .a-файлы не нужны.
Настройка QtCreator
Сначала нужно добавить в список все установленные компиляторы. Инструменты — Параметры — Сборка и запуск — Инструментарии:
QtCreator обычно нормально определяет ABI, но лучше перепроверить. Так же можно заметить, что системный x64 GCC в linux умеет генерировать и 32-битные приложения. Однако это не отменяет того, что также необходимы 32-битные версии библиотек.
После компиляторов можно добавить профили Qt:
Вот при добавлении профиля и пригодятся собранные ранее qmake, uic, moc, rcc, ведь нужно выбрать директорию с qmake. Жёлтый значок с восклицательным знаком слева от профиля означает warning, но QtCreator может использовать такой профиль Qt. А вот если значок красный, то профиль нерабочий. Такое может случиться при неправильной структуре каталогов. Или если удалить директорию, в которой компилировали Qt.
Следующие настройки нужно делать в каждом создаваемом проекте.
Для добавления конкретного профиля Qt надо при активном проекте зайти на вкладку «Проекты» (Ctrl+5):
По умолчанию в списке «Изменить конфигурацию сборки» есть только системный профиль Qt. Зато в списке кнопки «Добавить» есть все профили Qt, добавленные в параметры сборки.
В основных настройках сборки необходимо проверить пару библиотека-компилятор. Чтоб и то и другое было от одной и той же операционной системы.
Этапы сборки «qmake» и «Сборка» QtCreator ставит по умолчанию. А вот особые этапы «upx» и «dmgbuild» я добавил вручную для своего проекта. Этап «upx» выполняется каждый раз при нажатии на кнопку «Собрать проект». Однако если исполняемый файл не был изменён, то upx вернёт ошибку, что файл им уже обработан. В случае ошибки следующий этап не вызывается, т.е. dmg-файл обновится только если upx отработал успешно.
Для работы этапа upx он должен быть установлен в системе. Однако даже работая в linux-окружении и поставленный из пакетного менеджера upx умеет ужимать приложения: linux32/64, win32, macos32/64. Далеко не для всех проектов upx-сжатие реально нужно, этап показан скорее для примера.
Для этапа «dmgbuild» я воспользовался скриптом make_dmg. Ему нужны права root, поэтому добавил скрипт в файл /etc/sudoers
Изменения в проектном файле и использование сторонних библиотек
В моём проекте используется libusb, а это далеко не часть Qt. Также необходимо было включить платформенно-зависимую реализацию HID. В проектный файл были добавлены строки:
macx {
INCLUDEPATH += $$PWD/libusbx/
SOURCES += BootLoader/HIDAPI/mac/hid.c
LIBS += -framework IOKit -framework CoreFoundation -lusb-1.0
ICON = AqPicFlash.icns
}
win32: {
INCLUDEPATH += $$PWD/libusbx/
LIBS += -lsetupapi -lole32
SOURCES += BootLoader/HIDAPI/windows/hid.cpp
RC_FILE = WinIcon.rc
}
win32: !win64-x-g++ {
LIBS += -L$$PWD/libusbx/ -lusb-1.0-32.dll
}
win64-x-g++ {
LIBS += -L$$PWD/libusbx/ -lusb-1.0-64.dll
}
unix: !macx {
CONFIG += link_pkgconfig
PKGCONFIG += libusb-1.0
SOURCES += BootLoader/HIDAPI/linux/hid-libusb.c
}
В Mac OS X и Linux линкуемся с системной libusb, в Windows в зависимости от разрядности линкуемся с libusb-1.0-32.dll.a или libusb-1.0-64.dll.a. Помним, что .a-файл может быть переименован, но зависеть приложение всё-равно будет от libusb-1.0.dll. В Linux параметры для libusb берём через системную утилиту pkgconfig. Кроме libusb подключаем для каждой операционной системы необходимые системные библиотеки и иконки.
Удобно разнести итоговые файлы для разных операционных систем по директориям. Сделать это можно так:
macx {
DESTDIR = mac
OBJECTS_DIR = mac
MOC_DIR = mac
UI_DIR = mac
RCC_DIR = mac
}
unix: !macx {
DESTDIR = linux
OBJECTS_DIR = linux
MOC_DIR = linux
UI_DIR = linux
RCC_DIR = linux
}
win32 {
DESTDIR = windows/release
OBJECTS_DIR = windows
MOC_DIR = windows
UI_DIR = windows
RCC_DIR = windows
}
win64-x-g++ {
DESTDIR = win64/release
OBJECTS_DIR = win64
MOC_DIR = win64
UI_DIR = win64
RCC_DIR = win64
}
Цель win64-x-g++ относится к win32, однако в проектном файле идёт последней и переписывает настройки.
Результат
Теперь чтобы собрать приложение под ту или иную операционную систему достаточно выбрать тип сборки, как показано на самом первом скриншоте, и нажать «Собрать проект»
0 / 0 / 0 Регистрация: 28.05.2014 Сообщений: 11 |
|
1 |
|
23.05.2017, 21:00. Показов 11945. Ответов 11
Доброго времени суток! Имеется проект написанный на C++ в Qt, скомпилирован под Windows средствами Qt’а. P.S. использовать виртуальную машину не предлагать, проделывать кросс-компиляцию из-под Линукса не предлагать, прога сама по себе очень простая.
0 |
Programming Эксперт 94731 / 64177 / 26122 Регистрация: 12.04.2006 Сообщений: 116,782 |
23.05.2017, 21:00 |
11 |
1443 / 1326 / 131 Регистрация: 20.03.2009 Сообщений: 4,689 Записей в блоге: 11 |
|
23.05.2017, 21:51 |
2 |
Не могли бы Дорогие форумчане подсказать какой инструментарий использовать и какой алгоритм действий проделать. Такого магического инструментария нет.
0 |
1069 / 651 / 229 Регистрация: 14.01.2016 Сообщений: 2,031 Записей в блоге: 9 |
|
24.05.2017, 06:23 |
4 |
P.S. использовать виртуальную машину не предлагать, проделывать кросс-компиляцию из-под Линукса не предлагать, прога сама по себе очень простая. Наиболее простой вариант — установить виртуалку с целевой ОС, установить там Qt и в ней компилять. Всё остальное сильно сложнее. Удалённая же компиляция — это вообще отдельный разговор, который принципиально отличается от локальной кросс-компиляции. При удалённой компиляции вам придётся настраивать удалённую машину под компиляцию и под соединение.
0 |
1443 / 1326 / 131 Регистрация: 20.03.2009 Сообщений: 4,689 Записей в блоге: 11 |
|
24.05.2017, 11:54 |
5 |
почему же нет, прямо на данный момент тестирую вот такой алгоритм Это не кросс компиляция. И это требует виртуалку или отдельную машину с нужным дистрибутивом GNU/Linux. Что не соответствует
использовать виртуальную машину не предлагать
0 |
0 / 0 / 0 Регистрация: 28.05.2014 Сообщений: 11 |
|
24.05.2017, 11:58 [ТС] |
6 |
Добавлено через 1 минуту
Это не кросс компиляция. И это требует виртуалку или отдельную машину с нужным дистрибутивом GNU/Linux. Что не соответствует пункт 9, можно выбрать build the project localy with a cross-compiler
0 |
1443 / 1326 / 131 Регистрация: 20.03.2009 Сообщений: 4,689 Записей в блоге: 11 |
|
24.05.2017, 12:02 |
7 |
with a cross-compiler Для этого нужен кросс компилятор. Но вот беда, нет кросс компилятора, чтобы из под Windows собирать под Ubuntu.
0 |
зомбяк 1582 / 1216 / 345 Регистрация: 14.05.2017 Сообщений: 3,939 |
|
24.05.2017, 12:14 |
8 |
makson_a, виртуальная или отдельная локальная машина может потребоваться для проверки работоспособности программы. Кроме кросс-компилятора обычно поставляется также и кросс-дебаггер gdb, а QtCreator (и проект) можно настроить под запуск отладки на удалённой машине. Добавлено через 2 минуты
0 |
41 / 39 / 7 Регистрация: 21.05.2012 Сообщений: 198 |
|
24.05.2017, 13:14 |
9 |
ЕМНИП, в принципе можно кросс-скомпилить из Windows для Linux. Для этого нужен cygwin (если не ошибаюсь), rootfs того Linux для которого компилить (по крайней мере, не весь, а необходимые только пакеты и хедеры), и, кросс-компилятор. Например, похожий SDK поставляется с устройствами от MOXA, где из Windows можно собрать приложения для Linux под ARM. Но там уже все «настроено» и есть нормальный гайд по установке, и прочему и там все идет в «комплекте», и там в этом есть смысл. Но в Вашем случае, сложность всего этого процесса во много раз «пересиливает» выгоду. Проще всего (как уже говорили) — использовать виртуальные машины и не мучаться.
0 |
1443 / 1326 / 131 Регистрация: 20.03.2009 Сообщений: 4,689 Записей в блоге: 11 |
|
24.05.2017, 13:21 |
10 |
SDK поставляется с устройствами от MOXA Только это уже embedded. Для Android тоже собирают кросс компилятор, но для той же Ubuntu никто не делает.
0 |
1069 / 651 / 229 Регистрация: 14.01.2016 Сообщений: 2,031 Записей в блоге: 9 |
|
24.05.2017, 16:28 |
11 |
Главное не забывать, что при кросс-компиляции нужна ещё и библиотека Qt, которая скомпилирована соответствующим образом(под target в виде целевой системы).
0 |
0 / 0 / 0 Регистрация: 28.05.2014 Сообщений: 11 |
|
24.05.2017, 18:50 [ТС] |
12 |
Спасибо большое всем, кто потратил время на ответы. Будем смотреть в сторону компиляции из-под Linux под целевые системы с отладкой непосредственно на них (или виртуалках). Ну или предложим переписать проект на js и посадить на web — аля кросс-платформенность по-деревенски.
0 |
В связи с этой вирусной хренью у меня сейчас высвободилось какое-то количество свободного времени, которое я решил посвятить ревизии текущих проектов и документации. Гайд по сабж, написанный моим сотрудником полгода назад, безнадежно устарел за это время, поэтому решил его освежить. Ну а бонусом, выкинуть это в паблик — не срачами же едиными. Надеюсь, кому-то эта информация окажется полезной и через гугл этот гайд спасет ему какое-то количество времени.
Собирать будем на примере ARM linux, i-mx6. Host — ubuntu linux. Информацию я попытался предоставить таким образом, чтобы объяснить суть процесса, а не сделать очередной обезьяний рецепт для копирования. Местами ну уж очень для новичков — но лучше пусть обзор будет полным, чем потом тридцать раз дополнять.
1. Тулчейн
Для Qt необходимы одновременно C компилятор и С++ компилятор. К счастью, наконец это не приходится делать сбором из исходников и конфигурирования, либо использовать третьесортные репозитории. Все уже завезли в apt:
apt install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf
gcc — Си компилятор, g++ — соответственно С++
linux-gnu — обозначает сборку для выполнимых файлов в среде GNU/Linux. Для baremetall нужны пакеты с корнем none
hf — hardfloat. Скорее всего ваш application процессор будет именно таким.
В принципе все. Для windows пользователей необходимо
страдать
скачать/собрать аналогичный пакет на базе mingw.
2. Сборка Qt
Для кросс-компиляции исходники Qt необходимо пересобрать под целевую платформу.
Брать можно отсюда: https://download.qt.io/official_releases/qt/. Дальше выбираем ветку, каталог single. На момент написания последняя ревизия 5.14.2. Прямая ссылка.
Самый сложный этап в сборке это конфигурирование. В общем виде основные параметры конфигурирования выглядят так:
./configure <тип линковки> <рецепт> <настройки рецепта> <каталог установки> <лицензия> <тип сборки> <что пропустить> <тонкая настройка>
тип линковки — shared, static. Про статическую линковку и авторские права еще в двух словах чуть ниже.
рецепт. В общем случае это набор базовых правил для кросс-компиляции. Если используется ключевое слово xplatform, рецепты находятся по адресу /qtbase/mkspecs. Для device — /qtbase/mkspecs/devices. Чем еще отличаются эти два ключевых слова, я так и не понял.
настройки рецепта. Фактически это передача определенных DEFINE в рецепт. В большинстве случаев кросс-компиляции потребуется, как минимум, передать префикс имени компилятора — чтобы одновременно были доступны компиляторы под разные платформы, в системе кросс-компиляторам назначается дополнительный префикс. Например, наш компилятор под arm будет не просто gcc, a arm-linux-gnueabihf-gcc. Задается через device_option (даже если рецепт указан через xplatform). Соответственно, необходимо передать -device-option CROSS_COMPILE=arm-linux-g
каталог установки. Куда будет производиться установка. Некоторые говорят, что необходимо монтировать файловую систему удаленной машины в этот каталог. По моему мнению этот шаг лишний — монтирование вообще никак не влияло на выходные файлы и компиляцию. Так что просто выходной каталог. При динамической линковке выходные библиотеки (/usr/local/) необходимо скопировать на целевую машину. Если указано device, то задается через ключевое слово sysroot. А если xplatform — prefix. Это невозможно понять, нужно просто запомнить.
лицензия. Тут все просто — если вы купили коммерческую лицензию, у вас есть саппорт и данный гайд вам не нужен. Во всех остальных случаях указывайте -opensource -confirm-license
тип сборки — release, debug, debug-and-release. Я обычно ставлю только релиз.
что пропустить. Задается двумя ключевыми словами — nomake, варианты: libs, examples, tools, tests. И через skip: список пакетов, начинающихся с qt* в каталоге исходников. Я всегда выкидываю исходники и тесты.
тонкая настройка. Задается включением через -feature или выключение через -no-feature. Список с описанием можно получить через -list-features. Если собирается без этого, я не рекомендую лишний раз сюда лезть. Проблемы могут вылезти совершенно в другом месте.
Это базово, что необходимо знать про параметры конфигурирования. Полный список параметров доступен по —help. Но местами все не так просто, как может показаться — для конкретного пакета под определенную архитектуру может быть совершенно нетривиальный список зависимостей, который задается либо через features, либо через device-option. В более тяжелых случаях придется патчить исходники и/или править рецепты, предварительно перелопатив тонны кода. Я предпочитаю просто выкинуть пакет, если от него нет необходимости прямо сейчас.
Итого, рабочий набор параметров для сборки qt под arm для версии 5.14.2:
./configure -static -no-opengl -device linux-imx6-g++ -device-option CROSS_COMPILE=arm-linux-gnueabihf- -sysroot ~/opt/qt-cross/rootfs-arm -opensource -confirm-license -release -qt-sqlite -nomake examples -nomake tests -skip serialport -skip serialbus -skip quick3d -skip location
Дальше стандартно:
make && make install
Чтобы собиралось быстрее, рекомендую запускать make в несколько потоков. Общую рекомендацию где-то видел как кол-во ядер * 2 + 1. Т.е. для 6-ядерного процессора с гипертредингом должно быть:
make -j25
Один нюанс. Я натыкался на сообщения, что некоторые ревизии Qt валились при сборке в несколько потоков. Текущая ревизия собирается нормально, но…
Все. Можно собирать бинари. Если не используете qt-creator, следующий раздел можно не читать.
Логично было бы после этого собрать версию под windows, чтобы лишний раз не запускать богомерзкую для клиентских релизов. Авотхуй. Сборка безнадежно поломана в 5.14.2. Я уже и i686 и x64 собирал, и свои рецепты писал — бесполезно. Три совершенно разных ошибки. В одних случаях там что-то в libatomic поломали, в других даже внутренняя ошибка компилятора. Потратил кучу времени, не взлетело. А возможно и руки кривые. Забил.
3. Деплой
Данный раздел посвящен развертыванию приложений с использованием Qt Creator.
Открываем проект, Инструменты->Параметры.
Устройства
Добавить->Обычное Linux устройство. Для развертывания на устройстве нужны ssh, rsync.
Комплекты
Прописать компилятор для C/C++
Указать в комплектах путь к собранному qmake
И все вместе:
Чтобы Qt Creator понимал, какие файлы куда класть, необходимо это указать в .pro файле:
target.path += /home/ubuntu
INSTALLS += target
Т.е. кладем выходной бинарь в каталог /home/ubuntu на целевом устройстве. В проектах добавляется целевое устройство, после этого появляется пункт «Развернуть».
Теперь можно собирать кросс-платформенно и развертывать двумя кликами.
4. О статической линковке
В заключении о сабже в комлекте с LGPL. Очень долгое время я считал, что LGPL разрешает только динамическую линковку. Однако это не так и есть официальные разъяснения от FSF:
(1) Если вы статически компонуете с библиотекой под LGPL, вы должны предоставить свое приложение в формате объектного кода (не обязательно исходного текста), с тем чтобы у пользователя была возможность изменить библиотеку и перекомпоновать приложение.
Т.е. по запросу будете обязаны предоставить объектный файл, а не исходный код. Уточню, что запросить объектник у вас может исключительно покупатель вашего продукта, а не абы кто.
Почему я заострил на это внимание? Во-первых у меня возникли проблемы с компиляцией Qt с динамической линковкой — драйверы sql просто отказались подгружаться. Аналогичная проблема (но с чем-то другим, сейчас уже никто не помнит) была у моих ребят, когда они писали предыдущий гайд. Во-вторых, при статической линковке, бинарь будет в разы меньше, чем полный набор библиотек. Для embedded устройств это может быть критично.
Есть один нюанс. Если вдруг каким-то образом в сборке окажется GPL библиотека, придется предоставить весь исходный код.
Прошла компиляция qmake. Предложил собрать.
Qt is now configured for building. To start the build run:nmake.
To reconfigure, run ‘nmake confclean’ and configure.
d:\Raspberry\Qt>nmake
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
cd src/tools/bootstrap/ && «C:\Program Files (x86)\Microsoft Visual Stud
io 9.0\VC\BIN\nmake.exe» -f Makefile
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
«C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\BIN\nmake.exe» -f
Makefile.Release
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
cd src/tools/moc/ && «C:\Program Files (x86)\Microsoft Visual Studio 9.0
\VC\BIN\nmake.exe» -f Makefile
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
«C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\BIN\nmake.exe» -f
Makefile.Release
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
cd src/tools/rcc/ && «C:\Program Files (x86)\Microsoft Visual Studio 9.0
\VC\BIN\nmake.exe» -f Makefile
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
«C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\BIN\nmake.exe» -f
Makefile.Release
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
cd src/tools/uic/ && «C:\Program Files (x86)\Microsoft Visual Studio 9.0
\VC\BIN\nmake.exe» -f Makefile
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
«C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\BIN\nmake.exe» -f
Makefile.Release
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
cd src/corelib/ && «C:\Program Files (x86)\Microsoft Visual Studio 9.0\V
C\BIN\nmake.exe» -f Makefile
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
D:/Raspberry/Qt/bin/moc.exe -DQT_SHARED -DBCM_PI -DQT_BUILD_CORE_LIB -DQ
T_NO_USING_NAMESPACE -DQT_NO_CAST_TO_ASCII -DQT_ASCII_CAST_WARNINGS -DQT_MOC_COM
PAT -DQT_USE_QSTRINGBUILDER -DELF_INTERPRETER=\»\» -DQLIBRARYINFO_EPOCROOT -DHB_
EXPORT=Q_CORE_EXPORT -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEX
T -DQT_HAVE_SSE2 -I../../mkspecs/linux-rasp-pi-g++ -I. -I../../include -I/mnt/ra
sp-pi-rootfs/opt/vc/include -I/mnt/rasp-pi-rootfs/usr/include -I/opt/dev/src/qt-
platform-mkspecs/5.0/linux-rasp-pi-g++/header-taint -I../../include/QtCore -Itmp
\rcc\debug_shared -Iglobal -I../../tools/shared -I../3rdparty/zlib -I../3rdparty
/harfbuzz/src -I../3rdparty/md5 -I../3rdparty/md4 -Itmp/moc/debug_shared animati
on/qabstractanimation.h -o tmp/moc/debug_shared/moc_qabstractanimation.cpp
/opt/toolchains/arm-2011.09/bin/arm-none-linux-gnueabi-g++ -c -pipe -g —
Wall -W -D_REENTRANT -fPIC -DQT_SHARED -DBCM_PI -DQT_BUILD_CORE_LIB -DQT_NO_USIN
G_NAMESPACE -DQT_NO_CAST_TO_ASCII -DQT_ASCII_CAST_WARNINGS -DQT_MOC_COMPAT -DQT_
USE_QSTRINGBUILDER -DELF_INTERPRETER=\»\» -DQLIBRARYINFO_EPOCROOT -DHB_EXPORT=Q_
CORE_EXPORT -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HA
VE_SSE2 -I../../mkspecs/linux-rasp-pi-g++ -I. -I../../include -I/mnt/rasp-pi-roo
tfs/opt/vc/include -I/mnt/rasp-pi-rootfs/usr/include -I/opt/dev/src/qt-platform-
mkspecs/5.0/linux-rasp-pi-g++/header-taint -I../../include/QtCore -Itmp\rcc\debu
g_shared -Iglobal -I../../tools/shared -I../3rdparty/zlib -I../3rdparty/harfbuzz
/src -I../3rdparty/md5 -I../3rdparty/md4 -Itmp/moc/debug_shared -o tmp/obj/debug
_shared/qabstractanimation.o animation/qabstractanimation.cpp
Системе не удается найти указанный путь.
NMAKE : fatal error U1077: » : return code ‘0x1’
Stop.
NMAKE : fatal error U1077: ‘cd’ : return code ‘0x2’
Stop.
d:\Raspberry\Qt>nmake
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
cd src/tools/bootstrap/ && «C:\Program Files (x86)\Microsoft Visual Stud
io 9.0\VC\BIN\nmake.exe» -f Makefile
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
«C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\BIN\nmake.exe» -f
Makefile.Release
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
cd src/tools/moc/ && «C:\Program Files (x86)\Microsoft Visual Studio 9.0
\VC\BIN\nmake.exe» -f Makefile
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
«C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\BIN\nmake.exe» -f
Makefile.Release
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
cd src/tools/rcc/ && «C:\Program Files (x86)\Microsoft Visual Studio 9.0
\VC\BIN\nmake.exe» -f Makefile
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
«C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\BIN\nmake.exe» -f
Makefile.Release
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
cd src/tools/uic/ && «C:\Program Files (x86)\Microsoft Visual Studio 9.0
\VC\BIN\nmake.exe» -f Makefile
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
«C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\BIN\nmake.exe» -f
Makefile.Release
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
cd src/corelib/ && «C:\Program Files (x86)\Microsoft Visual Studio 9.0\V
C\BIN\nmake.exe» -f Makefile
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
D:/Raspberry/Qt/bin/moc.exe -DQT_SHARED -DBCM_PI -DQT_BUILD_CORE_LIB -DQ
T_NO_USING_NAMESPACE -DQT_NO_CAST_TO_ASCII -DQT_ASCII_CAST_WARNINGS -DQT_MOC_COM
PAT -DQT_USE_QSTRINGBUILDER -DELF_INTERPRETER=\»\» -DQLIBRARYINFO_EPOCROOT -DHB_
EXPORT=Q_CORE_EXPORT -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEX
T -DQT_HAVE_SSE2 -I../../mkspecs/linux-rasp-pi-g++ -I. -I../../include -I/mnt/ra
sp-pi-rootfs/opt/vc/include -I/mnt/rasp-pi-rootfs/usr/include -I/opt/dev/src/qt-
platform-mkspecs/5.0/linux-rasp-pi-g++/header-taint -I../../include/QtCore -Itmp
\rcc\debug_shared -Iglobal -I../../tools/shared -I../3rdparty/zlib -I../3rdparty
/harfbuzz/src -I../3rdparty/md5 -I../3rdparty/md4 -Itmp/moc/debug_shared animati
on/qabstractanimation.h -o tmp/moc/debug_shared/moc_qabstractanimation.cpp
/opt/toolchains/arm-2011.09/bin/arm-none-linux-gnueabi-g++ -c -pipe -g —
Wall -W -D_REENTRANT -fPIC -DQT_SHARED -DBCM_PI -DQT_BUILD_CORE_LIB -DQT_NO_USIN
G_NAMESPACE -DQT_NO_CAST_TO_ASCII -DQT_ASCII_CAST_WARNINGS -DQT_MOC_COMPAT -DQT_
USE_QSTRINGBUILDER -DELF_INTERPRETER=\»\» -DQLIBRARYINFO_EPOCROOT -DHB_EXPORT=Q_
CORE_EXPORT -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HA
VE_SSE2 -I../../mkspecs/linux-rasp-pi-g++ -I. -I../../include -I/mnt/rasp-pi-roo
tfs/opt/vc/include -I/mnt/rasp-pi-rootfs/usr/include -I/opt/dev/src/qt-platform-
mkspecs/5.0/linux-rasp-pi-g++/header-taint -I../../include/QtCore -Itmp\rcc\debu
g_shared -Iglobal -I../../tools/shared -I../3rdparty/zlib -I../3rdparty/harfbuzz
/src -I../3rdparty/md5 -I../3rdparty/md4 -Itmp/moc/debug_shared -o tmp/obj/debug
_shared/qabstractanimation.o animation/qabstractanimation.cpp
Системе не удается найти указанный путь.
NMAKE : fatal error U1077: » : return code ‘0x1’
Stop.
NMAKE : fatal error U1077: ‘cd’ : return code ‘0x2’
Stop.
Полезло куда то в /opt/toolchains/arm-2011.09/bin/arm-none-linux-gnueabi-g++. На моем компьютере таких папок вообще нет. Кхм. Откуда он их взял?
Я так понимаю это и должен быть тулчейн, вот только откуда блин его взять? тулчейн для raspbian не содержит таких файлов
In my view, the cross-platform power of Qt is not fully realized if you need a different build host for every target platform. It’s only natural to want to have one build machine that can deliver multiple targets. And if we’re talking about a CI server for a team to use in a cross-platform application development, then it’s a very worthwhile investment.
Accordingly, the aim of this article is to document how to create a cross-compilation environment that allows you to build Windows applications on a Linux host. Specifically, Qt-based applications.
Wilful Ignorance
When it comes to this topic, the internet is populated with naysayers. They will tell you that it’s too hard to setup, that it will take you days (if ever) to setup, that a Windows virtual box is easier, so on and so forth. I can only think such people have never done it, because it really isn’t that hard.
How To
The notes here have been prepared using Qt 5.11.1 (Open Source) and Ubuntu 18.04 LTS 64-bit, as a working example.
MinGW
The cornerstone of this exercise is MinGW. This is the cross-platform compiler you will need to use instead of the vanilla GCC in your distribution.
sudo apt install mingw-w64
Qt Source
You need to download the Qt source code from https://download.qt.io/official_releases/qt/.
You have two major approaches:
- Download the base source package ( https://download.qt.io/official_releases/qt/5.11/5.11.1/single/ ) and desired individual modules ( https://download.qt.io/official_releases/qt/5.11/5.11.1/submodules/ ).
- Include the source when you install Qt.
In my case, I took the second option, and installed Qt as follows:
chmod +x qt-opensource-linux-x64-5.11.1.run ./qt-opensource-linux-x64-5.11.1.run
Prerequisities
Depending on what optional Qt modules you want to include, your prerequisites will likely be different. For example, if you want to build Qt WebEngine, you need flex, bison and more. In my case, the only sub-modules I wanted to add to qtbase were qtserialport, qtsvg and qttools. Hence the only prerequisites were:
sudo apt install build-essential libgl1-mesa-dev python
Configuring Qt
The Qt build then needs to be configured for cross-compilation using MinGW. The following command configures for creation of a 64-bit Qt development kit. You can instead use i686-w64-mingw32- for 32-bit.
The -prefix clauses specifies the destination directory for the resultant Qt development kit.
As I installed the entire Qt source, and only wanted to build a handful of optional sub-modules, I needed many -skip clauses. YMMV; if you download only the source of sub-modules you want to build, you won’t need any -skip clauses. If the size of the build is not reduced one way or another, the build time will be very much greater, as will be the number of prerequisite packages.
./configure -xplatform win32-g++ -device-option CROSS_COMPILE=/usr/bin/x86_64-w64-mingw32- -prefix /home/foobar/Qt5.11.1/5.11.1/mingw_64 -opensource -no-compile-examples -opengl desktop -skip qtactiveqt -skip qtcharts -skip qtdoc -skip qtlocation -skip qtremoteobjects -skip qtserialbus -skip qtwebchannel -skip qtwebview -skip qtandroidextras -skip qtconnectivity -skip qtgamepad -skip qtmacextras -skip qtpurchasing -skip qtscript -skip qttranslations -skip qtwebengine -skip qtwinextras -skip qtdatavis3d -skip qtgraphicaleffects -skip qtmultimedia -skip qtquickcontrols -skip qtscxml -skip qtspeech -skip qtvirtualkeyboard -skip qtwebglplugin -skip qtx11extras -skip qt3d -skip qtcanvas3d -skip qtdeclarative -skip qtimageformats -skip qtnetworkauth -skip qtquickcontrols2 -skip qtsensors -skip qtwayland -skip qtwebsockets -skip qtxmlpattern
Make
OK, now you have to settle in for a long build. In my case, it was just over an hour.
Installation
You know it.
Qt Creator
If you’ve made it here, you now have a 64-bit MinGW development kit for Qt, installed side-by-side with your native vanilla GCC development kit. Now we need to configure Qt Creator to use it. If you’re a Qt developer, this part is probably trivial.
Add The Compiler
Add The Qt Version
Note that the warning is because there’s no qmlscene installed – this is not needed for merely making Windows-targeted builds for QA and production.
Add The Development Kit
Add a new Kit that references the new Compiler and new Qt Version. Note that the warning is because there’s no Debugger configured for this kit; we didn’t install the MinGW GDB as you would not use it to debug a Windows build on a Linux host. Instead you would debug using the native GCC and GDB.
Conclusion
So in reality, it’s not hard. The actual building of Qt is long, but the level of challenge is low.
The only real challenge lies in the relative dearth of clear information available on the web. Maybe I’m just bad at Googling, but it surprises me that this isn’t front and centre at qt.org.
References
The steps presented here were pieced together with the help of the following links, and a few hours of trial and error:
- https://marc.wäckerlin.ch/computer/cross-compile-on-ubuntu-linux-for-windows-using-mingw
- http://www.qtcentre.org/threads/67967-Can-a-Qt-program-compiled-on-Linux-run-on-windows
- https://stackoverflow.com/questions/49134517/cross-compile-qt5-mingw-with-mysql-driver-issue
- https://www.ics.com/blog/how-compile-qt-source-code-linux
- https://stackoverflow.com/questions/16646521/compiling-qt-5-getting-warning-the-build-will-most-likely-fail
- http://doc.qt.io/qt-5/configure-options.html
Tagged crosscompile, crossplatform, devops, mingw, qt