build: rework config generation
So far, we were using a sort operation on the generated .config to implement precedence of =y packages over =m, and =m over unset. Unfortunately, this sort not only used for packages, but for all config lines. This made it impossible to override settings from targets/generic in a target config when the new setting was sorted before the generic setting. To fix this, track configurations by their keys, so we can properly override config keys that were set before. Value-based precedence is only preserved for package configuration. The config() and try_config() calls always take key and value as separate arguments now. Strings are quoted automatically; the values true, nil and false map to y, m and unset for tristate options. config() can take an optional third argument to override the error message to display when the setting fails to apply. All existing target configs generate the same .config with the old and the new code. The new code is also a bit faster on targets with many devices.
This commit is contained in:
parent
97e5434b32
commit
9e23534ec3
@ -1,24 +1,5 @@
|
|||||||
local funcs = {}
|
local lib = dofile('scripts/target_config_lib.lua')()
|
||||||
|
|
||||||
function funcs.config_message(config, _, ...)
|
for _, config in pairs(lib.configs) do
|
||||||
config(...)
|
io.stdout:write(config:format(), '\n')
|
||||||
end
|
|
||||||
|
|
||||||
function funcs.config_package(config, pkg, value)
|
|
||||||
config('CONFIG_PACKAGE_%s=%s', pkg, value)
|
|
||||||
end
|
|
||||||
|
|
||||||
local lib = dofile('scripts/target_config_lib.lua')(funcs)
|
|
||||||
|
|
||||||
|
|
||||||
local output = {}
|
|
||||||
|
|
||||||
for config in pairs(lib.configs) do
|
|
||||||
table.insert(output, config)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- The sort will make =y entries override =m ones
|
|
||||||
table.sort(output)
|
|
||||||
for _, line in ipairs(output) do
|
|
||||||
io.stdout:write(line, '\n')
|
|
||||||
end
|
end
|
||||||
|
@ -1,17 +1,13 @@
|
|||||||
local errors = {}
|
local errors = false
|
||||||
|
|
||||||
|
local function fail(msg)
|
||||||
local function fail(...)
|
if not errors then
|
||||||
if not next(errors) then
|
errors = true
|
||||||
io.stderr:write('Configuration failed:', '\n')
|
io.stderr:write('Configuration failed:', '\n')
|
||||||
end
|
end
|
||||||
|
|
||||||
local msg = string.format(...)
|
|
||||||
if not errors[msg] then
|
|
||||||
errors[msg] = true
|
|
||||||
io.stderr:write(' * ', msg, '\n')
|
io.stderr:write(' * ', msg, '\n')
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
local function match_config(f)
|
local function match_config(f)
|
||||||
for line in io.lines('openwrt/.config') do
|
for line in io.lines('openwrt/.config') do
|
||||||
@ -23,49 +19,21 @@ local function match_config(f)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
local function check_config(pattern)
|
local function check_config(config)
|
||||||
return match_config(function(line) return line == pattern end)
|
return match_config(function(line) return line == config end)
|
||||||
end
|
|
||||||
|
|
||||||
local function check_config_prefix(pattern)
|
|
||||||
return match_config(function(line) return string.sub(line, 1, -2) == pattern end)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local funcs = {}
|
local lib = dofile('scripts/target_config_lib.lua')()
|
||||||
|
|
||||||
function funcs.config_message(_, message, ...)
|
for _, config in pairs(lib.configs) do
|
||||||
local pattern = string.format(...)
|
if config.required then
|
||||||
|
if not check_config(config:format()) then
|
||||||
if not check_config(pattern) then
|
fail(config.required)
|
||||||
fail('%s', message)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function funcs.config_package(_, pkg, value)
|
|
||||||
local pattern = string.format('CONFIG_PACKAGE_%s=%s', pkg, value)
|
|
||||||
local res
|
|
||||||
if value == 'y' then
|
|
||||||
res = check_config(pattern)
|
|
||||||
else
|
|
||||||
res = check_config_prefix(string.sub(pattern, 1, -2))
|
|
||||||
end
|
|
||||||
|
|
||||||
if not res then
|
|
||||||
fail("unable to enable package '%s'", pkg)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local lib = dofile('scripts/target_config_lib.lua')(funcs)
|
|
||||||
|
|
||||||
for config, v in pairs(lib.configs) do
|
|
||||||
if v == 2 then
|
|
||||||
if not check_config(config) then
|
|
||||||
fail("unable to set '%s'", config)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if next(errors) then
|
if errors then
|
||||||
os.exit(1)
|
os.exit(1)
|
||||||
end
|
end
|
||||||
|
@ -40,7 +40,7 @@ local function compact_list(list, keep_neg)
|
|||||||
return ret
|
return ret
|
||||||
end
|
end
|
||||||
|
|
||||||
return function(funcs)
|
return function()
|
||||||
local lib = dofile('scripts/target_lib.lua')
|
local lib = dofile('scripts/target_lib.lua')
|
||||||
local env = lib.env
|
local env = lib.env
|
||||||
|
|
||||||
@ -102,12 +102,29 @@ END_MAKE
|
|||||||
return pkgs
|
return pkgs
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local enabled_packages = {}
|
||||||
|
-- Arguments: package name and config value (true: y, nil: m, false: unset)
|
||||||
|
-- Ensures precedence of y > m > unset
|
||||||
|
local function config_package(pkg, v)
|
||||||
|
if v == false then
|
||||||
|
if not enabled_packages[pkg] then
|
||||||
|
lib.try_config('CONFIG_PACKAGE_' .. pkg, false)
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if v == true or not enabled_packages[pkg] then
|
||||||
|
lib.config('CONFIG_PACKAGE_' .. pkg, v, string.format("unable to enable package '%s'", pkg))
|
||||||
|
enabled_packages[pkg] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local function handle_target_pkgs(pkgs)
|
local function handle_target_pkgs(pkgs)
|
||||||
for _, pkg in ipairs(pkgs) do
|
for _, pkg in ipairs(pkgs) do
|
||||||
if string.sub(pkg, 1, 1) == '-' then
|
if string.sub(pkg, 1, 1) == '-' then
|
||||||
lib.try_config('# CONFIG_PACKAGE_%s is not set', string.sub(pkg, 2))
|
config_package(string.sub(pkg, 2), false)
|
||||||
else
|
else
|
||||||
funcs.config_package(lib.config, pkg, 'y')
|
config_package(pkg, true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -118,8 +135,8 @@ END_MAKE
|
|||||||
lib.check_devices()
|
lib.check_devices()
|
||||||
|
|
||||||
if not lib.opkg then
|
if not lib.opkg then
|
||||||
lib.config '# CONFIG_SIGNED_PACKAGES is not set'
|
lib.config('CONFIG_SIGNED_PACKAGES', false)
|
||||||
lib.config 'CONFIG_CLEAN_IPKG=y'
|
lib.config('CONFIG_CLEAN_IPKG', true)
|
||||||
lib.packages {'-opkg'}
|
lib.packages {'-opkg'}
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -133,7 +150,7 @@ END_MAKE
|
|||||||
local function handle_pkgs(pkgs)
|
local function handle_pkgs(pkgs)
|
||||||
for _, pkg in ipairs(pkgs) do
|
for _, pkg in ipairs(pkgs) do
|
||||||
if string.sub(pkg, 1, 1) ~= '-' then
|
if string.sub(pkg, 1, 1) ~= '-' then
|
||||||
funcs.config_package(lib.config, pkg, 'm')
|
config_package(pkg, nil)
|
||||||
end
|
end
|
||||||
device_pkgs = append_to_list(device_pkgs, pkg)
|
device_pkgs = append_to_list(device_pkgs, pkg)
|
||||||
end
|
end
|
||||||
@ -144,11 +161,15 @@ END_MAKE
|
|||||||
handle_pkgs(dev.options.packages or {})
|
handle_pkgs(dev.options.packages or {})
|
||||||
handle_pkgs(site_packages(dev.image))
|
handle_pkgs(site_packages(dev.image))
|
||||||
|
|
||||||
funcs.config_message(lib.config, string.format("unable to enable device '%s'", profile),
|
lib.config(
|
||||||
'CONFIG_TARGET_DEVICE_%s_DEVICE_%s=y', openwrt_config_target, profile)
|
string.format('CONFIG_TARGET_DEVICE_%s_DEVICE_%s', openwrt_config_target, profile),
|
||||||
lib.config('CONFIG_TARGET_DEVICE_PACKAGES_%s_DEVICE_%s="%s"',
|
true,
|
||||||
openwrt_config_target, profile,
|
string.format("unable to enable device '%s'", profile)
|
||||||
table.concat(device_pkgs, ' '))
|
)
|
||||||
|
lib.config(
|
||||||
|
string.format('CONFIG_TARGET_DEVICE_PACKAGES_%s_DEVICE_%s', openwrt_config_target, profile),
|
||||||
|
table.concat(device_pkgs, ' ')
|
||||||
|
)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- x86 fallback: no devices
|
-- x86 fallback: no devices
|
||||||
|
@ -150,14 +150,51 @@ local function add_image(image)
|
|||||||
table.insert(M.images[device], setmetatable(image, image_mt))
|
table.insert(M.images[device], setmetatable(image, image_mt))
|
||||||
end
|
end
|
||||||
|
|
||||||
function F.try_config(...)
|
|
||||||
M.configs[string.format(...)] = 1
|
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, k, v)
|
||||||
end
|
end
|
||||||
|
|
||||||
function F.config(...)
|
local config_mt = {
|
||||||
M.configs[string.format(...)] = 2
|
__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
|
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)
|
function F.packages(pkgs)
|
||||||
for _, pkg in ipairs(pkgs) do
|
for _, pkg in ipairs(pkgs) do
|
||||||
table.insert(M.target_packages, pkg)
|
table.insert(M.target_packages, pkg)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
config 'CONFIG_GLUON_SPECIALIZE_KERNEL=y'
|
config('CONFIG_GLUON_SPECIALIZE_KERNEL', true)
|
||||||
config 'CONFIG_TARGET_SQUASHFS_BLOCK_SIZE=64'
|
config('CONFIG_TARGET_SQUASHFS_BLOCK_SIZE', 64)
|
||||||
|
|
||||||
local ATH10K_PACKAGES = {
|
local ATH10K_PACKAGES = {
|
||||||
'kmod-ath10k',
|
'kmod-ath10k',
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
config 'CONFIG_GLUON_SPECIALIZE_KERNEL=y'
|
config('CONFIG_GLUON_SPECIALIZE_KERNEL', true)
|
||||||
|
|
||||||
defaults {
|
defaults {
|
||||||
factory = false,
|
factory = false,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
config 'CONFIG_GLUON_SPECIALIZE_KERNEL=y'
|
config('CONFIG_GLUON_SPECIALIZE_KERNEL', true)
|
||||||
|
|
||||||
local ATH10K_PACKAGES = {'kmod-ath10k', '-kmod-ath10k-ct', 'ath10k-firmware-qca988x', '-ath10k-firmware-qca988x-ct'}
|
local ATH10K_PACKAGES = {'kmod-ath10k', '-kmod-ath10k-ct', 'ath10k-firmware-qca988x', '-ath10k-firmware-qca988x-ct'}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
config 'CONFIG_GLUON_SPECIALIZE_KERNEL=y'
|
config('CONFIG_GLUON_SPECIALIZE_KERNEL', true)
|
||||||
|
|
||||||
no_opkg()
|
no_opkg()
|
||||||
|
|
||||||
|
@ -1,21 +1,21 @@
|
|||||||
assert(env.GLUON_LANGS)
|
assert(env.GLUON_LANGS)
|
||||||
|
|
||||||
|
|
||||||
config('CONFIG_GLUON_SITEDIR="%s"', env.GLUON_SITEDIR)
|
config('CONFIG_GLUON_SITEDIR', env.GLUON_SITEDIR)
|
||||||
config('CONFIG_GLUON_RELEASE="%s"', env.GLUON_RELEASE)
|
config('CONFIG_GLUON_RELEASE', env.GLUON_RELEASE)
|
||||||
try_config('CONFIG_GLUON_BRANCH="%s"', env.GLUON_BRANCH or '')
|
try_config('CONFIG_GLUON_BRANCH', env.GLUON_BRANCH or '')
|
||||||
|
|
||||||
for lang in string.gmatch(env.GLUON_LANGS, '%S+') do
|
for lang in string.gmatch(env.GLUON_LANGS, '%S+') do
|
||||||
try_config('CONFIG_GLUON_WEB_LANG_%s=y', lang)
|
try_config('CONFIG_GLUON_WEB_LANG_' .. lang, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
config('CONFIG_TARGET_%s=y', env.BOARD)
|
config('CONFIG_TARGET_' .. env.BOARD, true)
|
||||||
if env.SUBTARGET ~= '' then
|
if env.SUBTARGET ~= '' then
|
||||||
config('CONFIG_TARGET_%s_%s=y', env.BOARD, env.SUBTARGET)
|
config(string.format('CONFIG_TARGET_%s_%s', env.BOARD, env.SUBTARGET), true)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Disable non-default feeds in distfeeds.conf
|
-- Disable non-default feeds in distfeeds.conf
|
||||||
config('# CONFIG_FEED_gluon_base is not set')
|
config('CONFIG_FEED_gluon_base', false)
|
||||||
|
|
||||||
local default_feeds = {}
|
local default_feeds = {}
|
||||||
for feed in string.gmatch(exec_capture_raw('. scripts/default_feeds.sh && echo "$DEFAULT_FEEDS"'), '%S+') do
|
for feed in string.gmatch(exec_capture_raw('. scripts/default_feeds.sh && echo "$DEFAULT_FEEDS"'), '%S+') do
|
||||||
@ -24,52 +24,46 @@ end
|
|||||||
|
|
||||||
for feed in string.gmatch(exec_capture_raw('. scripts/modules.sh && echo -n "$FEEDS"'), '%S+') do
|
for feed in string.gmatch(exec_capture_raw('. scripts/modules.sh && echo -n "$FEEDS"'), '%S+') do
|
||||||
if not default_feeds[feed] then
|
if not default_feeds[feed] then
|
||||||
config('# CONFIG_FEED_%s is not set', feed)
|
config('CONFIG_FEED_' .. feed, false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
config '# CONFIG_TARGET_ROOTFS_INITRAMFS is not set'
|
config('CONFIG_TARGET_ROOTFS_INITRAMFS', false)
|
||||||
|
|
||||||
config 'CONFIG_DEVEL=y'
|
config('CONFIG_DEVEL', true)
|
||||||
config 'CONFIG_ALL_NONSHARED=y'
|
config('CONFIG_ALL_NONSHARED', true)
|
||||||
|
|
||||||
config '# CONFIG_PACKAGE_usbip is not set' -- fails to build
|
config('CONFIG_PACKAGE_usbip', false) -- fails to build
|
||||||
config '# CONFIG_PACKAGE_kmod-jool is not set' -- fails to build
|
config('CONFIG_PACKAGE_kmod-jool', false) -- fails to build
|
||||||
|
|
||||||
config 'CONFIG_BUSYBOX_CUSTOM=y'
|
config('CONFIG_BUSYBOX_CUSTOM', true)
|
||||||
config '# CONFIG_BUSYBOX_CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set'
|
config('CONFIG_BUSYBOX_CONFIG_FEATURE_PREFER_IPV4_ADDRESS', false)
|
||||||
|
|
||||||
config 'CONFIG_PACKAGE_ATH_DEBUG=y'
|
config('CONFIG_PACKAGE_ATH_DEBUG', true)
|
||||||
|
|
||||||
try_config 'CONFIG_TARGET_SQUASHFS_BLOCK_SIZE=256'
|
try_config('CONFIG_TARGET_SQUASHFS_BLOCK_SIZE', 256)
|
||||||
|
|
||||||
config '# CONFIG_KERNEL_IP_MROUTE is not set'
|
config('CONFIG_KERNEL_IP_MROUTE', false)
|
||||||
config '# CONFIG_KERNEL_IPV6_MROUTE is not set'
|
config('CONFIG_KERNEL_IPV6_MROUTE', false)
|
||||||
|
|
||||||
try_config 'CONFIG_TARGET_MULTI_PROFILE=y'
|
try_config('CONFIG_TARGET_MULTI_PROFILE', true)
|
||||||
try_config 'CONFIG_TARGET_PER_DEVICE_ROOTFS=y'
|
try_config('CONFIG_TARGET_PER_DEVICE_ROOTFS', true)
|
||||||
|
|
||||||
if istrue(env.GLUON_MULTIDOMAIN) then
|
config('CONFIG_GLUON_MULTIDOMAIN', istrue(env.GLUON_MULTIDOMAIN))
|
||||||
config 'CONFIG_GLUON_MULTIDOMAIN=y'
|
|
||||||
end
|
|
||||||
|
|
||||||
if istrue(env.GLUON_AUTOREMOVE) then
|
config('CONFIG_AUTOREMOVE', istrue(env.GLUON_AUTOREMOVE))
|
||||||
config 'CONFIG_AUTOREMOVE=y'
|
|
||||||
end
|
|
||||||
|
|
||||||
if istrue(env.GLUON_DEBUG) then
|
if istrue(env.GLUON_DEBUG) then
|
||||||
config 'CONFIG_DEBUG=y'
|
config('CONFIG_DEBUG', true)
|
||||||
config 'CONFIG_NO_STRIP=y'
|
config('CONFIG_NO_STRIP', true)
|
||||||
config '# CONFIG_USE_STRIP is not set'
|
config('CONFIG_USE_STRIP', false)
|
||||||
config '# CONFIG_USE_SSTRIP is not set'
|
config('CONFIG_USE_SSTRIP', false)
|
||||||
|
|
||||||
try_config 'CONFIG_TARGET_ROOTFS_PARTSIZE=500'
|
try_config('CONFIG_TARGET_ROOTFS_PARTSIZE', 500)
|
||||||
end
|
end
|
||||||
|
|
||||||
if not istrue(env.GLUON_MINIFY) then
|
config('CONFIG_GLUON_MINIFY', istrue(env.GLUON_MINIFY))
|
||||||
config '# CONFIG_GLUON_MINIFY is not set'
|
|
||||||
end
|
|
||||||
|
|
||||||
packages {
|
packages {
|
||||||
'-kmod-ipt-offload',
|
'-kmod-ipt-offload',
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
config '# CONFIG_KERNEL_KALLSYMS is not set'
|
config('CONFIG_KERNEL_KALLSYMS', false)
|
||||||
config 'CONFIG_GLUON_SPECIALIZE_KERNEL=y'
|
config('CONFIG_GLUON_SPECIALIZE_KERNEL', true)
|
||||||
|
|
||||||
no_opkg()
|
no_opkg()
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
config 'CONFIG_VDI_IMAGES=y'
|
config('CONFIG_VDI_IMAGES', true)
|
||||||
config 'CONFIG_VMDK_IMAGES=y'
|
config('CONFIG_VMDK_IMAGES', true)
|
||||||
|
|
||||||
packages {
|
packages {
|
||||||
'kmod-3c59x',
|
'kmod-3c59x',
|
||||||
|
Loading…
Reference in New Issue
Block a user