summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2025-12-09 22:38:02 +0800
committerruki <[email protected]>2025-12-09 22:38:02 +0800
commit841d121decc17e2fe5eb6c7930e4ca4d805b28fd (patch)
treebddd8cc775c291269bc2d1717416f66f6a2714a7
parent5931e48282914758fd7c4eeaf9ca05a16521692b (diff)
improve export_all
-rw-r--r--xmake/modules/utils/binary/readsyms.lua4
-rw-r--r--xmake/rules/utils/symbols/export_all/export_all.lua57
2 files changed, 57 insertions, 4 deletions
diff --git a/xmake/modules/utils/binary/readsyms.lua b/xmake/modules/utils/binary/readsyms.lua
index 7225177e9..6aaa414d0 100644
--- a/xmake/modules/utils/binary/readsyms.lua
+++ b/xmake/modules/utils/binary/readsyms.lua
@@ -56,14 +56,14 @@ function dump(binaryfile)
-- calculate column widths
local type_width = math.max(max_type_len, 4)
local name_width = math.max(max_name_len, 4)
-
+
-- print header
print("")
print("Symbols:")
local header_format = " %-" .. type_width .. "s %s"
print(string.format(header_format, "TYPE", "NAME"))
print(string.rep("-", 80))
-
+
-- print symbols
local format_str = " %-" .. type_width .. "s %s"
diff --git a/xmake/rules/utils/symbols/export_all/export_all.lua b/xmake/rules/utils/symbols/export_all/export_all.lua
index b218dca39..039c190cc 100644
--- a/xmake/rules/utils/symbols/export_all/export_all.lua
+++ b/xmake/rules/utils/symbols/export_all/export_all.lua
@@ -23,6 +23,7 @@ import("lib.detect.find_tool")
import("core.tool.toolchain")
import("core.base.option")
import("core.base.hashset")
+import("core.base.binutils")
import("core.project.depend")
import("utils.progress")
@@ -146,6 +147,52 @@ function _get_allsymbols_by_objdump(target, objdump, opt)
return allsymbols
end
+-- use readsyms to get all symbols from object files
+function _get_allsymbols_by_readsyms(target, opt)
+ opt = opt or {}
+ local allsymbols = hashset.new()
+ local export_classes = opt.export_classes
+ local export_filter = opt.export_filter
+ local sourcefiles_map = {}
+ if export_filter then
+ _get_sourcefiles_map(target, sourcefiles_map)
+ end
+ for _, objectfile in ipairs(target:objectfiles()) do
+ local symbols, errors = binutils.readsyms(objectfile)
+ if symbols then
+ local sourcefile = sourcefiles_map[objectfile]
+ for _, sym in ipairs(symbols) do
+ if sym.name and sym.type then
+ -- only export defined symbols (not undefined 'U')
+ if sym.type ~= "U" then
+ local symbol = sym.name
+ -- we need ignore DllMain, https://github.com/xmake-io/xmake/issues/3992
+ if target:is_arch("x86") and symbol:startswith("_") and not symbol:startswith("__") and not symbol:startswith("_DllMain@") then
+ symbol = symbol:sub(2)
+ end
+ if export_filter then
+ if export_filter(symbol, {objectfile = objectfile, sourcefile = sourcefile}) then
+ allsymbols:insert(symbol)
+ end
+ elseif not symbol:startswith("__") then
+ if export_classes or not symbol:startswith("?") then
+ if export_classes then
+ if not symbol:startswith("??_G") and not symbol:startswith("??_E") then
+ allsymbols:insert(symbol)
+ end
+ else
+ allsymbols:insert(symbol)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ return allsymbols
+end
+
-- export all symbols for dynamic library
function main(target, opt)
@@ -177,7 +224,7 @@ function main(target, opt)
export_classes = export_classes,
export_filter = export_filter})
end
- if not allsymbols then
+ if not allsymbols or allsymbols:empty() then
local msvc = toolchain.load("msvc", {plat = target:plat(), arch = target:arch()})
if msvc:check() then
local dumpbin = assert(find_tool("dumpbin", {envs = msvc:runenvs()}), "dumpbin not found!")
@@ -186,9 +233,15 @@ function main(target, opt)
export_filter = export_filter})
end
end
+ -- fallback to readsyms if still no symbols found
+ if not allsymbols or allsymbols:empty() then
+ allsymbols = _get_allsymbols_by_readsyms(target, {
+ export_classes = export_classes,
+ export_filter = export_filter})
+ end
-- export all symbols
- if allsymbols and allsymbols:size() > 0 then
+ if allsymbols and not allsymbols:empty() then
local allsymbols_file = io.open(allsymbols_filepath, 'w')
allsymbols_file:print("EXPORTS")
for _, symbol in allsymbols:keys() do