C module compatibility

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

C module compatibility

Antonin Décimo
Hello,

I'm working with a  library, lua-zip [1] that is a binding to libzip [2].
I would like to make sure that the library remains compatible with
Lua 5.1, 5.2, and 5.3, if possible.

lua-zip was written for Lua 5.1, and does not compile under Lua 5.2,
5.3 because the following functions are missing:
lua_equal, luaL_checkint, lua_objlen, luaL_register

I understand that I can use compatibility macros or replace lua_equal,
luaL_checkint, lua_objlen myself, so they are not the problem.

The problem is with luaL_register. With 5.3, it is an alias for
luaL_openlib, that is exported only if LUA_COMPAT_MODULE is defined
during compilation, which neither Debian nor Homebrew seem to do.

So, when I do `local zip = require "brimworks.zip"`, I get this
message:

/usr/local/share/lua/5.3/luarocks/loader.lua:153: error loading module
'brimworks.zip' from file
'/home/user/.luarocks/lib/lua/5.3/brimworks/zip.so':
    /home/user/.luarocks/lib/lua/5.3/brimworks/zip.so: undefined
symbol: luaL_checkint
stack traceback:
    [C]: in local 'a_loader'
    /usr/local/share/lua/5.3/luarocks/loader.lua:153: in function
</usr/local/share/lua/5.3/luarocks/loader.lua:150>
    (...tail calls...)
    [C]: in function 'require'
    stdin:1: in main chunk
    [C]: in ?

What would be a good, and clean way to fix this ? Should I copy/paste
the code from lauxlib? How can I disable this compatibility code if
I'm compiling for 5.2 or lower?

I hope I have everything right.

[1]: https://github.com/brimworks/lua-zip
[2]: https://libzip.org/

Thank you,

-- Antonin Décimo

Reply | Threaded
Open this post in threaded view
|

Re: C module compatibility

Andrew Gierth
>>>>> "Antonin" == Antonin Décimo <[hidden email]> writes:

 Antonin> The problem is with luaL_register. With 5.3, it is an alias
 Antonin> for luaL_openlib, that is exported only if LUA_COMPAT_MODULE
 Antonin> is defined during compilation, which neither Debian nor
 Antonin> Homebrew seem to do.

How about,

#if LUA_VERSION_NUM < 502
#define luaL_newlib(L_,f_) (lua_newtable(L_), luaL_register((L_),NULL,(f_)))
#endif

and use  luaL_newlib(L, fns);  where you currently have newtable/register

--
Andrew.

Reply | Threaded
Open this post in threaded view
|

Re: C module compatibility

Tomás Guisasola-2
Hi Antonin

Some years ago I wrote a small page on that subject, due to my efforts
with libraries such as LuaSQL, LuaExpat and others:

http://lua-users.org/wiki/CompatibilityWithLuaFive

I did not update it to Lua 5.3 but I think code targeted at Lua 5.2
will compile smoothly with Lua 5.3.  I hope it could be helpful.

Regards,
Tomás

Em dom, 7 de abr de 2019 às 15:41, Andrew Gierth
<[hidden email]> escreveu:

>
> >>>>> "Antonin" == Antonin Décimo <[hidden email]> writes:
>
>  Antonin> The problem is with luaL_register. With 5.3, it is an alias
>  Antonin> for luaL_openlib, that is exported only if LUA_COMPAT_MODULE
>  Antonin> is defined during compilation, which neither Debian nor
>  Antonin> Homebrew seem to do.
>
> How about,
>
> #if LUA_VERSION_NUM < 502
> #define luaL_newlib(L_,f_) (lua_newtable(L_), luaL_register((L_),NULL,(f_)))
> #endif
>
> and use  luaL_newlib(L, fns);  where you currently have newtable/register
>
> --
> Andrew.
>

Reply | Threaded
Open this post in threaded view
|

Re: C module compatibility

Antonin Décimo
Thank you all,

This is what I came up with:

https://github.com/brimworks/lua-zip/commit/4b37e9855e3b8d03ce92ec128aa41e6bbe87d6ce

All the checks may completely be an overkill, but I think it's the
best I can do. It seems to work without troubles on Debian with all
available versions of Lua, and on Homebrew too. (Also this code was
upstreamed and tagged as new version, so please^3 don't tell me
there's an obvious bug with this).


diff --git a/lua_zip.c b/lua_zip.c
index e9300b2..6570595 100644
--- a/lua_zip.c
+++ b/lua_zip.c
@@ -1,6 +1,3 @@
-#define LUA_COMPAT_ALL          /* Lua 5.2 -> Lua 5.1 */
-#define LUA_COMPAT_5_1          /* Lua 5.3 -> Lua 5.1 */
-
 #include <lauxlib.h>
 #include <lua.h>
 #include <zip.h>
@@ -8,6 +5,19 @@
 #include <errno.h>
 #include <string.h>

+#if LUA_VERSION_NUM > 502 && !defined(LUA_COMPAT_APIINTCASTS)
+#define luaL_checkint(L,n)      ((int)luaL_checkinteger(L, (n)))
+#endif
+
+#if LUA_VERSION_NUM > 501
+#if !defined(LUA_COMPAT_MODULE)
+#define luaL_register(L,_,funcs) luaL_setfuncs((L),funcs,0)
+#endif
+#if !defined(LUA_COMPAT_ALL) || !defined(LUA_COMPAT_5_1)
+#define lua_objlen(L,i)         lua_rawlen(L, (i))
+#define lua_equal(L,idx1,idx2)          lua_compare(L,(idx1),(idx2),LUA_OPEQ)
+#endif
+#endif

Thank you very much for the help!

-- Antonin

Reply | Threaded
Open this post in threaded view
|

Re: C module compatibility

Andrew Gierth
>>>>> "Antonin" == Antonin Décimo <[hidden email]> writes:

 Antonin> +#if LUA_VERSION_NUM > 502 && !defined(LUA_COMPAT_APIINTCASTS)
 Antonin> +#define luaL_checkint(L,n)      ((int)luaL_checkinteger(L, (n)))
 Antonin> +#endif
 Antonin> +
 Antonin> +#if LUA_VERSION_NUM > 501
 Antonin> +#if !defined(LUA_COMPAT_MODULE)
 Antonin> +#define luaL_register(L,_,funcs) luaL_setfuncs((L),funcs,0)
 Antonin> +#endif

This is emulating the old API on new systems. I would strongly
discourage this approach; instead, emulate the new API on old systems
instead.

--
Andrew.

Reply | Threaded
Open this post in threaded view
|

Re: C module compatibility

Luiz Henrique de Figueiredo
> This is emulating the old API on new systems. I would strongly
> discourage this approach; instead, emulate the new API on old systems

Indeed. That's exactly what I have done recently with my libraries.
It's just very few macros in my case. See mycompat.h in the tarballs.