18 from SCons.Builder
import Builder
19 from SCons.Scanner.C
import CScanner
24 re.compile(
r'^#pragma\s+link\s+C\+\+\s+[\w]*\s+([\w]*).*[+-]?\!?;\s*//.*global.*$', re.M)
27 linkdef_everything = \
28 re.compile(
r'^#pragma\s+link\s+C\+\+\s+[\w]*\s+Belle2::.*$', re.M)
32 re.compile(
r'^#pragma\s+link\s+C\+\+\s+[\w]*\s+Belle2::([\w]*::)?([\w]*).*[+-]?\!?;.*$', re.M)
36 re.compile(
r'^#pragma\s+link\s+C\+\+\s+[\w]*\s+Belle2::.*;\s*//.*implicit.*$', re.M)
39 def linkdef_emitter(target, source, env):
40 linkdef = source.pop()
42 source_dir = os.path.dirname(str(linkdef))
43 include_dir = source_dir
44 if include_dir.endswith(
'include'):
45 include_dir = os.path.dirname(include_dir)
46 include_dir = os.path.join(env[
'INCDIR'], include_dir)
48 dict_basename = os.path.splitext(str(target[0]))[0]
50 target.append(dict_basename +
'.rootmap')
52 target.append(dict_basename +
'_rdict.pcm')
55 contents = linkdef.get_text_contents()
56 for line
in contents.split(
'\n'):
58 match = linkdef_global.match(line)
60 classname = match.group(1)
61 if classname
is not None:
62 include_base = classname +
'.h'
63 header_file = os.path.join(source_dir, include_base)
64 if os.path.isfile(header_file):
65 include_file = os.path.join(include_dir, include_base)
66 if include_file
not in source:
67 source.append(include_file)
69 print(f
'Cannot find header file for the line "{line}".')
72 if linkdef_everything.search(line)
is None:
75 match = linkdef_class_re.search(line)
78 f
"{linkdef} contains '{line}' which we couldn't parse. The syntax may be incorrect,"
79 " or the build system may lack support for the feature you're using.")
81 namespace = match.group(1)
82 classname = match.group(2)
84 raise RuntimeError(
"%s contains '%s' without class name?" % (str(linkdef), str(line)))
86 is_implicit =
not linkdef_implicit.search(line)
is None
90 include_base = classname +
'.h'
91 header_file = os.path.join(source_dir, include_base)
93 if not os.path.isfile(header_file):
96 print(
"%s contains '%s' where we couldn't find a header file. "
97 "If dictionary compilation fails, this might be the reason. "
98 "For classes residing in other directories and already "
99 "included via other link requests, add '// implicit' at "
100 "the end to suppress this message." % (str(linkdef), str(line)))
104 include_base = namespace.split(
':')[0] +
'.h'
105 include_file = os.path.join(include_dir, include_base)
106 if include_file
not in source:
107 source.append(include_file)
110 source.append(linkdef)
111 return (target, source)
116 action=
'rootcling --failOnWarnings -f $TARGET $CLINGFLAGS -rmf "${TARGET.base}.rootmap" -rml lib${ROOTCLING_ROOTMAP_LIB}.so '
117 '$_CPPDEFFLAGS $_CPPINCFLAGS $SOURCES',
118 emitter=linkdef_emitter,
119 source_scanner=CScanner())
120 rootcling.action.cmdstr =
'${ROOTCLINGCOMSTR}'
123 classversion = Builder(action=
'b2code-classversion-check --error-style gcc $SOURCE && touch $TARGET')
124 classversion.action.cmdstr =
'${CLASSVERSIONCOMSTR}'
128 env[
'BUILDERS'][
'RootDict'] = rootcling
129 env[
'BUILDERS'][
'ClassVersionCheck'] = classversion