# Copyright (c) 2013, 2015-2020 ARM Limited # All rights reserved. # # The license below extends only to copyright in the software and shall # not be construed as granting a license to any other intellectual # property including but not limited to intellectual property relating # to a hardware implementation of the functionality of the software # licensed hereunder. You may use the software subject to the license # terms below provided that you ensure that this notice is replicated # unmodified and in its entirety in all distributions of the software, # modified or unmodified, in source code or in binary form. # # Copyright (c) 2011 Advanced Micro Devices, Inc. # Copyright (c) 2009 The Hewlett-Packard Development Company # Copyright (c) 2004-2005 The Regents of The University of Michigan # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer; # redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution; # neither the name of the copyright holders nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import contextlib import os import SCons.Script import SCons.Util def CheckCxxFlag(context, flag, autoadd=True): context.Message("Checking for compiler %s support... " % flag) last_cxxflags = context.env['CXXFLAGS'] context.env.Append(CXXFLAGS=[flag]) ret = context.TryCompile('// CheckCxxFlag DO NOTHING', '.cc') if not (ret and autoadd): context.env['CXXFLAGS'] = last_cxxflags context.Result(ret) return ret def CheckLinkFlag(context, flag, autoadd=True, set_for_shared=True): context.Message("Checking for linker %s support... " % flag) last_linkflags = context.env['LINKFLAGS'] context.env.Append(LINKFLAGS=[flag]) ret = context.TryLink('int main(int, char *[]) { return 0; }', '.cc') if not (ret and autoadd): context.env['LINKFLAGS'] = last_linkflags if set_for_shared: assert(autoadd) context.env.Append(SHLINKFLAGS=[flag]) context.Result(ret) return ret # Add a custom Check function to test for structure members. def CheckMember(context, include, decl, member, include_quotes="<>"): context.Message("Checking for member %s in %s..." % (member, decl)) text = """ #include %(header)s int main(){ %(decl)s test; (void)test.%(member)s; return 0; }; """ % { "header" : include_quotes[0] + include + include_quotes[1], "decl" : decl, "member" : member, } ret = context.TryCompile(text, extension=".cc") context.Result(ret) return ret def CheckPythonLib(context): context.Message('Checking Python version... ') ret = context.TryRun(r""" #include int main(int argc, char **argv) { pybind11::scoped_interpreter guard{}; pybind11::exec( "import sys\n" "vi = sys.version_info\n" "sys.stdout.write('%i.%i.%i' % (vi.major, vi.minor, vi.micro));\n"); return 0; } """, extension=".cc") context.Result(ret[1] if ret[0] == 1 else 0) if ret[0] == 0: return None else: return tuple(map(int, ret[1].split("."))) def CheckPkgConfig(context, pkgs, *args): if not SCons.Util.is_List(pkgs): pkgs = [pkgs] assert(pkgs) for pkg in pkgs: context.Message('Checking for pkg-config package %s... ' % pkg) ret = context.TryAction('pkg-config %s' % pkg)[0] if not ret: context.Result(ret) continue if len(args) == 0: break cmd = ' '.join(['pkg-config'] + list(args) + [pkg]) try: context.env.ParseConfig(cmd) ret = 1 context.Result(ret) break except Exception as e: ret = 0 context.Result(ret) return ret @contextlib.contextmanager def Configure(env, *args, **kwargs): kwargs.setdefault('conf_dir', os.path.join(env['BUILDROOT'], '.scons_config')) kwargs.setdefault('log_file', os.path.join(env['BUILDROOT'], 'scons_config.log')) kwargs.setdefault('custom_tests', {}) kwargs['custom_tests'].update({ 'CheckCxxFlag' : CheckCxxFlag, 'CheckLinkFlag' : CheckLinkFlag, 'CheckMember' : CheckMember, 'CheckPkgConfig' : CheckPkgConfig, 'CheckPythonLib' : CheckPythonLib, }) conf = SCons.Script.Configure(env, *args, **kwargs) # Recent versions of scons substitute a "Null" object for Configure() # when configuration isn't necessary, e.g., if the "--help" option is # present. Unfortuantely this Null object always returns false, # breaking all our configuration checks. We replace it with our own # more optimistic null object that returns True instead. if not conf: def NullCheck(*args, **kwargs): return True class NullConf: def __init__(self, env): self.env = env def Finish(self): return self.env def __getattr__(self, mname): return NullCheck conf = NullConf(main) try: yield conf finally: env.Replace(**conf.Finish().Dictionary())