Hammerspoon: Can't load lpeg with 0.9.79

Created on 20 Sep 2020  路  10Comments  路  Source: Hammerspoon/hammerspoon

With lpeg installed via luarocks install lpeg

package.path = "/usr/local/share/lua/5.3/?.lua;/usr/local/share/lua/5.3/?/init.lua;"..package.path
package.cpath = "/usr/local/lib/lua/5.3/?.so;"..package.cpath

local lpeg = require 'lpeg'

I am getting

2020-09-20 10:20:41: -- Lazy extension loading enabled
2020-09-20 10:20:41: -- Loading /Users/xxxxxxxxx/.config/hammerspoon/init.lua
2020-09-20 10:20:41: *** ERROR: error loading module 'lpeg' from file '/usr/local/lib/lua/5.3/lpeg.so':
    dlopen(/usr/local/lib/lua/5.3/lpeg.so, 6): Symbol not found: _lua_getuservalue
  Referenced from: /usr/local/lib/lua/5.3/lpeg.so
  Expected in: flat namespace
 in /usr/local/lib/lua/5.3/lpeg.so
stack traceback:
    [C]: in ?
    [C]: in function 'rawrequire'
    ...app/Contents/Resources/extensions/hs/_coresetup/init.lua:651: in function 'require'
    ...xxxx/somewhere/.config/hammerspoon/init.lua:4: in main chunk
    [C]: in function 'xpcall'
    ...app/Contents/Resources/extensions/hs/_coresetup/init.lua:702: in function 'hs._coresetup.setup'
    (...tail calls...)

It works with 0.9.78.

Most helpful comment

Has anyone checked macports? Sometimes they're a little ahead of hombrew.

I think I've found a way to get the homebrew luarocks to work on an externally installed version of lua, and assuming I can get it to work, I will write up the process and add it to the Hammerspoon wiki, hopefully later tonight or tomorrow.

Apologies for not trying this before and documenting it ahead of time -- I don't use luarocks very often and the few times I have in the past, the modules I used ended up getting rolled into Hammerspoon anyways.

All 10 comments

That's likely because we switched to Lua 5.4.0 (although I missed that from my first pass at the release notes. Now fixed)

Since homebrew is still on lua/luarocks 5.3.1, are these my current options?

  1. Stay on older hammerspoon until homebrew universe moves to 5.4.
  2. Use a pure Lua version of lpeg (if I can find one. Current search does not look promising).

Any others?

I suppose there would be the option to obtain a 5.4.0 luarocks from elsewhere

Has anyone checked macports? Sometimes they're a little ahead of hombrew.

I think I've found a way to get the homebrew luarocks to work on an externally installed version of lua, and assuming I can get it to work, I will write up the process and add it to the Hammerspoon wiki, hopefully later tonight or tomorrow.

Apologies for not trying this before and documenting it ahead of time -- I don't use luarocks very often and the few times I have in the past, the modules I used ended up getting rolled into Hammerspoon anyways.

Ok, check out https://github.com/Hammerspoon/hammerspoon/wiki/LuarocksAndHammerspon. In it I suggest a "safe" way to set the paths for LuaRocks that should track versions correctly and then go on to describe compiling a custom download of Lua 5.4 and getting your already installed luarocks to use it. I've successfully used it to install lpeg and luasocket and both load for me. Don't know enough about them to test them in depth, but I suspect they work fine now that they load.

Thank you, @asmagill, for writing it up and testing so quickly. Works great!

Here's my chicken scratch based on what you wrote and it has simplifications around not needing manual editing (by setting INSTALL_TOP) etc.

...
...
TO_INSTALL='5.4.0'
TO_INSTALL_SHORT="${TO_INSTALL%.?}"

##################
# Remove homebrew installed lua/rocks (optional)
##################
if [[ "$(command -v luarock)" = "$(brew --prefix)/bin/luarocks" ]]; then
    luarocks remove https://raw.githubusercontent.com/perusio/tamale/master/tamale-1.3.3-1.rockspec || true
    luarocks remove lpeg || true
    luarocks remove luacheck || true
fi
brew rm luarocks || true
brew rm lua || true
rm -r /usr/local/etc/luarocks || true
rm -f /usr/local/etc/luarocks/config-5.3.lua || true

