1
0
mirror of https://github.com/elua/elua.git synced 2025-01-08 20:56:17 +08:00
elua/build_elua.lua
Martin Guy fe4c8d86f7 Integrated Martin Guy's emBLOD bootloader patch in eLua. Original patch message:
emBLOD is Marcus Jansson's second-stage boot loader for AVR32UC3A
parts as used in the EVK1100 and Mizar32 boards, designed to allow
firmware images larger than the on-chip flash memory by loading the
eLua binary from SD card into SDRAM and executing it there.

The source for the emBLOD loader is here https://github.com/cmp1084/emBLOD

When compilation option  bootloader=emblod is given to scons, a special
version is compiled that
- locates the program at the start of SDRAM
- doesn't initialize the system clocks and SDRAM controller, as these
are already set up by emBLOD.

If the bootloader= option is not given, eLua is compiled exactly as before.

The changes I've made to Marcus' originally posted patches are to put
DATA and BSS in internal static RAM, the same as before, since in the
best case (memcpy) the SDRAM is three times slower than access to
static RAM
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=80657

This also has an impact on code speed: the interpreter runs 9 times
slower in external SDRAM than it does in internal flash.

Tested and working on Mizar32
2011-04-07 22:35:10 +03:00

561 lines
20 KiB
Lua

