Skip to content

Commit a8ffd4a

Browse files
authored
Merge pull request #44 from gilzoide/bugfix/require-luac
Fix requiring Lua/C modules in POSIX systems
2 parents e9c8ed8 + 78f3631 commit a8ffd4a

File tree

7 files changed

+156
-34
lines changed

7 files changed

+156
-34
lines changed

.github/workflows/test.yml

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,63 @@ env:
88
DEBUG: 1
99

1010
jobs:
11-
test:
12-
name: Run tests
11+
test_linux:
12+
name: Run tests on Linux
1313
runs-on: ubuntu-latest
1414
steps:
1515
- uses: actions/checkout@v3
1616
with:
1717
submodules: true
18-
- name: Install dependencies
19-
run: |
20-
sudo apt-get update
21-
sudo apt-get install libc6-dev-i386
2218
- name: Install Godot
23-
uses: vitorgus/setup-godot@v1
24-
with:
25-
godot-version: 3.4
26-
download-templates: false
19+
run: |
20+
curl --location $GODOT_RELEASE_URL --output godot.zip
21+
unzip godot.zip
22+
mv Godot_* godot
23+
touch _sc_
24+
env:
25+
GODOT_RELEASE_URL: https://github.com/godotengine/godot/releases/download/3.5.1-stable/Godot_v3.5.1-stable_linux_headless.64.zip
2726
- name: Build and test
2827
run: make test-linux64
28+
env:
29+
GODOT_BIN: ./godot
2930

31+
# Windows GitHub runner does not support creating an OpenGL context for running Godot =/
32+
# test_windows:
33+
# name: Run tests on Windows
34+
# runs-on: windows-latest
35+
# steps:
36+
# - uses: actions/checkout@v3
37+
# with:
38+
# submodules: true
39+
# - name: Install Godot
40+
# run: |
41+
# curl --location $GODOT_RELEASE_URL --output godot.zip
42+
# unzip godot.zip
43+
# mv Godot_*.exe godot.exe
44+
# touch _sc_
45+
# env:
46+
# GODOT_RELEASE_URL: https://github.com/godotengine/godot/releases/download/3.5.1-stable/Godot_v3.5.1-stable_win64.exe.zip
47+
# - name: Build and test
48+
# run: make test-windows64
49+
# env:
50+
# CC: gcc
51+
# GODOT_BIN: ./godot.exe
52+
53+
test_osx:
54+
name: Run tests on OSX
55+
runs-on: macos-latest
56+
steps:
57+
- uses: actions/checkout@v3
58+
with:
59+
submodules: true
60+
- name: Install Godot
61+
run: |
62+
curl --location $GODOT_RELEASE_URL --output godot.zip
63+
unzip godot.zip
64+
env:
65+
GODOT_RELEASE_URL: https://github.com/godotengine/godot/releases/download/3.5.1-stable/Godot_v3.5.1-stable_osx.universal.zip
66+
- name: Build and test
67+
run: make test-osx64
68+
env:
69+
GODOT_BIN: ./Godot.app/Contents/MacOS/Godot
70+

Makefile

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,9 @@ ifneq (,$(CODE_SIGN_IDENTITY))
132132
endif
133133

134134
define GEN_TEST
135-
test-$1: $1 $(LUASRCDIET_DEST) $(LUAJIT_JITLIB_DEST) $(DIST_DEST) build/project.godot
136-
@mkdir -p $(dir build/addons/godot-lua-pluginscript/$2)
137-
cp $2 build/addons/godot-lua-pluginscript/$2
135+
test-$1: $1 $(addprefix $2/, $3) $(LUASRCDIET_DEST) $(LUAJIT_JITLIB_DEST) $(DIST_DEST) build/project.godot
136+
@mkdir -p build/addons/godot-lua-pluginscript/$2
137+
cp $(addprefix $2/, $3) build/addons/godot-lua-pluginscript/$2
138138
$(GODOT_BIN) --path build --no-window --quit --script "$(CURDIR)/src/test/init.lua"
139139
endef
140140

@@ -177,7 +177,6 @@ build/%/liblua_pluginscript.so: $(BUILT_OBJS) build/%/luajit/src/libluajit.a
177177
$(call STRIP_CMD,$@)
178178

179179
build/%/lua_pluginscript.dll: TARGET_SYS = Windows
180-
build/%/lua_pluginscript.dll: EXE = .exe
181180
build/%/lua_pluginscript.dll: $(BUILT_OBJS) build/%/lua51.dll
182181
$(_CC) -o $@ $^ -shared $(CFLAGS) $(LDFLAGS)
183182
$(call STRIP_CMD,$@)
@@ -217,6 +216,15 @@ build/compile_commands.json: Makefile
217216
echo '[{"directory":"$(CURDIR)","file":"src/language_gdnative.c","command":"$(subst ",\",$(COMPILE_COMMAND))"}]' > $@
218217

219218

