gpt4 book ai didi

c++ - 使用自定义 Makefile 而不是 qmake 交叉编译 Ubuntu-Win7

转载 作者:搜寻专家 更新时间:2023-10-31 02:22:22 25 4
gpt4 key购买 nike

我有一个项目使用 Qt4,没有额外的库和 QtSql(用于使用 SQLLite 数据库),我想为 x86_64 Windows 7 机器交叉编译它。这是我总结的 makefile(它只使用 .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 这样的依赖会发生什么?还有 moc?

此外,我是否应该按照教程中的说明定义 LD、AR 或 PKG_CONFIG 变量?我没有在原始 makefile 中指定链接器或汇编器。如果我应该这样做,为什么?

编辑 我读过here mingw 在使用模板时遇到了麻烦,我在我的项目中深入使用了它们。由于 MXE 在内部使用 mingw,我是否应该考虑其他替代方案(例如直接在 Windows 中构建)而不是使用 MXE?

最佳答案

我将在这里发布我自己的答案,但充满了细节,因为我很迷茫,也许其他用户也处于类似情况。

I am going to follow the next tutorial: http://mxe.cc/#tutorial Supposing I've complete successfully the first fourth steps, my doubt comes from choosing between 5c and 5d steps. What shall I use and how in my case?

是的,您(我确实是在回答我自己的问题)可以使用 Makefile 交叉编译静态链接的 Qt 项目。问题是,由于 Qt 是静态链接的,任何其他 Qt 依赖项也必须是静态链接的,这会创建一个潜在的长字符串库依赖项以添加到您的 Makefile 中(并且您还需要知道要传递的正确选项到链接器)。问题是这些选项或库中的一些不是特定于 Windows 的,因此,如果您以前从未为 Windows 编译过程序,则很难知道它们是什么以及它们的用途。

出于这个原因,您可以做的最好的事情就是编写您自己的 .pro 文件,以使用 qmake 创建一个有效的 Makefile。在这一点上,如果你仍然想制作你的自定义 Makefile,你可以执行 qmake 生成的 makefile 并查看执行的命令,复制回去并在你的中进行实验自定义生成文件。

无论如何,我将发布我到达的最远的 makefile(在这篇文章的后面我将展示我的工作 *.pro 文件的样子)。它编译成功,但是在链接时崩溃了,因为有很多 Unresolved 依赖关系我无法按照上面的方法修复(我的 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.

What does it happen with dependencies like QtSql?

如您所见,您将依赖项视为其他普通库:使用 -l 选项指定它,但现在使用 Wl,-Bstatic(也就是说链接器链接必须是静态的),并使用 -L 选项指定交叉编译库的确切位置,如上面的代码所示。此外,在该 makefile 中,我添加了 -lwinmm-loleut32,因为它们属于下降依赖项。

无论如何,由于链接器的原因,这个 makefile 不能完全编译,但是要工作,你应该只添加其他间接需要的库和选项(参见 qmake 生成的 makefile)。无论如何,主要的配置 问题都显示在上面的makefile 中。

And with moc?

moc 工具是一个预处理器,因此与机器无关 (AFAIK)。因此,您可以使用本地安装的 moc 将 moc 传递给您的文件。不管怎样,MXE 当然也安装了一个特定于平台的 moc:

MXE_MOC=$(MXE_USR)/qt/bin/moc

mymoc1: header1.hpp
$(MXE_MOC) $< -o $@

但我认为 MXE 的 moc 和你的之间没有重要区别,除了 MXE 版本可能更现代(我不知道)。

Additionally, should I define LD, AR or PKG_CONFIG variables as the tutorial says?

没必要。如果您没有明确使用它们,则不需要定义它们。

I've read that mingw has troubles working with templates, and I make a deep use of them in my project.

错了。当前的 MXE 版本安装了 gcc 5.1.0 的 mingw32 forge,效果非常好。

.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。所以,我之前必须手动生成它们。我真正做的是用生成 moc 文件然后自动调用的目标调用 cross 修改我的原始 makefile(我用来为 Linux 编译项目的那个) qmake 加上适当的选项。

关于c++ - 使用自定义 Makefile 而不是 qmake 交叉编译 Ubuntu-Win7,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30386597/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com