Skip to content

Commit a5cf8c2

Browse files
committed
improve to export symbols
1 parent 0a965df commit a5cf8c2

File tree

1 file changed

+45
-36
lines changed

1 file changed

+45
-36
lines changed

xmake/rules/utils/symbols/export_all/export_all.lua

+45-36
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,44 @@ import("core.base.hashset")
2626
import("core.project.depend")
2727
import("utils.progress")
2828

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+
2967
-- export all symbols for dynamic library
3068
function main(target, opt)
3169

@@ -43,48 +81,19 @@ function main(target, opt)
4381
-- trace progress info
4482
progress.show(opt.progress, "${color.build.target}exporting.$(mode) %s", path.filename(target:targetfile()))
4583

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-
5084
-- export c++ class?
5185
local export_classes = target:extraconf("rules", "utils.symbols.export_all", "export_classes")
5286

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})
8493
end
8594

8695
-- export all symbols
87-
if allsymbols:size() > 0 then
96+
if allsymbols and allsymbols:size() > 0 then
8897
local allsymbols_file = io.open(allsymbols_filepath, 'w')
8998
allsymbols_file:print("EXPORTS")
9099
for _, symbol in allsymbols:keys() do

0 commit comments

Comments
 (0)