diff options
-rw-r--r-- | mesonbuild/coredata.py | 50 | ||||
-rw-r--r-- | mesonbuild/interpreter.py | 23 | ||||
-rw-r--r-- | mesonbuild/mconf.py | 2 | ||||
-rw-r--r-- | mesonbuild/mesonmain.py | 22 |
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 |