Improve error when using the dependencies kwarg

The error message is misleading (talks about external dependencies), and
doesn't tell you what you need to do (use the output of
declare_dependency, dependency, or find_library). At the same time
rename add_external_deps to add_deps since it adds internal deps too.

Plus many more error message improvements all over the place.
pull/915/head
Nirbheek Chauhan 9 years ago
parent f79c4396f8
commit 70265c3782
  1. 31
      mesonbuild/build.py
  2. 43
      mesonbuild/interpreter.py

@ -514,7 +514,7 @@ class BuildTarget():
deplist = kwargs.get('dependencies', [])
if not isinstance(deplist, list):
deplist = [deplist]
self.add_external_deps(deplist)
self.add_deps(deplist)
self.custom_install_dir = kwargs.get('install_dir', None)
if self.custom_install_dir is not None:
if not isinstance(self.custom_install_dir, str):
@ -644,7 +644,7 @@ class BuildTarget():
def get_include_dirs(self):
return self.include_dirs
def add_external_deps(self, deps):
def add_deps(self, deps):
if not isinstance(deps, list):
deps = [deps]
for dep in deps:
@ -664,7 +664,7 @@ class BuildTarget():
[], [], [])
self.external_deps.append(extpart)
# Deps of deps.
self.add_external_deps(dep.ext_deps)
self.add_deps(dep.ext_deps)
elif isinstance(dep, dependencies.Dependency):
self.external_deps.append(dep)
self.process_sourcelist(dep.get_sources())
@ -673,10 +673,13 @@ class BuildTarget():
# about the interpreter so we can't import it and use isinstance.
# This should be reliable enough.
if hasattr(dep, 'subproject'):
raise InvalidArguments('''Tried to use subproject object as a dependency.
You probably wanted to use a dependency declared in it instead. Access it
by calling get_variable() on the subproject object.''')
raise InvalidArguments('Argument is not an external dependency.')
raise InvalidArguments('Tried to use subproject object as a dependency.\n'
'You probably wanted to use a dependency declared in it instead.\n'
'Access it by calling get_variable() on the subproject object.')
raise InvalidArguments('Argument is of an unacceptable type {!r}.\nMust be '
'either an external dependency (returned by find_library() or '
'dependency()) or an internal dependency (returned by '
'declare_dependency()).'.format(type(dep).__name__))
def get_external_deps(self):
return self.external_deps
@ -702,7 +705,7 @@ by calling get_variable() on the subproject object.''')
return
elif len(pchlist) == 1:
if not environment.is_header(pchlist[0]):
raise InvalidArguments('Pch argument %s is not a header.' % pchlist[0])
raise InvalidArguments('PCH argument %s is not a header.' % pchlist[0])
elif len(pchlist) == 2:
if environment.is_header(pchlist[0]):
if not environment.is_source(pchlist[1]):
@ -745,8 +748,7 @@ by calling get_variable() on the subproject object.''')
class Generator():
def __init__(self, args, kwargs):
if len(args) != 1:
raise InvalidArguments('Generator requires one and only one positional argument')
raise InvalidArguments('Generator requires exactly one positional argument: the executable')
exe = args[0]
if hasattr(exe, 'held_object'):
exe = exe.held_object
@ -1168,8 +1170,7 @@ class CustomTarget:
raise InvalidArguments('Output must not contain a path segment.')
self.capture = kwargs.get('capture', False)
if self.capture and len(self.output) != 1:
raise InvalidArguments(
'Capturing can only output to a single file.')
raise InvalidArguments('Capturing can only output to a single file.')
if 'command' not in kwargs:
raise InvalidArguments('Missing keyword argument "command".')
if 'depfile' in kwargs:
@ -1190,7 +1191,7 @@ class CustomTarget:
final_cmd.append(c)
elif isinstance(c, dependencies.ExternalProgram):
if not c.found():
raise InvalidArguments('Tried to use not found external program in a build rule.')
raise InvalidArguments('Tried to use not found external program {!r} in a build rule.'.format(c.name))
final_cmd += c.get_command()
elif isinstance(c, (BuildTarget, CustomTarget)):
self.dependencies.append(c)
@ -1231,7 +1232,7 @@ class CustomTarget:
while hasattr(ed, 'held_object'):
ed = ed.held_object
if not isinstance(ed, (CustomTarget, BuildTarget)):
raise InvalidArguments('Can only depend on toplevel targets.')
raise InvalidArguments('Can only depend on toplevel targets: custom_target or build_target (executable or a library)')
self.extra_depends.append(ed)
depend_files = kwargs.get('depend_files', [])
if not isinstance(depend_files, list):
@ -1241,7 +1242,7 @@ class CustomTarget:
self.depend_files.append(i)
else:
mlog.debug(i)
raise InvalidArguments('Unknown type in depend_files.')
raise InvalidArguments('Unknown type {!r} in depend_files.'.format(type(i).__name__))
def get_basename(self):
return self.name

