我正在尝试获取一个可与 LuaLaTeX 配合使用的基本 Lua C .so 模块。
我能够使用本地 Lua 解释器顺利运行该库 ( lua test.lua
)。但当我尝试将其加载到 LuaLaTeX 中时,出现了如下所示的错误。
测试文件在test.tex
。Lua 包位于harfbuzz.sty
,lua 文件位于luaharfbuzz.lua
,C 库代码位于harfbuzz.c
我的环境:Mac OS X、TeXLive 2015 和 Lua 5.2.4。
最小代码示例如下: https://github.com/deepakjois/tex-sandbox/tree/master/luatex-lua-c-bridge
在上面的代码中,我将文件 harfbuzz.c 编译为 harfbuzz.so。当我将其加载到我的 Lua 代码中时lua test.lua
,它运行良好。但是,当我使用 LuaTeX 加载它时,lualatex test.tex
它会引发错误。
我究竟做错了什么?
错误详情:
lualatex test.tex
This is LuaTeX, Version beta-0.80.0 (TeX Live 2015) (rev 5238)
restricted \write18 enabled.
(./test.tex
LaTeX2e <2015/01/01>
…
<snip>
…
(./luaharfbuzz.lua)
! LuaTeX error error loading module 'harfbuzz' from file './harfbuzz.so':
dlopen(./harfbuzz.so, 6): Symbol not found: _luaL_setfuncs
Referenced from: ./harfbuzz.so
Expected in: flat namespace
in ./harfbuzz.so
stack traceback:
[C]: in ?
[C]: in ?
[C]: in function 'require'
./luaharfbuzz.lua:2: in main chunk
[C]: in function 'require'
[\directlua]:1: in main chunk.
\luacode@dbg@exec ...code@maybe@printdbg {#1} #1 }
l.6 \end{luacode*}
更新 1
以下是我的计算机上的 lua 和 luatex 二进制文件链接到的共享库的比较。这能帮助解释问题吗?
> otool -L `which lua` `which luatex`
/usr/local/bin/lua:
/usr/local/lib/liblua.5.2.dylib (compatibility version 5.2.0, current version 5.2.4)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1225.1.1)
/usr/lib/libedit.3.dylib (compatibility version 2.0.0, current version 3.0.0)
/Library/TeX/texbin/luatex:
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.9.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.11)
更新 2
问题似乎在于 TeXLive 附带的 luatex 二进制文件删除了很多符号。
nm `which luatex` | grep _luaL_setfu
<…nothing…>
但是我从 trunk 构建了自己的 luatex 版本,--nostrip
启用了标志,得到了这个
nm build/texk/web2c/luatex | grep _luaL_setfu
00000001002c54d0 T _luaL_setfuncs
那么,这是否意味着,无法在 TeXLive 2015 上使用默认 luatex 加载动态链接的 .so 文件,因为无法_luaL_setfuncs
找到?
答案1
问题出在 LuaTeX 分发时的编译方式上。所有符号都从二进制文件中剥离出来,因此动态链接的 .so 库无法找到所需的符号。
参见LuaTeX邮件列表的讨论:http://tug.org/pipermail/luatex/2015-November/005440.html
另一种方法是从 SVN 编译您自己的 LuaTeX 二进制文件,使用标志构建它--nostrip
,然后用新的二进制文件覆盖现有的 LuaTeX 二进制文件。请小心执行此步骤。确保您编译的是正确版本的库(最好是与 TeXLive 版本捆绑在一起的版本),并fmtutil --byengine luatex
在复制二进制文件后运行以更新格式。