Skip to content

Commit 2a1aed0

Browse files
authored
Merge 445fa1b into 57f91bb
2 parents 57f91bb + 445fa1b commit 2a1aed0

File tree

12 files changed

+127
-73
lines changed

12 files changed

+127
-73
lines changed

mesonbuild/backend/backends.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ def get_target_filename(self, t: T.Union[build.Target, build.CustomTargetIndex],
284284
if isinstance(t, build.CustomTarget):
285285
if warn_multi_output and len(t.get_outputs()) != 1:
286286
mlog.warning(f'custom_target {t.name!r} has more than one output! '
287-
'Using the first one.')
287+
f'Using the first one. Consider using `{t.name}[0]`.')
288288
filename = t.get_outputs()[0]
289289
elif isinstance(t, build.CustomTargetIndex):
290290
filename = t.get_outputs()[0]

mesonbuild/compilers/cpp.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ def non_msvc_eh_options(eh: str, args: T.List[str]) -> None:
5858
if eh == 'none':
5959
args.append('-fno-exceptions')
6060
elif eh in {'s', 'c'}:
61-
mlog.warning('non-MSVC compilers do not support ' + eh + ' exception handling.' +
62-
'You may want to set eh to \'default\'.')
61+
mlog.warning(f'non-MSVC compilers do not support {eh} exception handling. '
62+
'You may want to set eh to \'default\'.', fatal=False)
6363

6464
class CPPCompiler(CLikeCompiler, Compiler):
6565
def attribute_check_func(self, name: str) -> str:
@@ -690,7 +690,8 @@ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]
690690
key = OptionKey('std', machine=self.for_machine, lang=self.language)
691691
if options[key].value in {'vc++11', 'c++11'}:
692692
mlog.warning(self.id, 'does not support C++11;',
693-
'attempting best effort; setting the standard to C++14', once=True)
693+
'attempting best effort; setting the standard to C++14',
694+
once=True, fatal=False)
694695
# Don't mutate anything we're going to change, we need to use
695696
# deepcopy since we're messing with members, and we can't simply
696697
# copy the members because the option proxy doesn't support it.
@@ -730,7 +731,7 @@ def get_options(self) -> 'MutableKeyedOptionDictType':
730731
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
731732
key = OptionKey('std', machine=self.for_machine, lang=self.language)
732733
if options[key].value != 'none' and version_compare(self.version, '<19.00.24210'):
733-
mlog.warning('This version of MSVC does not support cpp_std arguments')
734+
mlog.warning('This version of MSVC does not support cpp_std arguments', fatal=False)
734735
options = copy.copy(options)
735736
options[key].value = 'none'
736737

mesonbuild/coredata.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,8 @@ def update_project_options(self, options: 'MutableKeyedOptionDictType') -> None:
782782
try:
783783
value.set_value(oldval.value)
784784
except MesonException:
785-
mlog.warning(f'Old value(s) of {key} are no longer valid, resetting to default ({value.value}).')
785+
mlog.warning(f'Old value(s) of {key} are no longer valid, resetting to default ({value.value}).',
786+
fatal=False)
786787

787788
def is_cross_build(self, when_building_for: MachineChoice = MachineChoice.HOST) -> bool:
788789
if when_building_for == MachineChoice.BUILD:

mesonbuild/dependencies/dev.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any]) ->
421421
# cmake if dynamic is required
422422
if not self.static:
423423
self.is_found = False
424-
mlog.warning('Ignoring LLVM CMake dependency because dynamic was requested')
424+
mlog.warning('Ignoring LLVM CMake dependency because dynamic was requested', fatal=False)
425425
return
426426

