17from SCons.Builder
import Builder
18from SCons.Scanner.C
import CScanner
23 re.compile(
r'^#pragma\s+link\s+C\+\+\s+[\w]*\s+([\w]*).*[+-]?\!?;\s*//.*global.*$', re.M)
27 re.compile(
r'^#pragma\s+link\s+C\+\+\s+[\w]*\s+Belle2::.*$', re.M)
31 re.compile(
r'^#pragma\s+link\s+C\+\+\s+[\w]*\s+Belle2::([\w]*::)?([\w]*).*[+-]?\!?;.*$', re.M)
35 re.compile(
r'^#pragma\s+link\s+C\+\+\s+[\w]*\s+Belle2::.*;\s*//.*implicit.*$', re.M)
38def linkdef_emitter(target, source, env):
39 linkdef = source.pop()
41 source_dir = os.path.dirname(str(linkdef))
42 include_dir = source_dir
43 if include_dir.endswith(
'include'):
44 include_dir = os.path.dirname(include_dir)
45 include_dir = os.path.join(env[
'INCDIR'], include_dir)
47 dict_basename = os.path.splitext(str(target[0]))[0]
49 target.append(dict_basename +
'.rootmap')
51 target.append(dict_basename +
'_rdict.pcm')
54 contents = linkdef.get_text_contents()
55 for line
in contents.split(
'\n'):
57 match = linkdef_global.match(line)
59 classname = match.group(1)
60 if classname
is not None:
61 include_base = classname +
'.h'
62 header_file = os.path.join(source_dir, include_base)
63 if os.path.isfile(header_file):
64 include_file = os.path.join(include_dir, include_base)
65 if include_file
not in source:
66 source.append(include_file)
68 print(f
'Cannot find header file for the line "{line}".')
71 if linkdef_everything.search(line)
is None:
74 match = linkdef_class_re.search(line)
77 f
"{linkdef} contains '{line}' which we couldn't parse. The syntax may be incorrect,"
78 " or the build system may lack support for the feature you're using.")
80 namespace = match.group(1)
81 classname = match.group(2)
83 raise RuntimeError(f
"{str(linkdef)} contains '{str(line)}' without class name?")
85 is_implicit =
not linkdef_implicit.search(line)
is None
89 include_base = classname +
'.h'
90 header_file = os.path.join(source_dir, include_base)
92 if not os.path.isfile(header_file):
95 print(f
"{str(linkdef)} contains '{str(line)}' where we couldn't find a header file. "
96 "If dictionary compilation fails, this might be the reason. "
97 "For classes residing in other directories and already "
98 "included via other link requests, add '// implicit' at "
99 "the end to suppress this message.")
103 include_base = namespace.split(
':')[0] +
'.h'
104 include_file = os.path.join(include_dir, include_base)
105 if include_file
not in source:
106 source.append(include_file)
109 source.append(linkdef)
110 return (target, source)
115 action=
'rootcling --failOnWarnings -f $TARGET $CLINGFLAGS -rmf "${TARGET.base}.rootmap" -rml lib${ROOTCLING_ROOTMAP_LIB}.so '
116 '$_CPPDEFFLAGS $_CPPINCFLAGS $SOURCES',
117 emitter=linkdef_emitter,
118 source_scanner=CScanner())
119rootcling.action.cmdstr =
'${ROOTCLINGCOMSTR}'
122classversion = Builder(action=
'b2code-classversion-check --error-style gcc $SOURCE && touch $TARGET')
123classversion.action.cmdstr =
'${CLASSVERSIONCOMSTR}'
127 env[
'BUILDERS'][
'RootDict'] = rootcling
128 env[
'BUILDERS'][
'ClassVersionCheck'] = classversion