@@ -26,15 +26,46 @@ import("core.base.hashset")
26
26
import (" core.project.depend" )
27
27
import (" utils.progress" )
28
28
29
+ -- It is not very accurate because some rules automatically
30
+ -- generate objectfiles and do not save the corresponding sourcefiles.
31
+ -- @see https://github.com/xmake-io/xmake/issues/5601
32
+ function _get_sourcefiles_map (target , sourcefiles_map )
33
+ for _ , sourcebatch in pairs (target :sourcebatches ()) do
34
+ for idx , sourcefile in ipairs (sourcebatch .sourcefiles ) do
35
+ local objectfiles = sourcebatch .objectfiles
36
+ if objectfiles then
37
+ local objectfile = objectfiles [idx ]
38
+ if objectfile then
39
+ sourcefiles_map [objectfile ] = sourcefile
40
+ end
41
+ end
42
+ end
43
+ end
44
+ local plaindeps = target :get (" deps" )
45
+ if plaindeps then
46
+ for _ , depname in ipairs (plaindeps ) do
47
+ local dep = target :dep (depname )
48
+ if dep and dep :is_object () then
49
+ _get_sourcefiles_map (dep , sourcefiles_map )
50
+ end
51
+ end
52
+ end
53
+ end
54
+
29
55
-- use dumpbin to get all symbols from object files
30
56
function _get_allsymbols_by_dumpbin (target , dumpbin , opt )
31
57
opt = opt or {}
32
58
local allsymbols = hashset .new ()
33
59
local export_classes = opt .export_classes
34
60
local export_filter = opt .export_filter
61
+ local sourcefiles_map = {}
62
+ if export_filter then
63
+ _get_sourcefiles_map (target , sourcefiles_map )
64
+ end
35
65
for _ , objectfile in ipairs (target :objectfiles ()) do
36
66
local objectsymbols = try { function () return os .iorunv (dumpbin , {" /symbols" , " /nologo" , objectfile }) end }
37
67
if objectsymbols then
68
+ local sourcefile = sourcefiles_map [objectfile ]
38
69
for _ , line in ipairs (objectsymbols :split (' \n ' , {plain = true })) do
39
70
-- https://docs.microsoft.com/en-us/cpp/build/reference/symbols
40
71
-- 008 00000000 SECT3 notype () External | add
@@ -47,7 +78,7 @@ function _get_allsymbols_by_dumpbin(target, dumpbin, opt)
47
78
symbol = symbol :sub (2 )
48
79
end
49
80
if export_filter then
50
- if export_filter (symbol ) then
81
+ if export_filter (symbol , { objectfile = objectfile , sourcefile = sourcefile } ) then
51
82
allsymbols :insert (symbol )
52
83
end
53
84
elseif not symbol :startswith (" __" ) then
@@ -75,9 +106,14 @@ function _get_allsymbols_by_objdump(target, objdump, opt)
75
106
local allsymbols = hashset .new ()
76
107
local export_classes = opt .export_classes
77
108
local export_filter = opt .export_filter
109
+ local sourcefiles_map = {}
110
+ if export_filter then
111
+ _get_sourcefiles_map (target , sourcefiles_map )
112
+ end
78
113
for _ , objectfile in ipairs (target :objectfiles ()) do
79
114
local objectsymbols = try { function () return os .iorunv (objdump , {" --syms" , objectfile }) end }
80
115
if objectsymbols then
116
+ local sourcefile = sourcefiles_map [objectfile ]
81
117
for _ , line in ipairs (objectsymbols :split (' \n ' , {plain = true })) do
82
118
if line :find (" (scl 2)" , 1 , true ) then
83
119
local splitinfo = line :split (" %s" )
@@ -88,7 +124,7 @@ function _get_allsymbols_by_objdump(target, objdump, opt)
88
124
symbol = symbol :sub (2 )
89
125
end
90
126
if export_filter then
91
- if export_filter (symbol ) then
127
+ if export_filter (symbol , { objectfile = objectfile , sourcefile = sourcefile } ) then
92
128
allsymbols :insert (symbol )
93
129
end
94
130
elseif not symbol :startswith (" __" ) then
0 commit comments