@@ -885,9 +885,9 @@ def get_value_object_and_value_for(self, key: OptionKey) -> T.Tuple[AnyOptionTyp
885885 assert isinstance (key , OptionKey )
886886 vobject = self .get_value_object_for (key )
887887 computed_value = vobject .value
888- if key . subproject is not None :
889- if key in self . augments :
890- computed_value = vobject . validate_value ( self .augments [key ])
888+ if key in self . augments :
889+ assert key . subproject is not None
890+ computed_value = self .augments [key ]
891891 return (vobject , computed_value )
892892
893893 def option_has_value (self , key : OptionKey , value : ElementaryOptionValues ) -> bool :
@@ -1004,6 +1004,7 @@ def sanitize_dir_option_value(self, prefix: str, option: OptionKey, value: T.Any
10041004 return value .as_posix ()
10051005
10061006 def set_option (self , key : OptionKey , new_value : ElementaryOptionValues , first_invocation : bool = False ) -> bool :
1007+ changed = False
10071008 error_key = key
10081009 if error_key .subproject == '' :
10091010 error_key = error_key .evolve (subproject = None )
@@ -1040,13 +1041,18 @@ def replace(v: str) -> str:
10401041 elif isinstance (opt .deprecated , str ):
10411042 mlog .deprecation (f'Option "{ error_key } " is replaced by { opt .deprecated !r} ' )
10421043 # Change both this aption and the new one pointed to.
1043- dirty = self .set_option (key .evolve (name = opt .deprecated ), new_value )
1044- dirty |= opt .set_value (new_value )
1045- return dirty
1044+ changed |= self .set_option (key .evolve (name = opt .deprecated ), new_value , first_invocation )
10461045
1047- old_value = opt .value
1048- changed = opt .set_value (new_value )
1046+ new_value = opt .validate_value (new_value )
1047+ if key in self .options :
1048+ old_value = opt .value
1049+ opt .set_value (new_value )
1050+ else :
1051+ assert key .subproject is not None
1052+ old_value = self .augments .get (key , opt .value )
1053+ self .augments [key ] = new_value
10491054
1055+ changed |= old_value != new_value
10501056 if opt .readonly and changed and not first_invocation :
10511057 raise MesonException (f'Tried to modify read only option "{ error_key } "' )
10521058
@@ -1060,12 +1066,12 @@ def replace(v: str) -> str:
10601066 optimization , debug = self .DEFAULT_DEPENDENTS [new_value ]
10611067 dkey = key .evolve (name = 'debug' )
10621068 optkey = key .evolve (name = 'optimization' )
1063- self .options [ dkey ]. set_value ( debug )
1064- self .options [ optkey ]. set_value ( optimization )
1069+ self .set_option ( dkey , debug , first_invocation )
1070+ self .set_option ( optkey , optimization , first_invocation )
10651071
10661072 return changed
10671073
1068- def set_option_maybe_root (self , o : OptionKey , new_value : ElementaryOptionValues , first_invocation : bool = False ) -> bool :
1074+ def set_user_option (self , o : OptionKey , new_value : ElementaryOptionValues , first_invocation : bool = False ) -> bool :
10691075 if not self .is_cross and o .is_for_build ():
10701076 return False
10711077
@@ -1076,37 +1082,34 @@ def set_option_maybe_root(self, o: OptionKey, new_value: ElementaryOptionValues,
10761082 # can be either
10771083 #
10781084 # A) a system option in which case the subproject is None
1079- # B) a project option, in which case the subproject is '' (this method is only called from top level)
1085+ # B) a project option, in which case the subproject is ''
10801086 #
10811087 # The key parsing function can not handle the difference between the two
10821088 # and defaults to A.
10831089 if o in self .options :
10841090 return self .set_option (o , new_value , first_invocation )
1091+
1092+ # could also be an augment...
1093+ global_option = o .evolve (subproject = None )
1094+ if o .subproject is not None and global_option in self .options :
1095+ return self .set_option (o , new_value , first_invocation )
1096+
10851097 if self .accept_as_pending_option (o , first_invocation = first_invocation ):
10861098 old_value = self .pending_options .get (o , None )
10871099 self .pending_options [o ] = new_value
10881100 return old_value is None or str (old_value ) != new_value
1089- else :
1101+ elif o . subproject is None :
10901102 o = o .as_root ()
10911103 return self .set_option (o , new_value , first_invocation )
1104+ else :
1105+ raise MesonException (f'Unknown option: "{ o } ".' )
10921106
10931107 def set_from_configure_command (self , D_args : T .List [str ], U_args : T .List [str ]) -> bool :
10941108 dirty = False
10951109 D_args = [] if D_args is None else D_args
1096- (global_options , perproject_global_options , project_options ) = self .classify_D_arguments (D_args )
10971110 U_args = [] if U_args is None else U_args
1098- for key , valstr in global_options :
1099- dirty |= self .set_option_maybe_root (key , valstr )
1100- for key , valstr in project_options :
1101- dirty |= self .set_option_maybe_root (key , valstr )
1102- for key , valstr in perproject_global_options :
1103- if key in self .augments :
1104- if self .augments [key ] != valstr :
1105- self .augments [key ] = valstr
1106- dirty = True
1107- else :
1108- self .augments [key ] = valstr
1109- dirty = True
1111+ for key , valstr in self .parse_D_arguments (D_args ):
1112+ dirty |= self .set_user_option (key , valstr )
11101113 for keystr in U_args :
11111114 key = OptionKey .from_string (keystr )
11121115 if key in self .augments :
@@ -1232,23 +1235,13 @@ def is_compiler_option(self, key: OptionKey) -> bool:
12321235 def is_module_option (self , key : OptionKey ) -> bool :
12331236 return key in self .module_options
12341237
1235- def classify_D_arguments (self , D : T .List [str ]) -> T .Tuple [T .List [T .Tuple [OptionKey , str ]],
1236- T .List [T .Tuple [OptionKey , str ]],
1237- T .List [T .Tuple [OptionKey , str ]]]:
1238- global_options = []
1239- project_options = []
1240- perproject_global_options = []
1238+ def parse_D_arguments (self , D : T .List [str ]) -> T .List [T .Tuple [OptionKey , str ]]:
1239+ options = []
12411240 for setval in D :
12421241 keystr , valstr = setval .split ('=' , 1 )
12431242 key = OptionKey .from_string (keystr )
1244- valuetuple = (key , valstr )
1245- if self .is_project_option (key ):
1246- project_options .append (valuetuple )
1247- elif key .subproject is None :
1248- global_options .append (valuetuple )
1249- else :
1250- perproject_global_options .append (valuetuple )
1251- return (global_options , perproject_global_options , project_options )
1243+ options .append ((key , valstr ))
1244+ return options
12521245
12531246 def prefix_split_options (self , coll : OptionDict ) -> T .Tuple [T .Optional [str ], OptionDict ]:
12541247 prefix = None
@@ -1319,7 +1312,7 @@ def initialize_from_top_level_project_call(self,
13191312 # should arguably be a hard error; the default
13201313 # value of project option should be set in the option
13211314 # file, not in the project call.
1322- self .set_option_maybe_root (key , valstr , True )
1315+ self .set_user_option (key , valstr , True )
13231316
13241317 # ignore subprojects for now for machine file and command line
13251318 # options; they are applied later
@@ -1329,14 +1322,14 @@ def initialize_from_top_level_project_call(self,
13291322 if not self .is_cross and key .is_for_build ():
13301323 continue
13311324 if not key .subproject :
1332- self .set_option_maybe_root (key , valstr , True )
1325+ self .set_user_option (key , valstr , True )
13331326 for key , valstr in cmd_line_options .items ():
13341327 # Due to backwards compatibility we ignore all build-machine options
13351328 # when building natively.
13361329 if not self .is_cross and key .is_for_build ():
13371330 continue
13381331 if not key .subproject :
1339- self .set_option_maybe_root (key , valstr , True )
1332+ self .set_user_option (key , valstr , True )
13401333
13411334 def accept_as_pending_option (self , key : OptionKey , first_invocation : bool = False ) -> bool :
13421335 # Some base options (sanitizers etc) might get added later.
@@ -1401,11 +1394,9 @@ def initialize_from_subproject_call(self,
14011394 continue
14021395
14031396 self .pending_subproject_options .pop (key , None )
1404- valstr = self .augments .pop (key , valstr )
1405- if key in self .project_options :
1406- self .set_option (key , valstr , True )
1407- else :
1408- self .augments [key ] = valstr
1397+ self .pending_options .pop (key , None )
1398+ if key not in self .augments :
1399+ self .set_user_option (key , valstr , True )
14091400
14101401 self .subprojects .add (subproject )
14111402
0 commit comments