这是本系列的第二部分,其中我们构建了一个“ Hello World”应用程序。 如果您迟到聚会,我建议您先检查第1部分。
因此,我们的老板来检查我们的进度。 他们开始怀疑为什么要花一整天的时间将3行应用程序移植到新系统上。 但是他们访问的真正原因是要求一个新功能。 当我们的“ Hello world”业务蓬勃发展时,市场营销部门认为缺少图形用户界面会损害销售。
看到,没有人逃脱软件膨胀。
仍然。 渴望让老板忘记在Linux上设置MSVC所花费的时间,我超越了这一步,完成了对我们应用程序的完全重写。
当然,我们还提供了一个小巧的构建文件。
Linux版本仍然可以正常运行。 h
让我们热情地构建Windows版本
是的,事实证明,我们需要一个与编译器兼容的Qt构建。 现在,即使QBS也不了解Qt。
我去https://www.qt.io/download下载Qt。 该站点每天都在恶化。 Qt公司试图劝阻人们获得开源版本。 但是,如果您访问https://download.qt.io/ ,则拥有所有的压缩包和安装程序。
说到安装程序,他们没有为Windows提供64位版本。 在2018年。我们可能不得不限制自己使用32位版本,并使用WINE进行提取。 除非它不起作用,因为Qt安装程序框架没有静默模式(显然,您可以在100行JavaScript中编写静默模式的脚本),并使用WINE不支持的某些Windows方法。
没关系。 我将自己构建Qt,以证明我的WINE工具链多么出色。 它将是64位。 我将获得晋升,拥有4个PHD的实习生将为我带来卡布奇诺咖啡。 也许人们甚至会将我的名字用作动词(如果您还没有Godbolt ,则应该明确地检查一下!)。
除了。 Qt仍然使用qmake
进行构建。 qmake
存在仅仅是为了使cmake
看起来cmake
酷又现代。 目前正在努力用qbs
构建Qt,尽管这非常令人兴奋,但即使对于本博客来说,也可能有点太前沿了。
因此,我们被qmake
所困扰。 qmake
是一个生成系统生成器,不幸的是,它会扩展工具链并生成系统。 我确实尝试为我的wine工具链创建配置,这实际上很简单,并且确实使用正确的命令生成了一些Makefile。 但是它们是用于nmake
Makefile,它是Windows的类似于make的工具,尽管其格式与原始make不太兼容。 我尝试使用nmake
(效果很好),但是随后所有随后的cl.exe
/ link.exe
调用都在wine环境中发生,这意味着它执行实际的cl.exe而不是我们的包装器,因此我们进行了粗斜杠到反斜杠的转换脚本永远不会运行,并且编译会失败,因为cl.exe
假定以/
开头的任何内容都是一个选项。 而且,由于nmake是Windows进程并且Windows不了解ELF,因此我们无法让nmake调用我们的假cl.exe
包装器。
留给读者练习是使用\
作为路径分隔符来计算Windows数百万美元的成本,这使整个行业付出了代价。
解决方案是修补qmake
。 甚至qmake
的维护者都积极避免这样做。 因此,我们不要这样做。
非常抱歉,我们将回到Windows VM并从那里构建Qt。
那应该很简单,对吧?
当然,VC构建工具无法正确设置其环境。
设置构建环境需要多少位Microsoft工程师? 当然可以,因为我能够在20个左右的文件中找到大约1900行用于该目的的批处理脚本。 可能还有更多。
我设法将环境分为3行。 请记住,无论您的构建系统多么复杂,它都归结为几个变量。 编译器不需要太多。
set "INCLUDE=C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Tools\MSVC\14.12.25827\include;
%INCLUDE%"
set "LIB=C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Tools\MSVC\14.12.25827\lib\x64\;%LIB%"
set "PATH=%PATH%;C:\Users\cor3ntin\Documents\qtbase-everywhere-src-5.10.0\gnuwin32"
之后,只需下载Qt 5.10即可设置x64构建环境(我使用了vcvars64.bat
+上面的三行代码,但是您可以手动设置PATH
,而完全不必理会vcvars.bat
)。
确保已安装perl
并在PATH
。
就本文而言,我只需要Qt Base(Core,Gui,Network…),这就是我要构建的。 构建使用铬的QtWebEngine涉及更多。
configure -release -opensource -confirm-license -platform win32-msvc -nomake examples -nomake tests
nmake
nmake install
Qt构建完成后,将文件夹复制回Linux主机。 您至少需要bin, include, lib, plugins
。 将它们放在新目录中。 我叫我qt5_10base-x64
。
我在include引用src
遇到问题。 因此,您可以从Windows上Qt目录中运行perl bin\syncqt.pl -copy -windows -version 5.10.0 -outdir cpy
并使用cpy
生成的include文件夹。 即使那样,我也必须从src文件夹手动将几个文件(qconfig.h,q {core,gui,widgets,network,xml} -config.h)复制到各自的include文件夹。 绝对有点怪异,但最终您会到达那里。
所以现在我们有了Qt。 但是,如何告诉QBS实际使用它呢?
QBS的配置文件系统是使它变得很棒的一件事。 您可以全局设置编译器工具链,然后轻松地从一个切换到另一个。
但是,要与Qt配合使用,qbs每个配置文件都需要一整套模块。 我们之前使用的gcc配置文件由160个qbs文件组成,用于设置每个Qt库和组件。
幸运的是,您所需要做的就是调用此便捷工具。
qbs-setup-qt -h
This tool creates qbs profiles from Qt versions.
Usage:
qbs-setup-qt [--settings-dir <settings directory>] --detect
qbs-setup-qt [--settings-dir <settings directory>] <path to qmake> <profile name>
qbs-setup-qt -h|--help
The first form tries to auto-detect all known Qt versions, looking them up via the PATH environment variable.
The second form creates one profile for one Qt version.
除非我们不能从linux调用该工具,因为内置的qmake是预期在Windows上运行的Windows应用程序。 希望有一天,我们将完全摆脱qmake,但现在回到我们的Windows计算机上。
我们首先安装Windows版本的qbs并运行该工具。
qbs-windows-x86_64-1.10.0\bin\qbs-setup-qt.exe --settings-dir . bin\qmake.exe msvc14-x64-qt
那应该创建一个具有正确Qt配置的qbs
文件夹。 将该文件夹移动到先前创建的qt5_10base-x64
文件夹中的Linux计算机上。
如果打开.qbs
文件,例如1.10.0/profiles/msvc14-x64-qt/modules/Qt/gui/gui.qbs
,则会注意到对路径的引用。 由于某种原因,在我的机器中是/usr/local/Qt-5.10.0
。 我想我弄乱了某个地方,因为我们应该有一个Windows路径。 无论如何,我们都需要将该路径转换为Linux计算机上Qt的实际位置,这很容易做到,只需使用sed
。
find -name "*.qbs" -exec sed -i -e 's\#/usr/local/Qt-5.10.0\#/home/cor3ntin/dev/cross-compilers/windows/qt-5.10-msvc-x64\#g' {} \;
然后,我们需要修改我们的qbs.conf
以使用那些qt模块。 编辑在第一部分中创建的QBS文件以引用它们:
qt-project\qbs\profiles\msvc14-x86_64\preferences\qbsSearchPaths=/home/cor3ntin/dev/Qt/qbs-wine-toolchain,/home/cor3ntin/dev/cross-compilers/windows/qt5_10base-x64/qbs/1.10.0/profiles/msvc14-x64-qt
我意识到这有点棘手。 但最终,我们可以运行qbs
并为Windows编译基于Qt的hello世界。
它不会运行,因为找不到Qt dll。 您可以将dll复制到构建目录,或确保它们在PATH.
Windows /酒的PATH
。
我发现执行此操作的唯一方法是运行regedit
确保从相应的WINEPREFIX
执行此WINEPREFIX
,并将Qt的bin目录的位置添加到HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
下的Path
中。
如果您知道一种脚本编写方法,请告诉我。
我们还需要在构建的helloworld.exe二进制文件旁边放置一个qt.conf
文件,以告诉Qt从何处加载插件。 就我而言
[Paths]
Prefix = /home/cor3ntin/dev/cross-compilers/windows/qt5_10base-x64/
Plugins = plugins
就是这样! 不太难,不是吗?
因此,Microsoft Studio Visual C ++编译器是有史以来最伟大的事情!
最近对两名学龄前儿童进行的研究表明,千禧一代喜欢彩虹。 我被立即要求使我们的应用程序更加彩虹色。 标记不明确的按钮显然是假装末日的骑士,因此我们也将其删除。
我们需要做的是遍历字符串,在每个字符周围注入一些html标记,以使它们以不同的颜色呈现。
迭代某些容器将需要我们使用range-v3
。 实际上没有其他方法。
那不是很好吗?
但是,我敢肯定,您将完全惊讶于msvc
无法编译range-v3
。 我知道,这完全是打击,完全是失望。
Microsoft Studio Visual C ++编译器被击败。
我们绝对无能为力。 并不是像存在一个range-v3
的msvc兼容端口或其他用于转换字符串的方式一样。 请不要再说我故意编造了一个虚构的故事,以便可以使用范围并用彩虹击败msvc。 那将是卑鄙的 。
唯一合理的办法是抛弃msvc
并将其替换为其他东西。 但是呢? Mingw
不了解MSVC标头和库, icc
相当昂贵, Cfront
不再维护。
现在,您当然知道我要去哪里了,不是吗? clang-cl
! 如果您不了解clang-cl
,那么它实际上代替了clang,而代替了cl.exe
,这会让您内心充满热情和模糊。
Clang的设计正确,出于很多原因,它是一个了不起的工具,但最重要的是:
- 它可以在所有主要操作系统上运行
- 它不会在编译时激活特定于操作系统的功能,而是在运行时激活。
- 这意味着它将使您可以从任何地方定位任何目标。
- 它提供与
msvc
兼容的驱动程序(如果需要,可以使用命令行界面) - 它很容易构建(并且,如果您曾经尝试构建GCC,您就会知道构建编译器的难度。)
- 它是开源的,其设计不受政治动机的积极限制。
因此,让我们使用Clang!
如果没有clang
遵循Linux发行版的文档,则默认情况下它应该随clang-cl一起提供(它只是clang的符号链接)。
或者,如果您像我一样,结帐并盖好行李箱, 那就太好了 !
除了减少替代品之外,我们还需要做一些事情。 我们为wine编写的QBS
工具链模块无法正常工作,因为它将斜杠转换为反斜杠。
我确实复制了工具链模块并修复了其他一些细节。 这将很快在GitHub上结束。
直接为clang-cl创建QBS配置文件,从wine复制一个,并将工具链名称从msvc
更改为clang-cl
,然后将toolchainInstallPath
指向包含clang-cl
和lld-link
。
哦,我没有提到lld-link
吗? 这是对link.exe
替代。 lld
也是unix上ld
的替代品,它比ld
和gold
快很多,因此您应该检查并使用它 !
我们还没有完成。
Microsoft Windows是围绕不区分大小写的文件系统设计的。 我确定当时看起来不错。
但是,除非您有足够的自负能力以在FAT
上运行Linux计算机,否则文件系统可能区分大小写。 这对我们来说是一个问题。
真的有多糟吗? 好…
A cl UI . L ib
ahadmin.lib
wdsClientAPI. LIB
P sapi. L ib
sensorsapi.lib
S etup API . L ib
这只是文件的一小部分。 我认为他们现在无法采取任何措施来解决该问题,为时已晚。
我们可以尝试通过更改每个库和标头的文件名来解决案例问题。 但这可能不起作用,因为第三方库也不一致。 因此,即使我们尝试早晚修复构建文件,也将在案例问题上运行。
因此,“适当的”(某种适当的定义)解决方案将是使Linux内核不区分大小写。 为此,我们需要使用不区分大小写的系统。 幸运的是,文件可以是文件系统,因此我们将创建一个足以容纳Windows SDK的文件,并使用不区分大小写的文件系统(例如EXFAT)对其进行格式化,然后将SDK放在其中。 请注意,即使Windows内核不是,NTFS区分大小写。
dd if=/dev/zero of=win_sdk_10.fs bs=1024 count=$((1024 * 100 * 3))
mkfs.exfat win_sdk_10.fs
mv sdk_10 sdk_10.bak
mkdir sdk_10
sudo mount win_sdk_10.fs
mv sdk_10.bak/* sdk_10
您一定喜欢Linux。
现在,使用clang-cl进行编译。 但是,运行该程序会暴露一个错误。
但是,复制到虚拟机的同一可执行文件运行良好。
我仍然不确定错误的实际位置。 它似乎是在range-v3中或在我的使用中,但是它暴露出不同的运行时行为似乎很奇怪。
但是,这对拥有更大的开发环境集非常有用,如果您有错误,那么更有可能暴露出来。 首先,这种令人讨厌的图形故障使我意识到我应该处理空白作为一种特殊情况。
哦,如果您想检查clang实际在做什么,则可以使用msvc2017/bin/Hostx64/x64/
Microsoft的dumpbin.exe
。 该工具相当于UNIX的ldd
和nm
。
有趣的是,尽管没有几个额外的部分,但Clang工件看起来完全像是msvc产生的工件。 包括CRT和vcruntime!
这是MSVC构建的二进制文件。
目前, ldd-link
仍处于试验阶段 ,不支持调试信息。 除了某些异常处理外, clang-cl
大多已完成 。 您可以混合并匹配cl.exe
clang-cl
link.exe
和lld-link
。
我不建议您在生产中使用clang-cl
(但是,它已经实现了),但这是添加到CI和开发环境中的绝佳工具。
今天我已经拥有了所有这些,希望您学到了一些东西!
… 还有一件事 …
第三部分见!
From: https://hackernoon.com/a-c-hello-world-and-the-cute-heartless-rainbow-3cc9695f4142