aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Claessens <xavier.claessens@collabora.com>2018-05-13 10:36:58 -0400
committerNirbheek Chauhan <nirbheek.chauhan@gmail.com>2018-06-06 20:02:37 +0000
commit75e501ceb8888562b2749d20ba2c43374e5c9671 (patch)
tree48418eb4a15442f262fbe2a35477b14cf8c0e0ca
parent8afbfe227bb4f8848865f95980d51caf569eeff9 (diff)
downloadmeson-75e501ceb8888562b2749d20ba2c43374e5c9671.zip
meson-75e501ceb8888562b2749d20ba2c43374e5c9671.tar.gz
meson-75e501ceb8888562b2749d20ba2c43374e5c9671.tar.bz2
coredata: Stop setting default option values as argparse attribute
All options are now the projectoptions list, regardless of how they got defined in the command line. This also delays setting builtin option values until the main project() default options are parsed to simplify the code. This is possible because we already delayed setting the backend after parsing main project() in a previous commit.
-rw-r--r--mesonbuild/coredata.py50
-rw-r--r--mesonbuild/interpreter.py23
-rw-r--r--mesonbuild/mconf.py2
-rw-r--r--mesonbuild/mesonmain.py22
4 files changed, 29 insertions, 68 deletions
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index 07e5857..d0521b6 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -196,7 +196,7 @@ class CoreData:
self.regen_guid = str(uuid.uuid4()).upper()
self.target_guids = {}
self.version = version
- self.init_builtins(options)
+ self.init_builtins()
self.backend_options = {}
self.user_options = {}
self.compiler_options = {}
@@ -292,18 +292,12 @@ class CoreData:
value = value[skip:]
return value
- def init_builtins(self, options):
+ def init_builtins(self):
+ # Create builtin options with default values
self.builtins = {}
- # Sanitize prefix
- options.prefix = self.sanitize_prefix(options.prefix)
- # Initialize other builtin options
+ prefix = get_builtin_option_default('prefix')
for key in get_builtin_options():
- if hasattr(options, key):
- value = getattr(options, key)
- value = self.sanitize_dir_option_value(options.prefix, key, value)
- setattr(options, key, value)
- else:
- value = get_builtin_option_default(key, prefix=options.prefix)
+ value = get_builtin_option_default(key, prefix)
args = [key] + builtin_options[key][1:-1] + [value]
self.builtins[key] = builtin_options[key][0](*args)
@@ -459,21 +453,17 @@ def get_builtin_option_action(optname):
return 'store_true'
return None
-def get_builtin_option_default(optname, prefix='', noneIfSuppress=False):
+def get_builtin_option_default(optname, prefix=''):
if is_builtin_option(optname):
o = builtin_options[optname]
if o[0] == UserComboOption:
return o[3]
if o[0] == UserIntegerOption:
return o[4]
- if optname in builtin_dir_noprefix_options:
- if noneIfSuppress:
- # Return None if argparse defaulting should be suppressed for
- # this option (so we can determine the default later based on
- # prefix)
- return None
- elif prefix in builtin_dir_noprefix_options[optname]:
- return builtin_dir_noprefix_options[optname][prefix]
+ try:
+ return builtin_dir_noprefix_options[optname][prefix]
+ except KeyError:
+ pass
return o[2]
else:
raise RuntimeError('Tried to get the default value for an unknown builtin option \'%s\'.' % optname)
@@ -495,11 +485,7 @@ def add_builtin_argument(p, name):
kwargs['action'] = b
if c and not b:
kwargs['choices'] = c
- default = get_builtin_option_default(name, noneIfSuppress=True)
- if default is not None:
- kwargs['default'] = default
- else:
- kwargs['default'] = argparse.SUPPRESS
+ kwargs['default'] = argparse.SUPPRESS
kwargs['dest'] = name
cmdline_name = get_builtin_option_cmdline_name(name)
@@ -511,18 +497,15 @@ def register_builtin_arguments(parser):
parser.add_argument('-D', action='append', dest='projectoptions', default=[], metavar="option",
help='Set the value of an option, can be used several times to set multiple options.')
-def filter_builtin_options(args, original_args):
+def filter_builtin_options(args):
"""Filter out any builtin arguments passed as -- instead of -D.
Error if an argument is passed with -- and -D
"""
for name in builtin_options:
- # Check if user passed --option. Cannot use hasattr(args, name) here
- # because they are all set with default value if user didn't pass it.
cmdline_name = get_builtin_option_cmdline_name(name)
- has_dashdash = any([a.startswith(cmdline_name) for a in original_args])
-
- # Chekc if user passed -Doption=value
+ # Chekc if user passed -Doption=value or --option=value
+ has_dashdash = hasattr(args, name)
has_dashd = any([a.startswith('{}='.format(name)) for a in args.projectoptions])
# Passing both is ambigous, abort
@@ -533,7 +516,6 @@ def filter_builtin_options(args, original_args):
# Pretend --option never existed
if has_dashdash:
args.projectoptions.append('{}={}'.format(name, getattr(args, name)))
- if hasattr(args, name):
delattr(args, name)
def create_options_dict(options):
@@ -546,8 +528,8 @@ def create_options_dict(options):
result[key] = value
return result
-def parse_cmd_line_options(args, original_args):
- filter_builtin_options(args, original_args)
+def parse_cmd_line_options(args):
+ filter_builtin_options(args)
args.cmd_line_options = create_options_dict(args.projectoptions)
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 320e543..ffe942f 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -2218,18 +2218,8 @@ to directly access options of other subprojects.''')
if coredata.is_builtin_option(key):
if self.subproject != '':
continue # Only the master project is allowed to set global options.
- # If this was set on the command line, do not override.
- if not self.environment.had_argument_for(key):
- self.coredata.set_builtin_option(key, value)
- # If we are setting the prefix, then other options which
- # have prefix-dependent defaults need their value updating,
- # if they haven't been explicitly set (i.e. have their
- # default value)
- if key == 'prefix':
- for option in coredata.builtin_dir_noprefix_options:
- if not (self.environment.had_argument_for(option) or
- any([k.startswith(option + '=') for k in default_options])):
- self.coredata.set_builtin_option(option, coredata.get_builtin_option_default(option, value))
+ newoptions = [option] + self.environment.cmd_line_options.projectoptions
+ self.environment.cmd_line_options.projectoptions = newoptions
else:
# Option values set with subproject() default_options override those
# set in project() default_options.
@@ -2256,6 +2246,14 @@ to directly access options of other subprojects.''')
newoptions = [defopt] + self.environment.cmd_line_options.projectoptions
self.environment.cmd_line_options.projectoptions = newoptions
+ def set_builtin_options(self):
+ # Create a dict containing only builtin options, then use
+ # coredata.set_options() because it already has code to set the prefix
+ # option first to sanitize all other options.
+ options = coredata.create_options_dict(self.environment.cmd_line_options.projectoptions)
+ options = {k: v for k, v in options.items() if coredata.is_builtin_option(k)}
+ self.coredata.set_options(options)
+
def set_backend(self):
# The backend is already set when parsing subprojects
if self.backend is not None:
@@ -2301,6 +2299,7 @@ to directly access options of other subprojects.''')
self.parse_default_options(default_options)
if not self.is_subproject():
self.build.project_name = proj_name
+ self.set_builtin_options()
if os.path.exists(self.option_file):
oi = optinterpreter.OptionInterpreter(self.subproject,
self.build.environment.cmd_line_options.projectoptions,
diff --git a/mesonbuild/mconf.py b/mesonbuild/mconf.py
index e4b62fd..c4d4bb4 100644
--- a/mesonbuild/mconf.py
+++ b/mesonbuild/mconf.py
@@ -155,7 +155,7 @@ def run(args):
if not args:
args = [os.getcwd()]
options = buildparser().parse_args(args)
- coredata.parse_cmd_line_options(options, args)
+ coredata.parse_cmd_line_options(options)
if len(options.directory) > 1:
print('%s <build directory>' % args[0])
print('If you omit the build directory, the current directory is substituted.')
diff --git a/mesonbuild/mesonmain.py b/mesonbuild/mesonmain.py
index 50a8c7e..0d210c4 100644
--- a/mesonbuild/mesonmain.py
+++ b/mesonbuild/mesonmain.py
@@ -52,26 +52,6 @@ def wrapmodetype(string):
msg = 'invalid argument {!r}, use one of {}'.format(string, msg)
raise argparse.ArgumentTypeError(msg)
-def filter_builtin_options(args, original_args):
- """Filter out any builtin arguments passed as -D options.
-
- Error if an argument is passed with -- and -D
- """
- arguments = dict(p.split('=', 1) for p in args.projectoptions)
- meson_opts = set(arguments).intersection(set(coredata.builtin_options))
- if meson_opts:
- for arg in meson_opts:
- value = arguments[arg]
- cmdline_name = coredata.get_builtin_option_cmdline_name(arg)
- if any([a.startswith(cmdline_name) for a in original_args]):
- raise MesonException(
- 'Argument "{0}" passed as both {1} and -D{0}, but only '
- 'one is allowed'.format(arg, cmdline_name))
- setattr(args, arg, value)
-
- # Remove the builtin option from the project args values
- args.projectoptions.remove('{}={}'.format(arg, value))
-
class MesonApp:
def __init__(self, dir1, dir2, handshake, options, original_cmd_line_args):
@@ -334,7 +314,7 @@ def run(original_args, mainfile):
args = mesonlib.expand_arguments(args)
options = parser.parse_args(args)
- filter_builtin_options(options, args)
+ coredata.parse_cmd_line_options(options)
args = options.directories
if not args or len(args) > 2:
# if there's a meson.build in the dir above, and not in the current