@@ -26,6 +26,44 @@ import("core.base.hashset")
26
26
import (" core.project.depend" )
27
27
import (" utils.progress" )
28
28
29
+ -- use dumpbin to get all symbols from object files
30
+ function _get_allsymbols_by_dumpbin (target , dumpbin , opt )
31
+ opt = opt or {}
32
+ local allsymbols = hashset .new ()
33
+ local export_classes = opt .export_classes
34
+ for _ , objectfile in ipairs (target :objectfiles ()) do
35
+ local objectsymbols = try { function () return os .iorunv (dumpbin , {" /symbols" , " /nologo" , objectfile }) end }
36
+ if objectsymbols then
37
+ for _ , line in ipairs (objectsymbols :split (' \n ' , {plain = true })) do
38
+ -- https://docs.microsoft.com/en-us/cpp/build/reference/symbols
39
+ -- 008 00000000 SECT3 notype () External | add
40
+ if line :find (" External" ) and not line :find (" UNDEF" ) then
41
+ local symbol = line :match (" .*External%s+| (.*)" )
42
+ if symbol then
43
+ symbol = symbol :split (' %s' )[1 ]
44
+ if not symbol :startswith (" __" ) then
45
+ -- we need ignore DllMain, https://github.com/xmake-io/xmake/issues/3992
46
+ if target :is_arch (" x86" ) and symbol :startswith (" _" ) and not symbol :startswith (" _DllMain@" ) then
47
+ symbol = symbol :sub (2 )
48
+ end
49
+ if export_classes or not symbol :startswith (" ?" ) then
50
+ if export_classes then
51
+ if not symbol :startswith (" ??_G" ) and not symbol :startswith (" ??_E" ) then
52
+ allsymbols :insert (symbol )
53
+ end
54
+ else
55
+ allsymbols :insert (symbol )
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ return allsymbols
65
+ end
66
+
29
67
-- export all symbols for dynamic library
30
68
function main (target , opt )
31
69
@@ -43,48 +81,19 @@ function main(target, opt)
43
81
-- trace progress info
44
82
progress .show (opt .progress , " ${color.build.target}exporting.$(mode) %s" , path .filename (target :targetfile ()))
45
83
46
- -- get dumpbin
47
- local msvc = toolchain .load (" msvc" , {plat = target :plat (), arch = target :arch ()})
48
- local dumpbin = assert (find_tool (" dumpbin" , {envs = msvc :runenvs ()}), " dumpbin not found!" )
49
-
50
84
-- export c++ class?
51
85
local export_classes = target :extraconf (" rules" , " utils.symbols.export_all" , " export_classes" )
52
86
53
- -- get all symbols from object files
54
- local allsymbols = hashset .new ()
55
- for _ , objectfile in ipairs (target :objectfiles ()) do
56
- local objectsymbols = try { function () return os .iorunv (dumpbin .program , {" /symbols" , " /nologo" , objectfile }) end }
57
- if objectsymbols then
58
- for _ , line in ipairs (objectsymbols :split (' \n ' , {plain = true })) do
59
- -- https://docs.microsoft.com/en-us/cpp/build/reference/symbols
60
- -- 008 00000000 SECT3 notype () External | add
61
- if line :find (" External" ) and not line :find (" UNDEF" ) then
62
- local symbol = line :match (" .*External%s+| (.*)" )
63
- if symbol then
64
- symbol = symbol :split (' %s' )[1 ]
65
- if not symbol :startswith (" __" ) then
66
- -- we need ignore DllMain, https://github.com/xmake-io/xmake/issues/3992
67
- if target :is_arch (" x86" ) and symbol :startswith (" _" ) and not symbol :startswith (" _DllMain@" ) then
68
- symbol = symbol :sub (2 )
69
- end
70
- if export_classes or not symbol :startswith (" ?" ) then
71
- if export_classes then
72
- if not symbol :startswith (" ??_G" ) and not symbol :startswith (" ??_E" ) then
73
- allsymbols :insert (symbol )
74
- end
75
- else
76
- allsymbols :insert (symbol )
77
- end
78
- end
79
- end
80
- end
81
- end
82
- end
83
- end
87
+ -- get all symbols
88
+ local allsymbols
89
+ local msvc = toolchain .load (" msvc" , {plat = target :plat (), arch = target :arch ()})
90
+ if msvc :check () then
91
+ local dumpbin = assert (find_tool (" dumpbin" , {envs = msvc :runenvs ()}), " dumpbin not found!" )
92
+ allsymbols = _get_allsymbols_by_dumpbin (target , dumpbin .program , {export_classes = export_classes })
84
93
end
85
94
86
95
-- export all symbols
87
- if allsymbols :size () > 0 then
96
+ if allsymbols and allsymbols :size () > 0 then
88
97
local allsymbols_file = io.open (allsymbols_filepath , ' w' )
89
98
allsymbols_file :print (" EXPORTS" )
90
99
for _ , symbol in allsymbols :keys () do
0 commit comments