Fix yielding when subproject option type is different

Earlier, we would replace the subproject option with the parent
project's option, which is incorrect if the types are not the same.

Now we retain the subproject's option and print a warning. It's not
advisable to issue an error in this case because subproject option
yielding is involuntary for the parent project (option names can match
because of coincidences).
pull/3906/head
Nirbheek Chauhan 7 years ago committed by Jussi Pakkanen
parent 28754ea621
commit 219dec39c0
  1. 19
      mesonbuild/interpreter.py
  2. 3
      test cases/common/175 yield/meson.build
  3. 1
      test cases/common/175 yield/meson_options.txt
  4. 1
      test cases/common/175 yield/subprojects/sub/meson.build
  5. 1
      test cases/common/175 yield/subprojects/sub/meson_options.txt

@ -2279,7 +2279,7 @@ external dependencies (including libraries) must go to "dependencies".''')
return self.subprojects[dirname]
def get_option_internal(self, optname):
undecorated_optname = optname
raw_optname = optname
try:
return self.coredata.base_options[optname]
except KeyError:
@ -2296,9 +2296,20 @@ external dependencies (including libraries) must go to "dependencies".''')
optname = self.subproject + ':' + optname
try:
opt = self.coredata.user_options[optname]
if opt.yielding and ':' in optname:
# If option not present in superproject, keep the original.
opt = self.coredata.user_options.get(undecorated_optname, opt)
if opt.yielding and ':' in optname and raw_optname in self.coredata.user_options:
popt = self.coredata.user_options[raw_optname]
if type(opt) is type(popt):
opt = popt
else:
# Get class name, then option type as a string
opt_type = opt.__class__.__name__[4:][:-6].lower()
popt_type = popt.__class__.__name__[4:][:-6].lower()
# This is not a hard error to avoid dependency hell, the workaround
# when this happens is to simply set the subproject's option directly.
mlog.warning('Option {0!r} of type {1!r} in subproject {2!r} cannot yield '
'to parent option of type {3!r}, ignoring parent value. '
'Use -D{2}:{0}=value to set the value for this option manually'
'.'.format(raw_optname, opt_type, self.subproject, popt_type))
return opt
except KeyError:
pass

@ -3,4 +3,5 @@ project('yield_options', 'c')
subproject('sub')
assert(get_option('unshared_option') == 'one', 'Unshared option has wrong value in superproject.')
assert(get_option('shared_option') == 'two', 'Unshared option has wrong value in superproject..')
assert(get_option('shared_option') == 'two', 'Shared option has wrong value in superproject..')
assert(get_option('wrongtype_option') == 'three', 'Wrongtype option has wrong value in superproject..')

@ -1,2 +1,3 @@
option('unshared_option', type : 'string', value : 'one')
option('shared_option', type : 'string', value : 'two')
option('wrongtype_option', type : 'string', value : 'three')

@ -2,3 +2,4 @@ project('subbie', 'c')
assert(get_option('unshared_option') == 'three', 'Unshared option has wrong value in subproject.')
assert(get_option('shared_option') == 'two', 'Shared option has wrong value in subproject.')
assert(get_option('wrongtype_option') == true, 'Wrongtype option has wrong value in subproject.')

@ -1,2 +1,3 @@
option('unshared_option', type : 'string', value : 'three', yield : false)
option('shared_option', type : 'string', value : 'four', yield : true)
option('wrongtype_option', type : 'boolean', value : true, yield : true)

Loading…
Cancel
Save