本文主要介绍了使用tcc编译器编译lua解释器源码。
1 介绍
lua是一门编程语言,开源且源码很容易编译,我平时用来测试C语言编程环境时经常使用。一般能编译成功就说明编程环境设置正常。下面用之前设置好的tcc编程环境进行测试。
2 获取源码
我一般有保留多个版本的lua源码进行测试,你可以去官网进行下载.
官网地址
下载页面
https://www.lua.org/download.html
最新版本即可,现在最新版为Lua 5.4.7,直接下载地址为
https://www.lua.org/ftp/lua-5.4.7.tar.gz
下载下来的文件保存到任意文件夹,我保存在C:\run\test,解压得到lua-5.4.7文件夹,文件如下
其中src就是源码文件夹。
3 初次编译
将前文配置好的tcc编程环境.bat复制到C:\run\test\lua-5.4.7\src下,直接打开。输入下面批处理指令
c
::编译所有c文件并生成可执行文件
tcc *.c
::可执行文件名称为lapi.exe
编译会失败,显示luac.c: error: 'main' defined twice,因为luac.c是一个lua编译器源码,里面也有一个main函数,luac.c文件暂时不用到,可以直接删除,或者想剪切到其他文件夹保留。
删除或移动后,重新执行上面命令,没有提示错误信息即编译成功,一般编译速度很快。文件夹下面会生成lapi.exe文件,点击打开
即说明编译成功,你可以输入一些lua代码测试一下效果。
lua
print("你好,世界")
4 编译测试
上面编译指令为最简单的编译指令,使用很简单,但是有一个问题,输出文件为lapi.exe文件而不是lua.exe,因为没有指定输出程序名称,可以使用-o文件进行指定输出文件名称。
c
::编译所有c文件并生成可执行文件,
::-o选项指定输出文件为lua.exe
tcc *.c -o lua.exe
上面编译命令虽然简单,但是隐藏了很多细节,下面进一步分析。
lua.c为解释器源码,如果直接编译lua.c文件则会出错,出错信息如下
c
tcc lua.c -o lua.exe

因为编译这个解释器需要链接到其他代码的信息。即所有c代码均要指出,如
c
::编译所有c代码,输出程序为lua.exe
::等价于tcc *.c -o lua.exe
tcc lapi.c lauxlib.c lbaselib.c lcode.c lcorolib.c lctype.c ldblib.c ldebug.c ldo.c ldump.c lfunc.c lgc.c linit.c liolib.c llex.c lmathlib.c lmem.c loadlib.c lobject.c lopcodes.c loslib.c lparser.c lstate.c lstring.c lstrlib.c ltable.c ltablib.c ltm.c lua.c lundump.c lutf8lib.c lvm.c lzio.c -o lua.exe
正常c语言程序包含编译和链接两个步骤,使用tcc编译和链接如下:
c
::编译所有c文件并生成obj文件,
::-c选项指定只编译不进行链接
tcc -c *.c
::将所有obj文件链接为可执行文件,-o选项指定输出文件为lua.exe
tcc *.o -o lua.exe
除了一次性编译所有c代码文件,还可以逐个编译c代码文件,再进行链接。
c
::逐个编译所有c文件并生成obj文件,
::-c选项指定只编译不进行链接
tcc -c lapi.c
tcc -c lauxlib.c
tcc -c lbaselib.c
tcc -c lcode.c
tcc -c lcorolib.c
tcc -c lctype.c
tcc -c ldblib.c
tcc -c ldebug.c
tcc -c ldo.c
tcc -c ldump.c
tcc -c lfunc.c
tcc -c lgc.c
tcc -c linit.c
tcc -c liolib.c
tcc -c llex.c
tcc -c lmathlib.c
tcc -c lmem.c
tcc -c loadlib.c
tcc -c lobject.c
tcc -c lopcodes.c
tcc -c loslib.c
tcc -c lparser.c
tcc -c lstate.c
tcc -c lstring.c
tcc -c lstrlib.c
tcc -c ltable.c
tcc -c ltablib.c
tcc -c ltm.c
tcc -c lua.c
tcc -c lundump.c
tcc -c lutf8lib.c
tcc -c lvm.c
tcc -c lzio.c
::将所有obj文件链接为可执行文件,-o选项指定输出文件为lua.exe
tcc *.o -o lua.exe
这样写的好处是当你修改某个c代码文件时可以,直接重新编译这个文件而其他未修改文件可以不编译,提高编译效率。
c
::若我们只修改了lua.c文件,不需编译其他文件,只需编译lua.c文件
tcc -c lua.c
::将所有obj文件链接为可执行文件,-o选项指定输出文件为lua.exe
tcc *.o -o lua.exe
此外还c语言开发中有两种特殊的编译方法,一个是生成静态链接库,如下
c
::编译除lua.c外所有c代码文件,生成静态链接库liblua.a
::-r代表重定向
tcc -r lapi.c lcode.c lctype.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c ltable.c ltm.c lundump.c lvm.c lzio.c lauxlib.c lbaselib.c lcorolib.c ldblib.c liolib.c lmathlib.c loslib.c lstrlib.c ltablib.c loadlib.c linit.c lutf8lib.c -o liblua.a
::生成文件静态链接库liblua.a,
::编译生成lua(静态链接库版本).exe,需用到liblua.a文件
tcc liblua.a lua.c -o lua(静态链接库版本).exe
还有一种是生成动态链接库版本
c
::编译除lua.c外所有c代码文件,生成动态链接库lua.dll
tcc -shared -rdynamic lapi.c lcode.c lctype.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c ltable.c ltm.c lundump.c lvm.c lzio.c lauxlib.c lbaselib.c lcorolib.c ldblib.c liolib.c lmathlib.c loslib.c lstrlib.c ltablib.c loadlib.c linit.c lutf8lib.c-o lua.dll
::生成文件动态链接库lua.dll,以及导出函数表lua.def文件
::编译生成lua(动态链接库版本).exe,需用到lua.def文件
tcc lua.def lua.c -o lua(动态链接库版本).exe
5 小结
使用tcc来编译lua源代码还是比较简单的,一方面是tcc编译器使用比较简单容易上手,另一方面是lua源代码也比较简单没有其他第三方库依赖,而且所有源码位于同一文件夹方便编译。