在 c 编译期间使用 luarocks 为 lua 安装 yaml 时出现问题

Issues installing yaml for lua with luarocks during the c-compile

我有 lua,我是用 luarocks 安装的。

编辑: 在 windows 系统上

我通过从 v202-3 from here 下载 luasocket-2.0.2-3.win32-x86.rock 文件成功安装了 luasocket。它是一个旧版本,但它可以工作。

但是现在我需要安装 yaml 以便我可以使用 yaml 文件。现在我被迫使用 *.src.rock 文件或 .rockspec 文件进行安装。

我试过:

luarocks install yaml 给出:

D:\user\workspace\_lua>luarocks install yaml
Warning: Failed searching manifest: Failed fetching manifest for https://luarocks.org - Failed downloading https://luarocks.org/manifest - C:\Users\user\AppData\Local/LuaRocks/Cache/https___luarocks.org/manifest
Warning: Failed searching manifest: Failed fetching manifest for https://raw.githubusercontent.com/rocks-moonscript-org/moonrocks-mirror/master/ - Failed downloading https://raw.githubusercontent.com/rocks-moonscript-org/moonrocks-mirror/master/manifest - C:\Users\user\AppData\Local/LuaRocks/Cache/https___raw.githubusercontent.com_rocks-moonscript-org_moonrocks-mirror_master_/manifest
Warning: Failed searching manifest: Failed fetching manifest for http://luafr.org/moonrocks/ - Failed downloading http://luafr.org/moonrocks/manifest - C:\Users\user\AppData\Local/LuaRocks/Cache/http___luafr.org_moonrocks_/manifest
Warning: Failed searching manifest: Failed fetching manifest for http://luarocks.logiceditor.com/rocks - Failed downloading http://luarocks.logiceditor.com/rocks/manifest - C:\Users\user\AppData\Local/LuaRocks/Cache/http___luarocks.logiceditor.com_rocks/manifest

Error: No results matching query were found.

所以,然后我下载了 yaml-1.1.2-1.src.rock 和 运行 命令: luarocks install yaml-1.1.2-1.src.rock

这告诉我,我有依赖项 yaml --> lub --> lua文件系统。于是我下载了:

然后我一个接一个地安装了它们,结果是:

错误日志:

D:\user\downloads\luarocks-2.3.0-win32\extras>luarocks install yaml-1.1.2-1.src.rock
Using yaml-1.1.2-1.src.rock... switching to 'build' mode
mingw32-gcc -O2 -c -o src/api.o -ID:/user/install/lua/luarocks/include src/api.c -Isrc
mingw32-gcc -O2 -c -o src/b64.o -ID:/user/install/lua/luarocks/include src/b64.c -Isrc
mingw32-gcc -O2 -c -o src/dumper.o -ID:/user/install/lua/luarocks/include src/dumper.c -Isrc
mingw32-gcc -O2 -c -o src/emitter.o -ID:/user/install/lua/luarocks/include src/emitter.c -Isrc
mingw32-gcc -O2 -c -o src/loader.o -ID:/user/install/lua/luarocks/include src/loader.c -Isrc
mingw32-gcc -O2 -c -o src/lyaml.o -ID:/user/install/lua/luarocks/include src/lyaml.c -Isrc
mingw32-gcc -O2 -c -o src/parser.o -ID:/user/install/lua/luarocks/include src/parser.c -Isrc
mingw32-gcc -O2 -c -o src/reader.o -ID:/user/install/lua/luarocks/include src/reader.c -Isrc
mingw32-gcc -O2 -c -o src/scanner.o -ID:/user/install/lua/luarocks/include src/scanner.c -Isrc
mingw32-gcc -O2 -c -o src/strtod.o -ID:/user/install/lua/luarocks/include src/strtod.c -Isrc
In file included from src/strtod.c:23:0:
src/strtod.c:24:17: warning: '_errno' redeclared without dllimport attribute: previous dllimport ignored [-Wattributes]
 extern  int     errno;
                 ^
