Win11如何用Emscripten构建lovejs运行库
📝3317 个字
 | ⌛要看完怎么也得9分钟吧
先超快地介绍一下背景
- 首先咱这小网站上整的小游戏,其实都是基于love2d引擎的,包括之前整的星空背景也是🌠。而之所以用love2d,主要就看中两点,一个是开源免费,还有就是轻量且全平台。如果小伙伴对这个引擎感兴趣的话,也可以去官网上瞅瞅,个人觉得是挺喜欢的😀。不过糟心的是,这个引擎虽然说是全平台,其实并不包含网页端😞。所以要在网页上运行的话,就还需要使用到第三方库。不过好在社区的活跃度还算高,因此相关的第三方库也非常多。
- 而其中用的比较多的则是lovejs,基本支持love2d最新版本的大部分功能特性🥰。它主要是通过Emscripten,把运行库编译成WebAssembly,同时配合上一些js的胶水代码,就可以完美实现在网页上运行love2d。不过这部分知识点可能有点密,要是感兴趣的话可以先稍微了解一下。咱这里因为重点不在这,就不再进一步展开了。
- 使用方式也算简单,直接把lovejs提供的运行库在网页上引入即可。所以一般正常使用下,是不需要进行任何打包编译工作的✌️。但因为咱这小网站的使用方式比较歪门邪道,与其说是游戏不如说是网页本身的一部分。尤其像弹幕界面上使用的星空背景,就非常接近这种使用模式。所以相对来说,对交互的紧密性要求也就会更高点🤔。而为了能进一步满足俺的脑洞,就不可避免得需要自己对运行库代码,增加一些独特的小改动💪。
- 结果这不月初的时候,因为自己一不小心手滑把系统盘干废了,最后只能屁颠屁颠地重装了一下系统。所以原有的开发环境,也全部都一起烟消云散了💩。但之后整活多多少少还得用上,而且以前刚刚接触的时候就发现,网上有关于这个引擎的中文文章那叫一个屈指可数。所以不如将错就错,在重新部署的同时,再顺便写篇小作文记录一下,也算是也来贡献一点绵薄之力了😎。
必要软件安装
安装Python
- 因为Emscripten内部有很多脚本,都是基于python开发的,所以在使用之前,还需要安装一下。官方的要求是使用3.8或以上的版本,但由于Python本身的兼容性问题,这里建议直接安装3.8.10版本,当然如果本地已经有更高版本,就可以先不折腾了,先用着试试😏。
- 安装过程就比较平常了,不过需要记得在开始安装前,勾选添加环境变量的选项,之后等待安装完成即可。

安装Emscripten
- 直接打开官方仓库下载最新的发行版本就行。俺这会最新的版本是4.0.23,所以后续演示就以此版本为主。
- 下载完成后,咱找个心仪的目录,把内容解压文件到文件夹里就行。如果在根目录能找到
emsdk.bat文件就没问题了。 - 然后在当前目录打开cmd窗口,依次输入以下指令:(注意这里的版本别输错了,虽然很夸张,但确实用的是这个上古版本🤣)
emsdk install 2.0.0 emsdk activate 2.0.0 - 全部执行完成后,根目录下应该会多出一个
upstream\emscripten目录,这时候就可以关闭cmd窗口了。不过俺习惯再手动把这个目录,加入到系统环境变量里。虽然之前的activate指令其实就是在自动添加环境变量,但为了避免之后麻烦就还是顺手再加上了😁。
安装Cmake
- 同样,因为love2d本身使用的是老版本,所以咱们保持一致,下载对应3.1版本的安装包。
- 下载完成后,直接打开安装即可。但在第二步的时候,同样记得把环境变量加上(默认是不添加的),后续保持默认配置一路点点点就完了✌️。

