summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2025-11-14 22:20:39 +0800
committerGitHub <[email protected]>2025-11-14 22:20:39 +0800
commit100900c957fa0db180ccaf5f1f157a78e9db665d (patch)
tree42bdffc19ea83d2f4b72af9a931ced20f2c0eaac
parent7b66ccfbd2db6925d6ccba7e56273396cb66b416 (diff)
parentd066068a571d6e6515e56270374e96518d20eaf0 (diff)
Merge pull request #7024 from xmake-io/show
Add json output for `xmake show -t target`
-rwxr-xr-xtests/modules/json/test.lua40
-rw-r--r--xmake/core/base/json.lua73
-rw-r--r--xmake/plugins/show/info/basic.lua142
-rw-r--r--xmake/plugins/show/info/target.lua228
-rw-r--r--xmake/plugins/show/showlist.lua7
-rw-r--r--xmake/plugins/show/xmake.lua1
6 files changed, 385 insertions, 106 deletions
diff --git a/tests/modules/json/test.lua b/tests/modules/json/test.lua
index a09f0918a..6bd89389c 100755
--- a/tests/modules/json/test.lua
+++ b/tests/modules/json/test.lua
@@ -3,20 +3,24 @@ import("core.base.json")
local json_null = json.null
local json_pure_null = json.purenull
-function json_decode(jsonstr)
- return json.decode(jsonstr)
+function json_decode(jsonstr, opt)
+ return json.decode(jsonstr, opt)
end
-function json_encode(luatable)
- return json.encode(luatable)
+function json_encode(luatable, opt)
+ return json.encode(luatable, opt)
end
-function json_pure_decode(jsonstr)
- return json.decode(jsonstr, {pure = true})
+function json_pure_decode(jsonstr, opt)
+ opt = opt or {}
+ opt.pure = true
+ return json.decode(jsonstr, opt)
end
-function json_pure_encode(luatable)
- return json.encode(luatable, {pure = true})
+function json_pure_encode(luatable, opt)
+ opt = opt or {}
+ opt.pure = true
+ return json.encode(luatable, opt)
end
function test_json_decode(t)
@@ -38,6 +42,16 @@ function test_json_encode(t)
t:are_equal(json_encode({1, "2", {a = 1}}), '[1,"2",{"a":1}]')
t:are_equal(json_encode({1, "2", {b = true}}), '[1,"2",{"b":true}]')
t:are_equal(json_encode(json.mark_as_array({1, 0xa, 0xdeadbeef, 0xffffffff, -1})), '[1,10,3735928559,4294967295,-1]')
+ local pretty_expected = table.concat({
+ "{",
+ " \"name\": \"xmake\",",
+ " \"targets\": [",
+ " \"foo\",",
+ " \"bar\"",
+ " ]",
+ "}"
+ }, "\n")
+ t:are_equal(json_encode({name = "xmake", targets = {"foo", "bar"}}, {pretty = true, indent = 4}), pretty_expected)
end
function test_pure_json_decode(t)
@@ -59,4 +73,14 @@ function test_pure_json_encode(t)
t:are_equal(json_pure_encode({1, "2", {a = 1}}), '[1,"2",{"a":1}]')
t:are_equal(json_pure_encode({1, "2", {b = true}}), '[1,"2",{"b":true}]')
t:are_equal(json_pure_encode(json.mark_as_array({1, 0xa, 0xdeadbeef, 0xffffffff, -1})), '[1,10,3735928559,4294967295,-1]')
+ local pretty_expected = table.concat({
+ "{",
+ " \"name\": \"xmake\",",
+ " \"targets\": [",
+ " \"foo\",",
+ " \"bar\"",
+ " ]",
+ "}"
+ }, "\n")
+ t:are_equal(json_pure_encode({name = "xmake", targets = {"foo", "bar"}}, {pretty = true, indent = 4}), pretty_expected)
end
diff --git a/xmake/core/base/json.lua b/xmake/core/base/json.lua
index c93d298a9..760adefa0 100644
--- a/xmake/core/base/json.lua
+++ b/xmake/core/base/json.lua
@@ -24,6 +24,7 @@ local json = json or {}
-- load modules
local io = require("base/io")
local os = require("base/os")
+local table = require("base/table")
local utils = require("base/utils")
-- export null
@@ -130,7 +131,18 @@ function json._pure_parse_num_val(str, pos)
return val, pos + #num_str
end
-function json._pure_stringify(obj, as_key)
+function json._pure_stringify(obj, level, as_key, opt)
+ opt = opt or {}
+ level = level or 0
+ local pretty = opt.pretty
+ local orderkeys = opt.orderkeys
+ if orderkeys == nil and pretty then
+ orderkeys = true
+ end
+ local indent_step = pretty and (opt.indent or 4) or nil
+ local newline = pretty and "\n" or ""
+ local curr_indent = indent_step and string.rep(" ", indent_step * level) or nil
+ local child_indent = indent_step and string.rep(" ", indent_step * (level + 1)) or nil
local s = {}
local kind = json._pure_kind_of(obj)
if kind == "array" then
@@ -138,9 +150,25 @@ function json._pure_stringify(obj, as_key)
os.raise("can\'t encode array as key.")
end
s[#s + 1] = '['
- for i, val in ipairs(obj) do
- if i > 1 then s[#s + 1] = ',' end
- s[#s + 1] = json._pure_stringify(val)
+ local arrlen = #obj
+ if pretty and arrlen > 0 then
+ s[#s + 1] = newline
+ end
+ for idx = 1, arrlen do
+ if idx > 1 then
+ s[#s + 1] = ','
+ if pretty then
+ s[#s + 1] = newline
+ end
+ end
+ if pretty then
+ s[#s + 1] = child_indent
+ end
+ s[#s + 1] = json._pure_stringify(obj[idx], level + 1, false, opt)
+ end
+ if pretty and arrlen > 0 then
+ s[#s + 1] = newline
+ s[#s + 1] = curr_indent
end
s[#s + 1] = ']'
elseif kind == "table" then
@@ -148,11 +176,27 @@ function json._pure_stringify(obj, as_key)
os.raise("can\'t encode table as key.")
end
s[#s + 1] = '{'
- for k, v in pairs(obj) do
- if #s > 1 then s[#s + 1] = ',' end
- s[#s + 1] = json._pure_stringify(k, true)
+ local first = true
+ local iter = orderkeys and table.orderpairs or pairs
+ for k, v in iter(obj) do
+ if not first then
+ s[#s + 1] = ','
+ end
+ if pretty then
+ s[#s + 1] = newline
+ s[#s + 1] = child_indent
+ end
+ s[#s + 1] = json._pure_stringify(k, level + 1, true, opt)
s[#s + 1] = ':'
- s[#s + 1] = json._pure_stringify(v)
+ if pretty then
+ s[#s + 1] = ' '
+ end
+ s[#s + 1] = json._pure_stringify(v, level + 1, false, opt)
+ first = false
+ end
+ if pretty and not first then
+ s[#s + 1] = newline
+ s[#s + 1] = curr_indent
end
s[#s + 1] = '}'
elseif kind == "string" then
@@ -237,7 +281,7 @@ end
-- encode json string using pua lua
function json._pure_encode(luatable, opt)
- return json._pure_stringify(luatable)
+ return json._pure_stringify(luatable, 0, false, opt)
end
-- support empty array
@@ -281,11 +325,14 @@ end
-- @return the json string
--
function json.encode(luatable, opt)
- local encode = cjson and cjson.encode or json._pure_encode
- if opt and opt.pure then
- encode = json._pure_encode
+ local use_pure = not cjson or (opt and (opt.pure or opt.pretty))
+ local encode = use_pure and json._pure_encode or cjson.encode
+ local ok, jsonstr_or_errors
+ if use_pure then
+ ok, jsonstr_or_errors = utils.trycall(encode, nil, luatable, opt)
+ else
+ ok, jsonstr_or_errors = utils.trycall(encode, nil, luatable)
end
- local ok, jsonstr_or_errors = utils.trycall(encode, nil, luatable)
if not ok then
return nil, string.format("encode json failed, %s", jsonstr_or_errors)
end
diff --git a/xmake/plugins/show/info/basic.lua b/xmake/plugins/show/info/basic.lua
index 440e6768a..4ad14fe98 100644
--- a/xmake/plugins/show/info/basic.lua
+++ b/xmake/plugins/show/info/basic.lua
@@ -21,51 +21,127 @@
-- imports
import("core.base.option")
import("core.base.global")
+import("core.base.json")
import("core.project.config")
import("core.project.project")
import("core.package.package")
--- show basic info
-function main()
+function _show_xmake_info(opt, result)
+ local json_enabled = opt and opt.json
+ local info = {
+ version = tostring(xmake.version()),
+ host = {os = os.host(), arch = os.arch()},
+ programdir = xmake.programdir(),
+ programfile = xmake.programfile(),
+ globaldir = global.directory(),
+ tmpdir = os.tmpdir(),
+ workingdir = os.workingdir(),
+ packagedir = package.installdir(),
+ packagedir_cache = package.cachedir()
+ }
+ if json_enabled then
+ result = result or {}
+ result.xmake = info
+ else
+ print("The information of xmake:")
+ cprint(" ${color.dump.string}version${clear}: %s", info.version)
+ cprint(" ${color.dump.string}host${clear}: %s/%s", info.host.os, info.host.arch)
+ cprint(" ${color.dump.string}programdir${clear}: %s", info.programdir)
+ cprint(" ${color.dump.string}programfile${clear}: %s", info.programfile)
+ cprint(" ${color.dump.string}globaldir${clear}: %s", info.globaldir)
+ cprint(" ${color.dump.string}tmpdir${clear}: %s", info.tmpdir)
+ cprint(" ${color.dump.string}workingdir${clear}: %s", info.workingdir)
+ cprint(" ${color.dump.string}packagedir${clear}: %s", info.packagedir)
+ cprint(" ${color.dump.string}packagedir(cache)${clear}: %s", info.packagedir_cache)
+ print("")
+ end
+ return result
+end
- -- get target
- config.load()
+function _show_project_info(opt, result)
+ local json_enabled = opt and opt.json
+ local projectfile = os.projectfile()
+ if not os.isfile(projectfile) then
+ return result
+ end
- -- show xmake information
- print("The information of xmake:")
- cprint(" ${color.dump.string}version${clear}: %s", xmake.version())
- cprint(" ${color.dump.string}host${clear}: %s/%s", os.host(), os.arch())
- cprint(" ${color.dump.string}programdir${clear}: %s", xmake.programdir())
- cprint(" ${color.dump.string}programfile${clear}: %s", xmake.programfile())
- cprint(" ${color.dump.string}globaldir${clear}: %s", global.directory())
- cprint(" ${color.dump.string}tmpdir${clear}: %s", os.tmpdir())
- cprint(" ${color.dump.string}workingdir${clear}: %s", os.workingdir())
- cprint(" ${color.dump.string}packagedir${clear}: %s", package.installdir())
- cprint(" ${color.dump.string}packagedir(cache)${clear}: %s", package.cachedir())
- print("")
+ local info = {
+ configdir = config.directory(),
+ projectdir = os.projectdir(),
+ projectfile = projectfile
+ }
+ local name = project.name()
+ if name then
+ info.name = name
+ end
+ local project_version = project.version()
+ if project_version ~= nil then
+ info.version = tostring(project_version)
+ end
+ local plat = config.plat()
+ if plat then
+ info.plat = plat
+ end
+ local arch = config.arch()
+ if arch then
+ info.arch = arch
+ end
+ local mode = config.mode()
+ if mode then
+ info.mode = mode
+ end
+ local builddir = config.builddir()
+ if builddir then
+ info.builddir = builddir
+ end
- local projectfile = os.projectfile()
- if os.isfile(projectfile) then
- print("The information of project: %s", project.name() and project.name() or "")
- local version = project.version()
- if version then
- cprint(" ${color.dump.string}version${clear}: %s", version)
+ if json_enabled then
+ result = result or {}
+ result.project = info
+ else
+ print("The information of project: %s", info.name or "")
+ if info.version then
+ cprint(" ${color.dump.string}version${clear}: %s", info.version)
end
- if config.plat() then
- cprint(" ${color.dump.string}plat${clear}: %s", config.plat())
+ if info.plat then
+ cprint(" ${color.dump.string}plat${clear}: %s", info.plat)
end
- if config.arch() then
- cprint(" ${color.dump.string}arch${clear}: %s", config.arch())
+ if info.arch then
+ cprint(" ${color.dump.string}arch${clear}: %s", info.arch)
end
- if config.mode() then
- cprint(" ${color.dump.string}mode${clear}: %s", config.mode())
+ if info.mode then
+ cprint(" ${color.dump.string}mode${clear}: %s", info.mode)
end
- if config.builddir() then
- cprint(" ${color.dump.string}builddir${clear}: %s", config.builddir())
+ if info.builddir then
+ cprint(" ${color.dump.string}builddir${clear}: %s", info.builddir)
end
- cprint(" ${color.dump.string}configdir${clear}: %s", config.directory())
- cprint(" ${color.dump.string}projectdir${clear}: %s", os.projectdir())
- cprint(" ${color.dump.string}projectfile${clear}: %s", projectfile)
+ cprint(" ${color.dump.string}configdir${clear}: %s", info.configdir)
+ cprint(" ${color.dump.string}projectdir${clear}: %s", info.projectdir)
+ cprint(" ${color.dump.string}projectfile${clear}: %s", info.projectfile)
print("")
end
+ return result
+end
+
+-- show basic info
+function main()
+
+ config.load()
+
+ local opt = {
+ json = option.get("json"),
+ pretty = option.get("pretty")
+ }
+ local result = opt.json and {} or nil
+
+ result = _show_xmake_info(opt, result)
+ result = _show_project_info(opt, result)
+
+ if opt.json then
+ local json_opt
+ if opt.pretty then
+ json_opt = {pretty = true, orderkeys = true}
+ end
+ print(json.encode(result or {}, json_opt))
+ end
end
diff --git a/xmake/plugins/show/info/target.lua b/xmake/plugins/show/info/target.lua
index d5ddfbe76..62d8b6ddd 100644
--- a/xmake/plugins/show/info/target.lua
+++ b/xmake/plugins/show/info/target.lua
@@ -20,34 +20,57 @@
-- imports
import("core.base.option")
+import("core.base.json")
import("core.base.hashset")
import("core.project.config")
import("core.language.language")
import("private.detect.check_targetname")
--- get source info string
-function _get_sourceinfo_str(target, name, item, opt)
+-- get source info data
+function _get_sourceinfo(target, name, item, opt)
opt = opt or {}
local sourceinfo = target:sourceinfo(name, item)
+ local tips = opt.tips
if sourceinfo then
- local tips = opt.tips
- if tips then
- tips = tips .. " -> "
- end
+ return {
+ file = sourceinfo.file,
+ line = sourceinfo.line,
+ tips = tips
+ }
+ elseif tips then
+ return {tips = tips}
+ end
+end
+
+-- format source info string with color
+function _format_sourceinfo(sourceinfo)
+ if not sourceinfo then
+ return ""
+ end
+ local tips = sourceinfo.tips
+ if tips then
+ tips = tips .. " -> "
+ end
+ if sourceinfo.file then
return string.format(" ${dim}-> %s%s:%s${clear}", tips or "", sourceinfo.file or "", sourceinfo.line or -1)
- elseif opt.tips then
- return string.format(" ${dim}-> %s${clear}", opt.tips)
+ elseif tips then
+ return string.format(" ${dim}-> %s${clear}", tips)
end
return ""
end
+-- get source info string
+function _get_sourceinfo_str(target, name, item, opt)
+ return _format_sourceinfo(_get_sourceinfo(target, name, item, opt))
+end
+
-- get values from target options
function _get_values_from_opts(target, name)
local values = {}
for _, opt_ in ipairs(target:orderopts()) do
for _, value in ipairs(opt_:get(name)) do
local tips = string.format("option(%s)", opt_:name())
- values[value] = _get_sourceinfo_str(opt_, name, value, {tips = tips})
+ values[value] = _get_sourceinfo(opt_, name, value, {tips = tips})
end
end
return values
@@ -78,7 +101,8 @@ function _get_values_from_pkgs(target, name)
local info = components[component_name]
if info then
for _, value in ipairs(info[name]) do
- values[value] = string.format(" -> package(%s)", pkg:fullname())
+ local tips = string.format("package(%s)", pkg:fullname())
+ values[value] = {tips = tips}
end
else
local components_str = table.concat(table.wrap(configinfo.components), ", ")
@@ -90,12 +114,14 @@ function _get_values_from_pkgs(target, name)
-- e.g. `add_packages("xxx", {links = "xxx"})`
elseif configinfo and configinfo[name] then
for _, value in ipairs(configinfo[name]) do
- values[value] = _get_sourceinfo_str(target, "packages", pkg:name())
+ local sourceinfo = _get_sourceinfo(target, "packages", pkg:name())
+ values[value] = sourceinfo
end
else
-- get values from the builtin package configs
for _, value in ipairs(pkg:get(name)) do
- values[value] = string.format(" -> package(%s)", pkg:fullname())
+ local tips = string.format("package(%s)", pkg:fullname())
+ values[value] = {tips = tips}
end
end
end
@@ -112,18 +138,21 @@ function _get_values_from_deps(target, name)
local depinherit = target:extraconf("deps", dep:name(), "inherit")
if depinherit == nil or depinherit then
for _, value in ipairs(dep:get(name, {interface = true})) do
- values[value] = string.format(" -> dep(%s)", dep:name())
+ local tips = string.format("dep(%s)", dep:name())
+ values[value] = {tips = tips}
end
local values_chunks = dep:get_from(name, "option::*", {interface = true})
for _, values_chunk in ipairs(values_chunks) do
for _, value in ipairs(values_chunk) do
- values[value] = string.format(" -> dep(%s) -> options", dep:name())
+ local tips = string.format("dep(%s) -> options", dep:name())
+ values[value] = {tips = tips}
end
end
values_chunks = dep:get_from(name, "package::*", {interface = true})
for _, values_chunk in ipairs(values_chunks) do
for _, value in ipairs(values_chunk) do
- values[value] = string.format(" -> dep(%s) -> packages", dep:name())
+ local tips = string.format("dep(%s) -> packages", dep:name())
+ values[value] = {tips = tips}
end
end
end
@@ -131,27 +160,36 @@ function _get_values_from_deps(target, name)
return values
end
--- show target information
-function _show_target(target)
- print("The information of target(%s):", target:name())
- cprint(" ${color.dump.string}at${clear}: %s", path.join(target:scriptdir(), "xmake.lua"))
- cprint(" ${color.dump.string}kind${clear}: %s", target:kind())
+function _collect_target_info(target)
+ local info = {
+ name = target:name(),
+ at = path.join(target:scriptdir(), "xmake.lua"),
+ kind = target:kind()
+ }
local targetfile = target:targetfile()
if targetfile then
- cprint(" ${color.dump.string}targetfile${clear}: %s", targetfile)
+ info.targetfile = targetfile
end
local deps = target:get("deps")
if deps then
- cprint(" ${color.dump.string}deps${clear}:")
+ local entries = {}
for _, dep in ipairs(deps) do
- cprint(" ${color.dump.reference}->${clear} %s%s", dep, _get_sourceinfo_str(target, "deps", dep))
+ local entry = {name = dep, source = _get_sourceinfo(target, "deps", dep)}
+ table.insert(entries, entry)
+ end
+ if #entries > 0 then
+ info.deps = entries
end
end
local rules = target:get("rules")
if rules then
- cprint(" ${color.dump.string}rules${clear}:")
+ local entries = {}
for _, value in ipairs(rules) do
- cprint(" ${color.dump.reference}->${clear} %s%s", value, _get_sourceinfo_str(target, "rules", value))
+ local entry = {name = value, source = _get_sourceinfo(target, "rules", value)}
+ table.insert(entries, entry)
+ end
+ if #entries > 0 then
+ info.rules = entries
end
end
local options = {}
@@ -161,18 +199,25 @@ function _show_target(target)
end
end
if #options > 0 then
- cprint(" ${color.dump.string}options${clear}:")
+ local entries = {}
for _, value in ipairs(options) do
- cprint(" ${color.dump.reference}->${clear} %s%s", value, _get_sourceinfo_str(target, "options", value))
+ table.insert(entries, {name = value, source = _get_sourceinfo(target, "options", value)})
+ end
+ if #entries > 0 then
+ info.options = entries
end
end
local packages = target:get("packages")
if packages then
- cprint(" ${color.dump.string}packages${clear}:")
+ local entries = {}
for _, value in ipairs(packages) do
- cprint(" ${color.dump.reference}->${clear} %s%s", value, _get_sourceinfo_str(target, "packages", value))
+ table.insert(entries, {name = value, source = _get_sourceinfo(target, "packages", value)})
+ end
+ if #entries > 0 then
+ info.packages = entries
end
end
+ info.api_entries = {}
for _, apiname in ipairs(table.join(language.apis().values, language.apis().paths)) do
if apiname:startswith("target.") then
local valuename = apiname:split('.add_', {plain = true})[2]
@@ -181,38 +226,44 @@ function _show_target(target)
local values = table.unique(table.wrap(target:get(valuename)))
if #values > 0 then
for _, value in ipairs(values) do
- table.insert(results, {value = value, sourceinfo = _get_sourceinfo_str(target, valuename, value)})
+ local sourceinfo = _get_sourceinfo(target, valuename, value)
+ table.insert(results, {value = value, source = sourceinfo})
end
end
local values_from_opts = _get_values_from_opts(target, valuename)
for value, sourceinfo in pairs(values_from_opts) do
- table.insert(results, {value = value, sourceinfo = sourceinfo})
+ table.insert(results, {value = value, source = sourceinfo})
end
local values_from_pkgs = _get_values_from_pkgs(target, valuename)
for value, sourceinfo in pairs(values_from_pkgs) do
- table.insert(results, {value = value, sourceinfo = sourceinfo})
+ table.insert(results, {value = value, source = sourceinfo})
end
local values_from_deps = _get_values_from_deps(target, valuename)
for value, sourceinfo in pairs(values_from_deps) do
- table.insert(results, {value = value, sourceinfo = sourceinfo})
+ table.insert(results, {value = value, source = sourceinfo})
end
if #results > 0 then
- cprint(" ${color.dump.string}%s${clear}:", valuename)
+ local entries = {}
for _, result in ipairs(results) do
- cprint(" ${color.dump.reference}->${clear} %s%s", result.value, result.sourceinfo)
+ table.insert(entries, result)
end
+ info[valuename] = entries
+ table.insert(info.api_entries, {name = valuename, entries = entries})
end
end
end
end
local files = target:get("files")
if files then
- cprint(" ${color.dump.string}files${clear}:")
+ local entries = {}
for _, file in ipairs(files) do
if not file:startswith("__remove_") then
- cprint(" ${color.dump.reference}->${clear} %s%s", file, _get_sourceinfo_str(target, "files", file))
+ table.insert(entries, {path = file, source = _get_sourceinfo(target, "files", file)})
end
end
+ if #entries > 0 then
+ info.files = entries
+ end
end
local sourcekinds = hashset.new()
for _, sourcebatch in pairs(target:sourcebatches()) do
@@ -223,25 +274,87 @@ function _show_target(target)
for _, sourcekind in sourcekinds:keys() do
local compinst = target:compiler(sourcekind)
if compinst then
- cprint(" ${color.dump.string}compiler (%s)${clear}: %s", sourcekind, compinst:program())
- cprint(" ${color.dump.reference}->${clear} %s", os.args(compinst:compflags()))
+ info.compilers = info.compilers or {}
+ table.insert(info.compilers, {
+ sourcekind = sourcekind,
+ program = compinst:program(),
+ flags = os.args(compinst:compflags()),
+ flags_with_target = os.args(compinst:compflags({target = target}))
+ })
end
end
local linker = targetfile and target:linker()
if linker then
- cprint(" ${color.dump.string}linker (%s)${clear}: %s", linker:kind(), linker:program())
- cprint(" ${color.dump.reference}->${clear} %s", os.args(linker:linkflags()))
+ info.linker = {
+ kind = linker:kind(),
+ program = linker:program(),
+ flags = os.args(linker:linkflags()),
+ flags_with_target = os.args(linker:linkflags({target = target}))
+ }
end
- for _, sourcekind in sourcekinds:keys() do
- local compinst = target:compiler(sourcekind)
- if compinst then
- cprint(" ${color.dump.string}compflags (%s)${clear}:", sourcekind)
- cprint(" ${color.dump.reference}->${clear} %s", os.args(compinst:compflags({target = target})))
+ return info
+end
+
+function _print_entries(label, items, formatter)
+ if not items or #items == 0 then
+ return
+ end
+ cprint(" ${color.dump.string}%s${clear}:", label)
+ for _, item in ipairs(items) do
+ local text, source = formatter(item)
+ cprint(" ${color.dump.reference}->${clear} %s%s", text, source or "")
+ end
+end
+
+function _print_target_info(info)
+ print("The information of target(%s):", info.name)
+ cprint(" ${color.dump.string}at${clear}: %s", info.at)
+ cprint(" ${color.dump.string}kind${clear}: %s", info.kind)
+ if info.targetfile then
+ cprint(" ${color.dump.string}targetfile${clear}: %s", info.targetfile)
+ end
+ _print_entries("deps", info.deps, function(item)
+ return item.name, _format_sourceinfo(item.source)
+ end)
+ _print_entries("rules", info.rules, function(item)
+ return item.name, _format_sourceinfo(item.source)
+ end)
+ _print_entries("options", info.options, function(item)
+ return item.name, _format_sourceinfo(item.source)
+ end)
+ _print_entries("packages", info.packages, function(item)
+ return item.name, _format_sourceinfo(item.source)
+ end)
+ if info.api_entries then
+ for _, entry in ipairs(info.api_entries) do
+ _print_entries(entry.name, entry.entries, function(item)
+ local source = _format_sourceinfo(item.source)
+ return item.value, source
+ end)
end
end
- if linker then
- cprint(" ${color.dump.string}linkflags (%s)${clear}:", linker:kind())
- cprint(" ${color.dump.reference}->${clear} %s", os.args(linker:linkflags({target = target})))
+ if info.files then
+ _print_entries("files", info.files, function(item)
+ return item.path, _format_sourceinfo(item.source)
+ end)
+ end
+ if info.compilers then
+ for _, compiler in ipairs(info.compilers) do
+ cprint(" ${color.dump.string}compiler (%s)${clear}: %s", compiler.sourcekind, compiler.program)
+ if compiler.flags then
+ cprint(" ${color.dump.reference}->${clear} %s", compiler.flags)
+ end
+ end
+ for _, compiler in ipairs(info.compilers) do
+ cprint(" ${color.dump.string}compflags (%s)${clear}:", compiler.sourcekind)
+ cprint(" ${color.dump.reference}->${clear} %s", compiler.flags_with_target)
+ end
+ end
+ if info.linker then
+ cprint(" ${color.dump.string}linker (%s)${clear}: %s", info.linker.kind, info.linker.program)
+ cprint(" ${color.dump.reference}->${clear} %s", info.linker.flags)
+ cprint(" ${color.dump.string}linkflags (%s)${clear}:", info.linker.kind)
+ cprint(" ${color.dump.reference}->${clear} %s", info.linker.flags_with_target)
end
end
@@ -249,8 +362,21 @@ function main(name)
-- get target
config.load()
+ local opt = {
+ json = option.get("json"),
+ pretty = option.get("pretty")
+ }
local target = assert(check_targetname(name))
- -- show target information
- _show_target(target)
+ local info = _collect_target_info(target)
+ if opt.json then
+ info.api_entries = nil
+ local json_opt
+ if opt.pretty then
+ json_opt = {pretty = true, orderkeys = true}
+ end
+ print(json.encode(info or {}, json_opt))
+ else
+ _print_target_info(info)
+ end
end
diff --git a/xmake/plugins/show/showlist.lua b/xmake/plugins/show/showlist.lua
index 9dadb59c6..205ae21ed 100644
--- a/xmake/plugins/show/showlist.lua
+++ b/xmake/plugins/show/showlist.lua
@@ -40,7 +40,12 @@ function _show_text(values)
end
function _show_json(values)
- print(json.encode(values))
+ local opt = {}
+ if option.get("pretty") then
+ opt.pretty = true
+ opt.orderkeys = true
+ end
+ print(json.encode(values, opt))
end
function main(values)
diff --git a/xmake/plugins/show/xmake.lua b/xmake/plugins/show/xmake.lua
index 475a771b8..331aeb468 100644
--- a/xmake/plugins/show/xmake.lua
+++ b/xmake/plugins/show/xmake.lua
@@ -31,6 +31,7 @@ task("show")
end},
{'g', "group", "kv", nil, "Filter targets by the given group name."},
{nil, "json", "k", false, "Show information with json format."},
+ {nil, "pretty", "k", false, "Enable pretty formatted json output."},
{'t', "target", "kv", nil, "Show the information of the given target.",
values = function (complete, opt)
return import("private.utils.complete_helper.targets")(complete, opt)