PR #2527 suggests "making failing tests more strict about failing
gracefully".
To achive this, make meson exit with distinct exit statuses for meson errors
and python exceptions, and check the exit status is as expected for failing
tests.
I can't see how to write a test for this, within the current framework.
You can test this change by reverting the fix (but not the test) from commit
1a159db8 and verifying that 'test cases/failing/66 string as link target'
fails.
Since c2a5ac39, MesonApp.generate() closes the logfile before returning,
which means that when invoked by mesonmain.run(), any MesonException is not
logged there.
MesonApp.generate() does not appear to have any other users I can find.
This somewhat reduces the diagnostic value of the logfile.
This also interacts badly with running project tests in CI, as _run_tests
chooses to report the logfile contents, rather than stdout, for the
configure step, and it thus doesn't report any configure error which caused
a test failure.
Examples:
meson.build:2:0: ERROR: Dependency is both required and not-found
meson.build:4: WARNING: Keyword argument "link_with" defined multiple times.
These are already matched by the default compilation-error-regexp-alist in
emacs.
Also:
Don't start 'red' markup until after the \n before an error
Unabsorb full-stop at end of warning with location from mlog.warning()
Update warning_location test
Currently passing a bad combo or array option, providing a non-boolean
to a bool arg, or a host of other things can cause an traceback from a
MesonException, don't do that.
Fixes#2683
Unfortunately, `time.time` and file timestamps are not guaranteed to be
in sync and due to various kernel caches may be different enough to
cause rebuilds to fail [1]. This was masked by older ninja versions that
could not read sub-second timestamps.
[1] https://travis-ci.org/mesonbuild/meson/jobs/296797872
Rather than requiring a bit of boilerplate in every meson.build, which is
only documented in a comment in mesoncore.py, use sensible defaults for
sysconfdir, localstatedir and sharedstatedir depending on the prefix.
Fixes#1637
v2:
For clarity, give get_builtin_option_default() a noneIfSuppress argument,
rather than overloading prefix '' and None with special meanings.
MESONINTROSPECT is set when running postconf scripts, which implies that
introspection is possible. But it isn't really possible because coredata
hasn't been written yet. We also still need to make sure to delete
coredata if any postconf scripts fail.
This is really useful when debugging test failures. Without a stack
trace, you have to grep the source code for the error message.
Also set this in run_tests.py.
Meson has a common pattern of using 'if len(foo) == 0:' or
'if len(foo) != 0:', however, this is a common anti-pattern in python.
Instead tests for emptiness/non-emptiness should be done with a simple
'if foo:' or 'if not foo:'
Consider the following:
>>> import timeit
>>> timeit.timeit('if len([]) == 0: pass')
0.10730923599840025
>>> timeit.timeit('if not []: pass')
0.030033907998586074
>>> timeit.timeit('if len(['a', 'b', 'c', 'd']) == 0: pass')
0.1154778649979562
>>> timeit.timeit("if not ['a', 'b', 'c', 'd']: pass")
0.08259823200205574
>>> timeit.timeit('if len("") == 0: pass')
0.089759664999292
>>> timeit.timeit('if not "": pass')
0.02340641999762738
>>> timeit.timeit('if len("foo") == 0: pass')
0.08848102600313723
>>> timeit.timeit('if not "foo": pass')
0.04032287199879647
And for the one additional case of 'if len(foo.strip()) == 0', which can
be replaced with 'if not foo.isspace()'
>>> timeit.timeit('if len(" ".strip()) == 0: pass')
0.15294511600222904
>>> timeit.timeit('if " ".isspace(): pass')
0.09413968399894657
>>> timeit.timeit('if len(" abc".strip()) == 0: pass')
0.2023209120015963
>>> timeit.timeit('if " abc".isspace(): pass')
0.09571301700270851
In other words, it's always a win to not use len(), when you don't
actually want to check the length.
Special wrap modes:
nofallback: Don't download wraps for dependency() fallbacks
nodownload: Don't download wraps for all subproject() calls
Subprojects are used for two purposes:
1. To download and build dependencies by using .wrap files if they
are not provided by the system. This is usually expressed via
dependency(..., fallback: ...).
2. To download and build 'copylibs' which are meant to be used by
copying into your project. This is always done with an explicit
subproject() call.
--wrap-mode=nofallback will never do (1)
--wrap-mode=nodownload will do neither (1) nor (2)
If you are building from a release tarball, you should be able to
safely use 'nodownload' since upstream is expected to ship all
required sources with the tarball.
If you are building from a git repository, you will want to use
'nofallback' so that any 'copylib' wraps will be download as
subprojects.
Note that these options do not affect subprojects that are git
submodules since those are only usable in git repositories, and you
almost always want to download them.
For newer VS versions, we can simply rely on 'VisualStudioVersion' being
set in the environment.
For VS2010, we fall back to check 'VSINSTALLDIR' for the version string.
If the backend can not be auto detected, we raise an exception to make the
user choose an explicit backend.
We also print the detected backend to the meson log.
VS2017 requires the 'WindowsTargetPlatformVersion' property to be set.
We gather the version to use from the environment variable
'WindowsSDKVersion' that will be set by the VS developer command prompt.
With the exception of things like sysconfdir (/etc), every other
installation directory option must be inside the prefix.
Also move the prefix checks to coredata.py since prefix can also be set
from inside project() with default_options and via mesonconf. Earlier
you could set prefix to a relative path that way.
This also allows us to return consistent values for get_option('xxxdir')
regardless of whether relative paths are passed or absolute paths are
passed while setting options on the command-line, via mesonconf, or via
default_options in project(). Now the returned path will *always* be
relative to the prefix.
Includes a unit test for this, and a failing test.
Closes#1299
The script will manually delete all custom_target outputs that are
directories instead of files. This is needed because on platforms other
than Windows, Ninja only deletes directories while cleaning if they are
empty.
Closes#1220
I hit an issue when building gtk-doc documentation. The issue is
my fault, but the error output from Meson makes it look like an
internal error:
[0/1] 'Running external command libtracker-sparql-doc.'
Building documentation for libtracker-sparql
Traceback (most recent call last):
File "/home/sam/meson/meson.py", line 26, in <module>
sys.exit(main())
File "/home/sam/meson/meson.py", line 23, in main
return mesonmain.run(launcher, sys.argv[1:])
File "/home/sam/meson/mesonbuild/mesonmain.py", line 249, in run
sys.exit(run_script_command(args[1:]))
File "/home/sam/meson/mesonbuild/mesonmain.py", line 239, in run_script_command
return cmdfunc(cmdargs)
File "/home/sam/meson/mesonbuild/scripts/gtkdochelper.py", line 183, in run
options.ignore_headers.split('@@') if options.ignore_headers else [])
File "/home/sam/meson/mesonbuild/scripts/gtkdochelper.py", line 133, in build_gtkdoc
gtkdoc_run_check(mkhtml_cmd, os.path.join(abs_out, 'html'))
File "/home/sam/meson/mesonbuild/scripts/gtkdochelper.py", line 55, in gtkdoc_run_check
raise MesonException('\n'.join(err_msg))
mesonbuild.mesonlib.MesonException: 'gtkdoc-mkhtml' failed with status 6
warning: failed to load external entity "../overview.sgml"
../libtracker-sparql-docs.sgml:20: element include: XInclude error :
could not load ../overview.sgml, and no fallback was found
warning: failed to load external entity "../examples.sgml"
../libtracker-sparql-docs.sgml:41: element include: XInclude error :
could not load ../examples.sgml, and no fallback was found
FAILED: libtracker-sparql-doc
After this patch, the output is much clearer:
[0/1] 'Running external command libtracker-sparql-doc.'
Building documentation for libtracker-sparql
Error in gtkdoc helper script:
'gtkdoc-mkhtml' failed with status 6
warning: failed to load external entity "../overview.sgml"
../libtracker-sparql-docs.sgml:20: element include: XInclude error :
could not load ../overview.sgml, and no fallback was found
warning: failed to load external entity "../examples.sgml"
../libtracker-sparql-docs.sgml:41: element include: XInclude error :
could not load ../examples.sgml, and no fallback was found
Note the actual errors from xsltproc are swallowed by gtkdoc-mkhtml
1.25.1, they're only displayed in the example above because I made a
patch: <https://bugzilla.gnome.org/show_bug.cgi?id=774812>