diff options
| author | ruki <[email protected]> | 2024-09-12 13:48:40 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-09-12 13:48:40 +0800 |
| commit | cb905957b80e9cfd8fbdd2bced9a1e7331041a87 (patch) | |
| tree | 9adf22c41a512d2f4ebab0e7514a0fcae72e1c3c | |
| parent | fa48b0f9caa3472252485d7c2514c4456935d2b3 (diff) | |
| parent | b3fa6a33fec098c147e3d978f010f12df5e994f6 (diff) | |
Merge pull request #5608 from xmake-io/exportall
Improve export all rule
| -rw-r--r-- | tests/projects/c++/shared_library_export_all/xmake.lua | 7 | ||||
| -rw-r--r-- | xmake/rules/utils/symbols/export_all/export_all.lua | 40 |
2 files changed, 43 insertions, 4 deletions
diff --git a/tests/projects/c++/shared_library_export_all/xmake.lua b/tests/projects/c++/shared_library_export_all/xmake.lua index 73159d4b5..bc7b0dd68 100644 --- a/tests/projects/c++/shared_library_export_all/xmake.lua +++ b/tests/projects/c++/shared_library_export_all/xmake.lua @@ -8,8 +8,10 @@ target("foo") target("bar") set_kind("shared") add_files("src/bar.cpp") - add_rules("utils.symbols.export_all", {export_filter = function (symbol) - if symbol:find("add", 1, true) then + add_rules("utils.symbols.export_all", {export_filter = function (symbol, opt) + local filepath = opt.sourcefile or opt.objectfile + if filepath and filepath:find("bar.cpp", 1, true) and symbol:find("add", 1, true) then + print("export: %s at %s", symbol, filepath) return true end end}) @@ -20,3 +22,4 @@ target("demo") add_files("src/main.cpp") + diff --git a/xmake/rules/utils/symbols/export_all/export_all.lua b/xmake/rules/utils/symbols/export_all/export_all.lua index 1c2806b79..b3a569d97 100644 --- a/xmake/rules/utils/symbols/export_all/export_all.lua +++ b/xmake/rules/utils/symbols/export_all/export_all.lua @@ -26,15 +26,46 @@ import("core.base.hashset") import("core.project.depend") import("utils.progress") +-- It is not very accurate because some rules automatically +-- generate objectfiles and do not save the corresponding sourcefiles. +-- @see https://github.com/xmake-io/xmake/issues/5601 +function _get_sourcefiles_map(target, sourcefiles_map) + for _, sourcebatch in pairs(target:sourcebatches()) do + for idx, sourcefile in ipairs(sourcebatch.sourcefiles) do + local objectfiles = sourcebatch.objectfiles + if objectfiles then + local objectfile = objectfiles[idx] + if objectfile then + sourcefiles_map[objectfile] = sourcefile + end + end + end + end + local plaindeps = target:get("deps") + if plaindeps then + for _, depname in ipairs(plaindeps) do + local dep = target:dep(depname) + if dep and dep:is_object() then + _get_sourcefiles_map(dep, sourcefiles_map) + end + end + end +end + -- use dumpbin to get all symbols from object files function _get_allsymbols_by_dumpbin(target, dumpbin, 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 objectsymbols = try { function () return os.iorunv(dumpbin, {"/symbols", "/nologo", objectfile}) end } if objectsymbols then + local sourcefile = sourcefiles_map[objectfile] for _, line in ipairs(objectsymbols:split('\n', {plain = true})) do -- https://docs.microsoft.com/en-us/cpp/build/reference/symbols -- 008 00000000 SECT3 notype () External | add @@ -47,7 +78,7 @@ function _get_allsymbols_by_dumpbin(target, dumpbin, opt) symbol = symbol:sub(2) end if export_filter then - if export_filter(symbol) then + if export_filter(symbol, {objectfile = objectfile, sourcefile = sourcefile}) then allsymbols:insert(symbol) end elseif not symbol:startswith("__") then @@ -75,9 +106,14 @@ function _get_allsymbols_by_objdump(target, objdump, opt) 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 objectsymbols = try { function () return os.iorunv(objdump, {"--syms", objectfile}) end } if objectsymbols then + local sourcefile = sourcefiles_map[objectfile] for _, line in ipairs(objectsymbols:split('\n', {plain = true})) do if line:find("(scl 2)", 1, true) then local splitinfo = line:split("%s") @@ -88,7 +124,7 @@ function _get_allsymbols_by_objdump(target, objdump, opt) symbol = symbol:sub(2) end if export_filter then - if export_filter(symbol) then + if export_filter(symbol, {objectfile = objectfile, sourcefile = sourcefile}) then allsymbols:insert(symbol) end elseif not symbol:startswith("__") then |
