lgi-devs / lgi

Dynamic Lua binding to GObject libraries using GObject-Introspection
MIT License
440 stars 70 forks source link

Use $LUA_LIB in makefile on linux #312

Closed unai-ndz closed 1 year ago

unai-ndz commented 1 year ago

Is there any reason why LUA_LIB is not being used?

In my system lua does not get linked unless LUA_LIB is set causing corelgilua51.so to be totally broken. Is the lua library supposed to get picked up at runtime? Otherwise how does it work for everyone else?

It may be because I have several lua versions, from 5.1 to 5.4 including luajit, all dependencies of something.

Besides fixing whatever is broken with multi-lua installations or in my system, this allows to specify the lua library you wan't like this: make LUA_LIB="-lluajit-5.1"

psychon commented 1 year ago

Is there any reason why LUA_LIB is not being used?

I don't know. I did not write this Makefile.

According to grep, $LUA_LIB is used in tests/Makefile to link the test binaries. Thus, when running the tests, the correct Lua library is already loaded and can directly be used from LGI.

CI just found another reason. Apparently your PR breaks the use of a statically compiled Lua (built without -fPIC so with position-dependent code, which is not allowed in a shared library).

In my system lua does not get linked unless LUA_LIB is set causing corelgilua51.so to be totally broken.

In what sense is it totally broken? Shared objects with undefined references supposedly work fine. At run time, there is already a Lua shared library in memory (the one that is loading lgi). Thus, at that time, all the undefined references should be resolved against the Lua library that is already present.

Besides fixing whatever is broken with multi-lua installations or in my system, this allows to specify the lua library you wan't like this: make LUA_LIB="-lluajit-5.1"

How does that pick the right header files? The Lua headers between versions are different. If you build code against Lua 5.2 and link it against Lua 5.3, the result should be unresolved references because things are trying to use C functions that are not present. So, right now you can specify the Lua version you want by specifying the right paths to headers and then using the resulting library from the right Lua version.

unai-ndz commented 1 year ago

In what sense is it totally broken?

Undefined references as if being linked to the wrong lua version

At run time, there is already a Lua shared library in memory (the one that is loading lgi). Thus, at that time, all the undefined references should be resolved against the Lua library that is already present.

Does this mean that a program compiled against lua5.1 will use the lua5.4 library if it's already loaded by another program unless specifically linking it against the correct version?

How does that pick the right header files?

The full command I'm using is: make LUA_LIB="-lluajit-5.1" LUA_INCDIR=/usr/include/luajit-2.1/ LUA_CFLAGS="$(pkg-config --cflags luajit) -O2"

psychon commented 1 year ago

Does this mean that a program compiled against lua5.1 will use the lua5.4 library if it's already loaded by another program unless specifically linking it against the correct version?

Nope, that means that you would get the behaviour you are already seeing:

Undefined references as if being linked to the wrong lua version

Simplified example (the actual #defines are less stupid than my version here):

Let's assume that Lua were doing the following in their headers:

#define lua_pushboolean(L, b) lua_pushboolean_I_am_on_lua_5_1(L, b)

Thus, when you call lua_pushboolean in C code, you are really calling the function lua_pushboolean_I_am_on_lua_5_1. At least when compiling against this version of Lua.

When you then try to dynamically link the resulting library with a different Lua version, the symbol lua_pushboolean_I_am_on_lua_5_1 would not be defined and loading fails.

If LGI were instead linked against Lua 5.1, the error in the above situation becomes worse. Now, Lua 5.1 would be loaded additionally and you would end up with two different versions of Lua in the running program. Lua is not designed to be used this way (e.g. some functions have the same name in different versions and then lgi could end up calling a function from a completely different Lua version than it was built against. The result would likely be a crash.)

The full command I'm using is: make LUA_LIB="-lluajit-5.1" LUA_INCDIR=/usr/include/luajit-2.1/ LUA_CFLAGS="$(pkg-config --cflags luajit) -O2"

I guess that looks fine to me... Well, according to git grep LUA_INCDIR, that flag does not exist. So that might be part of the problem.

I gave things a quick try on my system (Debian Testing) and the following more or less works for me (tests fail, but at least some tests succeed):

make LUA_LIB="$(pkg-config --libs luajit)" LUA_CFLAGS="$(pkg-config --cflags luajit)" LUA=luajit all check

Edit: Tests succeed with the following diff. That makes no sense. I'll ignore this...

diff --git a/tests/test.lua b/tests/test.lua
index 6361cf8..d41582d 100644
--- a/tests/test.lua
+++ b/tests/test.lua
@@ -66,6 +66,7 @@ function testsuite.group:run(id)
    id = id or ''
    self.results.total = 0
    self.results.failed = 0
+   print(self.name)
    if type(id) == 'number' then
       runfunc(id)
    else
unai-ndz commented 1 year ago

Thanks for letting me pick your brain.

For now I have things working, although requiring this patch. If I find the time I'll try to reproduce this issue in a fresh system and find a solution that doesn't break things.

Well, according to git grep LUA_INCDIR, that flag does not exist. So that might be part of the problem.

Woops I guess in the arch linux AUR we are just copying each other's useless make arguments. Recompiled without the flag and as expected nothing changed.