[MacPorts] #70420: neovim @0.10.0_1: error loading module 'nlua0' from file 'libnlua0.so'
MacPorts
noreply at macports.org
Thu Aug 8 00:10:24 UTC 2024
#70420: neovim @0.10.0_1: error loading module 'nlua0' from file 'libnlua0.so'
---------------------+----------------------
Reporter: wryfi | Owner: l2dy
Type: defect | Status: assigned
Priority: Normal | Milestone:
Component: ports | Version: 2.9.3
Resolution: | Keywords:
Port: neovim |
---------------------+----------------------
Comment (by wryfi):
Ok, I think I've got this figured out. There are a lot of things that are
suboptimal about how macports is managing lua. This may not be the right
place for detailing all of that, but I will do so anyway, and have faith
that someone on the macports team will land them in the right place.
Starting with this bug report and #66077 ...
`luajit` is used for much of the build process, and the neovim Portfile
contains `configure.args-append -DLUA_PRG=${prefix}/bin/luajit`. `luajit`
is its own thing and adheres only to the lua-5.1 language spec. `luajit`
works regardless of the state of other lua packages on my system. All good
so far.
But neovim also uses some C, and builds a library, `nlua0`, from
`src/nlua0.c` in the neovim source tree. The first line of this file is
`#include <lua.h>`.
When the `lua` port is installed, it creates `/opt/local/include/lua.h`,
which contains C headers for lua 5.3. Because this is the first `lua.h`
file the compiler finds in the include directory, the C compiler uses this
header and then builds `nlua0` against lua 5.3.
This breaks the neovim build as described in this ticket and in #66077
because `nlua0` pulls in symbols from lua 5.3 that `luajit` can't grok
(because `luajit` is strictly 5.1).
The fix for this is to get the compiler to look in
`/opt/local/include/lua5.1` and use the `lua.h` header from the `lua51`
port. ''See'' [https://github.com/macports/macports-ports/pull/25223
GitHub PR].
{{{
diff --git a/editors/neovim/Portfile b/editors/neovim/Portfile
index 6c79bb4bd3e..1d0825f863e 100644
--- a/editors/neovim/Portfile
+++ b/editors/neovim/Portfile
@@ -48,7 +48,7 @@ cmake.build_type Release
configure.args-append -DLUA_PRG=${prefix}/bin/luajit
# Building parsers is normally an extra step, see
https://github.com/neovim/neovim/issues/29042
-patchfiles embed-parsers-build.diff
+patchfiles embed-parsers-build.diff patch-
nlua0-includes.diff
subport neovim-devel {
github.setup neovim neovim
0c2860d9e5ec5417a94db6e3edd237578b76d418
diff --git a/editors/neovim/files/patch-nlua0-includes.diff
b/editors/neovim/files/patch-nlua0-includes.diff
new file mode 100644
index 00000000000..4e6f7c8faef
--- /dev/null
+++ b/editors/neovim/files/patch-nlua0-includes.diff
@@ -0,0 +1,12 @@
+diff --git src/nvim/CMakeLists.txt src/nvim/CMakeLists.txt
+index a100e733d..9c601819b 100644
+--- src/nvim/CMakeLists.txt
++++ src/nvim/CMakeLists.txt
+@@ -66,6 +66,7 @@ else()
+ target_include_directories(main_lib SYSTEM BEFORE INTERFACE
${LUAJIT_INCLUDE_DIR})
+ target_link_libraries(main_lib INTERFACE ${LUAJIT_LIBRARY})
+ target_include_directories(nlua0 SYSTEM BEFORE PUBLIC
${LUAJIT_INCLUDE_DIR})
++ target_include_directories(nlua0 AFTER PUBLIC
/opt/local/include/lua5.1)
+ if(WIN32)
+ target_link_libraries(nlua0 PUBLIC ${LUAJIT_LIBRARY})
+ endif()
}}}
(Note that I'm not a CMake expert, and I'm not certain that
`target_include_directories(nlua0 AFTER PUBLIC /opt/local/include/lua5.1)`
is strictly correct; but it does the job.)
----
Now on to some of my other discoveries while investigating this issue ...
I don't think the build/install issues with `luarocks` are as simple as
the commit referenced above suggests. There seem to be a few broken layers
to unpack here (though to be clear this is unrelated to the neovim build).
At the top of the
[https://github.com/luarocks/luarocks/blob/master/src/luarocks/core/cfg.lua
config file] referenced in that git commit:
{{{
-- Run `luarocks` with no arguments to see the locations of
-- these files in your platform.
}}}
When I run `luarocks` on my system, it provides some interesting info at
the end:
{{{
Configuration:
Lua:
Version : 5.3
Interpreter: /opt/local/bin/lua5.3 (ok)
LUA_DIR : /opt/local/libexec/lua53 (ok)
LUA_BINDIR : /opt/local/bin (ok)
LUA_INCDIR : /opt/local/libexec/lua53/include (ok)
LUA_LIBDIR : /opt/local/libexec/lua53/lib (ok)
Configuration files:
System : /opt/local/etc/luarocks/config-5.3.lua (ok)
User : /Users/wryfi/.luarocks/config-5.3.lua (not found)
Rocks trees in use:
/Users/wryfi/.luarocks ("user")
/opt/local/share/luarocks ("system")
}}}
Whether I run `luarocks`, `luarocks-5.1`, `luarocks-5.2`, `luarocks-5.3`,
or `luarocks-5.4`, they all return the same configuration. The versioned
copies are all symlinks to the same `/opt/local/bin/luarocks` script, so
this comes as no shock.
That `luarocks` script has lua-5.3 paths hard-coded into it:
{{{
package.path=[[/opt/local/share/lua/5.3/?.lua;]] .. package.path
local list = package.searchers or package.loaders; table.insert(list, 1,
function(name) if name:match("^luarocks%.") then return
loadfile([[/opt/local/share/lua/5.3/]] .. name:gsub([[%.]], [[/]]) ..
[[.lua]]) end end)
}}}
It also has its shebang set to `/opt/local/bin/lua`, which is installed by
the `lua` port, and seems to be (currently) version 5.3:
{{{
$ /opt/local/bin/lua
Lua 5.3.6 Copyright (C) 1994-2020 Lua.org, PUC-Rio
>
}}}
I find it interesting that `luarocks` reports `Interpreter:
/opt/local/bin/lua5.3 (ok)` even though the shebang is
`/opt/local/bin/lua`, especially since `lua` is **not** a ''symlink'' to
`lua5.3` but its own ''separate binary''. (I also have discrete `lua5.1`
and `lua5.3` binaries.) Not sure how this works.
The `lua` and `lua5.3` binaries have different checksums. They are
binaries, so I can't tell for sure if anything is different about them,
but they both start a lua-5.3 interpreter, and running `strings` against
them seems to return identical output.
I don't see a way to manage the version of `/opt/local/bin/lua`, other
than `mv lua5.1 lua`. It seems like an antipattern that the version of the
`lua` binary is arbitrarily set for me, with no input or obvious way to
change it.
----
So in summary:
1. The `lua` port decides for you what version of lua (currently 5.3) will
be the default lua on your system, and that all C libraries linking
against `lua.h` will build against that version without extra care.
1. The `lua` port installs a 5.3 binary in `/opt/local/bin/lua` that
appears to be similar, but not identical, to the `/opt/local/bin/lua5.3`
binary installed by the `lua53` port.
1. There is no facility to manage which version of lua
`/opt/local/bin/lua` provides.
1. `luarocks` always runs against the version of lua installed by the
`lua` port, because its shebang is `/opt/local/bin/lua`, which is
(currently) lua 5.3 by design of the `lua` port.
a. This remains true even if running `luarocks-5.n` because the
versioned copies are all symlinks to the same `luarocks` script.
1. `luarocks` always manages packages in `/opt/local/share/lua/5.3`
because this value is hard-coded in the script.
1. Building `neovim` is breaking because it links against the `lua.h`
provided by the `lua` port (currently 5.3), which is incompatible with
neovim and luajit (not for any reasons having to do with `luarocks`).
--
Ticket URL: <https://trac.macports.org/ticket/70420#comment:9>
MacPorts <https://www.macports.org/>
Ports system for macOS
More information about the macports-tickets
mailing list