Tencent / puerts

PUER(普洱) Typescript. Let's write your game in UE or Unity with TypeScript.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[UE] 关于 QuickJS 编译到 NS 平台的方法

NiceTry12138 opened this issue · comments

如题
想问问 quickJS 编译到 NS 平台的可行方案,或者关键词

花费了很多时间在 v8 编译上,但是都没成功

https://github.com/puerts/backend-quickjs
这是个cmake工程。
看看ns sdk有没提供cmake的toolchain配置文件,有直接用即可。
没有就指明c++和c编译器路径就能编译。

其实v8也是类似,不过不是cmake,而是gn
gn配置指明c++和c编译器路径就可以了,可以参考我加的鸿蒙支持:https://github.com/puerts/backend-v8/blob/master/ohos_armv8.sh#L74

免责声明:example 项目在 windows 平台打包成功,但是开发机未到,不确定开发机能否正常运行

exmaple 是自己的测试项目,只包括最简单的打开 UI、切换场景

NS 环境

  1. https://www.unrealengine.com/ja/blog/launch-your-game-on-the-nintendo-switch-with-unreal-engine-4-16 参考该文章申请 NS 的开发者和 Unreal Engine 的开发权限
  2. 提前准备好源码版引擎,因为会下载 Platform Switch 的平台支持
  3. https://forums.unrealengine.com/t/tutorial-nintendo-switch-set-up-with-unreal-5-1/1313063 参考该文章下载 NS 的 SDK、Tool等,全程科学上网

QuickJS

由于项目问题,最终决定不使用 QuickJS,不过提供一下 QuickJS 打包 NS 的思路

首先就是使用 backend-quickjs 项目,有前人栽树就可以方便一些
然后参考 XLua 编译 NS 平台的经验 XLua-make-nx64

得到 qjs 的 cmake

set CUR_DIR=%~dp0
cd %CUR_DIR%

del /s/q buildnx64
mkdir buildnx64 & pushd buildnx64
rem fix for io_tmpfile & os_tmpname
echo #if !__ASSEMBLER__ > switch_fix.h
echo static inline struct _IO_FILE* tmpfile(){ return 0; } >> switch_fix.h
echo static inline char* tmpnam(char* n){ return 0; } >> switch_fix.h
echo #endif >> switch_fix.h

set "NINTENDO_SDK_ROOT_CMAKE=%NINTENDO_SDK_ROOT:\=/%"
cmake -DCMAKE_C_COMPILER="%NINTENDO_SDK_ROOT_CMAKE%/Compilers/NX/nx/aarch64/bin/clang.exe" ^
	-DCMAKE_CXX_COMPILER="%NINTENDO_SDK_ROOT_CMAKE%/Compilers/NX/nx/aarch64/bin/clang++.exe" ^
	-G "Unix Makefiles" -DCMAKE_SYSTEM_NAME=Switch ^
        -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON ^
        -DSWITCH_PLATFORM=1 ^
        -DNS_US_ELF=1 ^
	-DCMAKE_C_FLAGS="-includeswitch_fix.h -I%CUR_DIR%buildnx64" ^
	..
popd
cmake --build buildnx64 --config Release

如果你的 NS 环境配置好了,在环境变量中会有 NINTENDO_SDK_ROOT_CMAKE

然后就是修改一下 CMakeLists.txt 文件

