手把手教你成功编译《Lua 程序设计》书中第24章简化版Lua解释器的例子
- 作者: FreeBlues
- 修订版本: 1.00
很多人都看过《Lua 程序设计》 这本书, 在 第24章 C API 概述
中, 提供了一个非常简单的 Lua
解释器的例子, 如下:
24.1 第一个示例 将通过一个简单的
Lua
解释器程序来开始C API
的学习. 以下代码就是一个最原始的解释器程序:
#include <stdio.h>
#include <string.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
int main (void) {
char buff[256];
int error;
lua_State *L = luaL_newstate();
luaL_openlibs(L);
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);
}
}
lua_close(L);
return 0;
}
就是这段代码, 可是当你把它原样照抄, 却发现怎么也没办法顺利地把它成功编译.
一般来说, 初学者都是这样开始的:
- 新建一个
Lua
文件, 比如myLua.c
, 把上述代码拷贝进去; - 从
lua.org
下载源码, 解压, 把其中的lua.c, lua.h, lauxlib.c, lauxlib.h, lualib.c, lualib.h
拷贝到新建文件myLua.c
所在的目录下(可能在源码中找不到lualib.c
这个文件, 先不管那么多, 把源码中所有的.c
文件和.h
文件全部拷贝过来, 试试再说); - 执行
gcc myluac.c
.
这时通常会返回错误, 提示说找不到这个找不到那个, 于是初学者就失败了, 那么究竟是什么原因导致编译失败呢?
其实, 主要还是作者在这里没有把操作细节交代清楚, 而不少初学者对于 C
的编译一知半解, 尤其在涉及到共享库(包括静态库和动态库)的编译和使用时更是如此.
具体来说, 这里需要先根据 Lua
源码把 lua.c
编译成一个静态共享库 liblua.a
, 然后再在编译我们的简化版的解释器时把这个静态共享库链接进去, 头文件 liblua.h
就是它的, 这样才可以顺利完成编译.
具体操作如下:
- 首先, 要把
Lua
编译成静态库的形式, 从Lua
官网下载回源码, 解压, 然后执行如下编译命令:
make macosx
说明: 我使用的环节是
MacOSX
, 所以加了参数macosx
, 你可以根据自己的平台选择不同的参数, 有这么一些参数可选aix bsd c89 freebsd generic linux macosx mingw posix solaris
这里因为 Lua
官方源码的 Makefile
文件默认会编译为静态共享库, 所以在 src
目录你会得到一个静态库文件 liblua.a
:
Air:src admin$ ls -al liblua.a
-rw-r--r-- 1 admin staff 342264 7 20 18:12 liblua.a
Air:src admin$
- 其次, 要把刚才编译好的静态库
liblua.a
拷贝到你myLua.c
所在的目录; - 最后编译时要在命令行中设置
3
个编译参数:
- 参数
-L.
指定库文件在当前目录.
- 参数
-llua
指定库名称为lua
(库名称不需要加lib
); - 参数
I./lua-src/5.3/
指定include
文件(这里就是.h
头文件)目录在./lua-src/5.3/
- 然后就可以顺利编译了, 完整的编译命令如下:
gcc mylua.c -L. -llua -I./lua-src/5.3/ -o mylua
这样就终于成功完成编译了, 操作记录如下:
Air:lua+c admin$ gcc mylua.c -L. -llua -I./lua-src/5.3/ -o mylua
Air:lua+c admin$ ls
liblua.a lua-src mylua mylua.c
Air:lua+c admin$ ls -al
total 1120
drwxr-xr-x 6 admin staff 204 8 15 23:54 .
drwxr-xr-x 19 admin staff 646 7 23 17:54 ..
-rw-r--r-- 1 admin staff 342264 8 15 23:54 liblua.a
drwxr-xr-x 4 admin staff 136 7 20 17:36 lua-src
-rwxr-xr-x 1 admin staff 221320 8 15 23:54 mylua
-rw-r--r-- 1 admin staff 447 7 20 21:48 mylua.c
Air:lua+c admin$
执行一下我们编译的这个简化版的 Lua
解释器:
Air:lua+c admin$ ./mylua
print("hello world!")
hello world!
print(12+23)
35
p = {}
OK, 至此大功告成!