安装make
- 这个没啥特别的版本需求,直接打开Gnu仓库下载最新版本即可。因为俺这会是4.4版本,所以后续描述以此版本为准。但这里需要注意一下,因为仓库上只提供了
tar.gz包,所以如果电脑上没安装WinRAR或者7z这种解压软件的话,需要再单独安装一下。 - 同样解压后找个心仪的位置,把目录内的所有文件拷贝至文件夹内,如果在根目录下能看到
WinRel目录即可。然后因为之后咱们需要使用的是make.exe程序,因此还需要把WinRel目录添加到系统的环境变量里。
下载lovejs工程
- lovejs的源工程主要分两个部分,分别是megasource、love2d,依次下载完整工程到本地即可。需要注意的是,咱这里使用的都是emscripten分支的工程,下载前需要注意一下分支选择是否正确。
- 然后再打开lovejs的官方仓库,但这里不需要下载所有内容,只需要下载根目录下的
build_lovejs.bat文件即可。都下载完成后,接下来咱们就可以像拼积木一样,开始把他们组装起来了👾。 - 同样先找个心仪的目录,首先把咱们的
build_lovejs.bat文件拷贝至当前目录。 - 然后为了之后打包的时候保持整洁,再在当前目录新建一个
project文件夹(具体叫啥不关键,但俺这就这么用了)。然后把下载的megasource工程中,根目录下的所有文件拷贝至project文件夹下即可。之后进入project文件夹,如果能看到libs文件夹和CMakeLists.txt文件就没问题了。 - 之后咱们需要依次打开文件夹至路径
...\project\libs\love,正常情况下该目录应该是完全空的。这时候只需要把之前下载好的,love2d的工程根目录下的所有文件,拷贝至此即可。同样需要确保在...\project\libs\love目录下,能看到love2d的CMakeLists.txt文件。 - 最后的目录结构大致如下,到此lovejs工程所有需要的工具,咱们就都准备好了,接下来就可以开始编译打包了💪。

打包编译lovejs
- 可能是因为作者之前做这个工程的时候,并没有真正的windows环境。所以为了后续打包编译能舒服地进行,在真正开始前,咱们还需要对脚本进行一些修改🤔。
- 首先回到工程最初的根目录,用编辑器打开一下
build_lovejs.bat文件。这里面有很多指令其实都是有问题的,甚至还能看到原作者的本地路径,所以需要配合咱自己的本地环境,进行以下调整:- 删除不必要的emsdk_env调用
- 调整最终输出目录
- 替换工程目录为本地相对路径
- 修改指令调用方式,防止意外退出
- 结尾增加暂停指令,方便错误调试
- 暂时关闭release包的编译工作(主要双版本编译太慢了,效率起见,先保证兼容版本能编译成功)
- 最后的指令完整内容如下(部分目录如果有不一样,记得自行调整):
@echo off
mkdir build
mkdir build\release
mkdir build\compat
mkdir output
mkdir output\release
mkdir output\compat
(
rem echo Building release version...
rem cd build\release
rem call emcmake cmake %~dp0\project -G "Unix Makefiles" -DLOVE_JIT=0 -DCMAKE_BUILD_TYPE=Release
rem call emmake make -j 6
rem copy "love\love.js*" ..\..\output\release
rem copy "love\love.wasm" ..\..\output\release
rem copy "love\love.worker.js" ..\..\output\release
rem cd ..\..
echo Building compatibility version...
cd build\compat
call emcmake cmake %~dp0\project -G "Unix Makefiles" -DLOVE_JIT=0 -DCMAKE_BUILD_TYPE=Release -DLOVEJS_COMPAT=1
call emmake make -j 6
copy "love\love.js*" ..\..\output\compat
copy "love\love.wasm" ..\..\output\compat
)
pause
exit /b
- 调整完成后,就可以开始咱们的第一次尝试编译工作了,直接双击运行
build_lovejs.bat文件即可。(完整编译会比较慢,需要一定等待时间) - 如果顺利的话,那这时候肯定就会跟俺一样,收到一个非常美丽的Error🤡。嘛,第一次嘛,总归是充满着意外的😶🌫️。既然报错了,那就具体看看哪里有问题,对症下药即可。

