Coverage for python/lsst/sconsUtils/state.py: 30%
Shortcuts on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""Global state for sconsUtils.
3This module acts like a singleton, holding all global state for sconsUtils.
4This includes the primary Environment object (`lsst.sconsUtils.state.env`),
5the message log (`lsst.sconsUtils.state.log`), the command-line variables
6object (`lsst.sconsUtils.state.state.opts`), and a dictionary of command-line
7targets used to setup aliases, default targets, and dependencies
8(`lsst.sconsUtils.state.targets`). All four of these variables are aliased
9to the main `lsst.sconsUtils` scope, so there should be no need for users to
10deal with the state module directly.
12These are all initialized when the module is imported, but may be modified
13by other code (particularly `lsst.sconsUtils.dependencies.configure`).
14"""
16import os
17import re
18import shlex
20import SCons.Script
21import SCons.Conftest
22from . import eupsForScons
23from .utils import get_conda_prefix, use_conda_compilers
25SCons.Script.EnsureSConsVersion(2, 1, 0)
27"""A dictionary of SCons aliases and targets.
29These are used to setup aliases, default targets, and dependencies by
30`lsst.sconsUtils.scripts.BasicSConstruct.finish`.
31While one can still use env.Alias to setup aliases (and should for "install"),
32putting targets here will generally provide better build-time dependency
33handling (like ensuring everything is built before we try to install, and
34making sure SCons doesn't rebuild the world before installing).
36Users can add additional keys to the dictionary if desired.
38Targets should be added by calling extend() or using ``+=`` on the dict
39values, to keep the lists of targets from turning into lists-of-lists.
40"""
41targets = {"doc": [], "tests": [], "lib": [], "python": [], "examples": [], "include": [], "version": [],
42 "shebang": []}
44env = None
45log = None
46opts = None
49def _initOptions():
50 SCons.Script.AddOption('--checkDependencies', dest='checkDependencies',
51 action='store_true', default=False,
52 help="Verify dependencies with autoconf-style tests.")
53 SCons.Script.AddOption('--filterWarn', dest='filterWarn', action='store_true', default=False,
54 help="Filter out a class of warnings deemed irrelevant"),
55 SCons.Script.AddOption('--force', dest='force', action='store_true', default=False,
56 help="Set to force possibly dangerous behaviours")
57 SCons.Script.AddOption('--linkFarmDir', dest='linkFarmDir', action='store', default=None,
58 help="The directory of symbolic links needed to build and use the package")
59 SCons.Script.AddOption('--prefix', dest='prefix', action='store', default=False,
60 help="Specify the install destination")
61 SCons.Script.AddOption('--setenv', dest='setenv', action='store_true', default=False,
62 help="Treat arguments such as Foo=bar as defining construction variables")
63 SCons.Script.AddOption('--tag', dest='tag', action='store', default=None,
64 help="Declare product with this eups tag")
65 SCons.Script.AddOption('--verbose', dest='verbose', action='store_true', default=False,
66 help="Print additional messages for debugging.")
67 SCons.Script.AddOption('--traceback', dest='traceback', action='store_true', default=False,
68 help="Print full exception tracebacks when errors occur.")
69 SCons.Script.AddOption('--no-eups', dest='no_eups', action='store_true', default=False,
70 help="Do not use EUPS for configuration")
73def _initLog():
74 from . import utils
75 global log
76 log = utils.Log()
79def _initVariables():
80 files = []
81 if "optfile" in SCons.Script.ARGUMENTS: 81 ↛ 82line 81 didn't jump to line 82, because the condition on line 81 was never true
82 configfile = SCons.Script.ARGUMENTS["optfile"]
83 if configfile not in files:
84 files.append(configfile)
85 for file in files: 85 ↛ 86line 85 didn't jump to line 86, because the loop on line 85 never started
86 if not os.path.isfile(file):
87 log.warn("Warning: Will ignore non-existent options file, %s" % file)
88 if "optfile" not in SCons.Script.ARGUMENTS: 88 ↛ 91line 88 didn't jump to line 91, because the condition on line 88 was never false
89 files.append("buildOpts.py")
90 global opts
91 opts = SCons.Script.Variables(files)
92 opts.AddVariables(
93 ('archflags', 'Extra architecture specification to add to CC/LINK flags (e.g. -m32)', ''),
94 ('cc', 'Choose the compiler to use', ''),
95 SCons.Script.BoolVariable('debug', 'Set to enable debugging flags (use --debug)', True),
96 ('eupsdb', 'Specify which element of EUPS_PATH should be used', None),
97 ('flavor', 'Set the build flavor', None),
98 SCons.Script.BoolVariable('force', 'Set to force possibly dangerous behaviours', False),
99 ('optfile', 'Specify a file to read default options from', None),
100 ('prefix', 'Specify the install destination', None),
101 SCons.Script.EnumVariable('opt', 'Set the optimisation level', 3,
102 allowed_values=('g', '0', '1', '2', '3')),
103 SCons.Script.EnumVariable('profile', 'Compile/link for profiler', 0,
104 allowed_values=('0', '1', 'pg', 'gcov')),
105 ('version', 'Specify the version to declare', None),
106 ('baseversion', 'Specify the current base version', None),
107 ('optFiles', "Specify a list of files that SHOULD be optimized", None),
108 ('noOptFiles', "Specify a list of files that should NOT be optimized", None),
109 ('macosx_deployment_target', 'Deployment target for Mac OS X', '10.9'),
110 )
113def _initEnvironment():
114 """Construction and basic setup of the state.env variable."""
116 ourEnv = {}
117 preserveVars = """
118 DYLD_LIBRARY_PATH
119 EUPS_DIR
120 EUPS_LOCK_PID
121 EUPS_PATH
122 EUPS_SHELL
123 EUPS_USERDATA
124 LD_LIBRARY_PATH
125 PATH
126 SHELL
127 TEMP
128 TERM
129 TMP
130 TMPDIR
131 XPA_PORT
132 CONDA_BUILD_SYSROOT
133 SDKROOT
134 """.split()
136 codeCheckerVars = """
137 LD_PRELOAD
138 CC_LOGGER_FILE
139 CC_LOGGER_GCC_LIKE
140 CC_LIB_DIR
141 CC_DATA_FILES_DIR
142 CC_LOGGER_BIN
143 """.split()
145 for key in preserveVars:
146 if key in os.environ:
147 ourEnv[key] = os.environ[key]
149 # check if running in CodeChecker environment
150 if "CC_LOGGER_BIN" in os.environ: 150 ↛ 151line 150 didn't jump to line 151, because the condition on line 150 was never true
151 for key in codeCheckerVars:
152 if key in os.environ:
153 ourEnv[key] = os.environ[key]
155 # Find and propagate EUPS environment variables.
156 cfgPath = []
157 for k in os.environ:
158 m = re.search(r"^(?P<name>\w+)_DIR(?P<extra>_EXTRA)?$", k)
159 if not m:
160 continue
161 cfgPath.append(os.path.join(os.environ[k], "ups"))
162 cfgPath.append(os.path.join(os.environ[k], "configs"))
163 if m.group("extra"): 163 ↛ 164line 163 didn't jump to line 164, because the condition on line 163 was never true
164 cfgPath.append(os.environ[k])
165 else:
166 cfgPath.append(os.path.join(os.environ[k], "ups"))
167 p = m.group("name")
168 varname = eupsForScons.utils.setupEnvNameFor(p)
169 if varname in os.environ: 169 ↛ 157line 169 didn't jump to line 157, because the condition on line 169 was never false
170 ourEnv[varname] = os.environ[varname]
171 ourEnv[k] = os.environ[k]
173 # add <build root>/ups directory to the configuration search path
174 # this allows the .cfg file for the package being built to be found without
175 # requiring <product name>_DIR to be in the env
176 cfgPath.append(os.path.join(SCons.Script.Dir('#').abspath, 'ups'))
178 #
179 # Add any values marked as export=FOO=XXX[,GOO=YYY] to ourEnv
180 #
181 exportVal = SCons.Script.ARGUMENTS.pop("export", None)
182 if exportVal: 182 ↛ 183line 182 didn't jump to line 183, because the condition on line 182 was never true
183 for kv in exportVal.split(','):
184 k, v = kv.split('=')
185 ourEnv[k] = v
186 global env
187 sconsUtilsPath, thisFile = os.path.split(__file__)
188 toolPath = os.path.join(sconsUtilsPath, "tools")
189 env = SCons.Script.Environment(
190 ENV=ourEnv,
191 variables=opts,
192 toolpath=[toolPath],
193 tools=["default", "cuda"]
194 )
195 env.cfgPath = cfgPath
196 #
197 # We don't want "lib" inserted at the beginning of loadable module names;
198 # we'll import them under their given names.
199 #
200 env['LDMODULEPREFIX'] = ""
201 if env['PLATFORM'] == 'darwin': 201 ↛ 202line 201 didn't jump to line 202, because the condition on line 201 was never true
202 env['LDMODULESUFFIX'] = ".so"
203 if not re.search(r"-install_name", str(env['SHLINKFLAGS'])):
204 env.Append(SHLINKFLAGS=["-install_name", "${TARGET.file}"])
205 if not re.search(r"-headerpad_max_install_names", str(env['SHLINKFLAGS'])):
206 env.Append(SHLINKFLAGS=["-Wl,-headerpad_max_install_names"])
207 #
208 # We want to be explicit about the OS X version we're targeting
209 #
210 env['ENV']['MACOSX_DEPLOYMENT_TARGET'] = env['macosx_deployment_target']
211 # This flag is required for std::variant and std::filesystem
212 # on deployment platforms < 10.13 and 10.15
213 for flag in ("-D_LIBCPP_DISABLE_AVAILABILITY=1", ):
214 env["CFLAGS"].append(flag)
215 env["CXXFLAGS"].append(flag)
216 log.info("Setting OS X binary compatibility level: %s" % env['ENV']['MACOSX_DEPLOYMENT_TARGET'])
217 #
218 # For XCode 7.3 we need to explicitly add a trailing slash to library
219 # paths. This does not hurt things on older XCodes. We can remove this
220 # once XCode is fixed. See Apple radar rdr://25313838
221 #
222 env['LIBDIRSUFFIX'] = '/'
224 if use_conda_compilers(): 224 ↛ 251line 224 didn't jump to line 251, because the condition on line 224 was never false
225 _conda_prefix = get_conda_prefix()
226 if "LDFLAGS" in os.environ: 226 ↛ 227line 226 didn't jump to line 227, because the condition on line 226 was never true
227 LDFLAGS = shlex.split(os.environ['LDFLAGS']) # respects quoting!
228 LDFLAGS = [v for v in LDFLAGS if v[0:2] != '-L']
229 # this one breaks some linking in the eups build
230 LDFLAGS = [v for v in LDFLAGS if v != '-Wl,-dead_strip_dylibs']
231 env.Append(LIBPATH=["%s/lib" % _conda_prefix])
232 env.Append(LINKFLAGS=LDFLAGS)
233 env.Append(SHLINKFLAGS=LDFLAGS)
235 if "CFLAGS" in os.environ: 235 ↛ 236line 235 didn't jump to line 236, because the condition on line 235 was never true
236 CFLAGS = shlex.split(os.environ['CFLAGS']) # respects quoting!
237 CFLAGS = [v for v in CFLAGS if v[0:2] != '-I']
238 env.Append(CCFLAGS=CFLAGS)
240 if "CXXFLAGS" in os.environ: 240 ↛ 241line 240 didn't jump to line 241, because the condition on line 240 was never true
241 CXXFLAGS = shlex.split(os.environ['CXXFLAGS']) # respects quoting!
242 CXXFLAGS = [v for v in CXXFLAGS if v[0:2] != '-I']
243 CXXFLAGS = [v for v in CXXFLAGS if v[0:5] != '-std='] # we let LSST set this
244 CXXFLAGS = [v for v in CXXFLAGS if v not in CFLAGS] # conda puts in duplicates
245 env.Append(CXXFLAGS=CXXFLAGS)
247 #
248 # Remove valid options from the arguments
249 #
250 # SCons Variables do not behave like dicts
251 for opt in opts.keys():
252 try:
253 del SCons.Script.ARGUMENTS[opt]
254 except KeyError:
255 pass
256 #
257 # Process those arguments
258 #
259 for k in ("force", "prefix"): # these may now be set as options instead of variables
260 if SCons.Script.GetOption(k): 260 ↛ 261line 260 didn't jump to line 261, because the condition on line 260 was never true
261 env[k] = SCons.Script.GetOption(k)
263 if env['debug']: 263 ↛ 272line 263 didn't jump to line 272, because the condition on line 263 was never false
264 env.Append(CCFLAGS=['-g'])
266 #
267 # determine if EUPS is present
268 #
270 # --no-eups overides probing
271 # XXX is it possible to test python snippets as a scons action?
272 if SCons.Script.GetOption("no_eups"): 272 ↛ 273line 272 didn't jump to line 273, because the condition on line 272 was never true
273 env['no_eups'] = True
274 else:
275 env['no_eups'] = not eupsForScons.haveEups()
277 if not env.GetOption("no_progress"): 277 ↛ 286line 277 didn't jump to line 286, because the condition on line 277 was never false
278 if env['no_eups']: 278 ↛ 279line 278 didn't jump to line 279, because the condition on line 278 was never true
279 log.info('EUPS integration: disabled')
280 else:
281 log.info('EUPS integration: enabled')
283 #
284 # Find the eups path, replace 'flavor' in favor of 'PLATFORM' if needed.
285 #
286 eupsPath = None
287 try:
288 db = env['eupsdb']
289 if 'EUPS_PATH' not in os.environ:
290 raise RuntimeError("You can't use eupsdb=XXX without an EUPS_PATH set")
291 eupsPath = None
292 for d in os.environ['EUPS_PATH'].split(':'):
293 if re.search(r"/%s$|^%s/|/%s/" % (db, db, db), d):
294 eupsPath = d
295 break
296 if not eupsPath:
297 raise RuntimeError("I cannot find DB \"%s\" in $EUPS_PATH" % db)
298 except KeyError:
299 if 'EUPS_PATH' in os.environ: 299 ↛ 301line 299 didn't jump to line 301, because the condition on line 299 was never false
300 eupsPath = os.environ['EUPS_PATH'].split(':')[0]
301 env['eupsPath'] = eupsPath
302 try:
303 env['PLATFORM'] = env['flavor']
304 del env['flavor']
305 except KeyError:
306 pass
307 #
308 # Check arguments
309 #
310 errorStr = ""
311 #
312 # Process otherwise unknown arguments. If setenv is true,
313 # set construction variables; otherwise generate an error
314 #
315 if SCons.Script.GetOption("setenv"): 315 ↛ 316line 315 didn't jump to line 316, because the condition on line 315 was never true
316 for key in SCons.Script.ARGUMENTS:
317 env[key] = SCons.Script.Split(SCons.Script.ARGUMENTS[key])
318 else:
319 for key in SCons.Script.ARGUMENTS: 319 ↛ 320line 319 didn't jump to line 320, because the loop on line 319 never started
320 errorStr += " %s=%s" % (key, SCons.Script.ARGUMENTS[key])
321 if errorStr: 321 ↛ 322line 321 didn't jump to line 322, because the condition on line 321 was never true
322 log.fail("Unprocessed arguments:%s" % errorStr)
323 #
324 # We need a binary name, not just "Posix"
325 #
326 env['eupsFlavor'] = eupsForScons.flavor()
329_configured = False
332def _configureCommon():
333 """Configuration checks for the compiler, platform, and standard
334 libraries."""
335 global _configured
336 if _configured:
337 return
338 _configured = True
340 def ClassifyCc(context):
341 """Return a pair of string identifying the compiler in use.
343 Parameters
344 ----------
345 context : context
346 Context.
348 Returns
349 -------
350 compiler : `str`
351 Compiler to use, or "unknown".
352 version : `str`
353 Compiler version or "unknown".
354 """
355 versionNameList = (
356 (r"gcc(?:\-.+)? +\(.+\) +([0-9.a-zA-Z]+)", "gcc"),
357 (r"gnu-cc(?:\-.+)? +\(.+\) +([0-9.a-zA-Z]+)", "gcc"), # catch the conda-build compiler on linux
358 (r"\(GCC\) +([0-9.a-zA-Z]+) ", "gcc"),
359 (r"LLVM +version +([0-9.a-zA-Z]+) ", "clang"), # clang on Mac
360 (r"clang +version +([0-9.a-zA-Z]+) ", "clang"), # clang on linux or clang w/ conda on Mac
361 (r"\(ICC\) +([0-9.a-zA-Z]+) ", "icc"),
362 (r"cc \(Ubuntu +([0-9\~\-.a-zA-Z]+)\)", "gcc"), # gcc on Ubuntu (not always caught by #3 above)
363 )
365 context.Message("Checking who built the CC compiler...")
366 result = context.TryAction(SCons.Script.Action(r"$CC --version > $TARGET"))
367 ccVersDumpOK, ccVersDump = result[0:2]
368 if ccVersDumpOK:
369 for reStr, compilerName in versionNameList:
370 match = re.search(reStr, ccVersDump)
371 if match:
372 compilerVersion = match.groups()[0]
373 context.Result("%s=%s" % (compilerName, compilerVersion))
374 return (compilerName, compilerVersion)
375 context.Result("unknown")
376 return ("unknown", "unknown")
378 if env.GetOption("clean") or env.GetOption("no_exec") or env.GetOption("help"):
379 env.whichCc = "unknown" # who cares? We're cleaning/not execing, not building
380 else:
381 if use_conda_compilers():
382 # conda-build expects you to use the compilers as-is
383 env['CC'] = os.environ['CC']
384 env['CXX'] = os.environ['CXX']
386 conf = env.Configure(custom_tests={'ClassifyCc': ClassifyCc})
387 env.whichCc, env.ccVersion = conf.ClassifyCc()
388 if not env.GetOption("no_progress"):
389 log.info("CC is **CONDA** %s version %s" % (env.whichCc, env.ccVersion))
390 conf.Finish()
391 else:
392 if env['cc'] != '':
393 CC = CXX = None
394 if re.search(r"^gcc(-\d+(\.\d+)*)?( |$)", env['cc']):
395 CC = env['cc']
396 CXX = re.sub(r"^gcc", "g++", CC)
397 elif re.search(r"^icc( |$)", env['cc']):
398 CC = env['cc']
399 CXX = re.sub(r"^icc", "icpc", CC)
400 elif re.search(r"^clang( |$)", env['cc']):
401 CC = env['cc']
402 CXX = re.sub(r"^clang", "clang++", CC)
403 elif re.search(r"^cc( |$)", env['cc']):
404 CC = env['cc']
405 CXX = re.sub(r"^cc", "c++", CC)
406 else:
407 log.fail("Unrecognised compiler: %s" % env['cc'])
408 env0 = SCons.Script.Environment()
409 if CC and env['CC'] == env0['CC']:
410 env['CC'] = CC
411 if CC and env['CXX'] == env0['CXX']:
412 env['CXX'] = CXX
413 conf = env.Configure(custom_tests={'ClassifyCc': ClassifyCc})
414 env.whichCc, env.ccVersion = conf.ClassifyCc()
416 # If we have picked up a default compiler called gcc that is really
417 # clang, we call it clang to avoid confusion (gcc on macOS has
418 # subtly different options)
419 if not env['cc'] and env.whichCc == "clang" and env['CC'] == "gcc":
420 env['CC'] = "clang"
421 env['CXX'] = "clang++"
423 if not env.GetOption("no_progress"):
424 log.info("CC is %s version %s" % (env.whichCc, env.ccVersion))
425 conf.Finish()
427 #
428 # Compiler flags, including CCFLAGS for C and C++ and CXXFLAGS for C++ only
429 #
430 ARCHFLAGS = os.environ.get("ARCHFLAGS", env.get('archflags'))
431 if ARCHFLAGS:
432 env.Append(CCFLAGS=ARCHFLAGS.split())
433 env.Append(LINKFLAGS=ARCHFLAGS.split())
434 # We'll add warning and optimisation options last
435 if env['profile'] == '1' or env['profile'] == "pg":
436 env.Append(CCFLAGS=['-pg'])
437 env.Append(LINKFLAGS=['-pg'])
438 elif env['profile'] == 'gcov':
439 env.Append(CCFLAGS='--coverage')
440 env.Append(LINKFLAGS='--coverage')
442 #
443 # Enable C++17 support
444 #
445 if not (env.GetOption("clean") or env.GetOption("help") or env.GetOption("no_exec")):
446 if not env.GetOption("no_progress"):
447 log.info("Checking for C++17 support")
448 conf = env.Configure()
449 for cpp17Arg in ("-std=%s" % (val,) for val in ("c++17",)):
450 conf.env = env.Clone()
451 conf.env.Append(CXXFLAGS=cpp17Arg)
452 if conf.CheckCXX():
453 env.Append(CXXFLAGS=cpp17Arg)
454 if not env.GetOption("no_progress"):
455 log.info("C++17 supported with %r" % (cpp17Arg,))
456 break
457 else:
458 log.fail("C++17 extensions could not be enabled for compiler %r" % env.whichCc)
459 conf.Finish()
461 #
462 # Byte order
463 #
464 import socket
465 if socket.htons(1) != 1:
466 env.Append(CCFLAGS=['-DLSST_LITTLE_ENDIAN=1'])
467 #
468 # If we're linking to libraries that themselves linked to
469 # shareable libraries we need to do something special.
470 #
471 if (re.search(r"^(Linux|Linux64)$", env["eupsFlavor"]) and "LD_LIBRARY_PATH" in os.environ):
472 env.Append(LINKFLAGS=["-Wl,-rpath-link"])
473 env.Append(LINKFLAGS=["-Wl,%s" % os.environ["LD_LIBRARY_PATH"]])
474 #
475 # Set the optimization level.
476 #
477 if env['opt']:
478 env["CCFLAGS"] = [o for o in env["CCFLAGS"] if not re.search(r"^-O(\d|s|g|fast)$", o)]
479 env.MergeFlags('-O%s' % env['opt'])
480 #
481 # Set compiler-specific warning flags.
482 #
483 if env.whichCc == "clang":
484 env.Append(CCFLAGS=['-Wall'])
485 env["CCFLAGS"] = [o for o in env["CCFLAGS"] if not re.search(r"^-mno-fused-madd$", o)]
487 ignoreWarnings = {
488 "unused-function": 'boost::regex has functions in anon namespaces in headers',
489 }
490 filterWarnings = {
491 "attributes": "clang pretends to be g++, but complains about g++ attributes such as flatten",
492 "char-subscripts": 'seems innocous enough, and is used by boost',
493 "constant-logical-operand": "Used by eigen 2.0.15. Should get this fixed",
494 "format-security": "format string is not a string literal",
495 "mismatched-tags": "mixed class and struct. Used by gcc 4.2 RTL and eigen 2.0.15",
496 "parentheses": "equality comparison with extraneous parentheses",
497 "shorten-64-to-32": "implicit conversion loses integer precision",
498 "self-assign": "x = x",
499 "unused-local-typedefs": "unused typedef", # lots from boost
500 "unknown-pragmas": "unknown pragma ignored",
501 "deprecated-register": "register is deprecated",
502 }
503 for k in ignoreWarnings:
504 env.Append(CCFLAGS=["-Wno-%s" % k])
505 if env.GetOption('filterWarn'):
506 for k in filterWarnings:
507 env.Append(CCFLAGS=["-Wno-%s" % k])
508 elif env.whichCc == "gcc":
509 env.Append(CCFLAGS=['-Wall'])
510 env.Append(CCFLAGS=["-Wno-unknown-pragmas"]) # we don't want complaints about icc/clang pragmas
511 env.Append(CCFLAGS=["-Wno-unused-local-typedefs"]) # boost generates a lot of these
512 elif env.whichCc == "icc":
513 env.Append(CCFLAGS=['-Wall'])
514 filterWarnings = {
515 21: 'type qualifiers are meaningless in this declaration',
516 68: 'integer conversion resulted in a change of sign',
517 111: 'statement is unreachable',
518 191: 'type qualifier is meaningless on cast type',
519 193: 'zero used for undefined preprocessing identifier "SYMB"',
520 279: 'controlling expression is constant',
521 304: 'access control not specified ("public" by default)', # comes from boost
522 383: 'value copied to temporary, reference to temporary used',
523 # 424: 'Extra ";" ignored',
524 444: 'destructor for base class "CLASS" is not virtual',
525 981: 'operands are evaluated in unspecified order',
526 1418: 'external function definition with no prior declaration',
527 1419: 'external declaration in primary source file',
528 1572: 'floating-point equality and inequality comparisons are unreliable',
529 1720: 'function "FUNC" has no corresponding member operator delete'
530 '(to be called if an exception is thrown during initialization of an allocated object)',
531 2259: 'non-pointer conversion from "int" to "float" may lose significant bits',
532 }
533 if env.GetOption('filterWarn'):
534 env.Append(CCFLAGS=["-wd%s" % (",".join([str(k) for k in filterWarnings]))])
535 # Workaround intel bug; cf. RHL's intel bug report 580167
536 env.Append(LINKFLAGS=["-Wl,-no_compact_unwind", "-wd,11015"])
537 #
538 # Disable link-time-optimization on GCC, for compatibility with conda
539 # binaries
540 #
541 if env.whichCc == "gcc":
542 env.Append(CCFLAGS=['-fno-lto'])
543 env.Append(LINKFLAGS=['-fno-lto'])
546def _saveState():
547 """Save state such as optimization level used.
549 Notes
550 -----
551 The scons mailing lists were unable to tell RHL how to get this back
552 from ``.sconsign.dblite``.
553 """
555 if env.GetOption("clean"):
556 return
558 # Python 2 uses ConfigParser, Python 3 uses configparser
559 try:
560 from configparser import ConfigParser
561 except ImportError:
562 from ConfigParser import ConfigParser
564 config = ConfigParser()
565 config.add_section('Build')
566 config.set('Build', 'cc', env.whichCc)
567 if env['opt']:
568 config.set('Build', 'opt', env['opt'])
570 try:
571 confFile = os.path.join(env.Dir(env["CONFIGUREDIR"]).abspath, "build.cfg")
572 with open(confFile, 'w') as configfile:
573 config.write(configfile)
574 except Exception as e:
575 log.warn("Unexpected exception in _saveState: %s" % e)
578_initOptions()
579_initLog()
580_initVariables()
581_initEnvironment()