From ab968d3705852af286a1d8de578485d892db3cb6 Mon Sep 17 00:00:00 2001 From: Trey Moller Date: Sat, 3 Jun 2023 17:49:08 -0500 Subject: [PATCH] Add luajit support for gdextension (#115) --- .github/workflows/gdextension-luajit.yml | 155 +++++++++++++++++++++++ README.md | 1 + SConstruct | 5 + external/SConscript | 123 ++++++++++++++++-- external/SCsub | 12 +- src/luaState.cpp | 2 +- 6 files changed, 282 insertions(+), 16 deletions(-) create mode 100644 .github/workflows/gdextension-luajit.yml diff --git a/.github/workflows/gdextension-luajit.yml b/.github/workflows/gdextension-luajit.yml new file mode 100644 index 00000000..493ce40f --- /dev/null +++ b/.github/workflows/gdextension-luajit.yml @@ -0,0 +1,155 @@ +name: GDExtension-LuaJIT +on: + pull_request: + branches: + - "*" + paths-ignore: + - "**/README.md" + - ".github/ISSUE_TEMPLATE/*" + push: + branches: + - "main" + paths-ignore: + - "**/README.md" + - ".github/ISSUE_TEMPLATE/*" +env: + BASE_BRANCH: main + +jobs: + build: + runs-on: ${{ matrix.runner }} + name: ${{ matrix.name }} + strategy: + fail-fast: false + matrix: + include: + - identifier: linux-debug (x86_64, luaJIT) + name: Linux (x86_64, luaJIT) - template_debug + runner: ubuntu-20.04 + target: template_debug + platform: linux + arch: x86_64 + - identifier: linux-release (x86_64, luaJIT) + name: Linux (x86_64, luaJIT) - template_release + runner: ubuntu-20.04 + target: template_release + platform: linux + arch: x86_64 + - identifier: linux-debug (x86_32, luaJIT) + name: Linux (x86_32, luaJIT) - template_debug + runner: ubuntu-20.04 + target: template_debug + platform: linux + arch: x86_32 + - identifier: linux-release (x86_32, luaJIT) + name: Linux (x86_32, luaJIT) - template_release + runner: ubuntu-20.04 + target: template_release + platform: linux + arch: x86_32 + + - identifier: windows-debug (x86_64, luaJIT) + name: Windows (x86_64, luaJIT) - template_debug + runner: ubuntu-20.04 + target: template_debug + platform: windows + arch: x86_64 + - identifier: windows-release (x86_64, luaJIT) + name: Windows (x86_64, luaJIT) - template_release + runner: ubuntu-20.04 + target: template_release + platform: windows + arch: x86_64 + - identifier: windows-debug (x86_32, luaJIT) + name: Windows (x86_32, luaJIT) - template_debug + runner: ubuntu-20.04 + target: template_debug + platform: windows + arch: x86_32 + - identifier: windows-release (x86_32, luaJIT) + name: Windows (x86_32, luaJIT) - template_release + runner: ubuntu-20.04 + target: template_release + platform: windows + arch: x86_32 + + - identifier: macos-release (universal, luaJIT) + name: MacOS (universal, luaJIT) - template_release + runner: macos-latest + target: template_release + platform: macos + arch: universal + - identifier: macos-debug (universal, luaJIT) + name: MacOS (universal, luaJIT) - template_debug + runner: macos-latest + target: template_debug + platform: macos + arch: universal + + steps: + - name: Checkout project + uses: actions/checkout@v3 + with: + submodules: recursive + - name: Install gcc-multilib + if: ${{ startsWith(matrix.arch, 'x86_32') }} + shell: sh + run: | + sudo apt install gcc-multilib g++-multilib + - name: (Windows) Install mingw64 + if: ${{ startsWith(matrix.identifier, 'windows-') }} + shell: sh + run: | + sudo apt-get install mingw-w64 + sudo update-alternatives --set x86_64-w64-mingw32-gcc /usr/bin/x86_64-w64-mingw32-gcc-posix + sudo update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix + + - name: Set up Python + uses: actions/setup-python@v2 + + - name: Set up Python + uses: actions/setup-python@v2 + + - name: Set up SCons + shell: bash + run: | + python -c "import sys; print(sys.version)" + python -m pip install scons + scons --version + - name: Load .scons_cache directory + id: godot-extension-cache + uses: actions/cache@v2 + with: + path: ${{github.workspace}}/.scons_cache/ + key: ${{github.job}}-${{env.BASE_BRANCH}}-${{github.ref}}-${{github.sha}} + restore-keys: | + ${{github.job}}-${{env.BASE_BRANCH}}-${{github.ref}}-${{github.sha}} + ${{github.job}}-${{env.BASE_BRANCH}}-${{github.ref}} + ${{github.job}}-${{env.BASE_BRANCH}}-${{env.BASE_BRANCH}} + - name: Compile extension + shell: sh + run: | + scons target='${{ matrix.target }}' platform='${{ matrix.platform }}' arch='${{ matrix.arch }}' luaappi_luaver=jit -j2 + ls -l project/addons/luaAPI/bin/ + - name: Strip bins + if: "!startsWith(matrix.identifier, 'windows-') && startsWith(matrix.arch, 'x86_')" + shell: sh + run: | + strip project/addons/luaAPI/bin/* + - name: Prepare artifact + shell: sh + env: + SCONS_CACHE: ${{github.workspace}}/.scons_cache/ + SCONS_CACHE_LIMIT: 7168 + run: | + rm -rf ${{ github.workspace }}/project/.g* ${{ github.workspace }}/project/project.godot ${{ github.workspace }}/project/testing ${{ github.workspace }}/project/addons/luaAPI/bin/.gitignore + cp -n '${{ github.workspace }}/README.md' '${{ github.workspace }}/LICENSE' ${{ github.workspace }}/project/addons/luaAPI + mkdir ${{ github.workspace }}/project/container + mv ${{ github.workspace }}/project/addons/ ${{ github.workspace }}/project/container/addons/ + mv ${{ github.workspace }}/project/demo/ ${{ github.workspace }}/project/container/demo/ + - name: Upload artifact + uses: actions/upload-artifact@v2 + with: + name: ${{ github.event.repository.name }}-luaJIT + path: | + ${{ github.workspace }}/project/ \ No newline at end of file diff --git a/README.md b/README.md index 699159a2..7f68413a 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,7 @@ If a feature is missing that you would like to see feel free to create a [Featur Nightly Builds --------------- - [⚙️ GDExtension](https://nightly.link/WeaselGames/godot_luaAPI/workflows/gdextension/main/godot_luaAPI.zip) +- [⚙️ GDExtension LuaJIT](https://nightly.link/WeaselGames/godot_luaAPI/workflows/gdextension-luajit/main/godot_luaAPI-luaJIT.zip) - [🐧 Linux Editor](https://nightly.link/WeaselGames/godot_luaAPI/workflows/linux/main/linux-editor.zip) - [🐧 Linux Editor LuaJIT](https://nightly.link/WeaselGames/godot_luaAPI/workflows/linux/main/linux-editor-luajit.zip) - [🐧 Linux Template](https://nightly.link/WeaselGames/godot_luaAPI/workflows/linux/main/linux-template.zip) diff --git a/SConstruct b/SConstruct index 2b1c1a78..2d4997fe 100644 --- a/SConstruct +++ b/SConstruct @@ -12,6 +12,11 @@ sources = Glob('*.cpp') sources.append(Glob('src/*.cpp')) sources.append(Glob('src/classes/*.cpp')) +if env["luaapi_luaver"] == 'jit': + env.Append(CPPDEFINES=['LAPI_LUAJIT', 'LAPI_51']) +elif env["luaapi_luaver"] == '5.1': + env.Append(CPPDEFINES=['LAPI_51']) + library = env.SharedLibrary( "project/addons/luaAPI/bin/libluaapi{}{}".format(env["suffix"], env["SHLIBSUFFIX"]), source=sources, diff --git a/external/SConscript b/external/SConscript index 66a7add6..f153df72 100644 --- a/external/SConscript +++ b/external/SConscript @@ -1,27 +1,122 @@ # Used for extension builds -import os import sys +import os +import platform + +def configure(env): + from SCons.Script import BoolVariable, EnumVariable, Variables, Help + + env_vars = Variables() + + env_vars.Add(BoolVariable("luaapi_luajit_build", + "When LuaAPI is using luaJIT, be defualt it will attempt to build it automatically. if you prefer you can build it manually and disable auto building with this flag. Make sure to build staticly and that the libs are in external/luaJIT/src", + True)) + + env_vars.Add(EnumVariable("luaapi_host_cc", + "LuaJIT builds some tools to assit with the rest of the build. You can set the host CC to be used here in the case of cross compilation.", "gcc", ("gcc", "clang"))) + + env_vars.Add(EnumVariable("luaapi_luaver", + "Build the LuaAPI module with the following lua VM", "5.4", ("5.4", "5.1", "jit"))) + + env_vars.Update(env) + Help(env_vars.GenerateHelpText(env)) + +def run(cmd): + print("Running: %s" % cmd) + res = os.system(cmd) + code = 0 + if (os.name == 'nt'): + code = res + else: + code = os.WEXITSTATUS(res) + if code != 0: + print("Error: return code: " + str(code)) + sys.exit(code) + +def build_luajit(): + os.chdir("luaJIT") + # cross compile linux->windows + if env['platform'] == 'windows': + host_arch = platform.machine() + run("make clean") + if (host_arch != env['arch']): + if (host_arch == 'x86_64' and env['arch'] == 'x86_32'): + host_cc = env['luaapi_host_cc'] + ' -m32' + run('make HOST_CC="%s" CROSS="%s" BUILDMODE="static" TARGET_SYS=Windows TARGET_CFLAGS="-fPIC"' % (host_cc, env['CC'].replace("-gcc", "-").replace("-clang", "-"))) + + else: + print("ERROR: Unsupported cross compile!") + sys.exit(-1) + else: + run('make HOST_CC="%s" CROSS="%s" BUILDMODE="static" TARGET_SYS=Windows TARGET_CFLAGS="-fPIC"' % (env['luaapi_host_cc'], env['CC'].replace("-gcc", "-").replace("-clang", "-"))) + + elif env['platform']=='macos': + run("make clean MACOSX_DEPLOYMENT_TARGET=10.12") + run('make CC="%s" TARGET_FLAGS="-arch %s" MACOSX_DEPLOYMENT_TARGET=10.12' % (env['CC'], env['arch'])) + + elif env['platform']=='linux': + host_arch = platform.machine() + run("make clean") + if (host_arch != env['arch']): + if (host_arch == 'x86_64' and env['arch'] == 'x86_32'): + host_cc = env['luaapi_host_cc'] + ' -m32' + run('make HOST_CC="%s" CROSS="%s" BUILDMODE="static" TARGET_CFLAGS="-fPIC"' % (host_cc, env['CC'].replace("-gcc", "-").replace("-clang", "-"))) + + else: + print("ERROR: Unsupported cross compile!") + sys.exit(-1) + + else: + run('make CC="%s" BUILDMODE="static" TARGET_CFLAGS="-fPIC"' % env['CC']) + + else: + print("ERROR: Unsupported platform '%s'." % env['platform']) + sys.exit(-1) env = SConscript("godot-cpp/SConstruct") +configure(env) env_lua = env.Clone() -if env_lua["platform"] == 'linux': - env_lua.Append(CPPDEFINES=['LUA_USE_POSIX']) -elif env_lua["platform"] == "ios": - env_lua.Append(CPPDEFINES=['LUA_USE_IOS']) +luaver = env["luaapi_luaver"] + +if luaver == "jit": + if env["luaapi_luajit_build"]: + build_luajit() + + env.Append(LIBPATH=[Dir("luaJIT/src").abspath]) + env.Append(LIBS=['libluajit']) + +elif luaver == "5.1": + env_lua.Append(CPPDEFINES='MAKE_LIB') + + if env['PLATFORM'] == 'posix' and env['platform'] == 'linux': + env_lua.Append(CPPDEFINES='LUA_USE_POSIX') + elif env['platform'] == 'ios': + env_lua.Append(CPPDEFINES=['LUA_USE_IOS']) + + sources = ['lua/onelua.c'] + library_name = "liblua{}{}".format(env['suffix'], env["LIBSUFFIX"]) + library = env_lua.StaticLibrary("bin/{}".format(library_name), source=sources) + Default(library) + + env.Append(LIBPATH=[Dir("bin").abspath]) + env.Append(LIBS=[library_name]) +else: + env_lua.Append(CPPDEFINES='MAKE_LIB') -env_lua.Append(CPPDEFINES = ['MAKE_LIB']) -env_lua.Append(CXXFLAGS = ['-std=c++17']) -env_lua.Append(CFLAGS = ['-std=c99']) + if env['PLATFORM'] == 'posix' and env['platform'] == 'linux': + env_lua.Append(CPPDEFINES='LUA_USE_POSIX') + elif env['platform'] == 'ios': + env_lua.Append(CPPDEFINES=['LUA_USE_IOS']) -sources = ['lua/onelua.c'] -library_name = "liblua{}{}".format(env['suffix'], env["LIBSUFFIX"]) -library = env_lua.StaticLibrary("bin/{}".format(library_name), source=sources) -Default(library) + sources = ['lua/onelua.c'] + library_name = "liblua{}{}".format(env['suffix'], env["LIBSUFFIX"]) + library = env_lua.StaticLibrary("bin/{}".format(library_name), source=sources) + Default(library) -env.Append(LIBPATH=[Dir("bin").abspath]) -env.Append(LIBS=[library_name]) + env.Append(LIBPATH=[Dir("bin").abspath]) + env.Append(LIBS=[library_name]) Return('env') \ No newline at end of file diff --git a/external/SCsub b/external/SCsub index bcf9a403..b33fe2f9 100644 --- a/external/SCsub +++ b/external/SCsub @@ -23,8 +23,18 @@ def build_luajit(): os.chdir("luaJIT") # cross compile linux->windows if env['PLATFORM'] == 'posix' and env['platform'] == 'windows': + host_arch = platform.machine() run("make clean") - run('make HOST_CC="%s" CROSS="%s" BUILDMODE="static" TARGET_SYS=Windows' % (env['luaapi_host_cc'], env['CC'].replace("-gcc", "-").replace("-clang", "-"))) + if (host_arch != env['arch']): + if (host_arch == 'x86_64' and env['arch'] == 'x86_32'): + host_cc = env['luaapi_host_cc'] + ' -m32' + run('make HOST_CC="%s" CROSS="%s" BUILDMODE="static" TARGET_SYS=Windows' % (host_cc, env['CC'].replace("-gcc", "-").replace("-clang", "-"))) + + else: + print("ERROR: Unsupported cross compile!") + sys.exit(-1) + else: + run('make HOST_CC="%s" CROSS="%s" BUILDMODE="static" TARGET_SYS=Windows' % (env['luaapi_host_cc'], env['CC'].replace("-gcc", "-").replace("-clang", "-"))) elif env['platform']=='macos': run("make clean MACOSX_DEPLOYMENT_TARGET=10.12") diff --git a/src/luaState.cpp b/src/luaState.cpp index 6a4e2c4a..f40cb366 100644 --- a/src/luaState.cpp +++ b/src/luaState.cpp @@ -100,7 +100,7 @@ void LuaState::bindLibraries(Array libs) { void LuaState::bindLibraries(Array libs) { for (int i = 0; i < libs.size(); i++) { - String lib = ((String)libs.get(i)).to_lower(); + String lib = ((String)libs[i]).to_lower(); if (lib=="base") { lua_pushcfunction(L, luaopen_base); lua_pushstring(L, "");