bd0133ad37
site_code is evaluated early during config generation, so a site.conf without site_code would hit this assertion that just printed 'Assertion failed'. Add a proper error message to tell users what went wrong. The inner assert() is removed, as it should never be hit (as site.conf syntax will have already been validated when this script runs), and it doesn't add anything (even without the assert, the attempt to index a nil value would throw an error).
341 lines
6.6 KiB
Lua
341 lines
6.6 KiB
Lua
-- Functions for use in targets/*
|
|
local F = {}
|
|
|
|
-- To be accessed by scripts using target_lib
|
|
local M = setmetatable({}, { __index = F })
|
|
|
|
local funcs = setmetatable({}, {
|
|
__index = function(_, k)
|
|
return F[k] or _G[k]
|
|
end,
|
|
})
|
|
|
|
local env = setmetatable({}, {
|
|
__index = function(_, k) return os.getenv(k) end
|
|
})
|
|
F.env = env
|
|
|
|
assert(env.GLUON_SITEDIR)
|
|
assert(env.GLUON_TARGETSDIR)
|
|
assert(env.GLUON_RELEASE)
|
|
assert(env.GLUON_DEPRECATED)
|
|
|
|
|
|
M.site_code = assert(
|
|
dofile('scripts/site_config.lua')('site.conf').site_code, 'site_code missing in site.conf'
|
|
)
|
|
M.target_packages = {}
|
|
M.configs = {}
|
|
M.devices = {}
|
|
M.images = {}
|
|
M.opkg = true
|
|
|
|
|
|
local default_options = {
|
|
profile = false,
|
|
factory = '-squashfs-factory',
|
|
factory_ext = '.bin',
|
|
sysupgrade = '-squashfs-sysupgrade',
|
|
sysupgrade_ext = '.bin',
|
|
extra_images = {},
|
|
aliases = {},
|
|
manifest_aliases = {},
|
|
packages = {},
|
|
class = 'standard',
|
|
deprecated = false,
|
|
broken = false,
|
|
}
|
|
|
|
|
|
local gluon_devices, unknown_devices = {}, {}
|
|
for dev in string.gmatch(env.GLUON_DEVICES or '', '%S+') do
|
|
gluon_devices[dev] = true
|
|
unknown_devices[dev] = true
|
|
end
|
|
|
|
function F.istrue(v)
|
|
return (tonumber(v) or 0) > 0
|
|
end
|
|
|
|
local function want_device(dev, options)
|
|
if options.broken and not F.istrue(env.BROKEN) then
|
|
return false
|
|
end
|
|
if options.deprecated and env.GLUON_DEPRECATED == '0' then
|
|
return false
|
|
end
|
|
|
|
if (env.GLUON_DEVICES or '') == '' then
|
|
return true
|
|
end
|
|
|
|
unknown_devices[dev] = nil
|
|
return gluon_devices[dev]
|
|
end
|
|
|
|
local full_deprecated = env.GLUON_DEPRECATED == 'full'
|
|
|
|
|
|
local function merge(a, b)
|
|
local ret = {}
|
|
for k, v in pairs(a) do
|
|
ret[k] = v
|
|
end
|
|
for k, v in pairs(b or {}) do
|
|
assert(ret[k] ~= nil, string.format("unknown option '%s'", k))
|
|
ret[k] = v
|
|
end
|
|
return ret
|
|
end
|
|
|
|
-- Escapes a single argument to be used in a shell command
|
|
-- The argument is surrounded by single quotes, single quotes inside the
|
|
-- argument are replaced by '\''.
|
|
-- To allow using shell wildcards, zero bytes in the arguments are replaced
|
|
-- by unquoted asterisks.
|
|
function F.escape(s)
|
|
s = string.gsub(s, "'", "'\\''")
|
|
s = string.gsub(s, "%z", "'*'")
|
|
return "'" .. s .. "'"
|
|
end
|
|
|
|
local function escape_command(command, raw)
|
|
local ret = ''
|
|
if not raw then
|
|
ret = 'exec'
|
|
end
|
|
for _, arg in ipairs(command) do
|
|
ret = ret .. ' ' .. F.escape(arg)
|
|
end
|
|
if raw then
|
|
ret = ret .. ' ' .. raw
|
|
end
|
|
return ret
|
|
end
|
|
|
|
function F.exec_raw(command, may_fail)
|
|
local ret = os.execute(command)
|
|
assert((ret == 0) or may_fail)
|
|
return ret
|
|
end
|
|
|
|
function F.exec(command, may_fail, raw)
|
|
return F.exec_raw(escape_command(command, raw), may_fail)
|
|
end
|
|
|
|
function F.exec_capture_raw(command)
|
|
local f = io.popen(command)
|
|
assert(f)
|
|
|
|
local data = f:read('*a')
|
|
f:close()
|
|
return data
|
|
end
|
|
|
|
function F.exec_capture(command, raw)
|
|
return F.exec_capture_raw(escape_command(command, raw))
|
|
end
|
|
|
|
|
|
local image_mt = {
|
|
__index = {
|
|
dest_name = function(image, name, site, release)
|
|
return env.GLUON_IMAGEDIR..'/'..image.subdir,
|
|
'gluon-'..(site or M.site_code)..'-'..(release or env.GLUON_RELEASE)..'-'..name..image.out_suffix..image.extension
|
|
end,
|
|
},
|
|
}
|
|
|
|
local function add_image(image)
|
|
local device = image.image
|
|
M.images[device] = M.images[device] or {}
|
|
table.insert(M.images[device], setmetatable(image, image_mt))
|
|
end
|
|
|
|
|
|
local function format_config(k, v)
|
|
local format
|
|
if type(v) == 'string' then
|
|
format = '%s=%q'
|
|
elseif v == true then
|
|
format = '%s=y'
|
|
elseif v == nil then
|
|
format = '%s=m'
|
|
elseif v == false then
|
|
format = '# %s is not set'
|
|
else
|
|
format = '%s=%d'
|
|
end
|
|
return string.format(format, 'CONFIG_' .. k, v)
|
|
end
|
|
|
|
local config_mt = {
|
|
__index = {
|
|
format = function(config)
|
|
return format_config(config.key, config.value)
|
|
end,
|
|
}
|
|
}
|
|
|
|
local function do_config(k, v, required)
|
|
M.configs[k] = setmetatable({
|
|
key = k,
|
|
value = v,
|
|
required = required,
|
|
}, config_mt)
|
|
end
|
|
|
|
function F.try_config(k, v)
|
|
do_config(k, v)
|
|
end
|
|
|
|
function F.config(k, v, message)
|
|
if not message then
|
|
message = string.format("unable to set '%s'", format_config(k, v))
|
|
end
|
|
do_config(k, v, message)
|
|
end
|
|
|
|
|
|
function F.packages(pkgs)
|
|
for _, pkg in ipairs(pkgs) do
|
|
table.insert(M.target_packages, pkg)
|
|
end
|
|
end
|
|
M.packages = F.packages
|
|
|
|
local function as_table(v)
|
|
if type(v) == 'table' then
|
|
return v
|
|
else
|
|
return {v}
|
|
end
|
|
end
|
|
|
|
function F.device(image, name, options)
|
|
options = merge(default_options, options)
|
|
|
|
if not want_device(image, options) then
|
|
return
|
|
end
|
|
|
|
table.insert(M.devices, {
|
|
image = image,
|
|
name = name,
|
|
options = options,
|
|
})
|
|
|
|
if options.sysupgrade then
|
|
add_image {
|
|
image = image,
|
|
name = name,
|
|
subdir = 'sysupgrade',
|
|
in_suffix = options.sysupgrade,
|
|
out_suffix = '-sysupgrade',
|
|
extension = options.sysupgrade_ext,
|
|
aliases = options.aliases,
|
|
manifest_aliases = options.manifest_aliases,
|
|
}
|
|
end
|
|
|
|
if options.deprecated and not full_deprecated then
|
|
return
|
|
end
|
|
|
|
if options.factory then
|
|
for _, ext in ipairs(as_table(options.factory_ext)) do
|
|
add_image {
|
|
image = image,
|
|
name = name,
|
|
subdir = 'factory',
|
|
in_suffix = options.factory,
|
|
out_suffix = '',
|
|
extension = ext,
|
|
aliases = options.aliases,
|
|
}
|
|
end
|
|
end
|
|
for _, extra_image in ipairs(options.extra_images) do
|
|
add_image {
|
|
image = image,
|
|
name = name,
|
|
subdir = 'other',
|
|
in_suffix = extra_image[1],
|
|
out_suffix = extra_image[2],
|
|
extension = extra_image[3],
|
|
aliases = options.aliases,
|
|
}
|
|
end
|
|
end
|
|
|
|
function F.factory_image(image, name, ext, options)
|
|
options = merge(default_options, options)
|
|
|
|
if not want_device(image, options) then
|
|
return
|
|
end
|
|
|
|
if options.deprecated and not full_deprecated then
|
|
return
|
|
end
|
|
|
|
add_image {
|
|
image = image,
|
|
name = name,
|
|
subdir = 'factory',
|
|
in_suffix = '',
|
|
out_suffix = '',
|
|
extension = ext,
|
|
aliases = options.aliases,
|
|
}
|
|
end
|
|
|
|
function F.sysupgrade_image(image, name, ext, options)
|
|
options = merge(default_options, options)
|
|
|
|
if not want_device(image, options) then
|
|
return
|
|
end
|
|
|
|
add_image {
|
|
image = image,
|
|
name = name,
|
|
subdir = 'sysupgrade',
|
|
in_suffix = '',
|
|
out_suffix = '-sysupgrade',
|
|
extension = ext,
|
|
aliases = options.aliases,
|
|
manifest_aliases = options.manifest_aliases,
|
|
}
|
|
end
|
|
|
|
function F.no_opkg()
|
|
M.opkg = false
|
|
end
|
|
|
|
function F.defaults(options)
|
|
default_options = merge(default_options, options)
|
|
end
|
|
|
|
function F.include(name)
|
|
local f = assert(loadfile(env.GLUON_TARGETSDIR .. '/' .. name))
|
|
setfenv(f, funcs)
|
|
return f()
|
|
end
|
|
|
|
|
|
function M.check_devices()
|
|
local device_list = {}
|
|
for device in pairs(unknown_devices) do
|
|
table.insert(device_list, device)
|
|
end
|
|
if #device_list ~= 0 then
|
|
table.sort(device_list)
|
|
io.stderr:write('Error: unknown devices given: ', table.concat(device_list, ' '), '\n')
|
|
os.exit(1)
|
|
end
|
|
end
|
|
|
|
|
|
return M
|