mingw32-gcc -O2 -c -o src/writer.o -ID:/user/install/lua/luarocks/include src/writer.c -Isrc
mingw32-gcc -shared -o yaml/core.dll src/api.o src/b64.o src/dumper.o src/emitter.o src/loader.o src/lyaml.o src/parser.o src/reader.o src/scanner.o src/strtod.o src/writer.o D:/user/install/lua/luarocks/lua5.1.lib -lMSVCR80
src/api.o:api.c:(.text+0x395): undefined reference to '_imp__yaml_realloc'
src/api.o:api.c:(.text+0x412): undefined reference to '_imp__yaml_string_extend'
            :
    LOTS OF THESE
            :
src/scanner.o:scanner.c:(.text.unlikely+0x29d0): undefined reference to '_imp__yaml_queue_extend'
src/scanner.o:scanner.c:(.text.unlikely+0x29e8): undefined reference to '_imp__yaml_token_delete'
collect2.exe: error: ld returned 1 exit status

Error: Build error: Failed compiling module yaml/core.dll

有谁知道为什么这个构建失败了? - 我直接从这里得到它:https://luarocks.org/modules/gaspard/yaml/1.1.2-1 这是下载次数最多的版本...所以我想它应该有用吗?

我的意思是,我可以看出错误是什么...但我不明白为什么会出现错误。我该如何解决这个问题?...感谢任何帮助:)

更新

感谢 siffiejoe 的评论,我能够编译 yaml rock。这是输出:

D:\user\downloads\luarocks-2.3.0-win32\extras>luarocks install yaml-1.1.2-1.src.rock CC="gcc -DYAML_DECLARE_STATIC"
Using yaml-1.1.2-1.src.rock... switching to 'build' mode
gcc -DYAML_DECLARE_STATIC -O2 -c -o src/api.o -ID:/user/install/lua/luarocks/include src/api.c -Isrc
gcc -DYAML_DECLARE_STATIC -O2 -c -o src/b64.o -ID:/user/install/lua/luarocks/include src/b64.c -Isrc
gcc -DYAML_DECLARE_STATIC -O2 -c -o src/dumper.o -ID:/user/install/lua/luarocks/include src/dumper.c -Isrc
gcc -DYAML_DECLARE_STATIC -O2 -c -o src/emitter.o -ID:/user/install/lua/luarocks/include src/emitter.c -Isrc
gcc -DYAML_DECLARE_STATIC -O2 -c -o src/loader.o -ID:/user/install/lua/luarocks/include src/loader.c -Isrc
gcc -DYAML_DECLARE_STATIC -O2 -c -o src/lyaml.o -ID:/user/install/lua/luarocks/include src/lyaml.c -Isrc
gcc -DYAML_DECLARE_STATIC -O2 -c -o src/parser.o -ID:/user/install/lua/luarocks/include src/parser.c -Isrc
gcc -DYAML_DECLARE_STATIC -O2 -c -o src/reader.o -ID:/user/install/lua/luarocks/include src/reader.c -Isrc
gcc -DYAML_DECLARE_STATIC -O2 -c -o src/scanner.o -ID:/user/install/lua/luarocks/include src/scanner.c -Isrc
gcc -DYAML_DECLARE_STATIC -O2 -c -o src/strtod.o -ID:/user/install/lua/luarocks/include src/strtod.c -Isrc
In file included from src/strtod.c:23:0:
src/strtod.c:24:17: warning: '_errno' redeclared without dllimport attribute: previous dllimport ignored [-Wattributes]
 extern  int     errno;
                 ^
gcc -DYAML_DECLARE_STATIC -O2 -c -o src/writer.o -ID:/user/install/lua/luarocks/include src/writer.c -Isrc
mingw32-gcc -shared -o yaml/core.dll src/api.o src/b64.o src/dumper.o src/emitter.o src/loader.o src/lyaml.o src/parser.o src/reader.o src/scanner.o src/strtod.o src/writer.o D:/user/install/lua/luarocks/lua5.1.lib -lMSVCR80
Updating manifest for D:\user\install\lua\luarocks\systree/lib/luarocks/rocks
yaml 1.1.2-1 is now built and installed in D:\user\install\lua\luarocks\systree (license: MIT)

所以它说它已安装。但是,当我尝试使用 yaml 包时,它找不到它:

local yaml = require("yaml")
local data = yaml.load("mytest.yaml")

系统报找不到yaml.lua或yaml.dll。然后我在 luarocks 文件夹中搜索 *.lua 和 *.dll,我发现:

D:\user\install\lua\luarocks\systree>dir *.lua *.dll /b /s
D:\user\install\lua\luarocks\systree\lib\lua.1\lfs.dll
D:\user\install\lua\luarocks\systree\lib\lua.1\mime\core.dll
D:\user\install\lua\luarocks\systree\lib\lua.1\socket\core.dll
D:\user\install\lua\luarocks\systree\lib\lua.1\yaml\core.dll
D:\user\install\lua\luarocks\systree\lib\luarocks\rocks\luafilesystem.6.3-2\tests\test.lua
D:\user\install\lua\luarocks\systree\share\lua.1\ltn12.lua
D:\user\install\lua\luarocks\systree\share\lua.1\mime.lua
D:\user\install\lua\luarocks\systree\share\lua.1\socket.lua
D:\user\install\lua\luarocks\systree\share\lua.1\lub\Autoload.lua
D:\user\install\lua\luarocks\systree\share\lua.1\lub\Dir.lua
D:\user\install\lua\luarocks\systree\share\lua.1\lub\init.lua
D:\user\install\lua\luarocks\systree\share\lua.1\lub\Param.lua
D:\user\install\lua\luarocks\systree\share\lua.1\lub\Template.lua
D:\user\install\lua\luarocks\systree\share\lua.1\socket\ftp.lua
D:\user\install\lua\luarocks\systree\share\lua.1\socket\http.lua
D:\user\install\lua\luarocks\systree\share\lua.1\socket\smtp.lua
D:\user\install\lua\luarocks\systree\share\lua.1\socket\tp.lua
D:\user\install\lua\luarocks\systree\share\lua.1\socket\url.lua
D:\user\install\lua\luarocks\systree\share\lua.1\yaml\init.lua

例如,我设法用 luarocks install luasocket-2.0.2-3.win32-x86.rock 安装了 luasocket,因为有一个 .rock 文件可用。所以你可以看到有一个 socket.lua。对于 yaml、lub 和 luafilesystem,我可以看到各种安装位置,但没有 .lua 或 .dll 文件... 我专门搜索了更多yaml:

D:\user\install\lua\luarocks\systree>dir *yaml* /b /s
D:\user\install\lua\luarocks\systree\lib\lua.1\yaml
D:\user\install\lua\luarocks\systree\lib\luarocks\rocks\yaml
D:\user\install\lua\luarocks\systree\lib\luarocks\rocks\yaml.1.2-1\yaml-1.1.2-1.rockspec
D:\user\install\lua\luarocks\systree\share\lua.1\yaml