- 一顿翻找之后,咱们可以看到刚刚开始的时候,zlib组件的编译就出现了一个报错。大概意思就是Emscripten在交叉编译的时候,因为无法确定
off64_t的大小,因此不能直接运行TRY_EUN()。 
- 解决方法也简单,按他的提示,在cmake的时候加上
OFF64_T_run_result和OFF64_T_run_result__TRYRUN_OUTPUT参数即可,修部分改内容如下:
...
echo Building compatibility version...
cd build\compat
call emcmake cmake %~dp0\project -G "Unix Makefiles" -DLOVE_JIT=0 -DCMAKE_BUILD_TYPE=Release -DLOVEJS_COMPAT=1 -DOFF64_T_run_result=0 -DOFF64_T_run_result__TRYRUN_OUTPUT=0
call emmake make -j 6
copy "love\love.js*" ..\..\output\compat
copy "love\love.wasm" ..\..\output\compat
...
- 因为刚刚那次编译有异常,所以修改完成后先把刚刚生成的
build和output文件夹删除,然后再次运行build_lovejs.bat文件即可。修改正确的话,这次应该就能正常进入编译阶段了,咱们等待编译完成即可。 
- 经过一段时间的编译后,终于是把进度条熬到离100%就差最后一步。但最恐怖的事情,无非就是在100%的时候,你以为马上就要胜利了,结果突然一个Error糊脸💩。而这次的报错就更经典了,直接就是一个
命令行太长。怼脸😑。 
- 之所以说他经典,主要就是因为巨硬当年也许是为了安全,在设计windows的cmd时,一直存在一个最大指令长度的限制。而恰好相反,这个限制在linux上是不存在的😐!所以经常会出现在linux中使用的makefile,到了windows下直接被一大串参数整懵逼,然后反手就甩出一个
命令行太长。的提示,剩下就让你自己解决去咯,简直无情😭! - 当然既然是经典问题,解决方式自然也非常丰富,甚至还有个
Ninja编译器,专门解决了这个问题。但咱们这里考虑到兼容性和工作量,还是选择使用最简单的修改方式——修改love2d的CmakeLists,启用响应文件支持。简单来说,就是把一堆又臭又长的参数,单独放到一个文件里面,程序执行的时候自行读取即可。 - 修改方式也很简单,首先咱们定位到love2d的
CmakeLists文件,具体路径如下...\project\libs\love\CMakeLists.txt。然后用编辑器打开该文件,在第28行找到project(love)指令。然后在该指令下,添加以下指令:
if(WIN32 AND CMAKE_GENERATOR MATCHES "Unix Makefiles")
set(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS 1)
set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_OBJECTS 1)
set(CMAKE_C_USE_RESPONSE_FILE_FOR_LIBRARIES 1)
set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_LIBRARIES 1)
endif()
# 针对 Emscripten 的特殊设置
if(EMSCRIPTEN)
# 重写静态库创建命令以使用响应文件
set(CMAKE_C_CREATE_STATIC_LIBRARY "<CMAKE_AR> cr <TARGET> <OBJECTS>")
set(CMAKE_CXX_CREATE_STATIC_LIBRARY "<CMAKE_AR> cr <TARGET> <OBJECTS>")
endif()
- 保存后再次回到工程根目录,同样删除
build和output文件夹后,再次运行build_lovejs.bat文件,等待直到编译完成。 
- 看到上述输出后,就说明编译成功完成了🎉。因为咱这次编译的是兼容版,所以输出的lovejs库,会保存在工程根目录的
output\compat目录下。同样的,如果是要编译发布版本,只要把build_lovejs.bat文件内注释的部分打开,并且同样加上OFF64_T_run_result和OFF64_T_run_result__TRYRUN_OUTPUT参数即可。 - 到此咱们就成功使用win11,编译打包了lovejs的运行库。后续就可以根据需要,随意修改love2d的源码,甚至可以添加或删减自己想要的功能😁。像俺这次其实主要就是为了,让之前做的星空背景加载速度更快,所以前前后后最终把运行库精简了50%的大小😎。好歹也能大幅减少一下大伙看到流星雨,所需要的下载时间。当然编译过程除了这里提到的问题以外,可能还会遇到一些比较碎的毛病。如果有困难,也可以随时评论,俺有看到的话也会帮忙一起瞅瞅💪。