Кросс-компиляция Ubuntu-Win7 с использованием собственного Makefile вместо qmake

У меня есть проект, который использует 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?

2

Решение

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

Я собираюсь следовать следующему уроку: 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_OBJECTs среди очень многих шаблонов. Итак, я должен был генерировать их вручную раньше. Что я действительно сделал, так это изменил мой оригинальный make-файл (тот, который я использую для компиляции моего проекта для Linux) с помощью целевого вызова cross который генерирует moc файлы, а затем вызвать автоматически qmake с правильными вариантами.

2

Другие решения


По вопросам рекламы [email protected]