This isn't safe given the way python implements default arguments.
Basically python store a reference to the instance it was passed, and
then if that argument is not provided it uses the default. That means
that two calls to the same function get the same instance, if one of
them mutates that instance every subsequent call that gets the default
will receive the mutated instance. The idiom to this in python is to use
None and replace the None,
def in(value: str, container: Optional[List[str]]) -> boolean:
return src in (container or [])
if there is no chance of mutation it's less code to use or and take
advantage of None being falsy. If you may want to mutate the value
passed in you need a ternary (this example is stupid):
def add(value: str, container: Optional[List[str]]) -> None:
container = container if container is not None else []
container.append(value)
I've used or everywhere I'm sure that the value will not be mutated by
the function and erred toward caution by using ternaries for the rest.
Warn when someone tries to use append() or prepend() on an env var
which already has an operation set on it. People seem to think that
multiple append/prepend operations stack, but they don't.
Closes https://github.com/mesonbuild/meson/issues/5087
we can avoid writing code like:
a = c[0]
b = c[1]
by using:
a, b = c
or
a = c[0]
b = c[1:]
by using:
a, *b = c
This saves just a bit of code and is a teeny bit faster. But mostly
for less code
Currently this is implemented as range(min(len(a), len(b)), an then
indexing into a and b to get what we actually want. Fortunately python
provides a function called zip that just does this.
On Windows, program on a different drive than srcdir won't have
an expressible relative path; cmd_path will be absolute instead and
shouldn't get added into build_def_files.
This function is used just once. It also seems all policy and no
mechanism (it raises, it calls the same function to do all the work
twice in a simple way). This makes it seem to be as a good candidate for
inlining.
`environment` and `coredata` are woefully intertwined and while this
change doesn't fix that, but at least it makes it easier to follow.
This patch creates an enum for selecting libtype as static, shared,
prefer-static, or prefer-shared. This also renames 'static-shared'
with 'prefer_static' and 'shared-static' with 'prefer_shared'. This is
just a refactor with no behavioral changes or user facing changes.
This provides an initial support for parsing TAP output. It detects failures
and skipped tests without relying on exit code, as well as early termination
of the test due to an error or a crash.
For now, subtests are not recorded in the TestRun object. However, because the
TAP output goes on stdout, it is printed by --print-errorlogs when a test does
not behave as expected. Handling subtests as TestRuns, and serializing them
to JSON, can be added later.
The parser was written specifically for Meson, and comes with its own
test suite.
Fixes#2923.
First of all, I'd like compilers and other modules that environment.py
currently imports to be able to take these without creating
hard-to-follow module cycles.
Second of all, environment.py's exact purpose seems a bit obscured.
Splitting the data types (and basic pure functions) from the more
complex logic that infers that data seems like a good way to separate
concerns.
This allows the person running configure (either a developer, user, or
distro maintainer) to keep a configuration of where various kinds of
files should end up.
Instead use coredata.compiler_options.<machine>. This brings the cross
and native code paths closer together, since both now use that.
Command line options are interpreted just as before, for backwards
compatibility. This does introduce some funny conditionals. In the
future, I'd like to change the interpretation of command line options so
- The logic is cross-agnostic, i.e. there are no conditions affected by
`is_cross_build()`.
- Compiler args for both the build and host machines can always be
controlled by the command line.
- Compiler args for both machines can always be controlled separately.
Previously, the default option string was compared to the actual project
option that has been converted to the proper type. This lead to messages
like 'Option x is: true [default: true]'.
Fixes#4806.
* Fixed spelling
* Merged the Buildoptions and Projectinfo interpreter
* Moved detect_compilers to Environment
* Added removed test case
* Split detect_compilers and moved even more code into Environment
* Moved set_default_options to coredata
* Small code simplification in mintro.run
* Move cmd_line_options back to `environment`
We don't actually wish to persist something this unstructured, so we
shouldn't make it a field on `coredata`. It would also be data
denormalization since the information we already store in coredata
depends on the CLI args.
Not need to catch exceptions in dependency_fallback(), it's already
handled in do_subproject(). This ensure subproject errors are handled
the same way when doing dependency() fallback and when doing
subproject().
If a configure_file has an install_dir set, the supported install
argument is ignored, while this should have actually higher priority
than the install_dir itself.
Also check that correct types are used for `install` and `install_dir`.
Add test to verify this.
Fixes#3983
Building a cross compiler (`build == host != target`) is not cross
compiling. As such, it doesn't make sense to handle it under
`is_cross_build`.
(N.B. Building a standard library for a cross compiler would require
cross compiling, but Meson has support to do such a thing as part of a
compiler build currently.)
It is possible that the subproject has been downloaded already, in that
case there is no reason to not use it. If the subproject has not been
downlaoded already it will fail do_subproject().
Because we need to inherit them in some cases, and python's
keyword-or-positional arguments make this really painful, especially
with inheritance. They do this in two ways:
1) If you want to intercept the arguments you need to check for both a
keyword and a positional argument, because you could get either. Then
you need to make sure that you only pass one of those down to the
next layer.
2) After you do that, if the layer below you decides to do the same
thing, but uses the other form (you used keyword by the lower level
uses positional or vice versa), then you'll get a TypeError since two
layers down got the argument as both a positional and a keyword.
All of this is bad. Fortunately python 3.x provides a mechanism to solve
this, keyword only arguments. These arguments cannot be based
positionally, the interpreter will give us an error in that case.
I have made a best effort to do this correctly, and I've verified it
with GCC, Clang, ICC, and MSVC, but there are other compilers like Arm
and Elbrus that I don't have access to.
Currently, ComplierHolder.determine_args() unconditionally adds the link
arguments to the commmand, even if we aren't linking, because it doesn't
have access to the mode (preprocess, compile, link) that
_get_compiler_check_args() will use.
This leads to command lines like:
'cl testfile.c /nologo /showIncludes /c /Fooutput.obj /Od kernel32.lib
user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib
uuid.lib comdlg32.lib advapi32.lib'
which clang-cl considers invalid; MSVS cl accepts this, ignoring the
unneeded libraries
Change from passing extra_args down to _get_compiler_check_args(), to
passing down a callback to CompilerHolder.determine_args() (with a bound
kwargs argument), so it can consult mode and kwargs to determine the args to
use.
Some compilers try very had to pretend they're another compiler (ICC
pretends to be GCC and Linux and MacOS, and MSVC on windows), Clang
behaves much like GCC, but now also has clang-cl, which behaves like MSVC.
This method provides an easy way to determine whether testing for MSVC
like arguments `/w1234` or gcc like arguments `-Wfoo` are likely to
succeed, without having to check for dozens of compilers and the host
operating system, (as you would otherwise have to do with ICC).
It is a common idiom to look for a function or a specific type or
a header in various locations/libraries, and it can be confusing to
see the (seemingly) identical compiler check being done multiple
times.
Now we print the dependencies being used when a compiler check is run
Before:
Checking for function "fbGetDisplay": NO
Checking for type "GLeglImageOES": YES
Checking for function "asinh": YES
After:
Checking for function "fbGetDisplay" with dependency egl: NO
Checking for type "GLeglImageOES" with dependencies glesv2, gl: YES
Checking for function "asinh" with dependency -lm: YES
If a subproject is not required and fails during its configuration, the
parent project continues, but should not include any target or state set
by the failed subproject. This fix ninja still trying to build targets
generated by subprojects before they fail in their configuration.
The 'build' object is now per-interpreter instead of being global. Once
a subproject interpreter succeed, values from its 'build' object are
merged back into its parent 'build' object.
When dependency(), find_library(), find_program(), or
python.find_installation() return a not-found object and disabler is
true, they return a Disabler object instead.
If builddir and sourcedir have different drive letters, a relative path
doesn't exist, and os.path.relpath fails with a ValueError exception.
This just fixes the places which are hit by test cases in a simple-minded
way. There are several other uses of os.path.relpath(), which might be
suspect.
Fixes Issue #4323.
The check to see if a call to configure_file() overwrites the output of
a preceding call should perform the substitution for the output file
before doing the check.
Added tests to ensure the proper behaviour.
Instead of just putting these together in the interpreter, put them
together in `environment.py` so Meson's implementation can also better
take advantage of them.
meson.add_dist_script, introduced in #3906, did not accept any arguments
other than script name. Since all other meson.add_*_script methods
do accept args, this makes the dist script accept them as well.