Write command line options into a separate file to be able to
reconfigure from scatch in the case coredata cannot be loaded. The most
common case is when we are reconfiguring with a newer meson version.
This means that we should try as much as possible to maintain backward
compatibility for the cmd_line.txt file format.
The main difference with a normal reconfigure is it will use new
default options values and will read again environment variables like
CFLAGS, etc.
This has the adventage that "meson --help" shows a list of all commands,
making them discoverable. This also reduce the manual parsing of
arguments to the strict minimum needed for backward compatibility.
All options are now the projectoptions list, regardless of how they got
defined in the command line.
This also delays setting builtin option values until the main project()
default options are parsed to simplify the code. This is possible
because we already delayed setting the backend after parsing main
project() in a previous commit.
This ensure all option groups are printed the same way. Also ensure that
we cannot miss some builtin options by taking the list of all builtin
options and excluding only directories/testing options.
When passing more than one -Dc_args it should override the value
instead of appending. This is how all other options works.
Value should be split on spaces using shlex just like it does with
CFLAGS environment variable.
Fixes#3473.
I'm not really happy about this to be honest, I don't like having both
-- and -D options, I think it's stupid to have two ways to do exactly
the same thing, especially since we then have to validate that someone
hasn't passed the argument both ways.
However, other people want this, so here it is.
Fixes#969
mesonconf prints build dir information in the order of
'Option' 'Description' 'Current Value' and, optionally, 'Possible Value'.
The Description tends to be longer and push the following values far
right, sometimes way far than fits in the full screen size of a
terminal on a FullHD monitor.
Experienced users know which options they want to change without
looking at the description string however they need to check the
current values for sure.
This patch moves the description to the last column. Now mesonconf
prints options in the following order:
'Option' 'Current Value' 'Possible Value' 'Description'
To implement this, mainly print_aligned() is modified. The second
argument of the function is changed from
- array of array of string to
- array of dict with 'name', 'descr', 'value', and 'choices,
which maps to 'option', 'description', 'current value' and 'possible
values', respectively.
Since the position of the possible values are moved before its
description, the presence and the length of it affects header as well
as the following description. Thus, we cal curate it before printing
the header.
To avoid re-calculation, we keep string version of the values and
flattened version of the possible values _in the given array_, which
means that now the print_aligned() function modify the the given
array. The current callers do not use the passing array. So there
should be no bad effects.
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.