427427
if self.traceparser is None:
@@ -454,7 +454,7 @@ def _map_module_list(self, modules: T.List[T.Tuple[str, bool]], components: T.Li
454454
if required:
455455
raise self._gen_exception(f'LLVM module {mod} was not found')
456456
else:
457-
mlog.warning('Optional LLVM module', mlog.bold(mod), 'was not found')
457+
mlog.warning('Optional LLVM module', mlog.bold(mod), 'was not found', fatal=False)
458458
continue
459459
for i in cm_targets:
460460
res += [(i, required)]
@@ -533,8 +533,11 @@ def __init__(self, environment: 'Environment', kwargs: JNISystemDependencyKW):
533533
modules: T.List[str] = mesonlib.listify(kwargs.get('modules', []))
534534
for module in modules:
535535
if module not in {'jvm', 'awt'}:
536-
log = mlog.error if self.required else mlog.debug
537-
log(f'Unknown JNI module ({module})')
536+
msg = f'Unknown JNI module ({module})'
537+
if self.required:
538+
mlog.error(msg)
539+
else:
540+
mlog.debug(msg)
538541
self.is_found = False
539542
return
540543

mesonbuild/environment.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ def __init__(self, source_dir: T.Optional[str], build_dir: T.Optional[str], opti
455455
# If we stored previous command line options, we can recover from
456456
# a broken/outdated coredata.
457457
if os.path.isfile(coredata.get_cmd_line_file(self.build_dir)):
458-
mlog.warning('Regenerating configuration from scratch.')
458+
mlog.warning('Regenerating configuration from scratch.', fatal=False)
459459
mlog.log('Reason:', mlog.red(str(e)))
460460
coredata.read_cmd_line_file(self.build_dir, options)
461461
self.create_new_coredata(options)
@@ -551,7 +551,8 @@ def __init__(self, source_dir: T.Optional[str], build_dir: T.Optional[str], opti
551551
if bt in self.options and (db in self.options or op in self.options):
552552
mlog.warning('Recommend using either -Dbuildtype or -Doptimization + -Ddebug. '
553553
'Using both is redundant since they override each other. '
554-
'See: https://mesonbuild.com/Builtin-options.html#build-type-options')
554+
'See: https://mesonbuild.com/Builtin-options.html#build-type-options',
555+
fatal=False)
555556

556557
exe_wrapper = self.lookup_binary_entry(MachineChoice.HOST, 'exe_wrapper')
557558
if exe_wrapper is not None:

mesonbuild/interpreter/interpreter.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2892,10 +2892,12 @@ def check_clang_asan_lundef(self) -> None:
28922892
return
28932893
if (self.coredata.options[OptionKey('b_lundef')].value and
28942894
self.coredata.options[OptionKey('b_sanitize')].value != 'none'):
2895-
mlog.warning('''Trying to use {} sanitizer on Clang with b_lundef.
2896-
This will probably not work.
2897-
Try setting b_lundef to false instead.'''.format(self.coredata.options[OptionKey('b_sanitize')].value),
2898-
location=self.current_node)
2895+
value = self.coredata.options[OptionKey('b_sanitize')].value
2896+
mlog.warning(textwrap.dedent(f'''\
2897+
Trying to use {value} sanitizer on Clang with b_lundef.
2898+
This will probably not work.
2899+
Try setting b_lundef to false instead.'''),
2900+
location=self.current_node) # noqa: E128
28992901

29002902
# Check that the indicated file is within the same subproject
29012903
# as we currently are. This is to stop people doing

mesonbuild/mlog.py

Lines changed: 85 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
from __future__ import annotations
16+
import enum
1517
import os
1618
import io
1719
import sys
@@ -27,6 +29,9 @@
2729
if T.TYPE_CHECKING:
2830
from ._typing import StringProtocol, SizedStringProtocol
2931

32+
from .mparser import BaseNode
33+
34+
3035
"""This is (mostly) a standalone module used to write logging
3136
information about Meson runs. Some output goes to screen,
3237
some to logging dir and some goes to both."""
@@ -218,12 +223,12 @@ def process_markup(args: T.Sequence[TV_Loggable], keep: bool) -> T.List[str]:
218223
arr.append(str(arg))
219224
return arr
220225

221-
def force_print(*args: str, nested: bool, **kwargs: T.Any) -> None:
226+
def force_print(*args: str, nested: bool, sep: T.Optional[str] = None,
227+
end: T.Optional[str] = None) -> None:
222228
if log_disable_stdout:
223229
return
224230
iostr = io.StringIO()
225-
kwargs['file'] = iostr
226-
print(*args, **kwargs)
231+
print(*args, sep=sep, end=end, file=iostr)
227232

228233
raw = iostr.getvalue()
229234
if log_depth:
@@ -242,11 +247,11 @@ def force_print(*args: str, nested: bool, **kwargs: T.Any) -> None:
242247
cleaned = raw.encode('ascii', 'replace').decode('ascii')
243248
print(cleaned, end='')
244249

245-
# We really want a heterogeneous dict for this, but that's in typing_extensions
246-
def debug(*args: TV_Loggable, **kwargs: T.Any) -> None:
250+
def debug(*args: TV_Loggable, sep: T.Optional[str] = None,
251+
end: T.Optional[str] = None) -> None:
247252
arr = process_markup(args, False)
248253
if log_file is not None:
249-
print(*arr, file=log_file, **kwargs)
254+
print(*arr, file=log_file, sep=sep, end=end)
250255
log_file.flush()
251256

252257
def _debug_log_cmd(cmd: str, args: T.List[str]) -> None:
@@ -260,27 +265,30 @@ def cmd_ci_include(file: str) -> None:
260265

261266

262267
def log(*args: TV_Loggable, is_error: bool = False,
263-
once: bool = False, **kwargs: T.Any) -> None:
268+
once: bool = False, nested: bool = True,
269+
sep: T.Optional[str] = None,
270+
end: T.Optional[str] = None) -> None:
264271
if once:
265-
log_once(*args, is_error=is_error, **kwargs)
272+
log_once(*args, is_error=is_error, nested=nested, sep=sep, end=end)
266273
else:
267-
_log(*args, is_error=is_error, **kwargs)
274+
_log(*args, is_error=is_error, nested=nested, sep=sep, end=end)
268275

269276

270277
def _log(*args: TV_Loggable, is_error: bool = False,
271-
**kwargs: T.Any) -> None:
272-
nested = kwargs.pop('nested', True)
278+
nested: bool = True, sep: T.Optional[str] = None,
279+
end: T.Optional[str] = None) -> None:
273280
arr = process_markup(args, False)
274281
if log_file is not None:
275-
print(*arr, file=log_file, **kwargs)
282+
print(*arr, file=log_file, sep=sep, end=end)
276283
log_file.flush()
277284
if colorize_console():
278285
arr = process_markup(args, True)
279286
if not log_errors_only or is_error:
280-
force_print(*arr, nested=nested, **kwargs)
287+
force_print(*arr, nested=nested, sep=sep, end=end)
281288

