Age | Commit message (Collapse) | Author | Files | Lines |
|
In the preceding commit we have started to perform compiler checks for
the value of `b_sanitize`, which allows us to detect sanitizers that
aren't supported by the compiler toolchain. But we haven't yet loosened
the option itself to accept arbitrary values, so until now it's still
only possible to pass sanitizer combinations known by Meson, which is
quite restrictive.
Lift that restriction by adapting the `b_sanitize` option to become a
free-form array. Like this, users can pass whatever combination of
comma-separated sanitizers to Meson, which will then figure out whether
that combination is supported via the compiler checks. This lifts a
couple of restrictions and makes the supporting infrastructure way more
future proof.
A couple of notes regarding backwards compatibility:
- All previous values of `b_sanitize` will remain valid as the syntax
for free-form array values and valid combo choices is the same. We
also treat 'none' specially so that we know to convert it into an
empty array.
- Even though the option has been converted into a free-form array,
callers of `get_option('b_sanitize')` continue to get a string as
value. We may eventually want to introduce a kwarg to alter this
behaviour, but for now it is expected to be good enough for most use
cases.
Fixes #8283
Fixes #7761
Fixes #5154
Fixes #1582
Co-authored-by: Dylan Baker <dylan@pnwbakers.com>
Signed-off-by: Patrick Steinhardt <ps@pks.im>
|
|
The `b_sanitize` option is used to specify which sanitizers to use. This
option is implemented as a combo option, where it only allows a specific
set of hardcoded choices. This implementation isn't quite scalable:
- The number of available sanitizers is steadily growing, so we have
to always catch up with what sanitizers exist out there.
- Sanitizers can be combined more freely nowadays, but we only allow
to combine the "address" and "undefined" sanitizers.
- A hardcoded list is not a good match given that a choice existing as
an option does not mean that it is supported by the compiler in the
first place.
Instead of hardcoding available options, it is way more future proof to
instead allow arbitrary values and perform a compiler check. This makes
us support new sanitizers readily while also providing good feedback to
our users why a specific option might not be allowed.
Implement the compiler checks for sanitizers as a first step. Note that
this does not yet loosen the set of allowed sanitizers as we only accept
hardcoded values as specified by the combo option. This restriction will
be lifted in the next commit.
|
|
When checking for multiple linker args we convert the supplied args to
flags that the compiler understands. But besides these supplied args, we
also try to convert linker flags that convert warnings into errors. This
mechanism causes an error though because we don't know to convert these
flags to linker flags:
gcc: error: unrecognized command-line option '--warning-as-error'; did you mean '--warn-no-error'?
-----------
ERROR: Linker nvcc does not support sanitizer arguments ['-Xcompiler=-fsanitize=address\\,undefined']
As you can see, the flag is passed to the underlying compiler, not to
the underlying linker.
The obvious fix would be to convert them to linker flags, which we can
do by using `-Xlinker=` instead of `-Xcompiler=`. But that is incorrect,
too:
/nix/store/j7p46r8v9gcpbxx89pbqlh61zhd33gzv-binutils-2.43.1/bin/ld: unrecognized option '--warning-as-error'
/nix/store/j7p46r8v9gcpbxx89pbqlh61zhd33gzv-binutils-2.43.1/bin/ld: use the --help option for usage information
collect2: error: ld returned 1 exit status
-----------
ERROR: Linker nvcc does not support sanitizer arguments ['-Xcompiler=-fsanitize=address\\,undefined']
Now we ended up passing the flag to the underlying linker, but the
`--warning-as-error` flag isn't known by it. What we really ought to do
is to pass on the flag to nvlink, which is the linker driver that
controls the underlying linker.
Do so by using `-Xnvlink=`, which fixes the bug.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
|
|
Same as the preceding commit, the CUDA toolchain does not yet know to
perform compile checks for multiple arguments. Backfill required
functions.
|
|
We're about to convert the `b_sanitize` option into a free-form array
whose value gets verified via a compiler check. This conversion will
also impact the Rust toolchain, which does not yet know to check for
multiple arguments at once.
Implement both `has_multi_arguments()` and `has_multi_link_arguments()`
to prepare the code accordingly.
|
|
|
|
Using str.split is faster than Path.parts
|
|
|
|
pathlib's implementation of Path iteration is expensive;
"foo.parents" has quadratic complexity when building it:
return self._path._from_parsed_parts(self._drv, self._root,
self._tail[:-idx - 1])
and comparisons performed by "path in file.parents" potentially
have the same issue. Use the newly introduced "is_parent_path"
function to check whether a file is under a path in the same way.
This removes Path from its hottest use.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
This saves about 1% of execution time; path manipulation is expensive.
About 1% more could be saved by avoiding usage of "foo in bar.parents",
which is an expensive way to say "bar.startswith(foo)".
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
Introduce an alternative to os.path.commonpath(name, path) == path,
which is a common idiom throughout Meson. Call it is_parent_path
just like the existing static method in Generator.
It is a bit faster and handles drives on Windows without the need
for an exception handler.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
|
At the moment it turns out this mostly means... me. But this was
discussed publicly, as requested by a third party, and as per the newly
added page this is open to anyone in the Project who wishes to let it be
known that they accept donations.
Closes: https://github.com/mesonbuild/meson/issues/14262
|
|
It can sometimes be hard to find content without digging through menus.
Try to guide people towards the specific content they are probably
looking for.
|
|
Bug: https://github.com/mesonbuild/meson/issues/14322
|
|
If a project uses PCH and they are for e.g. GCC, it will not help to build
them before running clang-tidy. Just skip creating the clang-tidy and
clang-tidy-fix targets in that case.
|
|
"ninja clang-tidy" will not work if you are using pch files and have
not run a full build yet: the pch files will not yet be built and
there is no dependency between the pch targets and the clang-tidy
target.
Fixes: #13499
|
|
|
|
|
|
|
|
|
|
this fixes the "frameworks: 15 llvm" tests with llvm 20.1
|
|
|
|
These are given a name that is different from __func.__name__, so
store the name when the descriptor is placed in the class.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
Fixes #14338
|
|
It basically served two purposes, to allow us to initialize UserOptions,
and to convert those options into Argparse values. The latter has been
transformed into a standalone function, the former can be easily
achieved without this class. This reduces LOC, simplifies setup, and
helps with our type safety.
|
|
Which will be used when BuiltinOption is removed
|
|
|
|
This is the first step do deleting the BuiltinOption altogether.
|
|
Since ba3460eb11bbceaf4fef7352bf286cf27184c99a, the workaround this was
applying was unnecessary.
|
|
|
|
The current approach of determining dub dependencies is by specifying
a name and, optionally, a version. Dub will then be called to generate
a json summary of the package and code in meson will parse that and
extract relevant information. This can be insufficient because dub
packages can provide multiple configurations for multiple use-cases,
examples include providing a configuration for an executable and a
configuration for a library. As a practical example, the dub package
itself provides an application configuration and multiple library
configurations, the json description of dub will, by default, be for
the application configuration which will make dub as a library
unusable in meson.
This can be solved without modifying the meson build interface by
having dub describe the entire local project and collecting
dependencies information from that. This way dub will generate
information based on the project's 'dub.json' file, which is free to
require dependencies in any way accepted by dub, by specifying
configurations, by modifying compilation flags etc. This is all
transparent to meson as dub's main purpose is to provide a path to the
library file generated by the dependency in addition to other
command-line arguments for the compiler.
This change will, however, require that projects that want to build
with meson also provided a 'dub.json' file in which dependency
information is recorded. Failure to do so will not break existing
projects that didn't use a 'dub.json', but they will be limited to
what the previous implementation offered. Projects that already have a
'dub.json' should be fine, so long as the file is valid and the
information in it matches the one in 'meson.build'. For example for a
'dependency()' call in 'meson.build' that dependency must exist in
'dub.json', otherwise the call will now fail when it worked
previously.
Using a 'dub.json' also has as a consequence that the version of the
dependencies that are found are the ones specified in
'dub.selections.json', which can be helpful for projects that already
provide a 'dub.json' in addition to 'meson.build' to de-duplicate code.
In terms of other code changes:
- multiple version requirements for a dub dependency now work, though
they can only be used when a 'dub.json' is present in which case the
version of dependencies is already pinned by 'dub.selections.json'
- the 'd/11 dub' test case has been changed to auto-generate the
'dub.json' config outside of the source directory, as the
auto-generated file triggers warning when parsed by dub, which upsets
the new code as the warnings interfere with the legitimate output.
Signed-off-by: Andrei Horodniceanu <a.horodniceanu@proton.me>
|
|
Which was improperly updated by the option store refactor.
Fixes: #14329
|
|
This should be `(key, value, is_first_invocation)`, but is instance
`(key, is_first_invocation, value)`
|
|
The project in question still exists but no longer has a dedicated
domain; instead it uses a group website in theory for multiple projects
hosted by the same group (but in practice still just the one).
Apparently changed almost 2 years ago.
See: https://github.com/theimpossibleastronaut/rmw/commit/0f53e40861c46916597990bfe2c95ca3e5cfb0a3
|
|
Added by the optionrefactor changes, but not used
|
|
|
|
This is just a wrapper around `get_value_object_and_value_for`, doing
needless work of unpacking a tuple, then repacking it.
|
|
This is just a bad warning, while it *could* give the user useful
information, it often doesn't since it can get values to warn about
from:
- environment variables
- the command line
- machine files
- `project(default_options : ...)`
- `subproject(default_options : ...)`
- `dependency(default_options : ...)`
The problem of course is that user may have no control over these
values. 3 of them are hardcoded into the meson.build files, so the user
can't do anything about them. And there are legitimate reasons to have
unused values in those, like setting defaults for a language only used
on specific platforms.
Environment variables may be set by the distro (NixOS sets them for any
enabled language, so just having a D compiler causes `DFLAGS` to be set,
for example). They likely don't want to special case "only set the
environment variables if the project is going to use them".
For machine files it limits the utility of the files, since the user
needs to be sure that they don't include any options that wont be used.
Finally, the command line could be altered by wrapper scripts, or simply
programmed to insert options that *may* be used but aren't required.
like setting `objc_args` regardless of whether ObjectivC bindings are
generated.
However, passing completely unknown builtin options should be an error,
as it was before the optionrefactor
|
|
As a cleanup, this causes the cache to use the same tuple layout that
the `_to_tuple` method does, which makes it easier to ensure everything
is right.
|
|
Bug: https://github.com/mesonbuild/meson/issues/13446
|
|
This class only served one purpose, to avoid typing the name of the
option twice. Unfortunately the way it was implemented made getting the
type checking right difficult, and required storing the same data twice.
This patch replaces this approach with a dictionary comprehension that
creates the OptionKey from the UserOption. This allows us to initialize
a single dictionary once, avoid typing the name twice, delete lines of
code, and get better type safety.
As an added bonus, it means that the exported data from the module can
be marked module constant, ie, ALL_CAPS.
|
|
These options are stored as a "global" options, ie, subproject=None.
Therefore, the call to `as_root()` could never be correct, and only the
`k in base_options` check could ever be correct. Since these options are
not supposed to be set here in the root project or in subprojects, we
want to check for the global option and skip.
|
|
Initially this is just used for getting builtin option default values,
but it could be extended to show the default value of an option in the
summary and in the introspection API.
|
|
We have the OptionKey in the one caller that exists already, and this
allows us to do a hash lookup instead of a linear walk.
|
|
|
|
self.post is only ever appended to on the right hand. However,
it is then reversed twice in flush_pre_post(), by using "for a in
reversed.post()" and appendleft() within the loop. It would be tempting
to use appendleft() in __iadd__ to avoid the call to reversed(), but that
is not a good idea because the loop of flush_pre_post() is part of a slow
path. It's rather more important to use a fast extend-with-list-argument
in the fast path where needs_override_check if False.
For clarity, and to remove the temptation, make "post" a list instead
of a deque.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
Unless an argument is marked as Dedup.OVERRIDDEN, pre_flush_set and
post_flush_set will always be empty and the loops in flush_pre_post()
will not be doing anything interesting:
for a in self.pre:
dedup = self._can_dedup(a)
if a not in pre_flush_set:
# This just makes new a copy of self.pre
new.append(a)
if dedup is Dedup.OVERRIDDEN:
# this never happens
pre_flush_set.add(a)
for a in reversed(self.post):
dedup = self._can_dedup(a)
if a not in post_flush_set:
# Here self.post is reversed twice
post_flush.appendleft(a)
if dedup is Dedup.OVERRIDDEN:
# this never happens
post_flush_set.add(a)
new.extend(post_flush)
In this case it's possible to avoid expensive calls and loops, instead
relying as much on Python builtins as possible. Track whether any options
have that flag and if not just concatenate pre, _container and post.
Before:
ncalls tottime cumtime
45127 0.251 4.530 arglist.py:142(__iter__)
81866 3.623 5.013 arglist.py:108(flush_pre_post)
76618 3.793 5.338 arglist.py:273(__iadd__)
After:
35647 0.156 0.627 arglist.py:160(__iter__)
78998 2.627 3.603 arglist.py:116(flush_pre_post)
73774 3.605 5.049 arglist.py:292(__iadd__)
The time in __iadd__ is reduced because it calls __iter__, which flushes
pre and post.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
"Inline" CompilerArgs.__iter__() into CompilerArgs.__init__(), so that
replace list(Iterable) is replaced by the much faster list(List).
Before:
ncalls tottime cumtime
19268 0.163 3.586 arglist.py:97(__init__)
After:
ncalls tottime cumtime
18674 0.211 3.442 arglist.py:97(__init__)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|