EnvironmentVariables was always broken, it used MutableMapping because
everyone <3 abstract interfaces, especially when they are broken and
don't actually do what you want.
This needs a dict interface, exposing `.copy()`. We either use a dict or
os._Environ, and the latter also supports that.
Also fix a broken import, and the fallout from forgetting to update the
signature of self.envvars in commit b926374205.
There are lots of warnings that become fatal, that are simply unfixable
by the end user. Things like using old versions of software (because
they're using some kind of LTS release), warnings about compilers not
supporting certain kinds of checks, or standards being upgraded due to
skipped implementations (MSVC has c++98 and c++14, but not c++11). None
of these should be fatal, they're informative, and too important to
reduce to notices, but not important enough to stop meson if they're
printed.
There should be a way to make mypy happy without casting, but I can't
figure it out, since the mlog.error and mlog.debug actually have
different signatures.
If `pkg-config --modversion foobar` fails, we don't know why. The
general issue here, though, is that call_pkgbin routinely logs stdout
for informational purposes, but not stderr.
Fixes#11076
Darwin-based systems, at least macOS, provide various JDK executable
stubs in
/System/Library/Frameworks/JavaVM.framework/Versions/*/Commands.
These stubs are placed in such a way that they break the heuristics of
the JNI system dependency. If a javac being analyzed to find a Java home
is a stub, use /usr/libexec/java_home.
See https://stackoverflow.com/a/15133344/7572728 for more details.
Closes#11173
T.Sequence is a questionable concept. The idea is to hammer out generic,
maximally forgiving APIs that operate on protocols, which is a fancy way
of saying "I don't care if you use tuples or lists". This is rarely
needed, actually, and in exchange for this fancy behavior you get free
bugs.
Specifically, `somestr` is of type `T.Sequence[str]`, and also
`somestr[0]` is another string of type you guessed it. It's ~~turtles~~
strings all the way down.
It's worth noting that trying to code for "protocols" is a broken
concept if the contents have semantic meaning, e.g. it operates on
"the install tags of this object" rather than "an iterable that supports
efficient element access".
The other way to use T.Sequence is "I don't like that T.List is
invariant, but also I don't like that T.Tuple makes you specify exact
ordering". This sort of works. In fact it probably does work as long as
you don't allow str in your sequences, which of course everyone allows
anyway.
Use of Sequence has cute side effects, such as actually passing lists
around, knowing that you are going to get a list and knowing that you
need to pass it on as a list, and then having to re-allocate as
`list(mylist)` "because the type annotations says it could be a str or
tuple".
Except it cannot be a str, because if it is then the application is
fatally flawed and logic errors occur to disastrous end user effects,
and the type annotations:
- do not enforce their promises of annotating types
- fail to live up to "minimal runtime penalties" due to all the `list()`
Shun this broken concept, by hardening the type annotations. As it turns
out, we do not actually need any of this covariance or protocol-ism for
a list of strings! The whole attempt was a slow, buggy waste of time.
We do some magic to figure out what names of pkg-config dependencies to
even search for. This magic simply checked for `pkg-config` the $PATH
executable, which was broken in a variety of ways and had a comment to
that effect.
The pkg-config dependency class has some interesting logic for finding a
good pkg-config that will be used for dependency lookups. We sometimes
need to use it, though, outside of the class. Make that possible.
Which adds the `use-set-for-membership` check. It's generally faster in
python to use a set with the `in` keyword, because it's a hash check
instead of a linear walk, this is especially true with strings, where
it's actually O(n^2), one loop over the container, and an inner loop of
the strings (as string comparison works by checking that `a[n] == b[n]`,
in a loop).
Also, I'm tired of complaining about this in reviews, let the tools do
it for me :)
This finds uses of deny-listed functions, which defaults to map and
filter. These functions should be replaced by comprehensions in
idiomatic python because:
1. comprehensions are more heavily optimized and are often faster
2. They avoid the need for lambdas in some cases, which make them
faster
3. you can do the equivalent in one statement rather than two, which
is faster
4. They're easier to read
5. if you need a concrete instance (ie, a list) then you don't have
to convert the iterator to a list afterwards
Which catches a very real bug. The zlib system dependency failed to work
on MSVC since initial implementation in commit
c1a3b37ab7 -- it looked for the wrong
name.
Add a MissingCompiler class returned by compiler detecting methods
intead of None - accessing such an object raises a DependencyException
Fixes#10586
Co-authored-by: duckflyer <duckflyer@gmail.com>
It is, after all, "safe". ;) That's why it exists. There's no reason to
think listing all pkg-config entries cannot print unicode descriptions,
it's absolutely possible, and we should handle it properly if we
encounter it.
- this fixes#10792
- Qt6EntryPoint(d) replaces qtmain(d) from Qt 4 & 5
- uses the same mechanism: `main: true`
- uses a special mixin class for pkg-config and config-tool dependency calculation
This catches some optimization problems, mostly in the use of `all()`
and `any()`. Basically writing `any([x == 5 for x in f])` vs `any(x == 5
for x in f)` reduces the performance because the entire concrete list
must first be created, then iterated over, while in the second f is
iterated and checked element by element.
Those classes are used by wrapper scripts and we should not have to
import the rest of mesonlib, build.py, and all their dependencies for
that.
This renames mesonlib/ directory to utils/ and add a mesonlib.py module
that imports everything from utils/ to not have to change `import
mesonlib` everywhere. It allows to import utils.core without importing
the rest of mesonlib.
Only import the ones we need for the language we are detecting, once we
actually detect that language.
This will allow finally dropping the main imports of these files in a
followup commit.
It turns out we don't generally need to proxy every compiler ever
through the top-level package. The number of times we directly poke at
one is negligible and direct imports are pretty clean.
In the debug logs, always log if a dependency lookup raises a
DependencyException. In the `required: false` case, this information
would otherwise disappear forever, and we would just not even log that
we tried it -- it doesn't appear in "(tried x, y and z)".
In the `required: true` case, we would re-raise the first exception if
it failed to be detected. Update the raise message with the same
information we print to the debug logs, indicating which dependency and
which method was used in the failing attempt.
functools.partial preserves information about how the method was
created, lambdas do not. Also, we just want to freeze the first argument
and forward the rest anyway.
This also lets us get rid of a mypy error that was being ignored.
A bunch of SystemDependency subclasses overrode log_tried() even though
they used the same function anyway. Delete them -- they still print
the same thing either way.
We use `__future__.annotations` to good effect everywhere we can, and
one of the effects of this is that annotations are automatically
stringized and don't need to be evaluated, using less memory and
computation. But this only affects actual annotations -- a cast is just
a function with an argument, so the compiler has no idea that it's an
annotation to be stringized.
Do this manually.
This is needed for 6.1 support as noted in commit
a606ce22eb but at the time there was no
pkg-config detection method at all. The stub code for Qt6 didn't support
libexecdir at all, and the pkg-config files added to newer versions of
Qt6 didn't export that information either until a further bugfix release.
Enforce that this information is required.
- `BuildTarget` should be `SharedLibrary | StaticLibrary`
- Needs to take `CustomTargetIndex` as well as `CustomTarget`
- don't assign to self until values have been converted to the correct
type
If we encounter a file under the Boost library directory that doesn't
look like a Boost library binary, we should ignore it.
We log a warning for each file we ignore, except for ones we know are
safe to ignore (e. g. PDB files from the SourceForge Windows
distribution). This should avoid polluting the log.
Fixes#8325.
By default, meson will try to look for shared libraries first before
static ones. In the meson.build itself, one can use the static keyword
to control if a static library will be tried first but there's no simple
way for an end user performing a build to switch back and forth at will.
Let's cover this usecase by adding an option that allows a user to
specify if they want dependency lookups to try static or shared
libraries first. The writer of the meson.build can manually specify the
static keyword where appropriate which will override the value of this
option.
In a couple of spots, kwargs.get('static', False) was being
unneccesarily used. In these spots, we can just use self.static instead
which is already inherited from the ExternalDependency. In additional,
the python system dependency oddly has a kwargs.get('static', False)
line which overrides the self.static in that dependency for no real
reason. Delete this line too.
This function can be used to add fundamental dependencies such as glib
to all build products in one fell swoop. This can be useful whenever,
due to a project's coding conventions, it is not really possible to
compile any source file without including the dependency.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Extract to a separate function the code that resolves dependencies
for compiler methods. We will reuse it for add_project_dependencies().
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
The new get_env() method that returns an EnvironmentVariables object
will be needed in next commit that will pass it to CustomTarget.
This has the side effect to use the proper os specific path separator
instead of hardcoding `:`. It is the obvious right thing to do here, but
has caused issues in the past. Hopefully issues have been fixed in the
meantime. If not, better deal with fallouts than keep doing the wrong
thing forever.
dep.get_variable() only supports string values for pkg-config and
config-tool, because those interfaces use text communication, and
internal variables (from declare_dependency) operate the same way.
CMake had an oddity, where get_variable doesn't document that it allows
list values but apparently it miiiiiight work? Actually getting that
kind of result would be dangerously inconsistent though. Also, CMake
does not support lists so it's a lie. Strings that are *treated* as
lists with `;` splitting don't count...
We could do two things here:
- raise an error
- treat it as a string and return a string
It's not clear what the use case of get_variable() on a maybe-list is,
and should probably be a hard error. But that's controversial, so
instead we just return the original `;`-delimited string. It is probably
the wrong thing, but users are welcome to cope with that somehow on
their own.
Qt now has official guidance for the symlinked names of the tools, which
is great.
Qt now officially calls the tools `fooX` instead of `foo-qtX` where the
major version of Qt is X. Which is not great, because a bit of an
unofficial standard had prior art and now needs to change, and we never
adapted.
Prefer the official name whenever looking up qmake, and in the
testsuite, specifically look only for the official name on versions of
qt which we know should have that.