2011-04-12 16:34:42 +02:00
#! /usr/bin/env lua
2011-04-12 17:05:08 +02:00
--[[
build_elua.lua : A build script for eLua written in Lua .
2012-01-20 18:15:53 -06:00
2011-04-12 17:05:08 +02:00
The command line syntax is the same as for the old scons / SConstruct system .
See http : // www.eluaproject . net / en_building.html
The only required option is the target board or CPU . e.g . :
lua build_elua.lua board = MIZAR32
2012-01-20 18:15:53 -06:00
2011-04-12 17:05:08 +02:00
This script requires some well - known Lua libraries to run .
To install them on Ubuntu / Debian , go ( as root ) :
apt - get install luarocks
luarocks install luafilesystem
luarocks install lpack
luarocks install md5
--]]
2011-02-21 01:01:21 +00:00
local args = { ... }
local b = require " utils.build "
local mkfs = require " utils.mkfs "
2012-07-01 01:07:59 +03:00
local bconf = require " config.config "
local board_base_dir = " boards "
local bd = require " build_data "
2011-02-21 01:01:21 +00:00
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
2011-02-21 23:29:54 +00:00
-- 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
2011-02-21 01:01:21 +00:00
-- 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
-------------------------------------------------------------------------------
2012-07-01 01:07:59 +03:00
-- Return the full path of a board configuration file
local function get_conf_file_path ( bname )
local known_board_name = utils.concat_path ( { board_base_dir , " known " , bname .. " .lua " } )
local custom_board_name = utils.concat_path ( { board_base_dir , " custom " , bname .. " .lua " } )
if utils.is_file ( custom_board_name ) then return custom_board_name end
if utils.is_file ( known_board_name ) then return known_board_name end
assert ( sf ( " board configuration file for board '%s' not found! " , bname ) )
end
-- Automatically build the list of available boards by scanning the board_base_dir directory
local board_flist = utils.linearize_array ( utils.string_to_table ( utils.get_files ( board_base_dir , " %.lua$ " ) ) )
local board_list = { }
for k , v in pairs ( board_flist ) do
local temp = utils.replace_extension ( v , ' ' )
temp = utils.string_to_table ( temp , utils.dir_sep )
temp = temp [ # temp ] -- now 'temp' contains the actual name of the board
if not utils.array_element_index ( board_list , temp ) then board_list [ # board_list + 1 ] = temp end
2011-02-21 01:01:21 +00:00
end
2012-07-20 23:30:25 +03:00
-- Check a single command line option against the corresponding value in the build configuration
local function check_cmdline_vs_conf ( argname , comp , bd )
if bd [ argname ] then
if comp [ argname ] == " auto " then
comp [ argname ] = bd [ argname ]
elseif bd [ argname ] ~= comp [ argname ] then
if builder : is_user_option ( argname ) then
print ( utils.col_yellow ( sf ( " [CONFIG] WARNING: changing '%s' from '%s' to '%s' as specified in the command line " ,
argname , tostring ( bd [ argname ] ) , tostring ( comp [ argname ] ) ) ) )
else
comp [ argname ] = bd [ argname ]
end
end
end
end
2011-10-18 15:52:37 +03:00
builder : add_option ( ' target ' , ' build "regular" float lua, 32 bit integer-only "lualong" or 64-bit integer only lua "lualonglong" ' , ' lua ' , { ' lua ' , ' lualong ' , ' lualonglong ' } )
2011-02-21 01:01:21 +00:00
builder : add_option ( ' allocator ' , ' select memory allocator ' , ' auto ' , { ' newlib ' , ' multiple ' , ' simple ' , ' auto ' } )
2012-07-01 01:07:59 +03:00
builder : add_option ( ' board ' , ' selects board for target (cpu will be inferred) ' , nil , board_list )
builder : add_option ( ' toolchain ' , ' specifies toolchain to use (auto=search for usable toolchain) ' , ' auto ' , { bd.get_all_toolchains ( ) , ' auto ' } )
2011-02-21 01:01:21 +00:00
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 ' } )
2011-02-21 23:29:54 +00:00
builder : add_option ( ' cpumode ' , ' ARM CPU compilation mode (only affects certain ARM targets) ' , nil , { ' arm ' , ' thumb ' } )
2011-04-07 22:35:10 +03:00
builder : add_option ( ' bootloader ' , ' Build for bootloader usage (AVR32 only) ' , ' none ' , { ' none ' , ' emblod ' } )
2018-06-01 00:59:49 +03:00
builder : add_option ( ' debug ' , ' Enable debug build ' , false )
builder : add_option ( ' extras ' , ' Path to directory containing build extras ' , ' ' )
builder : add_option ( ' extrasconf ' , ' Config file for build extras, defaults to conf.lua ' , ' ' )
2012-10-17 00:22:47 +03:00
builder : add_option ( " output_dir " , " choose executable directory " , " . " )
builder : add_option ( " romfs_dir " , ' choose ROMFS directory ' , ' romfs ' )
builder : add_option ( " board_config_file " , " choose board configuration file " , " " )
builder : add_option ( " skip_conf " , " skip board configuration step, use pre-generated header file directly " , false )
2013-05-25 01:30:08 +03:00
builder : add_option ( " config_only " , " execute only the configurator, then exit " , false )
2011-02-21 01:01:21 +00:00
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 } )
2013-05-25 19:43:51 +03:00
local function dprint ( ... )
if comp.disp_mode ~= " minimal " then
print ( ... )
end
end
2012-07-01 01:07:59 +03:00
if not comp.board then
print " You must specify the board "
2011-02-21 01:01:21 +00:00
os.exit ( - 1 )
end
2012-07-01 01:07:59 +03:00
-- Interpret the board definition file
2012-10-17 00:22:47 +03:00
local bfopt , bfname = builder : get_option ( " board_config_file " )
if # bfopt > 0 then
if not utils.is_file ( bfopt ) then
print ( utils.col_red ( sf ( " [CONFIG] Error: board configuration file '%s' not found. " , bfopt ) ) )
os.exit ( - 1 )
end
bfname = bfopt
else
bfname = get_conf_file_path ( comp.board )
if not bfname then
print ( utils.col_red ( sf ( " [CONFIG] Error: board configuration file for board '%s' not found in '%s'. " , comp.board , board_base_dir ) ) )
os.exit ( - 1 )
end
2012-07-01 01:07:59 +03:00
end
2013-05-25 19:43:51 +03:00
dprint ( utils.col_blue ( " [CONFIG] Found board description file at " .. bfname ) )
2012-07-01 01:07:59 +03:00
local bdata , err = bconf.compile_board ( bfname , comp.board )
if not bdata then
2012-07-01 20:47:33 +03:00
print ( utils.col_red ( " [CONFIG] Error compiling board description file: " .. err ) )
2013-05-20 22:49:42 +03:00
return
2012-07-01 01:07:59 +03:00
end
-- Check if the file has changed. If not, do not rewrite it. This keeps the compilation time sane.
local bhname = utils.concat_path ( { board_base_dir , " headers " , " board_ " .. comp.board : lower ( ) .. " .h " } )
2012-10-17 00:22:47 +03:00
if builder : get_option ( " skip_conf " ) then
2013-05-25 19:43:51 +03:00
dprint ( utils.col_blue ( " [CONFIG] skipping generation of configuration file " ) )
2012-07-01 20:47:33 +03:00
else
2012-10-17 00:22:47 +03:00
if ( utils.get_hash_of_string ( bdata.header ) ~= utils.get_hash_of_file ( bhname ) or not utils.is_file ( bhname ) ) then
-- Save the header file
local f = assert ( io.open ( bhname , " wb " ) )
f : write ( bdata.header )
f : close ( )
2013-05-25 19:43:51 +03:00
dprint ( utils.col_blue ( " [CONFIG] Generated board header file at " .. bhname ) )
2012-10-17 00:22:47 +03:00
else
2013-05-25 19:43:51 +03:00
dprint ( utils.col_blue ( " [CONFIG] Board header file is unchanged. " ) )
2012-10-17 00:22:47 +03:00
end
2011-02-21 01:01:21 +00:00
end
2013-05-25 01:30:08 +03:00
if comp.config_only then return end
2012-07-01 01:07:59 +03:00
-- Define the correct CPU header for inclusion in the platform_conf.h file
addm ( ' ELUA_CPU_HEADER=" \\ "cpu_ ' .. bdata.cpu : lower ( ) .. ' .h \\ "" ' )
-- Define the correct board header for inclusion in the platform_conf.h file
addm ( ' ELUA_BOARD_HEADER=" \\ "board_ ' .. comp.board : lower ( ) .. ' .h \\ "" ' )
-- Make available the board directory for the generated header files
addi ( utils.concat_path { board_base_dir , " headers " } )
2012-07-20 23:30:25 +03:00
-- Force compilation flags if needed
if bdata.build then
utils.foreach ( { ' target ' , ' allocator ' , ' optram ' , ' boot ' , ' romfs ' , ' cpumode ' , ' bootloader ' } , function ( k , v )
check_cmdline_vs_conf ( v , comp , bdata.build )
end )
2012-07-01 20:47:33 +03:00
end
2012-07-01 01:07:59 +03:00
-- Automatically set the allocator to 'multiple' if needed
if bdata.multi_alloc and comp.allocator == " newlib " then
2012-07-01 20:47:33 +03:00
io.write ( utils.col_yellow ( " [CONFIG] WARNING: your board has non-contigous RAM areas, but you specified an allocator ('newlib') that can't handle this configuration. " ) )
print ( utils.col_yellow ( " Rebuild with another allocator ('multiple' or 'simple') " ) )
2012-07-01 01:07:59 +03:00
end
2012-07-14 19:59:42 +03:00
if comp.allocator == " auto " then comp.allocator = bdata.multi_alloc and " multiple " or " newlib " end
2012-07-01 01:07:59 +03:00
comp.cpu = bdata.cpu : upper ( )
2012-07-20 23:30:25 +03:00
if not comp.optram then
print ( utils.col_yellow ( " [CONFIG] WARNING: you have disabled Lua Tiny RAM (LTR). You might experience compilation issues. Also, some modules might not work correctly. " ) )
end
2012-07-01 01:07:59 +03:00
platform = bd.get_platform_of_cpu ( comp.cpu )
2011-02-21 01:01:21 +00:00
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
2012-07-01 01:07:59 +03:00
local usable_chains = bd.get_toolchains_of_platform ( platform )
2011-02-21 01:01:21 +00:00
if comp.toolchain ~= ' auto ' then
2012-07-01 01:07:59 +03:00
if utils.array_element_index ( usable_chains , comp.toolchain ) == nil then
2011-02-21 01:01:21 +00:00
print ( sf ( " Invalid toolchain '%s' for CPU '%s' " , comp.toolchain , comp.cpu ) )
2012-07-01 01:07:59 +03:00
print ( sf ( " List of accepted toolchains (for %s): %s " , comp.cpu , table.concat ( usable_chains , " , " ) ) )
2011-02-21 01:01:21 +00:00
os.exit ( - 1 )
end
2012-07-01 01:07:59 +03:00
toolset = bd.get_toolchain_data ( comp.toolchain )
2011-02-21 01:01:21 +00:00
comp.CC = toolset.compile
comp.AS = toolset.compile
else
-- If 'auto' try to match a working toolchain with target
-- Try to execute all compilers, exit when one found
local chain
for i = 1 , # usable_chains do
local c = usable_chains [ i ]
2012-07-01 01:07:59 +03:00
local t = bd.get_toolchain_data ( c )
2011-02-21 13:22:47 +00:00
local res = utils.check_command ( t.compile .. " " .. t.version )
2016-02-21 21:17:45 +01:00
if res == 0 or res == true then chain = c break end
2011-02-21 01:01:21 +00:00
end
if chain then
comp.toolchain = chain
2012-07-01 01:07:59 +03:00
toolset = bd.get_toolchain_data ( chain )
comp.CC = toolset.compile
2011-02-21 01:01:21 +00:00
comp.AS = comp.CC
else
print " Unable to find an usable toolchain in your path. "
2012-07-01 01:07:59 +03:00
print ( sf ( " List of accepted toolchains (for %s): %s " , comp.cpu , table.concat ( usable_chains , " , " ) ) )
2011-02-21 01:01:21 +00:00
os.exit ( - 1 )
end
2012-01-20 18:15:53 -06:00
end
2011-02-21 01:01:21 +00:00
-- Build the compilation command now
2011-02-21 23:29:54 +00:00
local fscompcmd = ' '
2011-02-21 01:01:21 +00:00
if comp.romfs == ' compile ' then
2011-10-18 15:52:37 +03:00
if comp.target == ' lualonglong ' then
2012-07-01 01:07:59 +03:00
print " Cross-compilation is not yet supported for 64-bit integer-only Lua (lualonglong). "
2011-10-18 15:52:37 +03:00
os.exit ( - 1 )
end
2011-02-21 01:01:21 +00:00
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 ( ) ) }
2018-06-01 00:59:49 +03:00
dprint ( " Cross compile command: " .. cmdpath [ 2 ] )
2011-02-21 23:29:54 +00:00
fscompcmd = table.concat ( cmdpath , utils.dir_sep )
2011-02-21 01:01:21 +00:00
elseif comp.romfs == ' compress ' then
2018-06-01 00:59:49 +03:00
if comp.target == ' lualong ' or comp.target == ' lualonglong ' then fscompoptnums = ' --noopt-numbers ' else fscompoptnums = ' --opt-numbers ' end
2014-04-14 14:53:49 -05:00
fscompcmd = ' lua luasrcdiet.lua --quiet --maximum --opt-comments --opt-whitespace --opt-emptylines --opt-eols --opt-strings ' .. fscompoptnums .. ' --opt-locals -o %s %s '
2011-02-21 01:01:21 +00:00
end
2011-11-28 22:32:42 -06:00
-- Determine build version
2012-01-21 16:23:31 -06:00
if utils.check_command ( ' git describe --always ' ) == 0 then
2012-01-20 18:15:53 -06:00
addm ( " USE_GIT_REVISION " )
2011-11-28 22:32:42 -06:00
elua_vers = utils.exec_capture ( ' git describe --always ' )
-- If purely hexadecimal (no tag reference) prepend 'dev-'
if string.find ( elua_vers , " ^[+-]?%x+$ " ) then
elua_vers = ' dev- ' .. elua_vers
end
2012-07-01 01:07:59 +03:00
local sver = utils.gen_header_string ( ' git_version ' , { elua_version = elua_vers , elua_str_version = ( " \" " .. elua_vers .. " \" " ) } )
if utils.get_hash_of_string ( sver ) ~= utils.get_hash_of_file ( utils.concat_path { ' inc ' , ' git_version.h ' } ) then
utils.gen_header_file ( ' git_version ' , { elua_version = elua_vers , elua_str_version = ( " \" " .. elua_vers .. " \" " ) } )
end
2012-01-20 18:15:53 -06:00
else
print " WARNING: unable to determine version from repository "
elua_vers = " unknown "
2011-11-28 22:32:42 -06:00
end
2012-10-17 00:22:47 +03:00
-- Create the output directory if it is not created yet
local outd = builder : get_option ( " output_dir " )
if not utils.is_dir ( outd ) then
if not utils.full_mkdir ( outd ) then
print ( " [builder] Unable to create directory " .. outd )
os.exit ( 1 )
end
end
2011-02-21 01:01:21 +00:00
-- Output file
2013-05-25 19:43:51 +03:00
output = outd .. utils.dir_sep .. ' elua_ ' .. comp.target .. ' _ ' .. comp.board : lower ( )
2012-10-15 23:45:25 +03:00
builder : set_build_dir ( builder : get_build_dir ( ) .. utils.dir_sep .. comp.board : lower ( ) )
2011-02-21 01:01:21 +00:00
-- User report
2013-05-25 19:43:51 +03:00
dprint " "
dprint " ********************************* "
dprint " Compiling eLua ... "
dprint ( " CPU: " , comp.cpu )
dprint ( " Board: " , comp.board )
dprint ( " Platform: " , platform )
dprint ( " Allocator: " , comp.allocator )
dprint ( " Boot Mode: " , comp.boot )
dprint ( " Target: " , comp.target )
dprint ( " Toolchain: " , comp.toolchain )
dprint ( " ROMFS mode: " , comp.romfs )
2018-06-01 00:59:49 +03:00
dprint ( " Debug: " , comp.debug )
if comp.extras ~= ' ' then
dprint ( " Extras: " , comp.extras )
end
if comp.extrasconf ~= ' ' then
dprint ( " Extras conf: " , comp.extrasconf )
end
2013-05-25 19:43:51 +03:00
dprint ( " Version: " , elua_vers )
dprint " ********************************* "
dprint " "
2011-02-21 01:01:21 +00:00
-- 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
2011-03-06 03:29:31 +02:00
if comp.boot == ' luarpc ' then addm ( " ELUA_BOOT_RPC " ) end
2011-10-18 15:52:37 +03:00
if comp.target == ' lualong ' or comp.target == ' lualonglong ' then addm ( " LUA_NUMBER_INTEGRAL " ) end
if comp.target == ' lualonglong ' then addm ( " LUA_INTEGRAL_LONGLONG " ) end
2012-04-18 18:21:27 +03:00
if comp.target ~= ' lualong ' and comp.target ~= " lualonglong " then addm ( " LUA_PACK_VALUE " ) end
2012-07-01 01:07:59 +03:00
if bd.get_endianness_of_platform ( platform ) == " big " then addm ( " ELUA_ENDIAN_BIG " ) else addm ( " ELUA_ENDIAN_LITTLE " ) end
2011-02-21 01:01:21 +00:00
2012-07-01 01:07:59 +03:00
-- Special macro definitions for the SIM target
2011-03-06 03:29:31 +02:00
if platform == ' sim ' then addm ( { " ELUA_SIMULATOR " , " ELUA_SIM_ " .. cnorm ( comp.cpu ) } ) end
2011-02-21 01:01:21 +00:00
-- Lua source files and include path
2011-06-24 18:24:24 -05:00
exclude_patterns = { " ^src/platform " , " ^src/uip " , " ^src/serial " , " ^src/luarpc_desktop_serial.c " , " ^src/linenoise_posix.c " , " ^src/lua/print.c " , " ^src/lua/luac.c " }
2011-03-06 13:06:45 +02:00
local source_files = utils.get_files ( " src " , function ( fname )
2012-01-20 18:15:53 -06:00
fname = fname : gsub ( " \\ " , " / " )
2011-03-06 03:29:31 +02:00
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?)
2012-02-19 18:25:37 +01:00
local uip_files = " " .. utils.prepend_path ( " uip_arp.c uip.c uiplib.c dhcpc.c psock.c resolv.c uip-neighbor.c " , " src/uip " )
2011-02-21 01:01:21 +00:00
2018-05-19 23:02:27 +03:00
addi { { ' inc ' , ' inc/newlib ' , ' inc/remotefs ' , ' src/platform ' , ' src/lua ' } , { ' src/modules ' , ' src/platform/ ' .. platform , ' src/platform/ ' .. platform .. ' /cpus ' } , " src/uip " , " src/fatfs " , " inc/niffs " }
2011-02-21 01:01:21 +00:00
addm ( " LUA_OPTIMIZE_MEMORY= " .. ( comp.optram and " 2 " or " 0 " ) )
addcf ( { ' -Os ' , ' -fomit-frame-pointer ' } )
2018-06-01 00:59:49 +03:00
if comp.debug == true then
addcf ( { ' -g ' } )
end
2011-02-21 01:01:21 +00:00
-- Toolset data (filled by each platform in part)
tools = { }
specific_files = ' '
2018-06-01 00:59:49 +03:00
extras_files = ' '
2011-02-21 01:01:21 +00:00
-- We get platform-specific data by executing the platform script
dofile ( sf ( " src/platform/%s/conf.lua " , platform ) )
2018-06-01 00:59:49 +03:00
-- Read the extra configuration if needed. This can set
-- the extra files to compile in the 'extras_files' variable.
if comp.extras ~= ' ' then
if comp.extrasconf ~= ' ' then
dofile ( sf ( " %s/%s " , comp.extras , comp.extrasconf ) )
else
dofile ( sf ( " %s/conf.lua " , comp.extras ) )
end
end
2011-02-21 01:01:21 +00:00
-- Complete file list
2018-06-01 00:59:49 +03:00
source_files = source_files .. uip_files .. specific_files .. extras_files
2011-02-21 01:01:21 +00:00
-------------------------------------------------------------------------------
-- Create compiler/linker/assembler command lines and build
2011-11-20 20:38:36 -06:00
-- ROM file system builder
2011-11-20 20:36:44 -06:00
romfs_exclude_patterns = { ' %.DS_Store ' , ' %.gitignore ' }
function match_pattern_list ( item , list )
for k , v in pairs ( list ) do
2012-07-01 01:07:59 +03:00
if item : find ( v ) then return true end
2011-11-20 20:36:44 -06:00
end
end
2012-07-01 20:47:33 +03:00
local function make_romfs ( target , deps )
2011-02-21 01:01:21 +00:00
print " Building ROM file system ... "
2012-10-17 00:22:47 +03:00
local romdir = builder : get_option ( " romfs_dir " )
2011-02-21 01:01:21 +00:00
local flist = { }
2012-10-15 23:45:25 +03:00
flist = utils.string_to_table ( utils.get_files ( romdir , function ( fname ) return not match_pattern_list ( fname , romfs_exclude_patterns ) end ) )
2012-01-20 18:15:53 -06:00
flist = utils.linearize_array ( flist )
2011-06-23 11:50:58 +03:00
for k , v in pairs ( flist ) do
2012-10-15 23:45:25 +03:00
flist [ k ] = v : gsub ( romdir .. utils.dir_sep , " " )
2011-06-23 11:50:58 +03:00
end
2011-11-20 20:36:44 -06:00
2012-10-15 23:45:25 +03:00
if not mkfs.mkfs ( romdir , " romfiles " , flist , comp.romfs , fscompcmd ) then return - 1 end
2011-02-21 01:01:21 +00:00
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
2012-01-20 18:15:53 -06:00
if olddata == newdata then
2011-02-21 01:01:21 +00:00
os.remove ( " romfiles.h " )
2012-01-20 18:15:53 -06:00
return 1
2011-02-21 01:01:21 +00:00
end
os.remove ( " inc/romfiles.h " )
end
os.rename ( " romfiles.h " , " inc/romfiles.h " )
return 0
end
2011-02-27 18:31:09 +00:00
-- 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
2011-02-21 13:22:47 +00:00
-- Command lines for the tools (compiler, linker, assembler)
2011-02-21 23:29:54 +00:00
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 }
2013-05-25 19:43:51 +03:00
builder : set_exe_extension ( " .elf " )
2011-02-21 01:01:21 +00:00
builder : set_compile_cmd ( compcmd )
builder : set_link_cmd ( linkcmd )
builder : set_asm_cmd ( ascmd )
2012-07-01 20:47:33 +03:00
-- Create the ROMFS target
local romfs_target = builder : target ( " #phony:romfs " , nil , make_romfs )
romfs_target : force_rebuild ( true )
-- Create executable targets
2011-02-21 13:22:47 +00:00
odeps = builder : create_compile_targets ( source_files )
2012-07-01 20:47:33 +03:00
exetarget = builder : link_target ( output , { romfs_target , odeps } )
2011-02-21 01:01:21 +00:00
-- This is also the default target
2011-02-21 13:22:47 +00:00
builder : default ( builder : add_target ( exetarget , ' build eLua executable ' ) )
2011-02-21 01:01:21 +00:00
2011-02-27 18:31:09 +00:00
-- 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 " } )
2011-02-21 13:22:47 +00:00
-- 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
2011-02-21 01:01:21 +00:00
-- Finally build everything
builder : build ( )