-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathexternals.py
263 lines (213 loc) · 10.3 KB
/
externals.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import os
import subprocess
from setup_tools import env_vars, source_scripts, add_path, remove_path, \
lib_path_name
def get_python_incdir(bin_dir, lib_dir):
"""Determine the python include directory.
:param str bin_dir: directory containing the python executable
"""
script = os.path.join(bin_dir, "python3")
env = dict(os.environ)
env["LD_LIBRARY_PATH"] = lib_dir
proc = subprocess.Popen([script, "-c", "import sysconfig; print(sysconfig.get_path('include'))"],
stdout=subprocess.PIPE, env=env)
stdout = str(proc.communicate()[0].decode())
if proc.returncode != 0:
raise RuntimeError("Cannot determine python include directory" + script)
return stdout.strip()
def unsetup_externals(location, common=False):
"""function to unsetup an externals directory"""
if common:
subdir = os.path.join(os.environ["BELLE2_ARCH"], "common")
else:
unsetup_externals(location, True)
subdir = os.environ.get('BELLE2_EXTERNALS_SUBDIR',
os.environ['BELLE2_SUBDIR'])
# externals
bin_dir = os.path.join(location, subdir, 'bin')
lib_dir = os.path.join(location, subdir, 'lib')
remove_path('PATH', bin_dir)
remove_path(lib_path_name, lib_dir)
remove_path(lib_path_name, lib_dir + '64')
# geant4
remove_path("ROOT_INCLUDE_PATH", os.path.join(location, "include", "Geant4"))
remove_path("ROOT_INCLUDE_PATH", os.path.join(location, "include", "CLHEP"))
for var in os.environ.keys():
if var.startswith('G4'):
env_vars[var] = ''
# root
root_dir = os.path.join(location, subdir, "root")
if 'ROOTSYS' in env_vars and env_vars['ROOTSYS'] == root_dir:
env_vars['ROOTSYS'] = ''
remove_path('PATH', os.path.join(root_dir, 'bin'))
remove_path(lib_path_name, os.path.join(root_dir, 'lib'))
remove_path('PYTHONPATH', os.path.join(root_dir, 'lib'))
# remove root 6 include paths again
remove_path('ROOT_INCLUDE_PATH', location)
remove_path('ROOT_INCLUDE_PATH', os.path.join(location, 'include'))
if common:
# remove git
env_vars['GIT_EXEC_PATH'] = ''
env_vars['GIT_TEMPLATE_DIR'] = ''
env_vars['GIT_GUI_LIB_DIR'] = ''
env_vars['GITPERLLIB'] = ''
# and also intel compiler specific variable
env_vars['GXX_INCLUDE'] = ''
# and the valgrind tool directory
if os.path.exists(os.path.join(bin_dir, "valgrind")):
env_vars['VALGRIND_LIB'] = ''
# and remove python include path for all root classes which need python
remove_path('ROOT_INCLUDE_PATH', get_python_incdir(bin_dir, lib_dir))
# remove epics vars
env_vars['EPICS_BASE'] = ''
env_vars['EPICS_HOST_ARCH'] = ''
remove_path(lib_path_name, os.path.join(location, subdir, 'epics', 'lib', 'linux-x86_64'))
# pythia
env_vars['PYTHIA8DATA'] = ''
# panther
env_vars['PANTHER_TABLE_DIR'] = ''
def setup_externals(location, common=False):
"""function to setup an externals directory"""
if common:
subdir = os.path.join(os.environ["BELLE2_ARCH"], "common")
else:
setup_externals(location, True)
subdir = os.environ.get('BELLE2_EXTERNALS_SUBDIR',
os.environ['BELLE2_SUBDIR'])
bin_dir = os.path.join(location, subdir, 'bin')
lib_dir = os.path.join(location, subdir, 'lib')
add_path('PATH', bin_dir)
add_path(lib_path_name, lib_dir)
add_path(lib_path_name, lib_dir + '64')
# add include path so ROOT is able to find dictionary headers
add_path('ROOT_INCLUDE_PATH', location)
add_path('ROOT_INCLUDE_PATH', os.path.join(location, 'include'))
add_path('ROOT_INCLUDE_PATH', os.path.join(location, 'include', 'libxml2'))
# geant4
geant4_dir = os.path.join(location, subdir, 'bin')
if os.path.isfile(os.path.join(geant4_dir, 'geant4.sh')):
source_scripts.append([os.path.join(geant4_dir, 'geant4.sh'),
os.path.join(geant4_dir, 'geant4.csh')])
# make sure Geant4 includes are also found by ROOT in case someone
# includes those in a dataobject class
add_path("ROOT_INCLUDE_PATH", os.path.join(location, "include", "Geant4"))
add_path("ROOT_INCLUDE_PATH", os.path.join(location, "include", "CLHEP"))
# root
root_dir = os.path.join(location, subdir, "root", "bin")
if os.path.isfile(os.path.join(root_dir, "thisroot.sh")):
source_scripts.append([os.path.join(root_dir, "thisroot.sh"),
os.path.join(root_dir, "thisroot.csh")])
if common:
# we have to setup git to be relocatable. Inspired by bin-wrappers/git in the git build
# directory
env_vars['GIT_EXEC_PATH'] = os.path.join(location, subdir, 'lib', 'git-core')
env_vars['GIT_TEMPLATE_DIR'] = os.path.join(location, 'share', 'git-core', 'templates')
env_vars['GIT_GUI_LIB_DIR'] = os.path.join(location, 'share', 'git-gui', 'lib')
# set up perl path for for some git subcommands.
# Sadly this directory is somewhere depending on the distribution:
# - CentOS 7: share/perl5
# - Ubuntu: share/perl/$VERSION/
# So let's do the lazy approach and find it by looking at all
# possible directories and looking for Git.pm in there
def find_perl():
"""small helper to find the correct perl directory where the Git.pm is installed"""
for base in ["share/perl", "share/perl5"]:
abs_base = os.path.join(location, base)
for dirname, dirs, filenames in os.walk(abs_base):
if "Git.pm" in filenames:
return os.path.join(abs_base, dirname)
# nothing found ... let's not set it, only git-cvsexportcommit,
# git-svn, git-send-email, git-difftool, git-cvsimport and git-add
# --interactive seem to use it so this does not seem to be fatal.
sys.stderr.write("Warning: can not find Git perl bindings, some git commands might not work\n")
return ""
env_vars['GITPERLLIB'] = find_perl()
# set path to the GCC c++ includes for intel compiler. Seems to be
# needed in rare cases to avoid "icpc: error #10001: could not find
# directory in which the set of libstdc++ include files resides"
env_vars['GXX_INCLUDE'] = os.path.join(location, 'include', 'c++')
# another one: Valgrind has an absolute path to the tools compiled in
# (at least as far as I could find) so we have to set the environment
# correctly
if os.path.exists(os.path.join(bin_dir, "valgrind")):
env_vars['VALGRIND_LIB'] = os.path.join(location, subdir, 'lib', 'valgrind')
# and also add the python include path for all root classes which need python
add_path('ROOT_INCLUDE_PATH', get_python_incdir(bin_dir, lib_dir))
# set epics vars
env_vars['EPICS_BASE'] = os.path.join(location, subdir, 'epics')
env_vars['EPICS_HOST_ARCH'] = 'linux-x86_64'
add_path(lib_path_name, os.path.join(location, subdir, 'epics', 'lib', 'linux-x86_64'))
# ok, the rest is stuff we don't need fallbacks so we can return
return
# pythia
env_vars['PYTHIA8DATA'] = os.path.join(location, 'share', 'Pythia8', 'xmldoc')
# panther
env_vars['PANTHER_TABLE_DIR'] = os.path.join(location, 'share', 'belle_legacy', 'panther')
def check_externals(location):
"""function to check the externals installation"""
found_root = False
found_geant4 = False
option = os.environ.get('BELLE2_EXTERNALS_SUBDIR', os.environ['BELLE2_SUBDIR'])
for subdir in ["common", option]:
if not os.path.isfile(os.path.join(location, subdir, 'bin', 'geant4.sh')):
found_geant4 = True
root_dir = os.path.join(location, subdir, 'root')
if not os.path.isfile(os.path.join(root_dir, 'bin', 'root.exe')):
found_root = True
return found_root and found_geant4
def config_externals(conf):
"""function to configure the build system for the externals"""
from SCons.Script import Environment
subdir = os.environ.get('BELLE2_EXTERNALS_SUBDIR',
os.environ['BELLE2_SUBDIR'])
# fix externals directories
conf.env.Replace(
EXTINCDIR=os.path.join('$EXTDIR', 'include'),
EXTLIBDIR=os.path.join('$EXTDIR', subdir, 'lib'),
EXTBINDIR=os.path.join('$EXTDIR', subdir, 'bin'),
)
def add_incdir(*components):
"""small helper to add a directory to the system include path"""
conf.env.AppendUnique(CCFLAGS="-isystem%s" % os.path.normpath(os.path.join(*components)))
# configure python
python_env = Environment(ENV=os.environ)
python_env.ParseConfig("python3-config --includes --ldflags")
conf.env["PYTHON_LIBS"] = python_env["LIBS"]
conf.env.Append(LIBPATH=python_env["LIBPATH"])
for incdir in python_env["CPPPATH"]:
add_incdir(incdir)
# CLHEP
add_incdir(conf.env['EXTINCDIR'], 'CLHEP')
# Configure and setup Geant4
geant4_env = Environment(ENV=os.environ)
geant4_env.ParseConfig('geant4-config --cflags --libs')
conf.env['GEANT4_LIBS'] = geant4_env['LIBS']
conf.env.AppendUnique(CPPDEFINES=geant4_env['CPPDEFINES'])
for incdir in geant4_env['CPPPATH']:
add_incdir(incdir)
# PostgreSQL
conf.env['HAS_PGSQL'] = False
conf.env['PGSQL_LIBS'] = []
if conf.CheckLibWithHeader('pqxx', 'pgsql/pg_config.h', 'C++'):
conf.env['HAS_PGSQL'] = True
conf.env.Append(CPPDEFINES='-DHAS_PGSQL')
add_incdir(subprocess.Popen(['pg_config', '--includedir'],
stdout=subprocess.PIPE).communicate()[0].strip())
conf.env['PGSQL_LIBS'] = ['pqxx', 'pq']
# root
add_incdir(conf.env['EXTINCDIR'], 'root')
conf.env['ROOT_LIBS'] = conf.env['ROOT_GLIBS'] = []
if conf.CheckConfigTool('root-config'):
root_env = Environment(ENV=os.environ)
root_env.ParseConfig('root-config --libs')
conf.env['ROOT_LIBS'] = root_env['LIBS']
root_env.ParseConfig('root-config --glibs')
conf.env['ROOT_GLIBS'] = root_env['LIBS']
# Rave
conf.env.Append(CPPDEFINES={'RaveDllExport': ''})
# belle_legacy
add_incdir(conf.env['EXTINCDIR'], 'belle_legacy')
return True