前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >在你的ios、android应用中嵌入官方版nodejs是什么感觉?

在你的ios、android应用中嵌入官方版nodejs是什么感觉?

作者头像
车雄生
发布2022-10-05 15:55:09
1.9K0
发布2022-10-05 15:55:09
举报
文章被收录于专栏:咩嗒

目前网上找到的ios嵌入nodejs介绍,都是指向nodejs-mobile项目,nodejs-mobile对nodejs项目做了一定魔改,可以预想会难以及时的随nodejs升级,该项目目前的nodejs版本12.19.0,比起官方版本落后太多。而本文介绍的办法只需对nodejs的gyp添加少些修改以支持ios、android的编译,该方式编译的16.16.0版本nodejs已经在真机上测试通过并应用到puerts项目上。而且该修改方式也已经提PR给nodejs官方并合入到主干: libnode for ios app embedding

念念不忘的移动端nodejs支持

尽管我们反复的解释了nodejs是“JavaScript Runtime”之一,如果一个js库用了nodejs专有的api是不能直接在其它“JavaScript Runtime”,比如browser,puerts里运行的。

但奈何nodejs已经事实上约等于js,用puerts的童靴有时候找资料,找到的“如何用ts/js完成XXX”系列文章往往都是nodejs的。很自然的跑过来问puerts为啥不行,不是说支持js么?

其次puerts项目的出发点之一就是把繁荣的js生态引入到游戏开发,如果缺失了nodejs生态,这将是一个重大遗憾。

于是在去年,puerts就尝试在桌面平台支持nodejs脚本后端:《UE引擎里头跑个nodejs服务器是怎样一种体验?》【PuerTS】我们把Node.js放进了Unity里(一),但由于移动平台的缺失,我们只是推荐用在做引擎编辑器扩展开发。

不过发现还是有些没有发移动端需求的项目用了nodejs版本,而且反馈对他们开发十分有帮助:网络方面比UE提供的好用,除了界面相关,其它需求都很容易找到相应的nodejs组件。而界面相关又恰好是游戏引擎的强项,所谓强强联合了。于是我对移动端nodejs的支持更期待了,但nodejs并没有移动端的官方支持,特别是ios。

我在网上找移动端nodejs的支持情况,ios只找到nodejs-mobile,它支持nodejs版本远低于我们要求的版本,并不适用,而android下发现官方提供了个android-configure脚本,既然官方提供的,我想应该是能用的吧?但事实上没那么简单,一个接一个的坑,所幸最终还是搞定了,于是实现了puerts对nodejs的双引擎(UE、Unity)×多平台(Window,Mac,Linux,iOS、Android)支持。

具体做了那些修改就不细说了,这些修改都以git patch的形式放到这个项目,可自行查阅:https://github.com/puerts/backend-nodejs

如何嵌入nodejs

相关的资料不多,可以看看我之前两篇相关文章:

未来展望:游戏领域的electron?

nodejs本身除了GUI大多数任务都能完成,于是有人把chrome和nodejs缝合,做成个跨平台的桌面框架electron,十分火爆,这里是它的showcase ,我们程序员耳熟能详的VSCode也赫然此列。

如果把chrome换成专业的游戏引擎:UE、Unity。从2维升级到3维,而且除了桌面平台,还支持移动平台,甚至主机平台,是不是很有想象空间呢?期望有人能把它搞起来。

接下来的章节记录的是探索nodejs移动平台时踩过的坑,可以跳过,直接翻到文章结尾有现成编译好的全平台libnode。如果你个人需要定制什么编译参数,需要自行编译可以再来翻看。

nodejs移动平台支持踩过的坑

一个好开端

我抱着试试看的心态用android-configure编译了一下arm64的libnode.so(用的是puerts当时用的nodejs版本14.16.0),竟然顺利编译成功,习惯了困难模式的我隐隐觉得事情没那么简单。

哪有什么岁月静好

放到Unity版本的puerts在真机上测试,果然失败了,提示libnode.so失败。按经验应该是libnode.so依赖的某些库缺失。 用ndk提供的工具查看依赖

代码语言:javascript
复制
aarch64-linux-android-readelf -d libnode.so

对比下v8版本的puerts的依赖

发现多了个libc++_shared.so,感觉应该是这个导致的,回头查看nodejs的编译选项,发现--partly-static可能可以解决这个问题。编译后libc++_shared.so确实没了,上真机测试果然能正常跑了!!!

