使用Docker 对Qt for WebAssembly进行测试

作者:Richard Lin | May 20, 2019 6:34:13 AM

本文翻译自:Using Docker to test Qt for WebAssembly

原文作者:Maurice Kalinowski

校审:Richard Lin

最近,人们对WebAssembly的热情很高,更确切地说,是对Qt for WebAssembly的热情很高。不幸的是,暂时还没有可用的开发环境的镜像。即使有可用的版本,您也需要在本地安装好很多依赖项来设置您的开发环境。

我想试试这个过程,这篇文章的目的是创建一个开发环境,并用它测试一个基于最新进展的工程。此处我们引入了Docker。过去,Docker一直被用于在云环境中创建web应用程序,它允许轻松扩展、提供隐式沙箱和轻量级部署,至少比虚拟机轻量级多了。

现在Docker涵盖了更多的场景。

  • 构建环境(独立)
  • 开发环境(为其他用户创建SDK)
  • 连续集成(在容器内运行测试)
  • 嵌入式系统的运行时

容器和嵌入式并不是这篇博文的重点,但这种方式有很多好处:

  • 可以作为应用程序的开发环境来使用
  • 资源可控
  • 提供沙箱/安全相关项目
  • 提供云特性,如应用部署管理、OTA等…

我们可能会在以后的博文中更深入地讨论这个问题。在此期间,您还可以追踪我们合作伙伴韬睿在Torizon项目上的进展情况。此外,Burkard还写了一篇关于Docker与Open Embedded结合使用的文章。

让我们回到Qt WebAssembly,并讨论如何达到预定的目标。假设我们手头上有一个在其他平台上用Qt开发的项目。

我们的目标是创建一个容器,能编译上述基于Qt for WebAssembly的项目,并在浏览器中测试它。

1.创建开发环境

Morten写过一篇关于如何编译Qt for WebAssembly的文章。以后,我们将会创建一个Qt for WebAssembly二进制预编译库并通过Qt安装程序为您提供下载和使用。但就目前而言,我们的目标是实现一个最小的东西而且不需要处理依赖的问题。使用Docker Hub的另一个优点是,生成的镜像可以与他人共享。

Dockerfile的第一部分如下所示:

FROM trzeci/emscripten AS qtbuilder

RUN mkdir -p /development
WORKDIR /development

RUN git clone --branch=5.13 git://code.qt.io/qt/qt5.git

WORKDIR /development/qt5

RUN ./init-repository

RUN mkdir -p /development/qt5_build
WORKDIR /development/qt5_build

RUN /development/qt5/configure -xplatform wasm-emscripten -nomake examples -nomake tests -opensource --confirm-license
RUN make -j `grep -c '^processor' /proc/cpuinfo`
RUN make install

浏览Docker Hub可以发现很多可以作为基础的镜像。在本例中,我选择了一个基础镜像,它安装了Emscripten,并可以直接用于后续步骤。
接下来的步骤基本上就是一条一条地复制构建指令。
现在,我们有一个包含所有构建材料(object文件、生成的mocs、…)的大型容器,它太大了,无法共享,而且这些材料也没有继续分享的必要。有些人倾向于使用磁盘共享来解决。构建文件夹位于宿主系统中,然后挂载到镜像系统中,构建在这个文件夹中完成,执行安装时拷贝安装文件到镜像系统中。我个人不喜欢使用这种方法,因为可能破坏我的宿主操作系统。
在较新版本的Docker中可以进行多阶段构建,它允许基于前一个镜像来创建新镜像,并将前一个镜像中的内容复制到其中。接下来的Dockerfile实现了这一点:

FROM trzeci/emscripten AS userbuild

COPY --from=qtbuilder /usr/local/Qt-5.13.0/ /usr/local/Qt-5.13.0/
ENV PATH="/usr/local/Qt-5.13.0/bin:${PATH}"
WORKDIR /project/build
CMD qmake /project/source && make

同样的,我们可以使用相同的基础容器让em++及其相关库可用,并复制Qt构建的安装内容到新镜像中。接下来,我们将它添加到PATH并更改工作目录。这个路径在稍后会很重要。CMD指定了容器在非交互性启动时执行的命令。

2.使用开发环境/编译应用程序

现在,用于测试应用程序的镜像已经创建好了。若要测试项目的构建,需要创建一个build目录,并调用Docker,命令如下所示

docker run --rm -v :/project/source -v :/project/build maukalinow/qtwasm_builder:latest

这将启动容器,调用qmake和make,并将构建内容留在构建目录中。容器中的/project/build目录映射到外部构建目录,这就是上面设置工作目录的原因。
为了减少每次输入,我创建了一个最小的批处理脚本(是的,我用的是Windows) 。你可以在这里找到该脚本。

3.再次测试应用程序/容器

希望您已经能够编译您的项目了,可能需要进行一些额外的调试,接下来就可以在网页服务中验证运行是否正确的了。我们需要的是一个网页服务来支撑所创建的内容。同样,Docker在这里也很有用。由于没有指定参数,其实就是检查hub上的第一个命中,您可以通过下面的命令进行调用

docker run --rm -p 8090:8080 -v :/app/public:ro netresearch/node-webserver

这将创建一个Web服务,您可以从本地浏览器浏览。下面是animated tiles示例的屏幕截图


另外,您知道Qt最近还加入了QT Http Server功能吗?将它封装到容器中并检查是否可以删除其他文件以最小化镜像尺寸,这可能是一个有趣的想法。相关更多信息,请查看我们的文章
如果您想要尝试镜像本身,您可以从这个链接下载。
这篇博文就写到这里了,希望读者们能提供一些反馈,并进行一些相关的讨论。

  • 您是否已经将容器与Qt结合使用?
  • 你的使用场景是什么?
  • 你已经在容器中试用了Qt吗?你有什么经验可以分享吗?
  • 你想让Qt提供一些开箱即用的东西吗?你希望是什么呢?