219+
build/%/test_cmodule.so: src/test/test_cmodule.c
220+
$(_CC) -o $@ $^ -shared $(CFLAGS) $(LDFLAGS)
221+
build/%/test_cmodule.dll: src/test/test_cmodule.c build/%/lua51.dll
222+
$(_CC) -o $@ $^ -shared $(CFLAGS) $(LDFLAGS)
223+
build/%/test_cmodule.dylib: LDFLAGS += -Wl,-undefined,dynamic_lookup
224+
build/%/test_cmodule.dylib: src/test/test_cmodule.c
225+
$(_CC) -o $@ $^ -shared $(CFLAGS) $(LDFLAGS)
226+
227+
220228
# Phony targets
221229
.PHONY: clean dist docs set-version unzip-to-build update-copyright-year
222230
clean:
@@ -261,26 +269,28 @@ compdb: compilation-database
261269
linux32: MAKE_LUAJIT_ARGS += CC="$(CC) -m32 -fPIC"
262270
linux32: CFLAGS += -m32 -fPIC
263271
linux32: build/linux_x86/liblua_pluginscript.so
264-
$(eval $(call GEN_TEST,linux32,build/linux_x86/liblua_pluginscript.so))
272+
$(eval $(call GEN_TEST,linux32,build/linux_x86,liblua_pluginscript.so test_cmodule.so))
265273

266274
linux64: MAKE_LUAJIT_ARGS += CC="$(CC) -fPIC"
267275
linux64: CFLAGS += -fPIC
268276
linux64: build/linux_x86_64/liblua_pluginscript.so
269-
$(eval $(call GEN_TEST,linux64,build/linux_x86_64/liblua_pluginscript.so))
277+
$(eval $(call GEN_TEST,linux64,build/linux_x86_64,liblua_pluginscript.so test_cmodule.so))
270278

271279
windows32: build/windows_x86/lua_pluginscript.dll
272-
$(eval $(call GEN_TEST,windows32,build/windows_x86/lua_pluginscript.dll))
280+
$(eval $(call GEN_TEST,windows32,build/windows_x86,lua_pluginscript.dll lua51.dll test_cmodule.dll))
273281
mingw-windows32: CROSS = i686-w64-mingw32-
274282
mingw-windows32: MAKE_LUAJIT_ARGS += HOST_CC="$(CC) -m32" CROSS="$(CROSS)" LDFLAGS=-static-libgcc
275283
mingw-windows32: windows32
276-
$(eval $(call GEN_TEST,mingw-windows32,build/windows_x86/lua_pluginscript.dll))
284+
test-mingw-windows32: CROSS = i686-w64-mingw32-
285+
$(eval $(call GEN_TEST,mingw-windows32,build/windows_x86,lua_pluginscript.dll lua51.dll test_cmodule.dll))
277286

278287
windows64: build/windows_x86_64/lua_pluginscript.dll
279-
$(eval $(call GEN_TEST,windows64,build/windows_x86_64/lua_pluginscript.dll))
288+
$(eval $(call GEN_TEST,windows64,build/windows_x86_64,lua_pluginscript.dll lua51.dll test_cmodule.dll))
280289
mingw-windows64: CROSS = x86_64-w64-mingw32-
281290
mingw-windows64: MAKE_LUAJIT_ARGS += HOST_CC="$(CC)" CROSS="$(CROSS)" LDFLAGS=-static-libgcc
282291
mingw-windows64: windows64
283-
$(eval $(call GEN_TEST,mingw-windows64,build/windows_x86_64/lua_pluginscript.dll))
292+
test-mingw-windows64: CROSS = x86_64-w64-mingw32-
293+
$(eval $(call GEN_TEST,mingw-windows64,build/windows_x86_64,lua_pluginscript.dll lua51.dll test_cmodule.dll))
284294

285295
osx-x86_64: MACOSX_DEPLOYMENT_TARGET ?= 10.7
286296
osx-x86_64: _ADD_CFLAGS = -isysroot '$(shell xcrun --sdk macosx --show-sdk-path)' -arch x86_64
@@ -295,7 +305,7 @@ osx-arm64: MAKE_LUAJIT_ARGS += TARGET_FLAGS="$(_ADD_CFLAGS)" MACOSX_DEPLOYMENT_T
295305
osx-arm64: build/osx_arm64/lua_pluginscript.dylib
296306

297307
osx64: osx-x86_64 osx-arm64 build/osx_arm64_x86_64/lua_pluginscript.dylib
298-
$(eval $(call GEN_TEST,osx64,build/osx_arm64_x86_64/lua_pluginscript.dylib))
308+
$(eval $(call GEN_TEST,osx64,build/osx_arm64_x86_64,lua_pluginscript.dylib test_cmodule.dylib))
299309

300310
# Note: newer OSX systems can't run i386 apps, so LuaJIT can't build properly with the current Makefile
301311
#ios-armv7s: _ADD_CFLAGS = -isysroot "$(shell xcrun --sdk iphoneos --show-sdk-path)" -arch armv7s -miphoneos-version-min=$(IOS_VERSION_MIN)