64位机器编译arm架构

感觉更难的arm64都编译通过了,arm应该更简单,没想我还是天真了,碰到两个问题

  • 小问题:arm架构的TOOLCHAIN_NAME错了(估计是后面ndk改了,nodejs没同步)
  • 在64位linux下编译,交叉编译有的模块host用64位,有的用32位,链接失败,解决办法:CC_host和CXX_host强制加个-m32。

iOS支持可行性分析

nodejs的最主要部分:V8我们在iOS已经应用了很久(加--jitless选项)。而android-configure的存在,也证明了其它部分在arm架构下运行问题不大。推测iOS嵌入nodejs最大的门槛在编译。

失败的尝试

我尝试参考android的交叉编译做了一版iOS的交叉编译,结果失败了。

其生成的Makefile根本没法使用,我尝试去看gyp的代码,尝试调整Makefile的输入,仍然是失败的。

虽然失败,但也有收获,而且该收获直接导致后面成功:我初步搞懂了gyp是啥,它是一个python写的程序,该程序会根据gyp的配置生成编译工程:window下的vs工程,linux/unix下Makefile等等。gyp配置解析部分是通用的,然后调用一个个generator(msvs.py,android.py,make.py)去生成工程。

ninja是个好东西

iOS(unix系OS)调用的generator是make.py,但make很复杂,我也不熟悉,搞不定。于是把目光投到其它generator,最终锁定ninja。

ninja的规则十分简单(十分钟能学完),有问题比较容易找到并调整,借助它我最终把nodejs的ios交叉编译调通了。

当然,也不是一帆风顺,期间也碰到几个问题:

  • "multiple rules generate":这是我耗时最久的坑,iOS编译一直报这错误,但android切换到ninja却能很顺利的编译通过,我只能二分查找去缩写iOS和android的ninja文件的差异,最后却发现是ninja版本导致的,homebrew安装的ninja比较新,dupbuild会认为是错误,而ubuntu的apt-get安装的版本只是告警,加个参数可以临时解决这问题
  • 14.16.0的libuv不兼容iOS,可通过少许代码改造通过(升级nodejs版本也可以解决,后面我升级到当时最新的nodejs LTS版本16.16.0)

iOS静态库

苹果的动态库发布很麻烦,需要签名什么的。我们更希望以静态库提供。于是尝试编译静态库。把configure的--shared改为--enable-static即可,编译也很顺利,但链接找不到符号,这些符号位于这两个文件:http://node_snapshot_stub.cc,http://node_code_cache_stub.cc。构建libnode.so会包含,我们把这两也变成静态库链接即可。

这次很顺利,搞定了编译,用unity应用在iOS上测试直接就通过了。

unreal engine碰到的坑

搞定unity,ue上跑还算顺利,只是碰到一个问题:ue和nodejs都用了openssl,但ue的版本老,两种冲突了。表现为:

  • 用动态库版本的nodejs,编译没问题,运行时崩溃,崩在openssl的调用。
  • 静态库版本编译不过,两个版本的openssl的api就不兼容,并存的时候会报符号冲突,去掉其中一个又会报一些符号找不到

最终我先把nodejs的openssl去掉(加--without-ssl选项),如果自行编译ue引擎的童靴也可以选择保留nodejs的openssl,升级ue引擎的openssl。

全平台libnode下载链接

我们已经把libnode的全平台编译做成github action自动化编译:https://github.com/puerts/backend-nodejs ,也有编译好版本,可以直接使用:有带openssl的版本 ,也有不带openssl的版本

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-09-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 念念不忘的移动端nodejs支持
  • 如何嵌入nodejs
  • 未来展望:游戏领域的electron?
  • nodejs移动平台支持踩过的坑
    • 一个好开端
      • 哪有什么岁月静好
        • 64位机器编译arm架构
          • iOS支持可行性分析
            • 失败的尝试
              • ninja是个好东西
                • iOS静态库
                  • unreal engine碰到的坑
                  • 全平台libnode下载链接
                  相关产品与服务
                  SSL 证书
                  腾讯云 SSL 证书(SSL Certificates)为您提供 SSL 证书的申请、管理、部署等服务,为您提供一站式 HTTPS 解决方案。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档