282289
def log_once(*args: TV_Loggable, is_error: bool = False,
283-
**kwargs: T.Any) -> None:
290+
nested: bool = True, sep: T.Optional[str] = None,
291+
end: T.Optional[str] = None) -> None:
284292
"""Log variant that only prints a given message one time per meson invocation.
285293
286294
This considers ansi decorated values by the values they wrap without
@@ -296,7 +304,7 @@ def to_str(x: TV_Loggable) -> str:
296304
if t in _logged_once:
297305
return
298306
_logged_once.add(t)
299-
_log(*args, is_error=is_error, **kwargs)
307+
_log(*args, is_error=is_error, nested=nested, sep=sep, end=end)
300308

301309
# This isn't strictly correct. What we really want here is something like:
302310
# class StringProtocol(typing_extensions.Protocol):
@@ -308,26 +316,36 @@ def to_str(x: TV_Loggable) -> str:
308316
def get_error_location_string(fname: str, lineno: int) -> str:
309317
return f'{fname}:{lineno}:'
310318

311-
def _log_error(severity: str, *rargs: TV_Loggable,
312-
once: bool = False, fatal: bool = True, **kwargs: T.Any) -> None:
319+
320+
class _Severity(enum.Enum):
321+
322+
NOTICE = enum.auto()
323+
WARNING = enum.auto()
324+
ERROR = enum.auto()
325+
DEPRECATION = enum.auto()
326+
327+
328+
def _log_error(severity: _Severity, *rargs: TV_Loggable,
329+
once: bool = False, fatal: bool = True,
330+
location: T.Optional[BaseNode] = None,
331+
nested: bool = True, sep: T.Optional[str] = None,
332+
end: T.Optional[str] = None,
333+
is_error: bool = True) -> None:
313334
from .mesonlib import MesonException, relpath
314335

315336
# The typing requirements here are non-obvious. Lists are invariant,
316337
# therefore T.List[A] and T.List[T.Union[A, B]] are not able to be joined
317-
if severity == 'notice':
338+
if severity is _Severity.NOTICE:
318339
label = [bold('NOTICE:')] # type: TV_LoggableList
319-
elif severity == 'warning':
340+
elif severity is _Severity.WARNING:
320341
label = [yellow('WARNING:')]
321-
elif severity == 'error':
342+
elif severity is _Severity.ERROR:
322343
label = [red('ERROR:')]
323-
elif severity == 'deprecation':
344+
elif severity is _Severity.DEPRECATION:
324345
label = [red('DEPRECATION:')]
325-
else:
326-
raise MesonException('Invalid severity ' + severity)
327346
# rargs is a tuple, not a list
328347
args = label + list(rargs)
329348

330-
location = kwargs.pop('location', None)
331349
if location is not None:
332350
location_file = relpath(location.filename, os.getcwd())
333351
location_str = get_error_location_string(location_file, location.lineno)
@@ -336,25 +354,45 @@ def _log_error(severity: str, *rargs: TV_Loggable,
336354
location_list = T.cast('TV_LoggableList', [location_str])
337355
args = location_list + args
338356

339-
log(*args, once=once, **kwargs)
357+
log(*args, once=once, nested=nested, sep=sep, end=end, is_error=is_error)
340358

341359
global log_warnings_counter # pylint: disable=global-statement
342360
log_warnings_counter += 1
343361

344362
if log_fatal_warnings and fatal:
345363
raise MesonException("Fatal warnings enabled, aborting")
346364

347-
def error(*args: TV_Loggable, **kwargs: T.Any) -> None:
348-
return _log_error('error', *args, **kwargs, is_error=True)
349-
350-
def warning(*args: TV_Loggable, **kwargs: T.Any) -> None:
351-
return _log_error('warning', *args, **kwargs, is_error=True)
352-
353-
def deprecation(*args: TV_Loggable, **kwargs: T.Any) -> None:
354-
return _log_error('deprecation', *args, **kwargs, is_error=True)
355-
356-
def notice(*args: TV_Loggable, **kwargs: T.Any) -> None:
357-
return _log_error('notice', *args, **kwargs, is_error=False)
365+
def error(*args: TV_Loggable,
366+
once: bool = False, fatal: bool = True,
367+
location: T.Optional[BaseNode] = None,
368+
nested: bool = True, sep: T.Optional[str] = None,
369+
end: T.Optional[str] = None) -> None:
370+
return _log_error(_Severity.ERROR, *args, once=once, fatal=fatal, location=location,
371+
nested=nested, sep=sep, end=end, is_error=True)
372+
373+
def warning(*args: TV_Loggable,
374+
once: bool = False, fatal: bool = True,
375+
location: T.Optional[BaseNode] = None,
376+
nested: bool = True, sep: T.Optional[str] = None,
377+
end: T.Optional[str] = None) -> None:
378+
return _log_error(_Severity.WARNING, *args, once=once, fatal=fatal, location=location,
379+
nested=nested, sep=sep, end=end, is_error=True)
380+
381+
def deprecation(*args: TV_Loggable,
382+
once: bool = False, fatal: bool = True,
383+
location: T.Optional[BaseNode] = None,
384+
nested: bool = True, sep: T.Optional[str] = None,
385+
end: T.Optional[str] = None) -> None:
386+
return _log_error(_Severity.DEPRECATION, *args, once=once, fatal=fatal, location=location,
387+
nested=nested, sep=sep, end=end, is_error=True)
388+
389+
def notice(*args: TV_Loggable,
390+
once: bool = False, fatal: bool = True,
391+
location: T.Optional[BaseNode] = None,
392+
nested: bool = True, sep: T.Optional[str] = None,
393+
end: T.Optional[str] = None) -> None:
394+
return _log_error(_Severity.NOTICE, *args, once=once, fatal=fatal, location=location,
395+
nested=nested, sep=sep, end=end, is_error=False)
358396

359397
def get_relative_path(target: Path, current: Path) -> Path:
360398
"""Get the path to target from current"""
@@ -457,3 +495,14 @@ def stop_pager() -> None:
457495
pass
458496
log_pager.wait()
459497
log_pager = None
498+
499+
500+
def code_line(text: str, line: str, colno: int) -> str:
501+
"""Print a line with a caret pointing the colno
502+
503+
:param text: A message to display before the line
504+
:param line: The line of code to be pointed to
505+
:param colno: The column number to point at
506+
:return: A formatted string of the text, line, and a caret
507+
"""
508+
return f'{text}\n{line}\n{" " * colno}^'

mesonbuild/modules/gnome.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -319,14 +319,15 @@ def __print_gresources_warning(self, state: 'ModuleState') -> None:
319319
gresource_dep_needed_version):
320320
mlog.warning('GLib compiled dependencies do not work reliably with \n'
321321
'the current version of GLib. See the following upstream issue:',
322-
mlog.bold('https://bugzilla.gnome.org/show_bug.cgi?id=774368'))
322+
mlog.bold('https://bugzilla.gnome.org/show_bug.cgi?id=774368'),
323+
once=True, fatal=False)
323324

324325
@staticmethod
325326
def _print_gdbus_warning() -> None:
326327
mlog.warning('Code generated with gdbus_codegen() requires the root directory be added to\n'
327328
' include_directories of targets with GLib < 2.51.3:',
328329
mlog.bold('https://github.com/mesonbuild/meson/issues/1387'),
329-
once=True)
330+
once=True, fatal=False)
330331

331332
@typed_kwargs(
332333
'gnome.post_install',
@@ -1966,7 +1967,8 @@ def genmarshal(self, state: 'ModuleState', args: T.Tuple[str], kwargs: 'GenMarsh
19661967
else:
19671968
mlog.warning('The current version of GLib does not support extra arguments \n'
19681969
'for glib-genmarshal. You need at least GLib 2.53.3. See ',
1969-
mlog.bold('https://github.com/mesonbuild/meson/pull/2049'))
1970+
mlog.bold('https://github.com/mesonbuild/meson/pull/2049'),
1971+
once=True, fatal=False)
19701972
for k in ['internal', 'nostdinc', 'skip_source', 'stdinc', 'valist_marshallers']:
19711973
# Mypy can't figure out that this is correct
19721974
if kwargs[k]: # type: ignore

0 commit comments

Comments
 (0)