ehh...所以我去从 git 克隆了项目(不得不下载 zip 文件,因为我愚蠢的 IT 阻止了我的 git 克隆 ...(端口 443)。

所以终于整理好了,然后在我尝试的 yaml-master 文件夹中:

luarocks make yaml-1.1.2-1.rockspec CC-"gcc -DYAML_DECLARE_STATIC"

这与以前的效果相同。所以现在我已经尝试了 .src.rock 和 .rockspec 类型...

我又卡住了:(

更新 2

当我从 git 构建时,顶层有一个名为 yaml.lua 的文件。但它只包含文本 yaml/init.lua ...不知道该怎么做 - 尝试将它复制到我的 ..install\lua\luarocks\systree\share\lua.1 目录中,但是当我 运行 我的测试 lua projam 它给出了一个错误....这是怎么回事,安装不会这么难:(

更新 3

根据 siffiejoe 的精彩回答,我或多或少安装了这个 yaml。但是我有一个 bug 运行ning 它:

这是我的 lua 脚本:

package.path = "D:\user\install\lua\luarocks\systree\share\lua\5.1\?\init.lua;" .. package.path
print("package.path: " .. package.path)
local yaml = require("yaml")
local data = yaml.load("mytest.yaml")

我正在测试时手动添加 lua 路径。当我 运行 这个我得到 window:

我的日志如下所示:

D:\user\install\lua\luarocks\systree\share\lua.1\?\init.lua;D:\user\install\lua\luarocks\systree\share\lua.1\?.lua;D:\user\install\lua\luarocks\systree\share\lua.1\?\init.lua;./?.lua;./?/init.lua;./lua/?.lua;./lua/?/init.lua;D:\user\install\lua\zerobrane\lualibs/?/?.lua;D:\user\install\lua\zerobrane\lualibs/?.lua;D:\user\install\lua\zerobrane\lualibs/?/?/init.lua;D:\user\install\lua\zerobrane\lualibs/?/init.lua
D:\user\install\lua\zerobrane\bin\lua.exe: error loading module 'lfs' from file 'D:\user\install\lua\luarocks\systree\lib\lua.1\lfs.dll':
    The specified procedure could not be found.


stack traceback:
    [C]: at 0x66df0460
    [C]: in function 'require'
    ...\install\lua\luarocks\systree\share\lua.1\lub\init.lua:17: in main chunk
    [C]: in function 'require'
    ...install\lua\luarocks\systree\share\lua.1\yaml\init.lua:25: in main chunk
    [C]: in function 'require'
    D:\user\workspace\_lua\myluatest.lua:3: in main chunk
    [C]: at 0x00402a57
Program completed in 56.64 seconds (pid: 15856).

所以它似乎回到了这个 MSVCR80.dll ...这对我来说没有意义,我认为这与微软有关...我读到的一些内容可能是损坏的MSVCR80.dll 需要更换或其他东西。但我还不确定为什么会这样。有什么想法吗?

包含文件 src/yaml.h from the github repository 包含以下预处理器代码:

#ifdef WIN32
#   if defined(YAML_DECLARE_STATIC)
#       define  YAML_DECLARE(type)  type
#   elif defined(YAML_DECLARE_EXPORT)
#       define  YAML_DECLARE(type)  __declspec(dllexport) type
#   else
#       define  YAML_DECLARE(type)  __declspec(dllimport) type
#   endif
#else
#   define  YAML_DECLARE(type)  type
#endif

这意味着在 Windows 上所有与 yaml 相关的函数默认都用 __declspec(dllimport) 修饰(linker 错误消息中的 _imp__ 前缀是提示) .因此,linker 希望这些函数位于外部 DLL 中。但是 yaml 代码与 Lua 绑定一起捆绑并编译到单个 DLL yaml\core.dll 中,因此 linker 抱怨道。解决这个问题的正确方法是从 yaml 函数中删除所有 import/export-related 装饰,这可以通过定义 YAML_DECLARE_STATIC 来实现。这个宏绝对应该在 rockspec 中设置(稍后我会 post 一个错误报告),但是一个快速而肮脏的解决方案是通过命令行上的 CC 变量设置它:

luarocks install yaml-1.1.2-1.src.rock CC="mingw32-gcc -DYAML_DECLARE_STATIC"

之后在您的 LuaRocks 目录中应该有一个 yaml\core.dll 文件和一个 yaml\init.lua 文件。要使用 Lua yaml 绑定,您必须确保 require("yaml") 加载 yaml\init.lua 文件,并且 require("yaml.core") 加载 yaml\core.dll。这可以通过添加到 package.path/package.cpath(从您的 Lua 脚本中)或最好通过添加到 LUA_PATH/LUA_CPATH 来实现。由于安装的 LuaSocket 已经工作,您可能 LUA_PATH/LUA_CPATH 大部分设置正确,但 yaml 绑定使用不同的方法加载其主要 Lua 模块LuaSocket:LuaSocket 有 socket.lua for require("socket"),但是 yaml 有 yaml\init.lua for require("yaml")。这种方法的优点是任何 Lua 子模块(例如 yaml.a)都将与主 Lua 模块的代码位于同一目录中。无论如何,你还必须添加

D:\user\install\lua\luarocks\systree\share\lua.1\?\init.lua

到您的 LUA_PATH 环境变量。

顺便说一句,您在 github 存储库中找到的 yaml.lua 文件是一个符号 link 并且无论如何都无法在 Windows 上正常工作(但它可以干扰,所以你不应该把它放到你的岩石树中)。它只是为了在开发过程中提供方便。