The fact that UserOption is generic is really an implementation detail,
not something to be used publicly. So by having an `AnyOptionType`
alias, we can get better type checking, as can be seen by the patch as a
whole. One of the big fixes it replace open-coded equivlalents of
`MutableKeydOptionDictType` with that type alias.
Which wants a string, but then passes that string to a function that
wants an OptionKey, which means that we'll always miss the lookup in
BULITIN_DIR_NOPREFIX_OPTIONS, and return the default. The only case this
gets used we cast an OptionKey to str, and then pass that. So instead,
do the cast inside the function when necessary and pass the OptionKey
This reduces code, makes this clearer, and will be a nice step toward
the goal of getting everything typesafe.
For `UserIntegerOption` this makes a fairly nice, but substantial change
in that the old method used a tuple of `(min, value, max)` to pass to the
initializer, while all other types just passed `value`. The new
`UserIntegerOption` does the same, with keyword arguments for the min
and max values.
This saves a *tiny* bit of typing, but at the cost of requiring either
the current solution of throwing up our hands and saying "typing is too
hard, better to have bugs!" or an extensive amount of `TypedDict`s,
`overloads`, and a very new version of mypy. Let's get our type safety
back, even if it means writing a little bit more code.
This is an annoying issue to look at, because shutil.chown has (for our
purposes) three signatures:
```python
chown(path: int | AnyPathLike, uid: int | str, group: None = None) -> None: ...
chown(path: int | AnyPathLike, uid: None, group: int | str) -> None: ...
chown(path: int | AnyPathLike, uid: int | str, group: int | str) -> None: ...
```
This is a really difficult thing to guarantee from our code. We more or
less depend on being able to pass two parameters of `None | int | str`,
and it working. In our only caller we do ensure that at least one of the
variables is not None, but convincing mypy of this is more work than
it's worth.
This will show up in our CI only for python >= 3.13. An updated typshed
will make this show up for earlier versions, however. Pyright (which is
used by the VSCode Python extension) will spot this for earlier
versions. I have changed the code in such a way to make our CI turn
green.
Since we're going to split generate_rust_target() in multiple functions,
eliminate the only variable that spans large parts of it.
The cratetype ninja variable has been unused since Meson started invoking
rustc directly nine years ago (commit d952812b1, "Fix Rust to work with 1.3
release. Closes #277.", 2015-10-11).
Reviewed-by: Dylan Baker <dylan@pnwbakers.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Add functions to RustCompiler() to account for differences
between rustc and "rustdoc --test": rustdoc always generates
a binary, does not support -g, and does not need --emit.
Reviewed-by: Dylan Baker <dylan@pnwbakers.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Since the introduction of dep-info=... it is possible to move the depfile
away from the main build directory without using --out-dir. This is
less surprising, since the rules for mixing --emit, --out-dir and -o
are not really documented.
Reviewed-by: Dylan Baker <dylan@pnwbakers.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Implement RustCompiler.build_rpath_args, so that more code can
be shared between non-Rust and Rust targets. Then, RustCompiler
can override it to convert the arguments to "-C link-arg=" and
add the rustup sysroot.
Reviewed-by: Dylan Baker <dylan@pnwbakers.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
os.path.abspath of the target subdir is not guaranteed to give a sensible
answer; depending on what directory you run meson from, it could build
an absolute path relative the source directory or the build directory
or possibly neither one. In fact, using os.path.abspath is quite rare
in Meson's code and generally only done in code like
subdir = os.path.abspath(os.path.join(self.sourcedir, target['subdir']))
or
ndir1 = os.path.abspath(os.path.realpath(dir1))
While at it, don't use getattr unnecessarily, the cratetype is available.
Reviewed-by: Dylan Baker <dylan@pnwbakers.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
SharedModule (like Python extension modules) are loaded dynamically.
Therefore, they cannot be detected from executable dependencies, and
we must call `determine_windows_extra_paths` on them as well.
Also, those extra paths need to be computed even if the module or the
executable is not installed in the default location.
A Defaultable PerMachine has a type of `None | T`, in other words,
they have a base type of `PerMachine[None | T]`, but the purpose of
`PerMachine.default_missing()` is to get a `PerMachine[T]` from that
`PerMachine[None | T]`, therefore we should ensure that and annotate
that.
This enables generating Python bindings and linking against
`python3-embed` without resorting to later `install_name_tool` changes,
as the pkg-config module provided by Xcode doesn't say that
Python3.framework requires a rpath entry:
$ otool -L /Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Python3
/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Python3:
@rpath/Python3.framework/Versions/3.9/Python3 (compatibility version 3.9.0, current version 3.9.0)
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1933.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1319.0.0)
Some dependencies can bring include paths pointing to older macOS SDK's.
In this case, it was libffi pointing to SDK from 12.0. When the
Foundation
framework is imported in Swift, swiftc attempts to import the FFI module
from the most recent version of the SDK, which causes a compilation
error
because of conflicting definitions between the two SDK versions.
SwiftPM also had this problem:
https://github.com/swiftlang/swift-package-manager/pull/6772
The solution on our side is a simplified version of what SwiftPM did.
Let's naively look for .sdk paths in the compile args of our
dependencies
and replace them with the most recent one.
I included a test which is confirmed to fail without the workaround
added in this patch. This was not tested on anything else than macOS,
but I don't expect it to make the situation worse in any case.
On Windows, if you accidently add a space at the end of a file name, like
`files('myfile.txt ')`, the file is not reported as missing, because of
the normalization performed by the OS. However, ninja will reference it
with the trailing space, and will fail because the file does not exist.
See https://github.com/python/cpython/issues/115104 for reference.
For whatever reason Meson has always used None == <C Language>. This
doesn't make a lot of sense to me, but it's how things currently work,
and our dependency factories should handle that correctly.
It's not especially explanatory to say:
```
meson.build:357:34: ERROR: Automatic wrap-based subproject downloading is disabled
```
But if we instead say this:
```
ERROR: Subproject libsamplerate is buildable: NO
meson.build:357:34: ERROR: Automatic wrap-based subproject downloading is disabled
```
It becomes a lot clearer to casual inspection, why it failed. And it
matches the way we otherwise report errors for an unbuildable subproject
(configure errors).
Bug: https://github.com/jacktrip/jacktrip/issues/1380
It catches the exception message itself, but for multi-line exceptions
it may be worth print an error() as well as raising, to communicate
multiple bits of information.
When using the VS backend, this means that we get an actual `ERROR: ...`
printed during a successful run, which then breaks msbuild as msbuild
parses stdout of successful commands, regexes them for the word "error:"
and interprets that as... an error. So a meson project tests example
that uses testcase expect_error() and then successfully configures and
builds, fails to successfully `meson --internal regenerate`.
Sneak around this by doing our own pattern replace to evade msbuild.
There is probably a way to tell msbuild to stop doing this, but that
would require me understanding the vs backend well enough to patch the
xml it generates. No thanks...
Since this is optional, we should not accept that GCC is a valid ObjC or
G++ is a valid ObjC++ Compiler unless we've tested that they can
actually do a basic compile.
This requires fixing a number of tests that have broken assumptions. In
some cases I've split tests where issues with one language would hide
the other. It would be great if we had a competent test framework that
allowed subtests to skip, unfortunately we have python's unittest
instead. Because of that we can't avoid extra tests by use of subtests.