@ -1559,7 +1559,7 @@ class Interpreter():
r = wrap.Resolver(os.path.join(self.build.environment.get_source_dir(), self.subproject_dir))
resolved = r.resolve(dirname)
if resolved is None:
msg = 'Subproject directory {!r} does not exist and can not be downloaded.'
msg = 'Subproject directory {!r} does not exist and cannot be downloaded.'
raise InterpreterException(msg.format(os.path.join(self.subproject_dir, dirname)))
subdir = os.path.join(self.subproject_dir, resolved)
os.makedirs(os.path.join(self.build.environment.get_build_dir(), subdir), exist_ok=True)
@ -2266,9 +2266,18 @@ requirements use the version keyword argument instead.''')
@stringArgs
def func_add_global_arguments(self, node, args, kwargs):
if self.subproject != '':
raise InvalidCode('Global arguments can not be set in subprojects because there is no way to make that reliable.')
msg = 'Global arguments can not be set in subprojects because ' \
'there is no way to make that reliable.\nPlease only call ' \
'this if is_subproject() returns false. Alternatively, ' \
'define a variable that\ncontains your language-specific ' \
'arguments and add it to the appropriate *_args kwarg ' \
'in each target.'
raise InvalidCode(msg)
if self.global_args_frozen:
raise InvalidCode('Tried to set global arguments after a build target has been declared.\nThis is not permitted. Please declare all global arguments before your targets.')
msg = 'Tried to set global arguments after a build target has ' \
'been declared.\nThis is not permitted. Please declare all ' \
'global arguments before your targets.'
raise InvalidCode(msg)
if not 'language' in kwargs:
raise InvalidCode('Missing language definition in add_global_arguments')
lang = kwargs['language'].lower()
@ -2280,11 +2289,20 @@ requirements use the version keyword argument instead.''')
@stringArgs
def func_add_global_link_arguments(self, node, args, kwargs):
if self.subproject != '':
raise InvalidCode('Global arguments can not be set in subprojects because there is no way to make that reliable.')
msg = 'Global link arguments can not be set in subprojects because ' \
'there is no way to make that reliable.\nPlease only call ' \
'this if is_subproject() returns false. Alternatively, ' \
'define a variable that\ncontains your language-specific ' \
'arguments and add it to the appropriate *_args kwarg ' \
'in each target.'
raise InvalidCode(msg)
if self.global_args_frozen:
raise InvalidCode('Tried to set global arguments after a build target has been declared.\nThis is not permitted. Please declare all global arguments before your targets.')
msg = 'Tried to set global link arguments after a build target has ' \
'been declared.\nThis is not permitted. Please declare all ' \
'global arguments before your targets.'
raise InvalidCode(msg)
if not 'language' in kwargs:
raise InvalidCode('Missing language definition in add_global_arguments')
raise InvalidCode('Missing language definition in add_global_link_arguments')
lang = kwargs['language'].lower()
if lang in self.build.global_link_args:
self.build.global_link_args[lang] += args
@ -2405,7 +2423,7 @@ requirements use the version keyword argument instead.''')
for l in self.get_used_languages(target):
if self.environment.cross_info.has_stdlib(l) and \
self.subproject != self.environment.cross_info.get_stdlib(l)[0]:
target.add_external_deps(self.build.cross_stdlibs[l])
target.add_deps(self.build.cross_stdlibs[l])
def check_sources_exist(self, subdir, sources):
for s in sources:
@ -2413,7 +2431,7 @@ requirements use the version keyword argument instead.''')
continue # This means a generated source and they always exist.
fname = os.path.join(subdir, s)
if not os.path.isfile(fname):
raise InterpreterException('Tried to add non-existing source %s.' % s)
raise InterpreterException('Tried to add non-existing source file %s.' % s)
def function_call(self, node):
func_name = node.func_name
@ -2469,7 +2487,7 @@ requirements use the version keyword argument instead.''')
else:
return posargs[1]
else:
raise InterpreterException('bool.to_string() must have either no arguments or exactly two string arguments.')
raise InterpreterException('bool.to_string() must have either no arguments or exactly two string arguments that signify what values to return for true and false.')
elif method_name == 'to_int':
if obj == True:
return 1
@ -2509,7 +2527,7 @@ requirements use the version keyword argument instead.''')
return re.sub(r'[^a-zA-Z0-9]', '_', obj)
elif method_name == 'split':
if len(posargs) > 1:
raise InterpreterException('Split() must have at most one argument.')
raise InterpreterException('Split() must have at most one argument.')
elif len(posargs) == 1:
s = posargs[0]
if not isinstance(s, str):
@ -2530,7 +2548,7 @@ requirements use the version keyword argument instead.''')
try:
return int(obj)
except Exception:
raise InterpreterException('String can not be converted to int: ' + obj)
raise InterpreterException('String {!r} cannot be converted to int'.format(obj))
elif method_name == 'join':
if len(posargs) != 1:
raise InterpreterException('Join() takes exactly one argument.')
@ -2635,8 +2653,7 @@ requirements use the version keyword argument instead.''')
for i in node.ifs:
result = self.evaluate_statement(i.condition)
if not(isinstance(result, bool)):
print(result)
raise InvalidCode('If clause does not evaluate to true or false.')
raise InvalidCode('If clause {!r} does not evaluate to true or false.'.format(result))
if result:
self.evaluate_codeblock(i.block)
return

Loading…
Cancel
Save