summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2025-01-27 22:30:18 +0800
committerruki <[email protected]>2025-01-27 22:30:18 +0800
commit5c15297defaedeb9eca6baee6756b4797d39b6bb (patch)
treea2e3e89ba7700832e49385245aa446485dca03ca
parent9a6a8ada1ddde0d88e6eb03cbf82a7f02f3ed7c3 (diff)
rewrite configfiles
-rw-r--r--tests/apis/add_configfiles/config.h.in2
-rw-r--r--xmake/actions/config/configfiles.lua167
2 files changed, 99 insertions, 70 deletions
diff --git a/tests/apis/add_configfiles/config.h.in b/tests/apis/add_configfiles/config.h.in
index 0ea32a623..ff3d1fe20 100644
--- a/tests/apis/add_configfiles/config.h.in
+++ b/tests/apis/add_configfiles/config.h.in
@@ -10,4 +10,6 @@ ${define FOO2_ENABLE}
${define FOO2_ENABLE2}
${define FOO2_STRING}
+//{define_export MYLIB_EXPORT}
+
#define HAVE_SSE2 ${default HAVE_SSE2 0}
diff --git a/xmake/actions/config/configfiles.lua b/xmake/actions/config/configfiles.lua
index 60b313abb..53754be43 100644
--- a/xmake/actions/config/configfiles.lua
+++ b/xmake/actions/config/configfiles.lua
@@ -153,6 +153,94 @@ function _get_builtinvars_global()
return builtinvars
end
+function _preprocess_define_value(name, value, opt)
+ opt = opt or {}
+ local extraconf = opt.extraconf
+ if value == nil then
+ value = ("/* #undef %s */"):format(name)
+ elseif type(value) == "boolean" then
+ if value then
+ value = ("#define %s 1"):format(name)
+ else
+ value = ("/* #define %s 0 */"):format(name)
+ end
+ elseif type(value) == "number" then
+ value = ("#define %s %d"):format(name, value)
+ elseif type(value) == "string" then
+ local quote = true
+ local escape = false
+ if extraconf then
+ -- disable to wrap quote, @see https://github.com/xmake-io/xmake/issues/1694
+ if extraconf.quote == false then
+ quote = false
+ end
+ -- escape path seperator when with quote, @see https://github.com/xmake-io/xmake/issues/1872
+ if quote and extraconf.escape then
+ escape = true
+ end
+ end
+ if quote then
+ if escape then
+ value = value:gsub("\\", "\\\\")
+ end
+ value = ("#define %s \"%s\""):format(name, value)
+ else
+ value = ("#define %s %s"):format(name, value)
+ end
+ else
+ raise("unknown variable(%s) type: %s", name, type(value))
+ end
+ return value
+end
+
+function _preprocess_default_value(name, value, opt)
+ opt = opt or {}
+ local default = table.unpack(opt.argv or {})
+ assert(default ~= nil, "please set default value for variable(%s)", variable)
+
+ if value == nil then
+ value = default
+ else
+ value = tostring(value)
+ end
+ return value
+end
+
+function _preprocess_define_export_value(name, value, opt)
+end
+
+-- get variable value
+function _get_variable_value(variables, name, opt)
+ opt = opt or {}
+ local preprocessor_name = opt.preprocessor_name
+ local preprocessor_argv = opt.preprocessor_argv
+ local configfile = opt.configfile
+ local value = variables[name]
+ local extraconf = variables["__extraconf_" .. name]
+ if preprocessor_name then
+ local preprocessors = _g._preprocessors
+ if preprocessors == nil then
+ preprocessors = {
+ define = _preprocess_define_value,
+ default = _preprocess_default_value,
+ define_export = _preprocess_define_export_value
+ }
+ _g._preprocessors = preprocessors
+ end
+ local preprocessor = preprocessors[preprocessor_name]
+ if preprocessor == nil then
+ raise("unknown variable keyword, ${%s %s}", preprocessor_name, name)
+ end
+ value = preprocessor(name, value, {argv = preprocessor_argv, extraconf = extraconf})
+ end
+ assert(value ~= nil, "cannot get variable(%s) in %s.", name, configfile)
+ dprint(" > replace %s -> %s", name, value)
+ if type(value) == "table" then
+ dprint("invalid variable value", value)
+ end
+ return value
+end
+
-- generate the configuration file
function _generate_configfile(srcfile, dstfile, fileinfo, targets)
@@ -220,80 +308,19 @@ function _generate_configfile(srcfile, dstfile, fileinfo, targets)
-- replace all variables
local pattern = fileinfo.pattern or "%${([^\n]-)}"
io.gsub(dstfile_tmp, "(" .. pattern .. ")", function(_, variable)
-
- -- get variable name
variable = variable:trim()
- -- is ${define variable}?
- local isdefine = false
- if variable:startswith("define ") then
- variable = variable:split("%s")[2]
- isdefine = true
+ local preprocessor_argv
+ local preprocessor_name
+ local parts = variable:split("%s")
+ if #parts > 1 then
+ preprocessor_name = parts[1]
+ variable = parts[2]
+ preprocessor_argv = table.slice(parts, 3)
end
- -- is ${default variable xxx}?
- local default = nil
- local isdefault = false
- if variable:startswith("default ") then
- local varinfo = variable:split("%s")
- variable = varinfo[2]
- default = varinfo[3]
- isdefault = true
- assert(default ~= nil, "please set default value for variable(%s)", variable)
- end
-
- -- get variable value
- local value = variables[variable]
- local extraconf = variables["__extraconf_" .. variable]
- if isdefine then
- if value == nil then
- value = ("/* #undef %s */"):format(variable)
- elseif type(value) == "boolean" then
- if value then
- value = ("#define %s 1"):format(variable)
- else
- value = ("/* #define %s 0 */"):format(variable)
- end
- elseif type(value) == "number" then
- value = ("#define %s %d"):format(variable, value)
- elseif type(value) == "string" then
- local quote = true
- local escape = false
- if extraconf then
- -- disable to wrap quote, @see https://github.com/xmake-io/xmake/issues/1694
- if extraconf.quote == false then
- quote = false
- end
- -- escape path seperator when with quote, @see https://github.com/xmake-io/xmake/issues/1872
- if quote and extraconf.escape then
- escape = true
- end
- end
- if quote then
- if escape then
- value = value:gsub("\\", "\\\\")
- end
- value = ("#define %s \"%s\""):format(variable, value)
- else
- value = ("#define %s %s"):format(variable, value)
- end
- else
- raise("unknown variable(%s) type: %s", variable, type(value))
- end
- elseif isdefault then
- if value == nil then
- value = default
- else
- value = tostring(value)
- end
- else
- assert(value ~= nil, "cannot get variable(%s) in %s.", variable, srcfile)
- end
- dprint(" > replace %s -> %s", variable, value)
- if type(value) == "table" then
- dprint("invalid variable value", value)
- end
- return value
+ return _get_variable_value(variables, variable, {preprocessor_name = preprocessor_name,
+ preprocessor_argv = preprocessor_argv, configfile = srcfile})
end)
-- update file if the content is changed