Files
gem5/site_scons/gem5_scons/configure.py
Gabe Black 2bc3f873a9 scons: Add werror explicitly when checking for compatible options.
When checking whether a given option is supported, we try to compile or
link a small test program and see if that succeeded or not. There are
some options which are not really supported, but if you use them the
compiler might produce an error instead of failing to build. An example
of that is clang (version 9 at least) which will warn if you try to
disabled a warning it doesn't know about.

On the develop branch, this is fine since we have werror enabled, and
even these warnings will prevent the options from being enabled. On the
release branches where we disable werror for better future
compatibility, this causes a problem because these options still pass
the test and end up being enabled. This doesn't break the build, but
can cause a bunch of annoying and unnecessary warnings which clutter
up the build output.

To remove this inconsistency, we can enable werror just for the test
compiles or links which decide whether or not an option is supported.
That won't necessarily differentiate *why* a warning was generated, so
if through some strange combination of circumstances something else
causes a warning pervasively through the build, then this may think
an option is to blame and not enable it even though it's fine. This
seems unlikely though, and not worth worrying about without a specific
example showing that it can/will actually happen.

Change-Id: I6a1e3273c0b646a5636dc9986c70dcd5332f6f64
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/54624
Maintainer: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Bobby Bruce <bbruce@ucdavis.edu>
2021-12-21 22:09:11 +00:00

183 lines
6.5 KiB
Python

# 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])
pre_werror = context.env['CXXFLAGS']
context.env.Append(CXXFLAGS=['-Werror'])
ret = context.TryCompile('// CheckCxxFlag DO NOTHING', '.cc')
context.env['CXXFLAGS'] = pre_werror
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])
pre_werror = context.env['LINKFLAGS']
context.env.Append(CXXFLAGS=['-Werror'])
ret = context.TryLink('int main(int, char *[]) { return 0; }', '.cc')
context.env['LINKFLAGS'] = pre_werror
if not (ret and autoadd):
context.env['LINKFLAGS'] = last_linkflags
if (ret and 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 <pybind11/embed.h>
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())