-
Notifications
You must be signed in to change notification settings - Fork 946
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
started MesonToolchain improvements #10174
started MesonToolchain improvements #10174
Conversation
well, right now I am more interested and motivated in functional changes for users, than (mostly cosmetic) refactoring. |
self._conanfile.settings.get_safe("compiler") | ||
self._vscrt = self._conanfile.settings.get_safe("compiler.base.runtime") or \ | ||
self._conanfile.settings.get_safe("compiler.runtime") | ||
# Values are kept as Python built-ins so users can modify them more easily, and they are |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these were private (internal) variables, why do we need users to modify them?
in general, I expect users to modify inputs (in our world, settings and conf), instead of messing up with an internal structure of objects. our objects have public interfaces (e.g. generate
method and few others), but directly modifying object fields doesn't sound like a good idea for me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The self.backend
, self.b_vscrt
are public variables that can be changed, but are very inconveniently assigned as doubled quoted strings, not regular strings, they should be regular strings.
A design principle of all toolchains is that they should allow easy customization, like:
tc = MesonToolchain(self)
tc.b_vscrt = xxxx if something else yyyy
tc.generate()
This is only nice if b_vscrt
is a regular string
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree they shouldn't contain extra quotes, that's fine, I am not arguing with that at all
I just don't like to expose too many internal implementation details to the user
e.g. I didn't see anyone actually requested b_vscrt
to be modifiable directly
we have other (and more important) actual requests for Meson (e.g. cross-building), I'd just keep b_vscrt
and others to be fully private members for now, as they aren't currently documented anyway, and it gives us the freedom to do breaking changes
in other words, I wouldn't expose and document them right now, until it's actually requested
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
about self.backend
and self._backend
- two are redundant and confusing, for sure
but the method _get_backend
fully mimics _get_generator
from CMakeToolchain
(backend in meson worlds is just like generator in cmake world)
it could be consistent across different toolchains, I think
This is beyond cosmetic refactoring. A good design is important, I have changed the title to "improvements", as there are many of those requested changes that are not refactors. For example having the single-quoted strings is something that if not fixed now will be bad if we freeze it as stable in 2.0. Supporting |
I think we need to separate changes, at very least, the ones affecting users (e.g. changing the behavior, like MSVC compiler support) from ones doing "cosmetic" improvements (improving readability and maintenance of the class, but in general invisible to the user, like formatting in wrong places or extracting/inlining methods). otherwise, it's too hard to follow, there is no general goal, there is just a random collection of various unrelated improvements. |
else: | ||
self._write_native_file() | ||
content = Template(self._meson_file_template).render(self._context) | ||
filename = self.native_filename if not self.cross_build else self.cross_filename |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reversed condition would read better (without not
)
if cross_building(self._conanfile): | ||
cmd += ' --cross-file "{}"'.format(MesonToolchain.cross_filename) | ||
generators_folder = self._conanfile.generators_folder | ||
cross = os.path.join(generators_folder, MesonToolchain.cross_filename) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using the existence of the file, as the decission if it is cross-building or not was already taken by the toolchain.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is reliable enough. of course, some process could create or delete the file in the middle of conan's execution, but realistically it's a low chance, and anyway, further execution wouldn't be correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem with using here a hardcoded if cross_building()
is that if the MesonToolchain
decides (the user can do it) that it is not cross-building, this will be wrong. The build helpers like Meson
should not decide things just execute what the toolchain has decided to do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could it be problematic in some flows, e.g. if I run several toolchain executions for multiple profiles?
conan/tools/meson/toolchain.py
Outdated
if compiler == "Visual Studio": | ||
vscrt = self._conanfile.settings.get_safe("compiler.base.runtime") or \ | ||
self._conanfile.settings.get_safe("compiler.runtime") | ||
self._b_vscrt = {"MD": "md", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that might use .lower()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
another note (might be slightly unrelated), in CCI users, have started to adopt MSVC compiler already, and now recipes need to use a fairly complicated logic to manage compiler runtime, as settings are very different between old and new compilers. do you have a plan to add some sort of helper, with can return uniform runtime values (e.g. in formats like MD
or MultiThreadedDebug
)?
conan/tools/meson/toolchain.py
Outdated
arch_target = settings_target.get_safe("arch") | ||
self.cross_build["target"] = self._to_meson_machine(os_target, arch_target) | ||
|
||
default_comp = "" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to avoid anything related to the default comp here, as much as possible.
I think we already agreed to use explicit things rather than autodetection.
many people complain that conan picks the wrong compiler executable (e.g. /usr/bin/gcc
instead of gcc-10
or whatever).
for CL, we can make an exception, as we know it's always cl.exe
.
for GCC/Clang, we basically, don't know, it could be just gcc.exe
, gcc-10.exe
, something like arm-linux-gnueabi-gcc.exe
...
I'd prefer to hard fail instead of silently producing incorrect binaries with the wrong compiler.
and for this kind of thing, I suppose we need to follow blocks approach, as we discuss in #9710
I beg you to exclude this kind of tentative/risky changes from this PR, and continue the discussion we started before
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not true. This is not auto-detection, this is a very sane default.
The information is already defined in the settings.compiler
, we are not auto-detecting the compiler.
What doesn't make sense is to always force users to define a [buildenv] CC=gcc CXX=g++
when settings.compiler=gcc
. We don't do it in any other build system integration, and it shouldn't be done in Meson either. Assuming a gcc/g++
, clang/clang++
is a good default, and the user always has the chance to override it defining the env-var. Otherwise, it is impossible to build a Meson project in Linux or OSX with the default detected profile, and requires all users to manually add CC/CXX env-vars to it.
So this is staying, it must be possible for every build system integration to be able to build a basic project with the default detected profile, for a default system installation of compilers and build systems.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the user might not have a /usr/bin/gcc
or /usr/bin/clang
at all.
for the default
profile, it will pick /usr/bin/gcc
for settings.compiler=gcc
.
but it will also pick /usr/bin/gcc
for non default (e.g. armv7
) profile (e.g. settings.arch=armv7
).
that might not be something desired in this particular case, and in many others (e.g. Android NDK).
there is no check this choice is done for the default
profile only, it always applies.
yes, it makes some use-cases more smooth, but other use-cases might be silently broken because of that default.
I'd limit these defaults to some known cases only, e.g. :
- apple-clang with XCode, where the compiler should be located via XCRun
- MSVC/Visual Studio, where VCVars is responsible for the compiler discovery
- Android NDK, where we have a clear mapping of settings to the compiler executables
for others, we don't know and can't be sure what is the sane choice. it might be gcc.exe
, gcc-10.exe
, gcc-10.0.exe
or arm-linux-gnueabi-gcc.exe
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but it will also pick /usr/bin/gcc for non default (e.g. armv7) profile (e.g. settings.arch=armv7).
that might not be something desired in this particular case, and in many others (e.g. Android NDK).
Of course the default will not work in cases of cross-compiling, and it will require specifying the specific compiler you want for cross-compile. This doesn't mean that for 75% of the users, doing native builds, we shouldn't define a default. Again, this is the same default as our CMake integration, by default it will pick the system "gcc/g++", and only for cross-compile scenarios you need to specify the CC/CXX env-vars.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about limiting the scope for native file only?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you aware that if we don't add this, it will be also challenging to build packages using Meson in ConanCenter, where we are using the default profiles? If we change all default profiles in ConanCenter, which are different to the user default profiles, the risk of things not working also increases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right now, in CCI, the only problematic use case is M1. all other default profiles work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because the recipes there are not using MesonToolchain yet. If MesonToolchain requires defining CC/CXX in all profiles, for all builds, things will be broken, it will be not possible to update without changing all the profiles in ConanCenter. Recall that it is necessary to move all recipes to the new integrations to be ready for 2.0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we already tried MesonToolchain in CCI in the past: https://github.com/conan-io/conan-center-index/pull/7360/files https://github.com/conan-io/conan-center-index/pull/6678/files.
the thing is that it requires explicit CC/CXX for cross-building.
but it doesn't require it for native builds. e.g. it is able to deduce cl
for Visual studio and gcc
for GCC and clang
for XCode builds.
profiles don't need to change.
the only one we currently have trouble is M1, but for this one, it needs a bunch of other flags (like -arch
and -isysroot
) from the XCrun.
conan/tools/meson/meson.py
Outdated
source = self._conanfile.source_folder | ||
if source_folder: | ||
source = os.path.join(self._conanfile.source_folder, source_folder) | ||
def configure(self, build_script_folder=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I doubt in meson world they call it build script folder
, might be misleading for the people
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion for an alternative name?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in documentation, they refer to it as a builddir
self._conanfile.run(cmd) | ||
|
||
def test(self): | ||
cmd = 'meson test -v -C "{}"'.format(self._build_dir) | ||
meson_build_folder = self._conanfile.build_folder | ||
cmd = 'meson test -v -C "{}"'.format(meson_build_folder) | ||
# TODO: Do we need vcvars for test? | ||
# TODO: This should use conanrunenv, but what if meson itself is a build-require? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's actually most likely, meson is a build requirement
conan/tools/meson/toolchain.py
Outdated
"MT": "mt", | ||
"MTd": "mtd"}.get(vscrt, "none") | ||
elif compiler == "msvc": | ||
# TODO: Fill here the msvc model |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# TODO: Fill here the msvc model | |
# TODO: Fill here the msvc model | |
self._b_vscrt = "m{}{}".format( | |
"t" if self.settings.compiler.runtime == "static" else "d", | |
"d" if self.settings.compiler.runtime_type == "Debug" else "", | |
) |
…lchain Feature/refactor meson toolchain
…lchain Feature/refactor meson toolchain
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good! 👍
@memsharded I think we should add to the PR description that it closes (perhaps not completely) the issue #9710, wdyt?
Changelog: Feature: Improvements in
MesonToolchain
, including some cross-building functionality.Docs: Omit
Close #9710
I have started to do some changes to update
MesonToolchain
, it needs some updates:meson.build_type = "debug"
, and notmeson.build_type = "'debug'"
(double quoted).Environment
to handle the definition of environment instead of the rawEnvVars
should allow avoiding splitting them in the first place. Also avoid doing "to_meson_value" for these.self._backend
vars that aren't used later at all. Define just the public ones likeself.backend
that users can change later in recipesmsvc
new setting.Some other minor things:
_get_backend()
method can be collapsed to 2 very simple to read lines in the constructor.@SSE4 as you have been working in this, if you want to follow up and finish these changes, feel free to continue this work, otherwise I will keep working on it when possible, hopefully 1.44.