Lua Compiler

11 December 2019 Link


Some notes on the C code of the Lua Compiler

Lua 5.3.1

Compiling using Code::Blocks

  1. Download the Lua source code
  2. Create a console application with default settings on code blocks
  3. copy all the files from the src directory of the lua source to the code::blocks project directory
  4. Add all source files except luac.c to the project
  5. Build!

Compiling using MinGW

  1. Install MinGW from MSYS2 as described here
  2. Start the MinGW command line:
    > C:\msys64\mingw64.exe for 64 bit
    > C:\msys64\mingw32.exe for 32 bit
  3. Go to tua source code downloaded directory
  4. Execute:
    > mingw32-make mingw


In Linux

  • To compile the dynamic library add the following to the Makefile in the src directory:
LUA_SO=liblua.so

ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T) $(LUA_SO)

$(LUA_SO): $(CORE_O) $(LIB_O)
    $(CC) -o $@ -shared $?
Also in the main Makefile, have the shared library installed along
with the static one:
TO_LIB= liblua.a liblua.so

Code details

  1. lua.c is the main file
  2. The main prompt that provides the command line is inside function pmain in lua.c specifically the function dotty(L)
  3. There is a file loadlib.c which contains all the code to implement the require function. That file basically implements dynamic library linking code for different operating systems
  4. To change the default package.path and package.cpath edit it in the luaconf.h file. A sample for adding support for LuaDist directory structure:
    #define LUA_PATH_DEFAULT  \
    		LUA_LDIR"?.lua;"  LUA_LDIR"?\\init.lua;" \
    		LUA_CDIR"?.lua;"  LUA_CDIR"?\\init.lua;" ".\\?.lua;" \
    		LUA_CDIR"..\\lib\\lua\\?.lua;" LUA_CDIR"..\\lib\\lua\\?\\init.lua"
    #define LUA_CPATH_DEFAULT \
    		LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll;" ".\\?.dll;" \
    		LUA_CDIR"..\\lib\\lua\\?.dll;" LUA_CDIR"..\\lib\\lua\\loadall.dll"
    
    For my paths I have it like this for Lua5.2:
    #define LUA_LDIR	"!\\lua\\"
    #define LUA_CDIR	"!\\"
    #define LUA_PATH_DEFAULT  \
    		".\\?.lua;"  LUA_LDIR"?.lua;"  LUA_LDIR"?\\init.lua;" \
    		             LUA_CDIR"?.lua;"  LUA_CDIR"?\\init.lua;" \
    					 LUA_CDIR"..\\src\\?.lua;" LUA_CDIR"..\\..\\?\\src\\?.lua"
    #define LUA_CPATH_DEFAULT \
    	".\\?.dll;"  LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll;" ".\\?51.dll;" LUA_CDIR"?52.dll"
    
  5. Another way to change the default path is to create a separate include file like myconf.h and in that undef the LUA_PATH_DEFAULT and LUA_CPATH_DEFAULT variables and then define your own. To compile Lua with this include file do something like:
    >mingw32-make mingw "MYCFLAGS=-DLUA_USER_H="'""\"myconf.h\"""'""
    
    Note the quotes around myconf.h
  6. For compatibility with IUP (IUP 3.15 also) do
    >mingw32-make mingw "MYCFLAGS=-DLUA_USER_H="'""\"myconf.h\"""'" -DLUA_COMPAT_MODULE"
    
  7. Adding a submodule custom searcher in the pmain function of lua.c helps find sub modules in lua properly. The code added is:
      const char *subModSearcher = "package.searchers[#package.searchers + 1] = function(mod) \
          if mod:find(\".\",1,true) then  \
    		local totErr = \"\" \
    		local top = mod:sub(1,mod:find(\".\",1,true)-1) \
    		local sep = package.config:match(\"(.-)%s\") \
    		local delim = package.config:match(\".-%s+(.-)%s\") \
    		local subst = mod:gsub(\"%.\",sep) \
    		for path in package.path:gmatch(\"(.-)\"..delim) do \
    			if path:sub(-5,-1) == \"?.lua\" then \
    				path = path:sub(1,-6)..subst..\".lua\" \
    			end \
    			path = path:gsub(\"%?\",top) \
    			local f,err = loadfile(path) \
    			if not f then \
    				totErr = totErr..\"\\n\tno file '\"..path..\"'\" \
    			else\
    				return f \
    			end \
    		end \
    		return totErr \
    	   end \
    	end";
      luaL_dostring(L,subModSearcher); 
    
    It is added in the pmain function after handle_luainit is done. This adds a searcher in package.searchers. So if a path is a/b/?/c/?.lua then require("x.y") would search in the path a/b/x/c/x/y.lua path rather than the normal a/b/x/y/c/x/y.lua