src/lua_package_extras.lua

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,3 +193,23 @@ package.path = lua_path:join(';')
193193
--
194194
-- @see searchpath
195195
package.cpath = lua_cpath:join(';')
196+
197+
--- `dlopen`s the PluginScript library with `RTLD_LAZY | RTLD_GLOBAL`.
198+
-- This is necessary for loading Lua/C modules in POSIX systems.
199+
local function dlopen_self()
200+
ffi_cdef[[
201+
void *dlopen(const char *filename, int flags);
202+
int dlclose(void *handle);
203+
]]
204+
205+
local RTLD_LAZY = 0x00001
206+
local RTLD_GLOBAL = 0x00100
207+
local currentLibraryPath = tostring(gdnativelibrary:get_current_library_path():replace("res://", execdir_repl .. '/'))
208+
-- Maintain a reference to dlopened library while PluginScript is loaded
209+
-- When the Lua state closes, GC will kick in and the library will get dlclosed
210+
pluginscript_callbacks.__dlopened_self = ffi_gc(ffi.C.dlopen(currentLibraryPath, RTLD_LAZY + RTLD_GLOBAL), ffi.C.dlclose)
211+
end
212+
213+
if Array("Android", "iOS", "OSX", "Server", "X11"):has(OS:get_name()) then
214+
xpcall(dlopen_self, GD.print_error)
215+
end

src/test/init.lua

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,27 +24,55 @@ local TestRunner = {
2424
extends = 'SceneTree',
2525
}
2626

27-
function TestRunner:_init()
28-
local current_script_path = self:get_script().resource_path
29-
local current_script_filename = current_script_path:get_file()
30-
local current_script_base_dir = current_script_path:get_base_dir()
27+
local function error_handler(msg)
28+
if os.getenv('DEBUG_INTERACTIVE') then
29+
local have_dbg, dbg = pcall(require, 'debugger')
30+
if have_dbg then
31+
return dbg()
32+
end
33+
end
34+
GD.print_error(msg)
35+
end
3136

37+
function TestRunner:setup_luapath(current_script_base_dir)
3238
local additional_paths = { '../../lib/luaunit', '../../lib/debugger_lua' }
3339
for _, path in ipairs(additional_paths) do
3440
local additional_path = current_script_base_dir:plus_file(path)
35-
package.path = string.format('%s/?.lua;%s/?/init.lua;', additional_path, additional_path) .. package.path
41+
package.path = string.format('%s/?.lua;%s/?/init.lua;%s', additional_path, additional_path, package.path)
3642
end
43+
end
3744

38-
local function error_handler(msg)
39-
if os.getenv('DEBUG_INTERACTIVE') then
40-
local have_dbg, dbg = pcall(require, 'debugger')
41-
if have_dbg then
42-
return dbg()
43-
end
44-
end
45-
GD.print_error(msg)
45+
function TestRunner:setup_cpath()
46+
local additional_paths
47+
if OS:get_name() == 'Windows' then
48+
additional_paths = {
49+
'!/addons/godot-lua-pluginscript/build/windows_x86/?.dll',
50+
'!/addons/godot-lua-pluginscript/build/windows_x86_64/?.dll',
51+
}
52+
elseif OS:get_name() == 'OSX' then
53+
additional_paths = {
54+
'!/addons/godot-lua-pluginscript/build/osx_arm64_x86_64/?.dylib',
55+
}
56+
else
57+
additional_paths = {
58+
'!/addons/godot-lua-pluginscript/build/linux_x86/?.so',
59+
'!/addons/godot-lua-pluginscript/build/linux_x86_64/?.so',
60+
}
4661
end
4762

63+
for _, path in ipairs(additional_paths) do
64+
package.cpath = string.format('%s;%s', path, package.cpath)
65+
end
66+
end
67+
68+
function TestRunner:_init()
69+
local current_script_path = self:get_script().resource_path
70+
local current_script_filename = current_script_path:get_file()
71+
local current_script_base_dir = current_script_path:get_base_dir()
72+
73+
self:setup_luapath(current_script_base_dir)
74+
self:setup_cpath()
75+
4876
local dir, all_passed = Directory:new(), true
4977
assert(dir:open(current_script_base_dir) == GD.OK)
5078
dir:list_dir_begin(true)

src/test/require_luac.lua

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
local lu = require "luaunit"
2+
3+
local Test = {}
4+
5+
function Test:test_require_luac_module()
6+
lu.assert_true(pcall(require, 'test_cmodule'))
7+
end
8+
9+
return Test

src/test/test_cmodule.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#include "lua.h"
2+
3+
int luaopen_test_cmodule(lua_State *L) {
4+
lua_pushboolean(L, 1);
5+
return 1;
6+
}

src/tools/project.godot

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,11 @@ config/name="godot-lua-pluginscript-unittest"
1010

1111
singletons=[ "res://addons/godot-lua-pluginscript/lua_pluginscript.gdnlib" ]
1212

13+
[logging]
14+
15+
file_logging/enable_file_logging.pc=false
16+
file_logging/log_path="testlogdir"
17+
18+
[rendering]
19+
20+
quality/driver/driver_name="GLES2"

0 commit comments

Comments
 (0)