diff options
| author | ruki <[email protected]> | 2025-12-09 22:38:02 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2025-12-09 22:38:02 +0800 |
| commit | 841d121decc17e2fe5eb6c7930e4ca4d805b28fd (patch) | |
| tree | bddd8cc775c291269bc2d1717416f66f6a2714a7 | |
| parent | 5931e48282914758fd7c4eeaf9ca05a16521692b (diff) | |
improve export_all
| -rw-r--r-- | xmake/modules/utils/binary/readsyms.lua | 4 | ||||
| -rw-r--r-- | xmake/rules/utils/symbols/export_all/export_all.lua | 57 |
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 |
