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:
parent
908b3f5d8d
commit
26361ea4cd
62
SConstruct
62
SConstruct
@ -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" )
|
||||
|
@ -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
3725
luasrcdiet.lua
Executable file
File diff suppressed because it is too large
Load Diff
42
mkfs.py
42
mkfs.py
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user