Кросскомпиляция qt windows под linux

Время на прочтение
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, однако в проектном файле идёт последней и переписывает настройки.

Результат

Теперь чтобы собрать приложение под ту или иную операционную систему достаточно выбрать тип сборки, как показано на самом первом скриншоте, и нажать «Собрать проект»

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:

  1. 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/ ).
  2. 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

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

Собирать будем на примере 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-gnueabihf-.

каталог установки. Куда будет производиться установка. Некоторые говорят, что необходимо монтировать файловую систему удаленной машины в этот каталог. По моему мнению этот шаг лишний — монтирование вообще никак не влияло на выходные файлы и компиляцию. Так что просто выходной каталог. При динамической линковке выходные библиотеки (/usr/local/) необходимо скопировать на целевую машину. Если указано device, то задается через ключевое слово sysroot. А если xplatformprefix. Это невозможно понять, нужно просто запомнить.

лицензия. Тут все просто — если вы купили коммерческую лицензию, у вас есть саппорт и данный гайд вам не нужен. Во всех остальных случаях указывайте -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.
howto0

Комплекты

Прописать компилятор для C/C++
howto1

Указать в комплектах путь к собранному qmake
howto2

И все вместе:
howto3

Чтобы Qt Creator понимал, какие файлы куда класть, необходимо это указать в .pro файле:

target.path += /home/ubuntu

INSTALLS += target

Т.е. кладем выходной бинарь в каталог /home/ubuntu на целевом устройстве. В проектах добавляется целевое устройство, после этого появляется пункт «Развернуть».

Теперь можно собирать кросс-платформенно и развертывать двумя кликами.

4. О статической линковке

В заключении о сабже в комлекте с LGPL. Очень долгое время я считал, что LGPL разрешает только динамическую линковку. Однако это не так и есть официальные разъяснения от FSF:

(1) Если вы статически компонуете с библиотекой под LGPL, вы должны предоставить свое приложение в формате объектного кода (не обязательно исходного текста), с тем чтобы у пользователя была возможность изменить библиотеку и перекомпоновать приложение.

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

Почему я заострил на это внимание? Во-первых у меня возникли проблемы с компиляцией Qt с динамической линковкой — драйверы sql просто отказались подгружаться. Аналогичная проблема (но с чем-то другим, сейчас уже никто не помнит) была у моих ребят, когда они писали предыдущий гайд. Во-вторых, при статической линковке, бинарь будет в разы меньше, чем полный набор библиотек. Для embedded устройств это может быть критично.

Есть один нюанс. Если вдруг каким-то образом в сборке окажется GPL библиотека, придется предоставить весь исходный код.

0 / 0 / 0

Регистрация: 28.05.2014

Сообщений: 11

1

23.05.2017, 21:00. Показов 11951. Ответов 11


Студворк — интернет-сервис помощи студентам

Доброго времени суток!

Имеется проект написанный на C++ в Qt, скомпилирован под Windows средствами Qt’а.
Возникла такая задача: использую средства кросс-компиляции сделать так, чтобы прогу можно было запустить на целевой машине(преимущественно под Linux). Читал много инфы и алгоритмов действий для g++ и mingw, но кроме как кучи установленного софта и каши в голове ничего не вышло.
Не могли бы Дорогие форумчане подсказать какой инструментарий использовать и какой алгоритм действий проделать.

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

Цитата
Сообщение от makson_a
Посмотреть сообщение

Не могли бы Дорогие форумчане подсказать какой инструментарий использовать и какой алгоритм действий проделать.

Такого магического инструментария нет.



0



1069 / 651 / 229

Регистрация: 14.01.2016

Сообщений: 2,031

Записей в блоге: 9

24.05.2017, 06:23

4

Цитата
Сообщение от makson_a
Посмотреть сообщение

P.S. использовать виртуальную машину не предлагать, проделывать кросс-компиляцию из-под Линукса не предлагать, прога сама по себе очень простая.

Наиболее простой вариант — установить виртуалку с целевой ОС, установить там Qt и в ней компилять. Всё остальное сильно сложнее.

Удалённая же компиляция — это вообще отдельный разговор, который принципиально отличается от локальной кросс-компиляции. При удалённой компиляции вам придётся настраивать удалённую машину под компиляцию и под соединение.



0



1443 / 1326 / 131

Регистрация: 20.03.2009

Сообщений: 4,689

Записей в блоге: 11

24.05.2017, 11:54

5

Цитата
Сообщение от makson_a
Посмотреть сообщение

почему же нет, прямо на данный момент тестирую вот такой алгоритм

Это не кросс компиляция. И это требует виртуалку или отдельную машину с нужным дистрибутивом GNU/Linux. Что не соответствует

Цитата
Сообщение от makson_a
Посмотреть сообщение

использовать виртуальную машину не предлагать



0



0 / 0 / 0

Регистрация: 28.05.2014

Сообщений: 11

24.05.2017, 11:58

 [ТС]

6

Добавлено через 1 минуту

Цитата
Сообщение от Dmitriy_M
Посмотреть сообщение

Это не кросс компиляция. И это требует виртуалку или отдельную машину с нужным дистрибутивом 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

Цитата
Сообщение от makson_a
Посмотреть сообщение

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 минуты
mingw — это не кросс-компилятор. Это компилятор только под винду…



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

Цитата
Сообщение от kuzulis
Посмотреть сообщение

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



