We have all the information needed to calculate the builtin arguments in
the coredata module already, don't duplicate that in the mesonmain
module as well.
Currently we manually pass the argparse action, this isn't very DRY,
since the builtin_types already has all the data necessary to find that.
This adds a new function to determine the action based on the default
type.
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