3.3 伪交叉编译
首先electron-builder是支持在A操作系统下为B操作系统生成应用程序的安装包的,但限制颇多,而且这样做的人很少,所以我不建议使用这个功能。如果开发者没有B操作系统的机器,我的建议是想办法得到一台这样的机器,再在这台机器上为B操作系统的用户生成安装包。
即使electron-builder提供了这方面的支持,但也并非使用了交叉编译的技术,详见后面的讲解。
其次electron-userland组织下有一个开源项目electron-build-service(https://github.com/electron-userland/electron-build-service)为打包工作提供了服务支持,如果开发者想把打包工作迁移到服务器端,可以考虑使用这个开源项目。
我们要重点解释的是electron-builder是如何在64位的操作系统上生成32位的安装包的(反之也是同样的原理)。
electron-builder并不会在开发者电脑上完成Electron源码的编译工作,而是根据用户的配置信息去服务器上下载Electron团队编译好的二进制资源,配置信息如下所示:
{ win:{ target: [ { target: 'nsis', arch: ['ia32'], }, ], } ... } ... }
electron-builder下载并缓存Electron的逻辑与安装Electron依赖包时的下载和缓存逻辑不同。electron-builder下载Electron时使用的镜像环境变量为ELECTRON_BUILDER_BINARIES_MIRROR,缓存路径环境变量为ELECTRON_BUILDER_CACHE。
electron-builder判断是否存在缓存文件的逻辑代码如下所示:
export function getBin(name: string, url?: string | null, checksum?: string | null): Promise<string> { const cacheName = process.env.ELECTRON_BUILDER_CACHE + name; let promise = versionToPromise.get(cacheName); if (promise != null) { return promise } promise = doGetBin(name, url, checksum) versionToPromise.set(cacheName, promise) return promise }
在这段代码中看到了ELECTRON_BUILDER_CACHE的身影。如果缓存目录中存在相应的文件,则versionToPromise.get方法返回相应的文件信息,否则electron-builder将调用doGetBin方法下载对应的二进制Electron文件。下载逻辑代码如下所示:
export function getBinFromUrl(name: string, version: string, checksum: string): Promise<string> { const dirName = '${name}-${version}' let url: string if (process.env.ELECTRON_BUILDER_BINARIES_DOWNLOAD_OVERRIDE_URL) { url = process.env.ELECTRON_BUILDER_BINARIES_DOWNLOAD_OVERRIDE_URL + "/" + dirName + ".7z" } else { const baseUrl = process.env.NPM_CONFIG_ELECTRON_BUILDER_BINARIES_MIRROR || process.env.npm_config_electron_builder_binaries_mirror || process.env.npm_package_config_electron_builder_binaries_mirror || process.env.ELECTRON_BUILDER_BINARIES_MIRROR || "https:// github.com/electron-userland/electron-builder-binaries/releases/download/" const middleUrl = process.env.NPM_CONFIG_ELECTRON_BUILDER_BINARIES_CUSTOM_DIR || process.env.npm_config_electron_builder_binaries_custom_dir || process.env.npm_package_config_electron_builder_binaries_custom_dir || process.env.ELECTRON_BUILDER_BINARIES_CUSTOM_DIR || dirName const urlSuffix = dirName + ".7z" url = '${baseUrl}${middleUrl}/${urlSuffix}' } return getBin(dirName, url, checksum) }
在这段代码中看到了ELECTRON_BUILDER_BINARIES_MIRROR的身影,也就是说当开发者在64位操作系统上打32位的应用程序安装包时,electron-builder会去服务器下载32位的Electron二进制包,并把这个包的内容复制到你的win-ia32-unpacked目录下,从而完成“交叉编译”的需求。在A系统上为B系统制成安装包也使用了类似的机制。这实际上这并不是真正的交叉编译。