无法链接最小的Lua程序 [英] Cannot link a minimal Lua program

查看:109
本文介绍了无法链接最小的Lua程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下琐碎的Lua程序,是我从《 Lua编程》一书中复制的

#include <stdio.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
int main (void) 
{
    char buff[256];
    int error;
    lua_State *L = luaL_newstate(); /* opens Lua */
    luaL_openlibs(L); /* opens the standard libraries */
    while (fgets(buff, sizeof(buff), stdin) != NULL) 
    {
        error = luaL_loadbuffer(L, buff, strlen(buff), "line") ||
        lua_pcall(L, 0, 0, 0);

        if (error) 
        {
            fprintf(stderr, "%s", lua_tostring(L, -1));
            lua_pop(L, 1); /* pop error message from the stack */
        }
    }
    lua_close(L);
    return 0;
}

我的环境是cywin

我的make文件如下:

CC=gcc
INCLUDE='-I/home/xyz/c_drive/Program Files/Lua/5.1/include'
LINKFLAGS='-L/home/xyz/c_drive/Program Files/Lua/5.1/lib' -llua51 

li.o:li.c
    $(CC) $(INCLUDE)   -c li.c

main:li.o
    $(CC)  -o main  $(LINKFLAGS) li.o 

clean:
    rm *.o
    rm main

我的/home/xyz/c_drive/Program Files/Lua/5.1/lib目录包含lua5.1.dll lua5.1.lib lua51.dll和lua51.lib

尝试建立主要目标时,出现以下错误:

li.o:li.c:(.text+0x35): undefined reference to `_luaL_newstate'
li.o:li.c:(.text+0x49): undefined reference to `_luaL_openlibs'
li.o:li.c:(.text+0xaf): undefined reference to `_luaL_loadbuffer'
li.o:li.c:(.text+0xd9): undefined reference to `_lua_pcall'
li.o:li.c:(.text+0x120): undefined reference to `_lua_tolstring'
li.o:li.c:(.text+0x154): undefined reference to `_lua_settop'
li.o:li.c:(.text+0x167): undefined reference to `_lua_close'

关于我在这里做错什么的任何想法吗?

解决方案

问题是您已在需要它们的对象文件的链接文件之前上命名了这些库.链接器在命令行上从左到右加载模块.在您命名-llua51的那一行上,该库可能不满足未定义的符号.然后命名li.o,它确实有未知的符号.

某些类似Unix的环境不会将其视为错误,因为当满足对.so文件的引用时,链接过程的一部分将推迟到程序加载时进行.但是Cygwin,MinGW和Windows通常必须将其视为错误,因为DLL的工作方式与.so文件完全不同.

解决方案是将-llua51 放在所有.o文件之后.

顺便说一句,您似乎正在链接Lua for Windows发行版,但在Cygwin下使用GCC进行了构建.您将要使用 Dependency Walker 来确保您的程序不依赖Cygwin运行时,并且与Windows的Lua的lua51.dll确实依赖于相同的C运行时. IIRC,它将是Visual Studio早期版本的运行时.可以对此进行GCC链接,但是您将需要使用MinGW端口(可以从Cygwin使用),并链接到几个特定的​​库以获取该版本.我离开了通常的PC,或者引用了确切的链接行. (我相信您需要-lmoldname -lmsvcr80或类似的东西,作为链接行上的最后一项.)

如果使用多个C运行时库,它将引起神秘且很难诊断的问题.简单的答案是使用与您首选的Lua DLL相同的文件.另一种选择是, Lua Binaries项目已针对Windows上的各种C工具链预先编译了Lua DLL.如果您需要一个能够理解Cygwin环境的Lua应用程序,则需要一个由GCC为Cygwin构建的应用程序,而不是由Lua for Windows风味构建的应用程序. Lua Binaries将成为您的朋友,或者您可以从源头构建Lua.

I have the following trivial Lua program which I copied from the book Programming In Lua

#include <stdio.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
int main (void) 
{
    char buff[256];
    int error;
    lua_State *L = luaL_newstate(); /* opens Lua */
    luaL_openlibs(L); /* opens the standard libraries */
    while (fgets(buff, sizeof(buff), stdin) != NULL) 
    {
        error = luaL_loadbuffer(L, buff, strlen(buff), "line") ||
        lua_pcall(L, 0, 0, 0);

        if (error) 
        {
            fprintf(stderr, "%s", lua_tostring(L, -1));
            lua_pop(L, 1); /* pop error message from the stack */
        }
    }
    lua_close(L);
    return 0;
}

my environment is cywin

my make file looks like this:

CC=gcc
INCLUDE='-I/home/xyz/c_drive/Program Files/Lua/5.1/include'
LINKFLAGS='-L/home/xyz/c_drive/Program Files/Lua/5.1/lib' -llua51 

li.o:li.c
    $(CC) $(INCLUDE)   -c li.c

main:li.o
    $(CC)  -o main  $(LINKFLAGS) li.o 

clean:
    rm *.o
    rm main

My /home/xyz/c_drive/Program Files/Lua/5.1/lib directory contains lua5.1.dll lua5.1.lib lua51.dll and lua51.lib

Trying to build my main target I am getting the following errors:

li.o:li.c:(.text+0x35): undefined reference to `_luaL_newstate'
li.o:li.c:(.text+0x49): undefined reference to `_luaL_openlibs'
li.o:li.c:(.text+0xaf): undefined reference to `_luaL_loadbuffer'
li.o:li.c:(.text+0xd9): undefined reference to `_lua_pcall'
li.o:li.c:(.text+0x120): undefined reference to `_lua_tolstring'
li.o:li.c:(.text+0x154): undefined reference to `_lua_settop'
li.o:li.c:(.text+0x167): undefined reference to `_lua_close'

Any ideas about what I might be doing wrong here?

解决方案

The problem is that you have named the libraries on the link command line before the object files that require them. The linker loads modules from left to right on the command line. At the point on the line where you name -llua51, no undefined symbols that could be satisfied by that library are known. Then you name li.o, which does have unknown symbols.

Some Unix-like environments don't treat this as an error because part of the link process is deferred to the program load when reference to .so files are satisfied. But Cygwin, MinGW, and Windows in general must treat this as an error because DLLs work quite differently from .so files.

The solution is to put -llua51 after all the .o files on your link line.

Edit: Incidentally, it appears you are linking against the Lua for Windows distribution, but building with GCC under Cygwin. You will want to use Dependency Walker to make sure that your program does not depend on the Cygwin runtime, and that it does depend on the same C runtime as the lua51.dll from Lua for Windows. IIRC, that will be the runtime for the previous version of Visual Studio. It is possible to make GCC link against that, but you will need to be using the MinGW port (which you can use from Cygwin), and link against a couple of specific libraries to get that version. I'm away from my usual PC, or I'd quote an exact link line. (I believe you need -lmoldname -lmsvcr80 or something like that, as the last items on the link line.)

It will cause mysterious and very hard to diagnose problems if more than one C runtime library is in use. The easy answer is to use the same one as your preferred Lua DLL. Another alternative is that the Lua Binaries project has pre-compiled Lua DLLs for a wide array of C toolchains on Windows. If you need a Lua application that understands the Cygwin environment, you will want one that is built by GCC for Cygwin and not the Lua for Windows flavor. Lua Binaries will be your friend, or you can build Lua your self from source.

这篇关于无法链接最小的Lua程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