local args = { ... }
local b = require "utils.build"
local mkfs = require "utils.mkfs"
builder = b.new_builder()
utils = b.utils
sf = string.format
-------------------------------------------------------------------------------
-- Build configuration 'shortcuts'
cdefs, cflags, includes, lflags, asflags, libs = {}, {}, {}, {}, {}, {}
-- "Normalize" a name to make it a suitable C macro name
function cnorm( name )
name = name:gsub( "[%-%s]*", '' )
return name:upper()
end
-- Add a macro defition
function addm( data )
table.insert( cdefs, data )
end
-- Add an include directory
function addi( data )
table.insert( includes, data )
end
-- Add a compiler flag
function addcf( data )
table.insert( cflags, data )
end
-- Delete a compiler flag
function delcf( data )
cflags = utils.linearize_array( cflags )
for _, v in pairs( data ) do
local i = utils.array_element_index( cflags, v )
if i then table.remove( cflags, i ) end
end
end
-- Add a linker flag
function addlf( data )
table.insert( lflags, data )
end
-- Add an assembler flag
function addaf( data )
table.insert( asflags, data )
end
-- Add a library
function addlib( data )
table.insert( libs, data )
end
-------------------------------------------------------------------------------
-- Build data
-- List of toolchains
local toolchain_list =
{
[ 'arm-gcc' ] = {
compile = 'arm-elf-gcc',
link = 'arm-elf-ld',
asm = 'arm-elf-as',
bin = 'arm-elf-objcopy',
size = 'arm-elf-size',
cross_cpumode = 'little',
cross_lua = 'float_arm 64',
cross_lualong = 'int 32',
version = '--version'
},
[ 'arm-eabi-gcc' ] = {
compile = 'arm-eabi-gcc',
link = 'arm-eabi-ld',
asm = 'arm-eabi-as',
bin = 'arm-eabi-objcopy',
size = 'arm-eabi-size',
cross_cpumode = 'little',
cross_lua = 'float 64',
cross_lualong = 'int 32',
version = '--version'
},
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',
cross_cpumode = 'little',
cross_lua = 'float 64',
cross_lualong = 'int 32',
version = '--version'
},
[ 'avr32-gcc' ] = {
compile = 'avr32-gcc',
link = 'avr32-ld',
asm = 'avr32-as',
bin = 'avr32-objcopy',
size = 'avr32-size',
cross_cpumode = 'big',
cross_lua = 'float 64',
cross_lualong = 'int 32',
version = '--version'
},
[ 'avr32-unknown-none-gcc' ] = {
compile = 'avr32-unknown-none-gcc',
link = 'avr32-unknown-none-ld',
asm = 'avr32-unknown-none-as',
bin = 'avr32-unknown-none-objcopy',
size = 'avr32-unknown-none-size',
cross_cpumode = 'big',
cross_lua = 'float 64',
cross_lualong = 'int 32',
version = '--version'
},
[ 'i686-gcc' ] = {
compile = 'i686-elf-gcc',
link = 'i686-elf-ld',
asm = 'nasm',
bin = 'i686-elf-objcopy',
size = 'i686-elf-size',
cross_cpumode = 'little',
cross_lua = 'float 64',
cross_lualong = 'int 32',
version = '--version'
}
}
-- Toolchain Aliases
toolchain_list[ 'devkitarm' ] = toolchain_list[ 'arm-eabi-gcc' ]
-- List of platform/CPU/toolchains combinations
-- The first toolchain in the toolchains list is the default one
-- (the one that will be used if none is specified)
local platform_list =
{
at91sam7x = { cpus = { 'AT91SAM7X256', 'AT91SAM7X512' }, toolchains = { 'arm-gcc', 'codesourcery', 'devkitarm', 'arm-eabi-gcc' } },
lm3s = { cpus = { 'LM3S1968', 'LM3S8962', 'LM3S6965', 'LM3S6918', 'LM3S9B92' }, toolchains = { 'arm-gcc', 'codesourcery', 'devkitarm', 'arm-eabi-gcc' } },
str9 = { cpus = { 'STR912FAW44' }, toolchains = { 'arm-gcc', 'codesourcery', 'devkitarm', 'arm-eabi-gcc' } },
i386 = { cpus = { 'I386' }, toolchains = { 'i686-gcc' } },
sim = { cpus = { 'LINUX' }, toolchains = { 'i686-gcc' } },
lpc288x = { cpus = { 'LPC2888' }, toolchains = { 'arm-gcc', 'codesourcery', 'devkitarm', 'arm-eabi-gcc' } },
str7 = { cpus = { 'STR711FR2' }, toolchains = { 'arm-gcc', 'codesourcery', 'devkitarm', 'arm-eabi-gcc' } },
stm32 = { cpus = { 'STM32F103ZE', 'STM32F103RE' }, toolchains = { 'arm-gcc', 'codesourcery', 'devkitarm', 'arm-eabi-gcc' } },
avr32 = { cpus = { 'AT32UC3A0512', 'AT32UC3A0128', 'AT32UC3B0256' }, toolchains = { 'avr32-gcc', 'avr32-unknown-none-gcc' } },
lpc24xx = { cpus = { 'LPC2468' }, toolchains = { 'arm-gcc', 'codesourcery', 'devkitarm', 'arm-eabi-gcc' } },
lpc17xx = { cpus = { 'LPC1768' }, toolchains = { 'arm-gcc', 'codesourcery', 'devkitarm', 'arm-eabi-gcc' } }
}
-- List of board/CPU combinations
local board_list =
{
[ 'SAM7-EX256' ] = { 'AT91SAM7X256', 'AT91SAM7X512' },
[ 'EK-LM3S1968' ] = { 'LM3S1968' },
[ 'EK-LM3S8962' ] = { 'LM3S8962' },
[ 'EK-LM3S6965' ] = { 'LM3S6965' },
[ 'EK-LM3S9B92' ] = { 'LM3S9B92' },
[ 'STR9-COMSTICK' ] = { 'STR912FAW44' },
[ 'STR-E912' ] = { 'STR912FAW44' },
[ 'PC' ] = { 'I386' },
[ 'SIM' ] = { 'LINUX' },
[ 'LPC-H2888' ] = { 'LPC2888' },
[ 'MOD711' ] = { 'STR711FR2' },
[ 'STM3210E-EVAL' ] = { 'STM32F103ZE' },
[ 'ATEVK1100' ] = { 'AT32UC3A0512' },
[ 'ATEVK1101' ] = { 'AT32UC3B0256' },
[ 'ET-STM32' ] = { 'STM32F103RE' },
[ 'EAGLE-100' ] = { 'LM3S6918' },
[ 'ELUA-PUC' ] = { 'LPC2468' },
[ 'MBED' ] = { 'LPC1768' },
[ 'MIZAR32' ] = { 'AT32UC3A0128' },
[ 'NETDUINO' ] = { 'AT91SAM7X512' },
}
-- Build the CPU list starting from the above list
local cpu_list = {}
for k, v in pairs( board_list ) do
local clist = v
for i = 1, #clist do
if not utils.array_element_index( cpu_list, clist[ i ] ) then
table.insert( cpu_list, clist[ i ] )
end
end
end
-- ROMFS file list "groups"
-- To include a file in a ROMFS build, include it in a group here (or create one
-- if you need) and make sure the group is included on your platform's file_list
-- definition (right after this).
-- The following table will be left here just as an example
-- eLua examples were removed from the distro since v0.8
--[[
local romfs =
{
bisect = { 'bisect.lua' },
hangman = { 'hangman.lua' },
lhttpd = { 'index.pht', 'lhttpd.lua', 'test.lua' },
led = { 'led.lua' },
piano = { 'piano.lua' },
pwmled = { 'pwmled.lua' },
tvbgone = { 'tvbgone.lua', 'codes.bin' },
hello = { 'hello.lua' },
info = { 'info.lua' },
morse = { 'morse.lua' },
dualpwm = { 'dualpwm.lua' },
adcscope = { 'adcscope.lua' },
adcpoll = { 'adcpoll.lua' },
life = { 'life.lua' },
logo = {'logo.lua', 'logo.bin' },
pong = { 'pong.lua' },
spaceship = { 'spaceship.lua' },
tetrives = { 'tetrives.lua' },
snake = { 'snake.lua' },
dataflash = { 'dataflash.lua' },
pachube = { 'pachube_demo.lua' },
inttest = { 'inttest.lua' }
}
--]]
local romfs = {}
-- List of board/romfs data combinations
-- The following table will be left here just as an example
-- eLua examples were removed from the distro since v0.8
--[[
local file_list =
{
[ 'SAM7-EX256' ] = { 'bisect', 'hangman' , 'led', 'piano', 'hello', 'info', 'morse' },
[ 'EK-LM3S1968' ] = { 'bisect', 'hangman', 'pong', 'led', 'piano', 'pwmled', 'hello', 'info', 'morse', 'adcscope', 'adcpoll', 'logo', 'spaceship', 'tetrives', 'snake' },
[ 'EK-LM3S8962' ] = { 'lhttpd','bisect', 'led', 'pachube' },
[ 'EK-LM3S6965' ] = { 'bisect', 'hangman', 'pong', 'led', 'piano', 'pwmled', 'hello', 'info', 'morse', 'adcscope', 'adcpoll', 'logo', 'tetrives' },
[ 'EK-LM3S9B92' ] = { 'bisect', 'hangman', 'led', 'pwmled', 'hello', 'info', 'adcscope','adcpoll', 'life' },
[ 'STR9-COMSTICK' ] = { 'bisect', 'hangman', 'led', 'hello', 'info' },
[ 'STR-E912' ] = { 'bisect', 'hangman', 'led', 'hello', 'info', 'piano', 'adcscope' },
[ 'PC' ] = { 'bisect', 'hello', 'info', 'life', 'hangman' },
[ 'SIM' ] = { 'bisect', 'hello', 'info', 'life', 'hangman' },
[ 'LPC-H2888' ] = { 'bisect', 'hangman', 'led', 'hello', 'info' },
[ 'MOD711' ] = { 'bisect', 'hangman', 'led', 'hello', 'info', 'dualpwm' },
[ 'STM3210E-EVAL' ] = { 'bisect', 'hello', 'info' },
[ 'ATEVK1100' ] = { 'bisect', 'hangman', 'led', 'hello', 'info', 'dataflash' },
[ 'ATEVK1101' ] = { 'bisect', 'led', 'hello', 'info', 'dataflash' },
[ 'ET-STM32' ] = { 't' },
[ 'EAGLE-100' ] = { 'bisect', 'hangman', 'lhttpd', 'led', 'hello', 'info' },
[ 'ELUA-PUC' ] = { 'bisect', 'hangman', 'led', 'hello', 'info', 'pwmled', 'adcscope', 'adcpoll', 'inttest' },
[ 'MBED' ] = { 'bisect', 'hangman', 'hello', 'info', 'led', 'pwmled', 'dualpwm', 'life', 'adcscope', 'adcpoll' },
[ 'MIZAR32' ] = { },
[ 'NETDUINO' ] = { },
}
--]]
local file_list =
{
[ 'SAM7-EX256' ] = {},
[ 'EK-LM3S1968' ] = {},
[ 'EK-LM3S8962' ] = {},
[ 'EK-LM3S6965' ] = {},
[ 'EK-LM3S9B92' ] = {},
[ 'STR9-COMSTICK' ] = {},
[ 'STR-E912' ] = {},
[ 'PC' ] = {},
[ 'SIM' ] = {},
[ 'LPC-H2888' ] = {},
[ 'MOD711' ] = {},
[ 'STM3210E-EVAL' ] = {},
[ 'ATEVK1100' ] = {},
[ 'ATEVK1101' ] = {},
[ 'ET-STM32' ] = {},
[ 'EAGLE-100' ] = {},
[ 'ELUA-PUC' ] = {},
[ 'MBED' ] = {},
[ 'MIZAR32' ] = {},
[ 'NETDUINO'] = {},
}
builder:add_option( 'target', 'build "regular" float lua or integer-only "lualong"', 'lua', { 'lua', 'lualong' } )
builder:add_option( 'cpu', 'build for the specified CPU (board will be inferred, if possible)', 'auto', { cpu_list, 'auto' } )
builder:add_option( 'allocator', 'select memory allocator', 'auto', { 'newlib', 'multiple', 'simple', 'auto' } )
builder:add_option( 'board', 'selects board for target (cpu will be inferred)', 'auto', { utils.table_keys( board_list ), 'auto' } )
builder:add_option( 'toolchain', 'specifies toolchain to use (auto=search for usable toolchain)', 'auto', { utils.table_keys( toolchain_list ), 'auto' } )
builder:add_option( 'optram', 'enables Lua Tiny RAM enhancements', true )
builder:add_option( 'boot', 'boot mode, standard will boot to shell, luarpc boots to an rpc server', 'standard', { 'standard' , 'luarpc' } )
builder:add_option( 'romfs', 'ROMFS compilation mode', 'verbatim', { 'verbatim' , 'compress', 'compile' } )
builder:add_option( 'cpumode', 'ARM CPU compilation mode (only affects certain ARM targets)', nil, { 'arm', 'thumb' } )
builder:add_option( 'bootloader', 'Build for bootloader usage (AVR32 only)', 'none', { 'none', 'emblod' } )
builder:init( args )
builder:set_build_mode( builder.BUILD_DIR_LINEARIZED )
-- Build the 'comp' target which will 'redirect' all the requests
-- for its fields to builder:get_option
comp = {}
setmetatable( comp, { __index = function( t, key ) return builder:get_option( key ) end } )
-- Variants: board = <board>
-- cpu = <cpuname>
-- board = <board> cpu=<cpuname>
if comp.board == 'auto' and comp.cpu == 'auto' then
print "Must specifiy board, cpu, or both"
os.exit( -1 )
elseif comp.board ~= 'auto' and comp.cpu ~= 'auto' then
-- Check if the board, cpu pair is correct
if utils.array_element_index( board_list[ comp.board:upper() ], comp.cpu:upper() ) == nil then
print( sf( "Invalid CPU '%s' for board '%s'" , comp.cpu, comp.board ) )
os.exit( -1 )
end
elseif comp.board ~= 'auto' then
-- Find CPU
comp.cpu = board_list[ comp.board:upper() ][ 1 ]
else
-- cpu = <cputype>
-- Find board name
for b, v in pairs( board_list ) do
if utils.array_element_index( v, comp.cpu:upper() ) then
comp.board = b
break
end
end
if comp.board == 'auto' then
print( sf( "CPU '%s' not found", comp.cpu ) )
os.exit( -1 )
end
end
-- Look for the given CPU in the list of platforms
for p, v in pairs( platform_list ) do
if utils.array_element_index( v.cpus, comp.cpu:upper() ) then
platform = p
break
end
end
if not platform then
print( "Unable to find platform (this shouldn't happen, check the build script for errors)" )
os.exit( -1 )
end
-- Check the toolchain
if comp.toolchain ~= 'auto' then
if utils.array_element_index( platform_list[ platform ].toolchains, comp.toolchain ) == nil then
print( sf( "Invalid toolchain '%s' for CPU '%s'", comp.toolchain, comp.cpu ) )
os.exit( -1 )
end
toolset = toolchain_list[ comp.toolchain ]
comp.CC = toolset.compile
comp.AS = toolset.compile
else
-- If 'auto' try to match a working toolchain with target
local usable_chains = platform_list[ platform ].toolchains
-- Try to execute all compilers, exit when one found
local chain
for i = 1, #usable_chains do
local c = usable_chains[ i ]
local t = toolchain_list[ c ]
local res = utils.check_command( t.compile .. " " .. t.version )
if res == 0 then chain = c break end
end
if chain then
comp.toolchain = chain
comp.CC = toolchain_list[ chain ].compile
comp.AS = comp.CC
toolset = toolchain_list[ chain ]
else
print "Unable to find an usable toolchain in your path."
print( sf( "List of accepted toolchains (for %s): %s", comp.cpu, table.concat( usable_chains ) ) )
os.exit( -1 )
end
end
-- CPU/allocator mapping (if allocator not specified)
if comp.allocator == 'auto' then
if utils.array_element_index( { 'LPC-H2888', 'ATEVK1100', 'MBED' }, comp.board:upper() ) then
comp.allocator = 'multiple'
else
comp.allocator = 'newlib'
end
end
-- Build the compilation command now
local fscompcmd = ''
if comp.romfs == 'compile' then
local suffix = ''
if utils.is_windows() then
suffix = '.exe'
end
-- First check for luac.cross in the current directory
if not utils.is_file( "luac.cross" .. suffix ) then
print "The eLua cross compiler was not found."
print "Build it by running 'lua cross-lua.lua'"
os.exit( -1 )
end
local cmdpath = { lfs.currentdir(), sf( 'luac.cross%s -ccn %s -cce %s -o %%s -s %%s', suffix, toolset[ "cross_" .. comp.target:lower() ], toolset.cross_cpumode:lower() ) }
fscompcmd = table.concat( cmdpath, utils.dir_sep )
elseif comp.romfs == 'compress' then
fscompcmd = 'lua luasrcdiet.lua --quiet --maximum --opt-comments --opt-whitespace --opt-emptylines --opt-eols --opt-strings --opt-numbers --opt-locals -o %s %s'
end
-- Output file
output = 'elua_' .. comp.target .. '_' .. comp.cpu:lower()
builder:set_output_dir( ".build" .. utils.dir_sep .. comp.board:lower() )
-- User report
print ""
print "*********************************"
print "Compiling eLua ..."
print( "CPU: ", comp.cpu )
print( "Board: ", comp.board )
print( "Platform: ", platform )
print( "Allocator: ", comp.allocator )
print( "Boot Mode: ", comp.boot )
print( "Target: ", comp.target )
print( "Toolchain: ", comp.toolchain )
print( "ROMFS mode: ", comp.romfs )
print "*********************************"
print ""
-- Build list of source files, include directories, macro definitions
addm( "ELUA_CPU=" .. comp.cpu:upper() )
addm( "ELUA_BOARD=" .. comp.board:upper() )
addm( "ELUA_PLATFORM=" .. platform:upper() )
addm( "__BUFSIZ__=128" )
-- Also make the above into direct defines (to use in conditional C code)
addm( "ELUA_CPU_" .. cnorm( comp.cpu ) )
addm( "ELUA_BOARD_" .. cnorm( comp.board ) )
addm( "ELUA_PLATFORM_" .. cnorm( platform ) )
if comp.allocator == 'multiple' then
addm( "USE_MULTIPLE_ALLOCATOR" )
elseif comp.allocator == 'simple' then
addm( "USE_SIMPLE_ALLOCATOR" )
end
if comp.boot == 'luarpc' then addm( "ELUA_BOOT_RPC" ) end
if comp.target == 'lualong' then addm( "LUA_NUMBER_INTEGRAL" ) end
-- Special macro definitions for the SYM target
if platform == 'sim' then addm( { "ELUA_SIMULATOR", "ELUA_SIM_" .. cnorm( comp.cpu ) } ) end
-- Lua source files and include path
exclude_patterns = { "^src/platform", "^src/uip", "^src/serial", "^src/luarpc_desktop_serial.c", "^src/lua/print.c", "^src/lua/luac.c" }
local source_files = utils.get_files( "src", function( fname )
fname = fname:gsub( "\\", "/" )
local include = fname:find( ".*%.c$" )
if include then
utils.foreach( exclude_patterns, function( k, v ) if fname:match( v ) then include = false end end )
end
return include
end )
-- Add uIP files manually because not all of them are included in the build ([TODO] why?)
local uip_files = " " .. utils.prepend_path( "uip_arp.c uip.c uiplib.c dhcpc.c psock.c resolv.c", "src/uip" )
addi{ { 'inc', 'inc/newlib', 'inc/remotefs', 'src/platform', 'src/lua' }, { 'src/modules', 'src/platform/' .. platform }, "src/uip", "src/fatfs" }
addm( "LUA_OPTIMIZE_MEMORY=" .. ( comp.optram and "2" or "0" ) )
addcf( { '-Os','-fomit-frame-pointer' } )
-- Toolset data (filled by each platform in part)
tools = {}
specific_files = ''
-- We get platform-specific data by executing the platform script
dofile( sf( "src/platform/%s/conf.lua", platform ) )
-- Complete file list
source_files = source_files .. uip_files .. specific_files
-------------------------------------------------------------------------------
-- Create compiler/linker/assembler command lines and build
-- ROM file system builder
local function make_romfs()
print "Building ROM file system ..."
local romdir = "romfs"
local flist = {}
for _, sample in pairs( file_list[ comp.board:upper() ] ) do
table.insert( flist, romfs[ sample ] )
end
flist = utils.linearize_array( flist )
if not mkfs.mkfs( romdir, "romfiles", flist, comp.romfs, fscompcmd ) then return -1 end
if utils.is_file( "inc/romfiles.h" ) then
-- Read both the old and the new file
local oldfile = io.open( "inc/romfiles.h", "rb" )
assert( oldfile )
local newfile = io.open( "romfiles.h", "rb" )
assert( newfile )
local olddata, newdata = oldfile:read( "*a" ), newfile:read( "*a" )
oldfile:close()
newfile:close()
-- If content is similar return '1' to builder to indicate that the target didn't really
-- produce a change even though it ran
if olddata == newdata then
os.remove( "romfiles.h" )
return 1
end
os.remove( "inc/romfiles.h" )
end
os.rename( "romfiles.h", "inc/romfiles.h" )
return 0
end
-- Generic 'prog' action function
local function genprog( target, deps )
local outname = deps[ 1 ]:target_name()
local outtype = target:find( "%.hex$" ) and "ihex" or "binary"
print( sf( "Generating binary image %s...", target ) )
os.execute( sf( "%s %s", toolset.size, outname ) )
os.execute( sf( "%s -O %s %s %s", toolset.bin, outtype, outname, target ) )
return 0
end
-- Generic 'size' action function
local function sizefunc( target, deps )
local outname = deps[ 1 ]:target_name()
os.execute( sf( "%s %s", toolset.size, outname ) )
return 0
end
-- Command lines for the tools (compiler, linker, assembler)
compcmd = compcmd or builder:compile_cmd{ flags = cflags, defines = cdefs, includes = includes, compiler = toolset.compile }
linkcmd = linkcmd or builder:link_cmd{ flags = lflags, libraries = libs, linker = toolset.compile }
ascmd = ascmd or builder:asm_cmd{ flags = asflags, defines = cdefs, includes = includes, assembler = toolset.asm }
builder:set_compile_cmd( compcmd )
builder:set_link_cmd( linkcmd )
builder:set_asm_cmd( ascmd )
builder:set_exe_extension( ".elf" )
-- Create the ROM file system
make_romfs()
-- Creaate executable targets
builder:make_depends( source_files )
odeps = builder:create_compile_targets( source_files )
exetarget = builder:link_target( output, odeps )
-- This is also the default target
builder:default( builder:add_target( exetarget, 'build eLua executable' ) )
-- Create 'prog' target(s)
local ptargets = {}
local progfunc = tools[ platform ].progfunc or genprog
utils.foreach( tools[ platform ].prog_flist, function( _, t )
local target = builder:target( t, { exetarget }, progfunc )
table.insert( ptargets, target )
end )
if #ptargets > 0 then
progtarget = builder:target( "#phony:prog", ptargets )
builder:add_target( progtarget, "build eLua firmware image", { "prog" } )
end
-- Create generic 'size' target
local size_target = builder:target( "#phony:size", { exetarget }, sizefunc )
size_target:force_rebuild( true )
builder:add_target( size_target, "shows the size of the eLua firmware", { "size" } )
-- If the backend needs to do more processing before the build starts, do it now
if tools[ platform ].pre_build then
tools[ platform ].pre_build()
end
-- Finally build everything
builder:build()