if (SWITCH_PLATFORM) 
    set(NINTENDO_SDK_ROOT $ENV{NINTENDO_SDK_ROOT})
    set(NS_INCLUDE "${NINTENDO_SDK_ROOT}/Include")
    set(NS_SPECIFIC_INCLUDE "${NINTENDO_SDK_ROOT}/TargetSpecificInclude/NX-Win32-v142")
    set(NS_AARCH64 "${NINTENDO_SDK_ROOT}/Compilers/NX/nx/aarch64")

    set(NS_INCLUDE_LIST ${NS_INCLUDE})                                      # 定义搜索路径
    list(APPEND NS_INCLUDE_LIST ${NS_SPECIFIC_INCLUDE})                     # 添加特殊文件搜索路径
    list(APPEND NS_INCLUDE_LIST "${NS_AARCH64}/include")                    # 添加 AARCH64 头文件
    list(APPEND NS_INCLUDE_LIST "${NINTENDO_SDK_ROOT}/Include/nn/socket")   # 网络库相关
    
    set(NS_LIB_LIST "$${NS_AARCH64}/lib")                                   # 添加 AARCH64 静态库
   
    if(NS_US_ELF)
        list(APPEND NS_INCLUDE_LIST "${NS_AARCH64}/include/aarch64-nintendo-nx-elf")
        list(APPEND NS_LIB_LIST "${NS_AARCH64}/lib/aarch64-nintendo-nx-elf")
    else ()
        list(APPEND NS_INCLUDE_LIST "${NS_AARCH64}/include/aarch64-nintendo-nx-nncfi")
        list(APPEND NS_LIB_LIST "${NS_AARCH64}/lib/aarch64-nintendo-nx-nncfi")
    endif()
    
    add_compile_options(-fdeclspec)
    add_definitions(-DNN_SDK_BUILD_RELEASE)
    
    include_directories(${NS_INCLUDE_LIST})
    link_directories(${NS_LIB_LIST})
        
endif()

我也是临时学的 CMake,思路就是将 include 和 lib 添加到索引目录上,满足 quickjs 的源码需要

接下来我对 quickjs 的源码做了一些修改,不知道会不会出现问题,因为 quickjs 中需要使用 sys/time.h,但是 ns 环境中对网络的依赖关系有点麻烦,所以我直接做了如下修改

// #include <sys/time.h>

struct timeval
{
   long long      tv_sec;     // seconds
   long long tv_usec;    // microseconds
};

直接注释掉,然后将需要使用的结构体定义一份

因为多个项目使用的都是 v8,改成 qjs 要全部重新测试,甚至项目需要修改,所以最后还是决定使用 v8,如果 v8 成功,也会在这里提供思路 🙏🙏🙏🙏

之前尝试过 cmake-v8 项目,但是 windows 平台很多问题,还是参考 bakend-v8 项目吧
PS. 如果前面有问题,请指出说明,虚心讨教

PPS. 为了快速测试,项目最后还是使用 qjs。如果 qjs 测试为能够运行,就先不处理 v8。

字段无法访问 “widget.count” 无法访问 count 控件, 蓝图下可访问,问题是 FName 的大小写不敏感
https://github.com/Tencent/puerts/blob/master/doc/unreal/zhcn/faq.md
#892
尝试全部设置为首字母大写,解决问题

使用 quickjs 打开项目出现的循环引用和堆栈溢出
虽然报错了循环引用,但是通过 quickjs 提供 JS_SetMaxStackSize 接口设置堆栈大小为 10m 就解决了

#ifdef WITH_QUICKJS
    MainIsolate = InExternalRuntime ? v8::Isolate::New(InExternalRuntime) : v8::Isolate::New(CreateParams);
    JS_SetMaxStackSize(MainIsolate->runtime_, 10 * 1024 * 1024); // 设置调用堆栈为 10m
#else

Puerts 的 .plugin 中记得在 WhitelistPlatforms 添加 Switch,否则JsEnv、WasmCore、Puerts模块不会启动

免责声明:example 项目在 windows 平台打包成功,但是开发机未到,不确定开发机能否正常运行

exmaple 是自己的测试项目,只包括最简单的打开 UI、切换场景

NS 环境

  1. https://www.unrealengine.com/ja/blog/launch-your-game-on-the-nintendo-switch-with-unreal-engine-4-16 参考该文章申请 NS 的开发者和 Unreal Engine 的开发权限
  2. 提前准备好源码版引擎,因为会下载 Platform Switch 的平台支持
  3. https://forums.unrealengine.com/t/tutorial-nintendo-switch-set-up-with-unreal-5-1/1313063 参考该文章下载 NS 的 SDK、Tool等,全程科学上网

QuickJS

由于项目问题,最终决定不使用 QuickJS,不过提供一下 QuickJS 打包 NS 的思路

首先就是使用 backend-quickjs 项目,有前人栽树就可以方便一些 然后参考 XLua 编译 NS 平台的经验 XLua-make-nx64

