10 from SCons.Builder
import Builder
11 from SCons.Scanner.C
import CScanner
16 re.compile(
r'^#pragma\s+link\s+C\+\+\s+[\w]*\s+([\w]*).*[+-]?\!?;\s*//.*global.*$', re.M)
19 linkdef_everything = \
20 re.compile(
r'^#pragma\s+link\s+C\+\+\s+[\w]*\s+Belle2::.*$', re.M)
24 re.compile(
r'^#pragma\s+link\s+C\+\+\s+[\w]*\s+Belle2::([\w]*::)?([\w]*).*[+-]?\!?;.*$', re.M)
28 re.compile(
r'^#pragma\s+link\s+C\+\+\s+[\w]*\s+Belle2::.*;\s*//\s*implicit\s*$', re.M)
31 def linkdef_emitter(target, source, env):
32 linkdef = source.pop()
34 source_dir = os.path.dirname(str(linkdef))
35 include_dir = source_dir
36 if include_dir.endswith(
'include'):
37 include_dir = os.path.dirname(include_dir)
38 include_dir = os.path.join(env[
'INCDIR'], include_dir)
40 dict_basename = os.path.splitext(str(target[0]))[0]
42 target.append(dict_basename +
'.rootmap')
44 target.append(dict_basename +
'_rdict.pcm')
47 contents = linkdef.get_text_contents()
48 for line
in contents.split(
'\n'):
50 match = linkdef_global.match(line)
52 classname = match.group(1)
53 if classname
is not None:
54 include_base = classname +
'.h'
55 header_file = os.path.join(source_dir, include_base)
56 if os.path.isfile(header_file):
57 include_file = os.path.join(include_dir, include_base)
58 if include_file
not in source:
59 source.append(include_file)
61 print(f
'Cannot find header file for the line "{line}".')
64 if linkdef_everything.search(line)
is None:
67 match = linkdef_class_re.search(line)
70 "%s contains '%s' which we couldn't parse. The syntax may be incorrect," +
71 " or the build system may lack support for the feature you're using." %
74 namespace = match.group(1)
75 classname = match.group(2)
77 raise RuntimeError(
"%s contains '%s' without class name?" % (str(linkdef), str(line)))
79 is_implicit =
not linkdef_implicit.search(line)
is None
83 include_base = classname +
'.h'
84 header_file = os.path.join(source_dir, include_base)
86 if not os.path.isfile(header_file):
89 print(
"%s contains '%s' where we couldn't find a header file. "
90 "If dictionary compilation fails, this might be the reason. "
91 "For classes residing in other directories and already "
92 "included via other link requests, add '// implicit' at "
93 "the end to suppress this message." % (str(linkdef), str(line)))
97 include_base = namespace.split(
':')[0] +
'.h'
98 include_file = os.path.join(include_dir, include_base)
99 if include_file
not in source:
100 source.append(include_file)
103 source.append(linkdef)
104 return (target, source)
108 rootcling = Builder(action=
'rootcling -f $TARGET $CLINGFLAGS -rmf "${TARGET.base}.rootmap" -rml lib${ROOTCLING_ROOTMAP_LIB}.so '
109 '$_CPPDEFFLAGS $_CPPINCFLAGS $SOURCES', emitter=linkdef_emitter, source_scanner=CScanner())
110 rootcling.action.cmdstr =
'${ROOTCLINGCOMSTR}'
114 env[
'BUILDERS'][
'RootDict'] = rootcling