5 This tool supports the export_symbols_regex to export the symbols in a shared library.
6 by default, all symbols are exported by gcc, and nothing by msvc.
7 to use the tool, do something like:
10 ctx(features='c cshlib syms', source='a.c b.c', export_symbols_regex='mylib_.*', target='testlib')
12 only the symbols starting with 'mylib_' will be exported.
16 from waflib
.Context
import STDOUT
17 from waflib
.Task
import Task
18 from waflib
.Errors
import WafError
19 from waflib
.TaskGen
import feature
, after_method
26 reg
= getattr(self
.generator
, 'export_symbols_regex', '.+?')
27 if 'msvc' in (self
.env
.CC_NAME
, self
.env
.CXX_NAME
):
28 re_nm
= re
.compile(r
'External\s+\|\s+_(?P<symbol>%s)\b' % reg
)
29 cmd
= (self
.env
.DUMPBIN
or ['dumpbin']) + ['/symbols', obj
.abspath()]
31 if self
.env
.DEST_BINFMT
== 'pe': #gcc uses nm, and has a preceding _ on windows
32 re_nm
= re
.compile(r
'(T|D)\s+_(?P<symbol>%s)\b' % reg
)
33 elif self
.env
.DEST_BINFMT
=='mac-o':
34 re_nm
=re
.compile(r
'(T|D)\s+(?P<symbol>_?(%s))\b' % reg
)
36 re_nm
= re
.compile(r
'(T|D)\s+(?P<symbol>%s)\b' % reg
)
37 cmd
= (self
.env
.NM
or ['nm']) + ['-g', obj
.abspath()]
38 syms
= [m
.group('symbol') for m
in re_nm
.finditer(self
.generator
.bld
.cmd_and_log(cmd
, quiet
=STDOUT
, **kw
))]
39 self
.outputs
[0].write('%r' % syms
)
41 class compile_sym(Task
):
45 slist
= eval(x
.read())
48 lsyms
= list(syms
.keys())
50 if self
.env
.DEST_BINFMT
== 'pe':
51 self
.outputs
[0].write('EXPORTS\n' + '\n'.join(lsyms
))
52 elif self
.env
.DEST_BINFMT
== 'elf':
53 self
.outputs
[0].write('{ global:\n' + ';\n'.join(lsyms
) + ";\nlocal: *; };\n")
54 elif self
.env
.DEST_BINFMT
=='mac-o':
55 self
.outputs
[0].write('\n'.join(lsyms
) + '\n')
57 raise WafError('NotImplemented')
60 @after_method('process_source', 'process_use', 'apply_link', 'process_uselib_local', 'propagate_uselib_vars')
61 def do_the_symbol_stuff(self
):
62 def_node
= self
.path
.find_or_declare(getattr(self
, 'sym_file', self
.target
+ '.def'))
63 compiled_tasks
= getattr(self
, 'compiled_tasks', None)
65 ins
= [x
.outputs
[0] for x
in compiled_tasks
]
66 self
.gen_sym_tasks
= [self
.create_task('gen_sym', x
, x
.change_ext('.%d.sym' % self
.idx
)) for x
in ins
]
67 self
.create_task('compile_sym', [x
.outputs
[0] for x
in self
.gen_sym_tasks
], def_node
)
69 link_task
= getattr(self
, 'link_task', None)
71 self
.link_task
.dep_nodes
.append(def_node
)
73 if 'msvc' in (self
.env
.CC_NAME
, self
.env
.CXX_NAME
):
74 self
.link_task
.env
.append_value('LINKFLAGS', ['/def:' + def_node
.bldpath()])
75 elif self
.env
.DEST_BINFMT
== 'pe':
76 # gcc on windows takes *.def as an additional input
77 self
.link_task
.inputs
.append(def_node
)
78 elif self
.env
.DEST_BINFMT
== 'elf':
79 self
.link_task
.env
.append_value('LINKFLAGS', ['-Wl,-version-script', '-Wl,' + def_node
.bldpath()])
80 elif self
.env
.DEST_BINFMT
=='mac-o':
81 self
.link_task
.env
.append_value('LINKFLAGS',['-Wl,-exported_symbols_list,' + def_node
.bldpath()])
83 raise WafError('NotImplemented')