From e962066eca9967087a9a4495cf6a82fb2b4bd367 Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 12 Sep 2024 22:36:09 +0800 Subject: improve export all #5601 --- tests/projects/c++/shared_library_export_all/xmake.lua | 2 +- xmake/rules/utils/symbols/export_all/export_all.lua | 4 ++-- 2 files changed, 3 insertions(+), 3 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..50043a52a 100644 --- a/tests/projects/c++/shared_library_export_all/xmake.lua +++ b/tests/projects/c++/shared_library_export_all/xmake.lua @@ -8,7 +8,7 @@ target("foo") target("bar") set_kind("shared") add_files("src/bar.cpp") - add_rules("utils.symbols.export_all", {export_filter = function (symbol) + add_rules("utils.symbols.export_all", {export_filter = function (symbol, opt) if symbol:find("add", 1, true) then return true end diff --git a/xmake/rules/utils/symbols/export_all/export_all.lua b/xmake/rules/utils/symbols/export_all/export_all.lua index 1c2806b79..0101bcfa5 100644 --- a/xmake/rules/utils/symbols/export_all/export_all.lua +++ b/xmake/rules/utils/symbols/export_all/export_all.lua @@ -47,7 +47,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}) then allsymbols:insert(symbol) end elseif not symbol:startswith("__") then @@ -88,7 +88,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}) then allsymbols:insert(symbol) end elseif not symbol:startswith("__") then -- cgit v1.3.1 From c72f5f04b33f65c5b2fd4cae5037a1bdaf4dab84 Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 12 Sep 2024 22:37:10 +0800 Subject: improve test --- tests/projects/c++/shared_library_export_all/xmake.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/projects/c++/shared_library_export_all/xmake.lua b/tests/projects/c++/shared_library_export_all/xmake.lua index 50043a52a..33d2c7d0c 100644 --- a/tests/projects/c++/shared_library_export_all/xmake.lua +++ b/tests/projects/c++/shared_library_export_all/xmake.lua @@ -9,7 +9,8 @@ target("bar") set_kind("shared") add_files("src/bar.cpp") add_rules("utils.symbols.export_all", {export_filter = function (symbol, opt) - if symbol:find("add", 1, true) then + local objectfile = opt.objectfile + if objectfile:find("bar.cpp", 1, true) and symbol:find("add", 1, true) then return true end end}) @@ -20,3 +21,4 @@ target("demo") add_files("src/main.cpp") + -- cgit v1.3.1 From e22e69c851c611e5ab42d36e592534dc2e02ea92 Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 12 Sep 2024 22:40:41 +0800 Subject: get sourcefile for export all --- .../c++/shared_library_export_all/xmake.lua | 5 +-- .../rules/utils/symbols/export_all/export_all.lua | 41 ++++++++++++++++++++-- 2 files changed, 42 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 33d2c7d0c..bc7b0dd68 100644 --- a/tests/projects/c++/shared_library_export_all/xmake.lua +++ b/tests/projects/c++/shared_library_export_all/xmake.lua @@ -9,8 +9,9 @@ target("bar") set_kind("shared") add_files("src/bar.cpp") add_rules("utils.symbols.export_all", {export_filter = function (symbol, opt) - local objectfile = opt.objectfile - if objectfile:find("bar.cpp", 1, true) and symbol:find("add", 1, true) then + 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}) diff --git a/xmake/rules/utils/symbols/export_all/export_all.lua b/xmake/rules/utils/symbols/export_all/export_all.lua index 0101bcfa5..50d8a8ace 100644 --- a/xmake/rules/utils/symbols/export_all/export_all.lua +++ b/xmake/rules/utils/symbols/export_all/export_all.lua @@ -26,6 +26,35 @@ 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_sourcefile_from_objectfile(target, objectfile) + local sourcefile + for _, sourcebatch in pairs(target:sourcebatches()) do + local sourcefiles = sourcebatch.sourcefiles + if sourcefiles then + for idx, obj in ipairs(sourcebatch.objectfiles) do + if obj == objectfile then + sourcefile = sourcefiles[idx] + break + end + end + end + end + if not sourcefile then + for _, dep in ipairs(target:orderdeps()) do + if dep:is_object() then + sourcefile = _get_sourcefile_from_objectfile(dep, objectfile) + if sourcefile then + break + end + end + end + end + return sourcefile +end + -- use dumpbin to get all symbols from object files function _get_allsymbols_by_dumpbin(target, dumpbin, opt) opt = opt or {} @@ -35,6 +64,10 @@ function _get_allsymbols_by_dumpbin(target, dumpbin, opt) for _, objectfile in ipairs(target:objectfiles()) do local objectsymbols = try { function () return os.iorunv(dumpbin, {"/symbols", "/nologo", objectfile}) end } if objectsymbols then + local sourcefile + if export_filter then + sourcefile = _get_sourcefile_from_objectfile(target, objectfile) + end 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 +80,7 @@ function _get_allsymbols_by_dumpbin(target, dumpbin, opt) symbol = symbol:sub(2) end if export_filter then - if export_filter(symbol, {objectfile = objectfile}) then + if export_filter(symbol, {objectfile = objectfile, sourcefile = sourcefile}) then allsymbols:insert(symbol) end elseif not symbol:startswith("__") then @@ -78,6 +111,10 @@ function _get_allsymbols_by_objdump(target, objdump, opt) for _, objectfile in ipairs(target:objectfiles()) do local objectsymbols = try { function () return os.iorunv(objdump, {"--syms", objectfile}) end } if objectsymbols then + local sourcefile + if export_filter then + sourcefile = _get_sourcefile_from_objectfile(target, objectfile) + end 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 +125,7 @@ function _get_allsymbols_by_objdump(target, objdump, opt) symbol = symbol:sub(2) end if export_filter then - if export_filter(symbol, {objectfile = objectfile}) then + if export_filter(symbol, {objectfile = objectfile, sourcefile = sourcefile}) then allsymbols:insert(symbol) end elseif not symbol:startswith("__") then -- cgit v1.3.1 From b3fa6a33fec098c147e3d978f010f12df5e994f6 Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 12 Sep 2024 22:42:20 +0800 Subject: optimize get sourcefile for export all --- .../rules/utils/symbols/export_all/export_all.lua | 47 +++++++++++----------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/xmake/rules/utils/symbols/export_all/export_all.lua b/xmake/rules/utils/symbols/export_all/export_all.lua index 50d8a8ace..b3a569d97 100644 --- a/xmake/rules/utils/symbols/export_all/export_all.lua +++ b/xmake/rules/utils/symbols/export_all/export_all.lua @@ -29,30 +29,27 @@ 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_sourcefile_from_objectfile(target, objectfile) - local sourcefile +function _get_sourcefiles_map(target, sourcefiles_map) for _, sourcebatch in pairs(target:sourcebatches()) do - local sourcefiles = sourcebatch.sourcefiles - if sourcefiles then - for idx, obj in ipairs(sourcebatch.objectfiles) do - if obj == objectfile then - sourcefile = sourcefiles[idx] - break + 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 - if not sourcefile then - for _, dep in ipairs(target:orderdeps()) do - if dep:is_object() then - sourcefile = _get_sourcefile_from_objectfile(dep, objectfile) - if sourcefile then - break - 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 - return sourcefile end -- use dumpbin to get all symbols from object files @@ -61,13 +58,14 @@ function _get_allsymbols_by_dumpbin(target, dumpbin, 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(dumpbin, {"/symbols", "/nologo", objectfile}) end } if objectsymbols then - local sourcefile - if export_filter then - sourcefile = _get_sourcefile_from_objectfile(target, objectfile) - end + 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 @@ -108,13 +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 - if export_filter then - sourcefile = _get_sourcefile_from_objectfile(target, objectfile) - end + 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") -- cgit v1.3.1