1
0
mirror of https://github.com/elua/elua.git synced 2025-01-08 20:56:17 +08:00

EXPERIMENTAL FEATURE: romfs compression/precompilation.

Added another "romfs" parameter to SConstruct. It can take one of 3 values:

- "verbatim" (default): copy all the files from the eLua romfs/ directory to the binary image (exactly what happened until now)
- "compress": use LuaSrcDiet (http://luaforge.net/projects/luasrcdiet, now included in the eLua distribution) to "compress" the source code by using different tricks (shorter identifiers, removing comments and EOLS, and so on). The output is still a compilable Lua file (although in most case it looks completely different from the original) which is copied in the eLua binary image instead of the original Lua file. The compression obtained by using this method seems to be very good in practice, thus it will save flash when needed.
- "compile": use the eLua cross compiler (that must be built first by running 'scons -f cross-lua.py') to precompile the Lua files to bytecode, and write the bytecode to the image instead of the source file. This way, one can save both time (the scripts don't need to be compiled anymore) and RAM (for the same reason, especially since the Lua parser uses the stack a lot, which can lead to very nasty and hard to diagnose stack overflow bugs). It will be even more useful in the future, when (hopefully) more and more Lua bytecode data structures will be available directly from Flash (without having to copy them RAM as it happens now). It might also decrease the romfs memory footprint, but then again, it might not; it pretty much depends on the Lua programs included in the romfs.
This commit is contained in:
Bogdan Marinescu 2009-12-02 19:33:03 +00:00
parent 908b3f5d8d
commit 26361ea4cd
4 changed files with 3811 additions and 22 deletions

View File

@ -6,6 +6,7 @@ boardname = ARGUMENTS.get( 'board' , '').upper()
toolchain = ARGUMENTS.get( 'toolchain', '')
optram = int( ARGUMENTS.get( 'optram', '1' ) )
boot = ARGUMENTS.get( 'boot', '').lower()
romfsmode = ARGUMENTS.get( 'romfs', 'verbatim' ).lower()
# Helper: "normalize" a name to make it a suitable C macro name
def cnorm( name ):
@ -20,35 +21,50 @@ toolchain_list = {
'link' : 'arm-elf-ld',
'asm' : 'arm-elf-as',
'bin' : 'arm-elf-objcopy',
'size' : 'arm-elf-size'
'size' : 'arm-elf-size',
'cross_cpumode' : 'little',
'cross_lua' : 'float_arm 64',
'cross_lualong' : 'int 32'
},
'arm-eabi-gcc' : {
'compile' : 'arm-eabi-gcc',
'link' : 'arm-eabi-ld',
'asm' : 'arm-eabi-as',
'bin' : 'arm-eabi-objcopy',
'size' : 'arm-eabi-size'
'size' : 'arm-eabi-size',
'cross_cpumode' : 'little',
'cross_lua' : 'float 64',
'cross_lualong' : 'int 32'
},
'codesourcery' : {
'compile' : 'arm-none-eabi-gcc',
'link' : 'arm-none-eabi-ld',
'asm' : 'arm-none-eabi-as',
'bin' : 'arm-none-eabi-objcopy',
'size' : 'arm-none-eabi-size'
'size' : 'arm-none-eabi-size',
'cross_cpumode' : 'little',
'cross_lua' : 'float 64',
'cross_lualong' : 'int 32'
},
'avr32-gcc' : {
'compile' : 'avr32-gcc',
'link' : 'avr32-ld',
'asm' : 'avr32-as',
'bin' : 'avr32-objcopy',
'size' : 'avr32-size'
'size' : 'avr32-size',
'cross_cpumode' : 'big',
'cross_lua' : 'float 64',
'cross_lualong' : 'int 32'
},
'i686-gcc' : {
'compile' : 'i686-elf-gcc',
'link' : 'i686-elf-ld',
'asm' : 'nasm',
'bin' : 'i686-elf-objcopy',
'size' : 'i686-elf-size'
'size' : 'i686-elf-size',
'cross_cpumode' : 'little',
'cross_lua' : 'float 64',
'cross_lualong' : 'int 32'
}
}
@ -207,21 +223,34 @@ if boot == '':
elif boot not in ['standard', 'luaremote']:
print "Unknown boot mode: ", boot
print "Boot mode can be either 'standard' or 'luaremote'"
sys.exit( -1 );
sys.exit( -1 )
# Check romfs mode
if romfsmode not in ['verbatim', 'compile', 'compress']:
print "Unknown romfs mode: ", romfsmode
print "romfs mode can be either 'verbatin', 'compile' or 'compress'"
sys.exit( -1 )
# Build the compilation command now
compcmd = ''
if romfsmode == 'compile':
compcmd = 'luac.cross -ccn %s -cce %s -o %%s -s %%s' % ( toolset[ 'cross_%s' % target ], toolset[ 'cross_cpumode' ] )
elif romfsmode == 'compress':
compcmd = 'lua luasrcdiet.lua --quiet --maximum --opt-comments --opt-whitespace --opt-emptylines --opt-eols --opt-strings --opt-numbers --opt-locals -o %s %s'
# User report
if not GetOption( 'clean' ):
print
print "*********************************"
print "Compiling eLua ..."
print "CPU: ", cputype
print "Board: ", boardname
print "Platform: ", platform
print "Allocator: ", allocator
print "Boot Mode: ", boot
print "Target: ", target == 'lua' and 'fplua' or 'target'
print "Toolchain: ", toolchain
print "CPU: ", cputype
print "Board: ", boardname
print "Platform: ", platform
print "Allocator: ", allocator
print "Boot Mode: ", boot
print "Target: ", target == 'lua' and 'fplua' or 'target'
print "Toolchain: ", toolchain
print "ROMFS mode: ", romfsmode
print "*********************************"
print
@ -281,7 +310,6 @@ opt = "-Os -fomit-frame-pointer"
#opt += " -ffreestanding"
#opt += " -fconserve-stack" # conserve stack at potential speed cost, >=GCC4.4
# Toolset data (filled by each platform in part)
tools = {}
@ -298,14 +326,14 @@ if not GetOption( 'clean' ):
flist = []
for sample in file_list[ boardname ]:
flist += romfs[ sample ]
# Automatically includes the autorun.lua file in the ROMFS
# Automatically includes the autorun.lua file in the ROMFS
if os.path.isfile( os.path.join( romdir, 'autorun.lua' ) ):
flist += [ 'autorun.lua' ]
# Automatically includes platform specific Lua module
# Automatically includes platform specific Lua module
if os.path.isfile( os.path.join( romdir, boardname + '.lua' ) ):
flist += [boardname + '.lua']
import mkfs
mkfs.mkfs( romdir, "romfiles", flist )
mkfs.mkfs( romdir, "romfiles", flist, romfsmode, compcmd )
print
if os.path.exists( "inc/romfiles.h" ):
os.remove( "inc/romfiles.h" )

View File

@ -1,6 +1,6 @@
import os, sys
output = 'luac'
output = 'luac.cross'
cdefs = '-DLUA_CROSS_COMPILER'
# Lua source files and include path
@ -11,7 +11,7 @@ lua_full_files = " " + " ".join( [ "src/lua/%s" % name for name in lua_files.spl
local_include = "-Isrc/lua"
# Compiler/linker options
cccom = "gcc -g %s -Wall %s -c $SOURCE -o $TARGET" % ( local_include, cdefs )
cccom = "gcc -O2 %s -Wall %s -c $SOURCE -o $TARGET" % ( local_include, cdefs )
linkcom = "gcc -o $TARGET $SOURCES -lm"
# Env for building the program

3725
luasrcdiet.lua Executable file

File diff suppressed because it is too large Load Diff

42
mkfs.py
View File

@ -26,8 +26,13 @@ def _add_data( data, outfile, moredata = True ):
# dirname - the directory where the files are located.
# outname - the name of the C output
# flist - list of files
# mode - preprocess the file system:
# "verbatim" - copy the files directly to the FS as they are
# "compile" - precompile all files to Lua bytecode and then copy them
# "compress" - keep the source code, but compress it with LuaSrcDiet
# compcmd - the command to use for compiling if "mode" is "compile"
# Returns True for OK, False for error
def mkfs( dirname, outname, flist ):
def mkfs( dirname, outname, flist, mode, compcmd ):
# Try to create the output files
outfname = outname + ".h"
try:
@ -63,13 +68,43 @@ def mkfs( dirname, outname, flist ):
# Try to open and read the file
try:
crtfile = file( realname, "rb" )
filedata = crtfile.read()
except:
outfile.close()
os.remove( outfname )
print "Unable to read %s" % fname
return False
# Do we need to process the file?
if mode == "compile" or mode == "compress":
fnamepart, fextpart = os.path.splitext( realname )
if mode == "compress":
newext = ".lua.tmp"
else:
newext = ".luac"
if fextpart == ".lua":
newname = fnamepart + newext
if mode == "compress":
print "Compressing %s to %s ..." % ( realname, newname )
else:
print "Cross compiling %s to %s ..." % ( realname, newname )
os.system( compcmd % ( newname, realname ) )
# TODO: this assumes that the cross compiler ended OK
crtfile.close()
try:
crtfile = file( newname, "rb" )
except:
outfile.close()
os.remove( outfname )
print "Unable to read %s" % newname
return False
if mode == "compile":
fnamepart, fextpart = os.path.splitext( fname )
fname = fnamepart + ".lc"
filedata = crtfile.read()
crtfile.close()
if mode == 'compile' or mode == "compress":
os.remove( newname )
# Write name, size, id, numpars
for c in fname:
_add_data( ord( c ), outfile )
@ -91,3 +126,4 @@ def mkfs( dirname, outname, flist ):
outfile.close()
print "Done, total size is %d bytes" % _bytecnt
return True