summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2024-09-12 13:48:40 +0800
committerGitHub <[email protected]>2024-09-12 13:48:40 +0800
commitcb905957b80e9cfd8fbdd2bced9a1e7331041a87 (patch)
tree9adf22c41a512d2f4ebab0e7514a0fcae72e1c3c
parentfa48b0f9caa3472252485d7c2514c4456935d2b3 (diff)
parentb3fa6a33fec098c147e3d978f010f12df5e994f6 (diff)
Merge pull request #5608 from xmake-io/exportall
Improve export all rule
-rw-r--r--tests/projects/c++/shared_library_export_all/xmake.lua7
-rw-r--r--xmake/rules/utils/symbols/export_all/export_all.lua40
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