得到 qjs 的 cmake

set CUR_DIR=%~dp0
cd %CUR_DIR%

del /s/q buildnx64
mkdir buildnx64 & pushd buildnx64
rem fix for io_tmpfile & os_tmpname
echo #if !__ASSEMBLER__ > switch_fix.h
echo static inline struct _IO_FILE* tmpfile(){ return 0; } >> switch_fix.h
echo static inline char* tmpnam(char* n){ return 0; } >> switch_fix.h
echo #endif >> switch_fix.h

set "NINTENDO_SDK_ROOT_CMAKE=%NINTENDO_SDK_ROOT:\=/%"
cmake -DCMAKE_C_COMPILER="%NINTENDO_SDK_ROOT_CMAKE%/Compilers/NX/nx/aarch64/bin/clang.exe" ^
	-DCMAKE_CXX_COMPILER="%NINTENDO_SDK_ROOT_CMAKE%/Compilers/NX/nx/aarch64/bin/clang++.exe" ^
	-G "Unix Makefiles" -DCMAKE_SYSTEM_NAME=Switch ^
        -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON ^
        -DSWITCH_PLATFORM=1 ^
        -DNS_US_ELF=1 ^
	-DCMAKE_C_FLAGS="-includeswitch_fix.h -I%CUR_DIR%buildnx64" ^
	..
popd
cmake --build buildnx64 --config Release

如果你的 NS 环境配置好了,在环境变量中会有 NINTENDO_SDK_ROOT_CMAKE

然后就是修改一下 CMakeLists.txt 文件

if (SWITCH_PLATFORM) 
    set(NINTENDO_SDK_ROOT $ENV{NINTENDO_SDK_ROOT})
    set(NS_INCLUDE "${NINTENDO_SDK_ROOT}/Include")
    set(NS_SPECIFIC_INCLUDE "${NINTENDO_SDK_ROOT}/TargetSpecificInclude/NX-Win32-v142")
    set(NS_AARCH64 "${NINTENDO_SDK_ROOT}/Compilers/NX/nx/aarch64")

    set(NS_INCLUDE_LIST ${NS_INCLUDE})                                      # 定义搜索路径
    list(APPEND NS_INCLUDE_LIST ${NS_SPECIFIC_INCLUDE})                     # 添加特殊文件搜索路径
    list(APPEND NS_INCLUDE_LIST "${NS_AARCH64}/include")                    # 添加 AARCH64 头文件
    list(APPEND NS_INCLUDE_LIST "${NINTENDO_SDK_ROOT}/Include/nn/socket")   # 网络库相关
    
    set(NS_LIB_LIST "$${NS_AARCH64}/lib")                                   # 添加 AARCH64 静态库
   
    if(NS_US_ELF)
        list(APPEND NS_INCLUDE_LIST "${NS_AARCH64}/include/aarch64-nintendo-nx-elf")
        list(APPEND NS_LIB_LIST "${NS_AARCH64}/lib/aarch64-nintendo-nx-elf")
    else ()
        list(APPEND NS_INCLUDE_LIST "${NS_AARCH64}/include/aarch64-nintendo-nx-nncfi")
        list(APPEND NS_LIB_LIST "${NS_AARCH64}/lib/aarch64-nintendo-nx-nncfi")
    endif()
    
    add_compile_options(-fdeclspec)
    add_definitions(-DNN_SDK_BUILD_RELEASE)
    
    include_directories(${NS_INCLUDE_LIST})
    link_directories(${NS_LIB_LIST})
        
endif()

我也是临时学的 CMake,思路就是将 include 和 lib 添加到索引目录上,满足 quickjs 的源码需要

接下来我对 quickjs 的源码做了一些修改,不知道会不会出现问题,因为 quickjs 中需要使用 sys/time.h,但是 ns 环境中对网络的依赖关系有点麻烦,所以我直接做了如下修改

// #include <sys/time.h>

struct timeval
{
   long long      tv_sec;     // seconds
   long long tv_usec;    // microseconds
};

直接注释掉,然后将需要使用的结构体定义一份

v8其实也是类似,你看鸿蒙的编译,也是改改编译器的路径,编译参数什么的。