Tutorials > Porting > Porting a QT Application from Windows to Linux

This tutorial shows how to use the QT framework to create a basic application for Windows in Visual Studio and seamlessly port it to Linux. The use of cross-platform QT API ensures that the code written once will run on all platforms supported by QT.

To follow this tutorial you will need the following tools installed:

  • Microsoft Visual Studio
  • QT Libraries for Visual Studio and the QT Add-in
  • VisualGDB 4.1 or later

We will create a basic QT application using the QT wizard, modify the main window, port the application to Linux and demonstrate the use of the cross-platform API provided by QT by listing files in the current directory.

  1. Start Visual Studio. Begin creating a new project using the QT wizard:01-newprj
  2. The first page shows the summary about the created project. Press “next” to proceed:02-core
  3. The second page allows selecting involved QT modules. Keep the default ones and press “Next”:02-prjsettings
  4. The last page allows customizing the generated class names. We will keep the default ones and press “Finish”:03-generated
  5. The wizard has generated a QT project for Windows. It consists of a .pro file containing various project settings, a .ui file describing the main window and some source files. Press Ctrl-Shift-B to build it:04-build
  6. Visual Studio will build the project using its own C++ compiler. Press F5 to start debugging it:05-run
  7. QT framework allows building both Windows and Linux applications from the same source code. To create a new Linux configuration select “Project->Add VisualGDB Configuration->New Linux Configuration”:06-newcfg
  8. On the first page of the wizard select “qmake” as the build system. This is required to ensure that the QT-specific files, such as .pro and .ui are handled correctly under Linux:07-linuxcfg
  9. On the next page select the Linux machine you are targeting. When you build your Linux configuration VisualGDB will transfer the source files to the Linux machine and build them there just like a normal Linux project:08-machine
  10. On the last wizard page you can change the way source files are handled. By default they will be transferred to a subdirectory in /tmp and built there:09-source
  11. Press “Finish” to complete the wizard. VisualGDB will download the QT Include directories from your Linux machine and configure IntelliSense to parse them:10-includes
  12. Build your new Linux configuration by pressing Ctrl-Shift-B. The Output window will show how the files are transferred to the Linux machine and built there using qmake:11-build
  13. Set a breakpoint in the constructor of the main window class and press F5 to start debugging. The debugging experience will be similar to debugging normal Windows apps. Additionally to that you can interact with the underlying GDB debugging using the GDB Session pane:12-breakpoint
  14. Press F5 to continue debugging. The program running on the Linux machine will display the main window that will be shown on your Windows machine using the XMing window server. You can also switch to showing the windows on the Linux machine directly via VisualGDB Project Properties:13-xming
  15. Now we will add some functionality to our basic app. Double-click on the .ui file to launch QT Designer. Add a button to the main window:14-button
  16. Creating a click handler is a bit more complex than using Windows frameworks like MFC, WTL or WPF and requires two steps. First switch to the signal/slot mode (F4) click on the button and drag the signal connector to the form outside the button:15-slot
  17. QT Designer will start creating a new signal/slot connection. A signal is the event produced by the form. A slot is the handler method defined inside your form class:16-editslots
  18. Select “clicked()” on the left and click “Edit” on the right to add another slot. Click “+” and type in the new slot name: ButtonClickHandler():17-addslot
  19. Press OK to finish creating the connection. Verify the results in the Configure Connection window:18-connected
  20.  The QT Designer will show the newly created
    signal/slot connection:19-updated
  21. Save the .ui file and close QT Designer. Go back to Visual Studio and add the following code inside the declaration of the QtProject1 class:

    protected slots:

        void ButtonClickHandler();

    Then add the body of the method to QtProject1.cpp:

    #include <QMessageBox>

    //…

    void QtProject1::ButtonClickHandler()

    {

        QMessageBox msgBox;

        msgBox.setText(«You have pushed the button!»);

        msgBox.exec();

    }

    Note that the method name should match the slot name created in Qt Designer.
    Build your project with the new code: 20-build

  22. Press F5 to run the project. Click the button you added to see the message box:21-messagebox
  23. Now we will demonstrate how to use cross-platform QT API. In this tutorial we will list all entries in the current directory and display them in the message box. Include <QtDir> in your .cpp file and replace the body of the button click handler with the following code:

    QMessageBox msgBox;

    QDir currentDir(«.»);

    QString fileList = «Files in « + currentDir.absolutePath() + «:\n»;

    QStringList entries = currentDir.entryList();

    foreach(QString fn, entries)

    {

        if(fn != tr(«.») && fn != tr(«..»))

        {

            fileList += fn + «\n»;

        }

    }

    msgBox.setText(fileList);

    msgBox.exec();

    Note that foreach is a preprocessor macro defined inside QT to simplify iterating over QT collections.

  24. Build the project and press F5. You will see the list of files on the Linux machine:22-filelist
  25. Now simply select “Debug” from the configuration list, build and press F5 again. The same source code will be built for Windows and will show a Windows message box listing files in the Windows directory:23-winflielist

If you want to add more cross-platform functionality that will work on Windows, Linux and Linux-based systems such as Raspberry PI, simply implement it using QT API that is documented here. The QT framework will abstract out the differences between operating systems and let you write easily portable code.

  • Ксерокс 3100 mfp драйвера windows 10
  • Крутые иконки для windows 10
  • Кроме windows boot manager ничего нет
  • Кто сидит на windows 2000
  • Крутые виджеты для windows 10