##################
# install Lua 5.4.0 in ~/lua if needed
##################
if [[ ! -x ~/lua/bin/lua || ! -x ~/lua/bin/luac || $(~/lua/bin/lua -v) != Lua\ ${TO_INSTALL}* ]]; then

    echo "Installing Lua $TO_INSTALL in ${HOME:?HOME is not set}/lua"

    mkdir -p ~/lua || die "Could not create ~/lua"
    mkdir -p "/tmp/lua.${USER:?USER is not set}.$$" \
        && cd "/tmp/lua.$USER.$$" \
        && curl -R -O "http://www.lua.org/ftp/lua-${TO_INSTALL}.tar.gz" \
        && tar zxf "lua-${TO_INSTALL}.tar.gz" \
        && cd "lua-${TO_INSTALL}" || die "Could not install lua"

        sed -i "" -e "s|^INSTALL_TOP=.*$|INSTALL_TOP=$HOME/lua|" Makefile
        grep '^INSTALL_TOP' Makefile
        sed -i "" -e "s|^#define LUA_ROOT.*$|#define LUA_ROOT \"$HOME/lua/\"|" src/luaconf.h
        grep '^#define LUA_ROOT' src/luaconf.h

    case "$(uname -s)" in
    [Dd]arwin*) make macosx test install INSTALL_TOP="$HOME/lua" ;;
        [Ll]inux*) make linux test install INSTALL_TOP="$HOME/lua" ;;
        *)
            echo "No idea what to do on this platform" >&2
            exit 1
            ;;
    esac
    rm -rf "/tmp/lua.$USER.$$"
fi

export PATH="$HOME/lua/bin:$PATH"
hash -r

##################
# install Luarocks if needed
##################
if [[ ! -x ~/lua/bin/luarocks ]]; then
    mkdir -p "/tmp/luarocks.$USER.$$" \
        && cd "/tmp/luarocks.$USER.$$" \
        && curl -RL -O http://luarocks.org/releases/luarocks-3.3.1.tar.gz \
        && tar xzf luarocks-3.3.1.tar.gz \
        && cd luarocks-3.3.1 \
        && ./configure \
            --prefix="$HOME/lua" \
            --with-lua="$HOME/lua" \
            --with-lua-include="$HOME/lua/include" \
            --with-lua-bin=/"$HOME/lua/bin" \
        && make build install || die "Could not install luarocks"
    rm -rf "/tmp/luarocks.$USER.$$"
fi

##################
# Define 5.4 luarocks config
##################
if [[ ! -r ~/.luarocks/config-"$TO_INSTALL_SHORT".lua ]]; then
    mkdir -p ~/.luarocks
    rm -f ~/.luarocks/config-"$TO_INSTALL_SHORT".lua || true
    cat <<EOLUAROCKS >~/.luarocks/config-"$TO_INSTALL_SHORT".lua
lua_version = "$TO_INSTALL_SHORT"
lua_interpreter = "lua"
rocks_trees = {
    {
    name = "user",
    root = "/Users/$USER/.luarocks"
    },
}
variables = {
    LUA_DIR = "/Users/$USER/lua"
}
EOLUAROCKS
fi

##################
# Use it to install rocks
##################
cd || die "Could not cd"
luarocks --lua-version "${TO_INSTALL_SHORT}" install https://raw.githubusercontent.com/perusio/tamale/master/tamale-1.3.3-1.rockspec
luarocks --lua-version "${TO_INSTALL_SHORT}" install lpeg
luarocks --lua-version "${TO_INSTALL_SHORT}" install luacheck
...
...

Nice. The only problem I see with INSTALL_TOP is that it doesn't change the default paths in luaconf.h (which actually surprises me and I would consider a bug if I were one of the maintainers), so if you want to actually use the lua binary that was compiled for non-Hammerspoon reasons, you'll need to set the LUA_PATH and LUA_CPATH environment variables, or change them in your code.

Long term, I'm hoping #2479 proves to be fairly easy to implement, in which case I'll need to update the instructions into something a little easier anyways.

Cool, added a couple of sed s above to make the edits automatically.

@junkblocker can we consider this issue closed or do you still have questions/issues?

Thank you for your help, I am all set with this one!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

reestr picture reestr  路  3Comments

specter78 picture specter78  路  3Comments

aaronjensen picture aaronjensen  路  3Comments

lazandrei19 picture lazandrei19  路  4Comments

tomrbowden picture tomrbowden  路  3Comments