[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