QtCreator: Qt кросс-компиляция из linux 64 в linux 32, win32, win64 и Mac OS X; upx, usb, dmg, etc



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

    Результат

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

    Подробнее
    Реклама
    Комментарии 24
    • +3
      Правильный заход со статьей, послееднее время QT развивается быстрыми шагами, думаю актуально сейчас. А как насчет сборки под мобильные ОС, что то пробовали?
      • +1
        Нет, мобильные пока не пробовал. Но суть будет та же: 1) Получить работающий кросс-компилятор; 2) Где-нибудь взять системные библиотеки целевой системы; 3) Скачать/собрать Qt; 4) Для QtCreator'a собрать uic, moc

        С Android'ом проблем будет меньше всего — под него сборка Qt есть на официальном сайте, SDK открыт, да и компилятор есть.
        • +1
          Как насчет WinCE? Понятно что платформа уже мертвая, но есть еще довольно много встраиваемых систем на ней, да ТСД до сих пор выпускают. По опыту Qt4 знаю что под CE нет QPrinter, QtXmlPatterns и что-то еще.
          • +2
            На официальном сайте последняя сборка для WinCE — именно Qt4. С одной стороны, я не думаю, что они вырезали старые наработки по этой системе. С другой стороны — если кода в 4 версии не было, то он почти наверняка не появился и в 5.
          • +1
            Как насчет WinCE?

            А что именно интересует? На WinCE работает.

            Я компилировал из VS (под winxp) на Win CE 6 (ARM) — всё прекрасно работало.
            Qt 4 версии.

            P.S. В wiki написано, что QtSerialPort тестировался только на эмуляторе — у меня заработал на реальном устройстве без проблем (это я на всякий случай, мало ли кому пригодится).
        • 0
          QT — QuickTime
        • +1
          Супер! А я всё ручками исходники таскаю, хотя подозревал, что несложно настроить кросс-компиляцию. Среда разработки — Linux, сборки нужны и под win32. Благо редко — только финальные релизы.
          • 0
            Я долгое время использовал bash-скрипт, вариант кросс-компиляции от Silmor'a. Но каждый раз в консоль переключаться и искать скрипт стало лениво. Вот и настроил сборку прям из QtCreator
          • +2
            А можно ли вместо gcc собрать clang для кросскомпиляции под мак?
            • +1
              Максимум, что выдал Tatsh — это LLVM-GCC. Эта инструкция наиболее полная из тех, что я нашёл. На OpenSource Apple clang есть. Так что теоретическая возможность кросскомпилировать clang есть. Но GCC без патчей не собирается. А на clang патчей нет… Чуть позже попробую собрать, гляну что из этого получится.
              • +2
                В макпортах я помню был ванильный clang и с ним программы работали. Просто сейчас уже на gcc4.2 сидеть совсем никак, там очень многого нету.
                • +1
                  Эх… А мы пока облизываемся даже на 4.2, потому что сидеть приходится на 3.4. Потому что поддержка старой армовой железки под которую новее никак.

                  Интересно, в QtC 3.0 lldb под Win будет поддерживаться?
                  • +2
                    Там же нумерация версий не совпадает и 4.2яббл это всего лишь 3.3 обычной llvm.
                  • 0
                    Макпорты — несколько иная ситуация. Чтоб собрать маковский clang под Linux нужен набор утилит. Как минимум нету xcrun и dsymutil. Также в инструкции от Tatsh не собирается компилятор ресурсов, но вроде с этой задачей справляется и g++, т.к. иконки есть.
                    • 0
                      Ну все-таки Qt им возможно и не пользуется, и потом иконки же просто кладутся в app bundle и пишутся в plist
                      • 0
                        А если пойти другим путем и просто загрузить нативные средства сборки при помощи mach-o загрузчика?

                        github.com/shinh/maloader
                        • 0
                          Попробовал взять нативные средства из Xcode 4.6. Не получилось:
                          Скрытый текст
                          $ ./ld-mac /usr/i686-apple-darwin10/usr/bin/g++ mach/hello.c
                          collect2: ld terminated with signal 6 [Аварийный останов], core dumped
                          _ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv: undefined symbol
                          _ZNSt3__112__next_primeEm: undefined symbol
                          _ZNSt3__16__sortIRNS_6__lessImmEEPmEEvT0_S5_T_: undefined symbol
                          _ZNSt3__16__sortIRNS_6__lessIyyEEPyEEvT0_S5_T_: undefined symbol
                          __cxa_throw: obj=0xccd630
                          library not found for -lcrt1.10.5.o
                          Aborted(6) -6 (@0x3e80000372d) PC: 0x7fc93763d425

                          /media/big/soft/MaxOS/MacWrite/x64/usr/llvm-gcc-4.2/bin/../libexec/gcc/i686-apple-darwin11/4.2.1/ld(_Z6throwfPKcz+b2) [0x100000f0c(f0c)]
                          /media/big/soft/MaxOS/maloader/libmac.so(strlcpy+0) [0x7fc9373ffb7d]
                          /lib/x86_64-linux-gnu/libc.so.6(abort+0x17b) [0x7fc937640b8b]
                          /lib/x86_64-linux-gnu/libc.so.6(gsignal+0x35) [0x7fc93763d425]
                          /lib/x86_64-linux-gnu/libpthread.so.0(+0xfcb0) [0x7fc9381e7cb0]

                          С clang всё ещё хуже.
                          Автор частично реализует стандартную библиотеку для Mac OS. Возможно более свежие версии используют больше функций? Можно попробовать с Xcode 4.1 — последняя версия, которая поддерживается shinh'ом
                • +1
                  В Ubuntu нельзя поставить 2 dev пакета которые отличаются только разрядностью. Как это обходится?
                  • +2
                    Это разве не Debian MultiArch?
                    wiki.debian.org/Multiarch
                    • +1
                      А вы попробуйте boost две версии поставить. Это недоMultiArch.
                    • +2
                      Как уже было сказано — MultiArch. По крайней мере, основные 32 библиотеки ставятся прямо из пакетного менеджера (ia32-libs). Qt4 i386 у меня оттуда почему-то вставать не захотело. Тоже кросс-компилировал.
                      • +1
                        ia32-libs не нужно ставить. Как написано в описании пакета, это «Transitional package to migrate ia32-libs to multiarch». Если его ставить — он просто тянет кучу 32-битных библиотек. Лучше ставить только то, что действительно нужно.

                        По поводу 32-битного Qt4: вы наверное опять же ставите transition package (типа libqt4-core). Нужно ставить libqtcore4:i386, тогда всё ок (проверил у себя). Просто посмотрите вывод «aptitude search ~i^libqt | grep 4 | grep -vi transitional», чтобы понять, какие пакеты нужно ставить.
                    • –2
                      Как ни странно вчера занимался практически тем же самым, qt creator + hidapi, все плавно заработало, хотя настройки креатора не отличаются интуитивностью. Надо будет попробовать кросс-компиляцию. Впечатления от QT положительные, но vb6 все же намного опередил свое время.

                      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.