W64devkit:一个可移植的Windows C和C++开发包

2020-05-25 16:30:28

作为一名计算机工程师,我的工作是用计算机解决重要问题。理想情况下,我的解决方案将是高效的,通常这意味着最大限度地利用手头的资源。很多时候,这些资源都是运行Windows的机器,尽管我对该平台心存疑虑,但正确有效地利用它会带来很多好处。

有时在另一个平台上工作时以Windows为目标就足够了,但其他时候我必须在平台上工作。C开发有多种选择,我最终正式确定了我自己的开发工具包:w64devkit。

对于大多数用户来说,这个值在GitHub的“Release”中提供的78MiB.zip中。这个(相对)小的软件包包括最先进的C和C++编译器(最新的GCC)、一个功能强大的文本编辑器、调试器、一个完整的x86汇编器和微型UNIX环境。它是“便携的”,因为没有安装。只需将其解压并开始就地使用即可。有了w64devkit,在任何Windows上都只需要几秒钟的时间就可以在功能齐全、设备齐全的一流开发环境中启动并运行。

开发工具包完全使用Docker从源代码交叉编译,但实际使用时并不需要Docker。存储库只是一个Dockerfile和一些文档。唯一的构建依赖项是Docker本身。如果您出于任何原因不信任我的发行版,您也可以很容易地为您自己的个人使用定制它,或者审核和构建您自己的发行版。这与大多数开源软件的Windows构建形成了鲜明对比,在Windows构建过程中,构建过程通常没有文档、文档不足、迟钝或非常复杂。

发布本文并不一定要保证w64devkitt始终保持最新,但是这个Dockerfile是从(并取代)我已经连续使用了两年多的shell脚本派生而来的。在这段时间里,GCC每次发布,我都会给自己搭建一个新的开发工具包,所以我已经养成了这个习惯。

我断断续续地使用Docker大约有18个月了。这很奇怪,因为这是我在工作中学到的东西,而不是在自己的时间里学到的。我早期形成的印象仍然基本成立:Docker的主要目的是遏制和隔离行为不佳的软件,以提高其可靠性。行为良好、设计良好的软件几乎不会从容器中获益。

我在这里对Docker的不同寻常的应用也不例外。大多数软件构建都是不必要的复杂和脆弱的,特别是基于Autoconf的构建。具有讽刺意味的是,我处理过的最糟糕的配置脚本来自GNU项目。他们浪费时间做无用的检查(“您的编译器是否定义size_t?”)。然后生成一个无论如何都不能工作的构建,因为您正在做一些稍微不寻常的事情。最糟糕的是,尽管我尽了最大努力,构建还是会被执行构建的系统的状态所污染。

我最初的构建脚本扩展起来很脆弱。它可以在一个系统上工作,但不能在另一个系统上工作,这是因为一些微妙的环境变化-一个稍微不同的系统头显示了一个构建系统错误(例如在GCC中),或者系统在某个不应该硬编码的硬编码绝对路径上没有文件。将MyScript转换为Dockerfile可以锁定这些问题,并使构建更加可靠和可重复。这一不端行为已由多克负责处理。

不幸的是,它并没有完全得到控制。在每种情况下,我都使用make的-j选项来并行化构建,否则将花费数小时。一些构建具有微妙的竞争条件,一些糟糕的Luckin计时可能会导致构建失败。多克善于从停止的地方重新开始,所以只需要再试一次就行了。

在一种情况下,构建失败是因为没有安装Bison和Flex,尽管通常不需要它们。某些依赖项没有正确表达,并且不吉利的排序会导致未使用的.y文件具有错误的时间戳。呃.。我在Docker中遇到这种情况的次数比在Out中多得多,可能是因为Docker内部的文件系统操作很慢,造成了更大的时间差异。

自述文件解释了我的一些决定,但我将在这里总结几个:

吉特。又重要又有用,所以我很想要它。但是它有奇怪的依赖项(Perl、Bourne shell等),并且构建系统不支持交叉编译。我希望看到用一种(合适的)实现语言编写干净、直截了当的Git。想象一下用go get git-scm.com/git安装最新的Git。

巴什。它是一个比BusyBox-W32ash更好的交互式shell。但是构建系统不支持交叉编译,而且我不确定它是否支持没有某种兼容层的Windows。

艾玛克。又一位实力雄厚的编辑。但是构建系统不支持交叉编译。它也太大了。

去。我很想把它扔进去,但是围棋已经正确而有效地做到了这一点。它根本不需要专门的发行版。在任何系统上管理一个完整的围棋工具链,除了围棋本身什么都没有,这是微不足道的。人们可能会说它的语言设计来自20世纪70年代,但它的工具比其他任何人都领先了几十年。

在很长很长一段时间里,Cygwin为我填补了这个角色。然而,我从来不喜欢它的笨重特性,这与便携完全相反。Cygwin进程在Windows上总是感觉是二流的,特别是与其他Windows进程相比,Cygwin进程对文件系统有自己的看法,它们永远不能完全合作。我也不喜欢以Cygwin为目标进行交叉编译的工具链--比如编译Linux中的Cygwin二进制文件。最后,它基本上已经被WSL淘汰了,它在每一条战线上都与它不相上下,甚至超过了它。

还有msys和msys2,它们稍微轻一些。然而,我仍然在一个与世隔绝的二流环境中,有奇怪的路径翻译问题。这些工具确实有重要的用途,而且它是在Windows上本地编译大多数开源软件的唯一方法。对于那些不支持交叉编译的构建,这是生成Windows构建的唯一途径。这不是我在开发自己的软件时想要的。

我还将我的GnuPG构建脚本转换为Dockerfile。当然,我不打算在Windows上实际使用GnuPG。我只需要它作为Passphrase2pgp,我用它来测试GnuPG。这将测试Windows版本。

将来,我可能会将这个想法扩展到其他一些我不打算包含在w64devkit中的工具。如果您有什么想法,可以使用my Dockerfiles作为一种入门模板。

对这篇文章有什么评论吗?通过发送电子邮件至~Skeeto/[email protected][邮件列表礼仪]开始我的公共收件箱中的讨论,或查看现有讨论。