想知道“魔笛手”在这里能发挥什么作用吗?想象一下,把 CMake 当做法力高强的魔笛手,C++ 的项目则是故事中的那些被魔笛手拯救的孩子。
父母要抚养一个孩子并非易事,营养需要面面俱到,保证身体健康,关心事无巨细,确保快乐成长。其难度不亚于 C++ 项目的交叉编译,但一个保姆就能让事情变得更简单。类似地,我们也有 CMake 来简化交叉编译中的烦琐事。
交叉编译到底是什么?
以一个著名的应用程序为例,比如 Microsoft Paint。在它成为可执行文件之前,是一组源代码文件。编译源代码并将目标代码链接到单个可执行文件,这是编译器的工作。在正常情况下:
Microsoft Paint 的源代码是一组C++文件,在 Microsoft windows 中使用 Visual Studio 编译器进行编译。现在来看交叉编译场景:
因此,当源代码编译器对应的操作系统与其当前所在的操作系统不同时,就会发生交叉编译。这张图应该更清楚一点:
现在,交叉编译这个术语从何而来已经很明显了。跨平台软件开发并不容易,因为每个操作系统都有自己的特点。为 Windows 编写的源代码通常不能为 Linux 编译,反之亦然。这就是 Qt 等框架和 POSIX 等标准发挥作用的地方。
我不能忍受简单编译吗?
不总是这样。举个例子,一个开发者正在为 Android 开发的应用程序,他会利用开发机器(Windows、Linux 或 Mac)的计算能力为 Android 交叉编译应用程序。如果开发人员将目标锁定为 Raspberry Pi 这样的平台,情况也是如此。比起要在一台低性能机器上耗费大量时间运行编译,在功能强大的开发机器上设置交叉编译环境并将二进制文件复制到 Raspberry Pi,则容易得多。
交叉编译的另一个用例,是使用目标机器的本机编译器生成依赖项的复杂性。例如,以 Chromium(Microsoft Edge 浏览器和 Google Chrome 浏览器的基础)这样一个在多个平台上都受支持的开源项目为例。由于存在多个依赖项,因此不建议尝试以本机方式构建 Chromium。更确切地说,本地镜像是一个 Linux 容器,承载 GNU GCC 来交叉编译源代码。
能举个交叉编译的例子吗?
Windows 10 桌面操作系统有两种不同的风格:
- Windows 10, Intel CPUs ( 32 Bit 和 64 Bit 版本)
- Windows 10,ARM CPUs (ARM32 和ARM64 Bit 版本)
为 Intel CPU 编译的程序与 ARM CPU 不兼容,反之亦然。Microsoft Visual Studio 附带以下命令工具,其中一些用于交叉编译:
- VS2015 x64 ARM Cross Tools Command
- VS2015 x64 Native Tools Command
- VS2015 x64 x86 Cross Tools Command
- VS2015 x86 ARM Cross Tools Command
- VS2015 x86 Native Tools Command
- VS2015 x86 x64 Cross Tools Command
我们对交叉编译工具很感兴趣。让我们试着创建一个简单的 “Hello, World!” C++ 程序:
#include int main(int argc, char** argv){std::cout << “Hello, World!” &