У меня есть проект, который использует Qt4 без дополнительных библиотек и QtSql (для работы с базой данных SQLLite), и я хочу кросс-компилировать его для компьютера с Windows 7 x86_64. Это мой обобщенный make-файл (он использует только файлы .hpp, кроме main.cpp, так как я использую множество шаблонов):
CXX=g++-4.8
CXXFLAGS=-std=c++11 -pedantic -Wall -pedantic-errors -Wextra
IPATH=-I/usr/include/qt4/ -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtSql
LDFLAGS=-lQtGui -lQtSql -lQtCore
OBJS=main.o
HEADERS=mymoc1.hpp mymoc2.hpp other-headers
all: myexec
myexec: $(OBJS)
$(CXX) $(CXXFLAGS) $(OBJS) -o $@ $(LDFLAGS)
main.o: main.cpp $(HEADERS)
$(CXX) -c $(CXXFLAGS) $< -o $@ $(IPATH)
mymoc1.hpp: the-header-needing-moc.hpp
moc $< -o $@
mymoc2.hpp: other-header-needing-moc.hpp
moc $< -o $@
Я собираюсь следовать следующему уроку: http://mxe.cc/#tutorial
Предположим, что я успешно выполнил первые четвертые шаги, мои сомнения связаны с выбором между 5c и 5d шагами. Что я буду использовать и как в моем случае? Что происходит с такими зависимостями, как QtSql? А с мокко?
Кроме того, я должен определить переменные LD, AR или PKG_CONFIG, как говорится в учебнике? Я не указал компоновщик или ассемблер в моем исходном make-файле. И если я должен, почему?
РЕДАКТИРОВАТЬ я прочел Вот тот mingw
У меня проблемы с шаблонами, и я глубоко их использую в своем проекте. Поскольку MXE использует mingw
внутренне, я должен рассмотреть другие альтернативы (как сборка в Windows непосредственно) вместо использования MXE?
Я собираюсь опубликовать свой собственный ответ здесь, но полный деталей, потому что я очень потерян и, возможно, другие пользователи находятся в аналогичных условиях.
Я собираюсь следовать следующему уроку: http://mxe.cc/#tutorial Предположим, что я успешно выполнил первые четвертые шаги, мои сомнения связаны с выбором между 5c и 5d шагами. Что я буду использовать и как в моем случае?
Да, вы (я действительно отвечаю на свой вопрос) можете использовать Makefile для кросс-компиляции статически связанного проекта Qt. Проблема в том, что, поскольку Qt статически связан, любые другие зависимости Qt также должны быть статически связаны, и это создает потенциальную длинную строку библиотечных зависимостей, которая будет добавлена в ваш Makefile (и вам также нужно знать правильные параметры, которые нужно передать компоновщику). Проблема в том, что некоторые из этих опций или библиотеки не относятся к конкретным окнам, поэтому, если вы никогда ранее не компилировали программу для Windows, вам трудно узнать, для чего они и для чего они используются.
По этой причине лучшее, что вы можете сделать, это написать свой собственный .pro
файл для создания рабочего Makefile с qmake
, На этом этапе, если вы все еще хотите создать свой собственный Makefile, вы можете выполнить makefile
создано qmake
и увидеть выполненные команды, чтобы скопировать их обратно и поэкспериментировать в вашем собственном Makefile.
Во всяком случае, я выложу самые последние makefile
Я достигаю (позже в этом посте я покажу, как моя работа *.pro
файл выглядит так). Он успешно скомпилировался, но при соединении завис, потому что было много неразрешенных зависимостей, которые я не смог исправить, как сказано выше (моя установка mxe находится в `/ usr / local / mxe):
ifndef CROSS
CROSS=x86_64
endif
CROSS_ID=$(CROSS)-w64-mingw32.static
MXE_BASE=/usr/local/mxe/usr
MXE_USR=$(MXE_BASE)/$(CROSS_ID)
MXE_INCL=$(MXE_USR)/include
MXE_QTINCL=$(MXE_USR)/qt/include
MXE_LIB=$(MXE_USR)/lib
MXE_QTLIB=$(MXE_USR)/qt/lib
LDIFLAGS=-I$(MXE_INCL) -I$(MXE_QTINCL)/QtCore -I$(MXE_QTINCL)/QtGui -I$(MXE_QTINCL)/QtSql
LDLFLAGS=-L$(MXE_LIB) -L$(MXE_QTLIB)
LDLIBS=-Wl,-Bstatic -lwinmm -loleut32 -lQtGui -lQtSql -lQtCore
CXX=$(MXE_PATH)/bin/$(CROSS_ID)-g++
CXXFLAGS=-std=c++11 -pedantic -pedantic-errors -Wall
OBJS=main.o
MOC_HEADERS=mymoc1.hpp mymoc2.hpp
HEADERS=$(MOC_HEADERS) myheaders
APP=myapp.exe
all: $(APP)
$(APP): $(OBJS)
$(CXX) $(CXXFLAGS) $(OBJS) -o $@ $(LDLFLAGS) $(LDLIBS)
main.o: main.cpp $(HEADERS)
$(CXX) $(CXXFLAGS) $< -o $@ $(LDIFLAGS)
mymoc1: header1.hpp
moc $< -o $@
mymoc2: header2.hpp
moc $< -o $@
# Thee ways of call it:
# make # CROSS=x86_64 by default as shown in the first line.
# make CROSS=x86_64 # Make it explicit.
# make CROSS=i686 # Choose 32 bit.
Что происходит с такими зависимостями, как QtSql?
Как видите, вы относитесь к своим зависимостям как к другим обычным библиотекам: указав их с помощью -l
варианты, но теперь с Wl,-Bstatic
(сказать, что компоновщик, ссылка должна быть статической), и указав с -L
параметры точное место кросс-скомпилированных библиотек, как показано в коде выше. Кроме того, в этом makefile
я добавил -lwinmm
а также -loleut32
потому что они были одной из падающих зависимостей.
В любом случае, этот make-файл не полностью компилируется из-за компоновщика, но для работы вам нужно только добавить другие косвенно необходимые библиотеки и опции (см. qmake
генерироваться makefile
). Во всяком случае, основной configuration
вопросы все они показаны в makefile
выше.
А с мокко?
Инструмент moc
является препроцессором и, следовательно, машинно-независимым (AFAIK). Итак, вы можете пройти moc
к вашим файлам, используя локальную установку moc. Во всяком случае, MXE, конечно, также устанавливает платформу для конкретной moc
:
MXE_MOC=$(MXE_USR)/qt/bin/moc
mymoc1: header1.hpp
$(MXE_MOC) $< -o $@
Но я не думаю, что есть важные различия между moc
о MXE и вашей, за исключением, возможно, версии MXE более современной (я не знаю).
Кроме того, я должен определить переменные LD, AR или PKG_CONFIG, как говорится в учебнике?
Это не обязательно. Если вы не используете их явно, вам не нужно определять их.
Я читал, что у mingw проблемы с шаблонами, и я глубоко их использую в своем проекте.
Ложь. Текущая версия MXE устанавливает mingw32
кузница gcc
5.1.0, которая работает как шарм.
А как насчет .pro
файл?
MXE = /usr/local/mxe/usr/$$CROSS
MXE_INCL = $$MXE/include
MXE_LIB = $$MXE/lib
MXE_QT = $$MXE/qt
MXE_QTINCL = $$MXE_QT/include
MXE_QTLIB = $$MXE_QT/lib
TARGET = myapp # .exe no required.
OBJS = main.o
MOC_HEADERS = mymoc1.hpp mymoc2.hpp
HEADERS = $$MOC_HEADERS other-headers
SOURCES = main.cpp
QMAKE_CXX = $${CROSS}-g++
QMAKE_CXXFLAGS = -static -std=c++11 -pedantic -pedantinc-errors -Wall
QMAKE_LFLAGS += -Xlinker -Bstatic
INCLUDE_PATH += $$MXE_QTINCL $$MXE_QTINCL/QtGui $$MXE_QTINCL/QtSql
TEMPLATE = app
CONFIG += qt release
QT += core gui sql
LIBS += -L$$MXE_QTLIB -L$$MXE_LIB
# Call it (for x86_64):
# /usr/local/mxe/usr/x86_64-w64-mingw32.static/qt/bin/qmake\
# -makefile -o cross_makefile -nomoc CROSS=x86_64 myapp.pro
# make -f cross_makefile
Как видите, я говорю qmake
не генерировать moc
файлы (опция -nomoc
), потому что по какой-то странной причине, qmake
не способен найти мой Q_OBJECT
s среди очень многих шаблонов. Итак, я должен был генерировать их вручную раньше. Что я действительно сделал, так это изменил мой оригинальный make-файл (тот, который я использую для компиляции моего проекта для Linux) с помощью целевого вызова cross
который генерирует moc
файлы, а затем вызвать автоматически qmake
с правильными вариантами.