Skip to content
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

[POC] MesonToolchain and GNU flags coming from dependencies #11557

Merged
merged 8 commits into from Jul 11, 2022

Conversation

franramirez688
Copy link
Contributor

@franramirez688 franramirez688 commented Jun 30, 2022

Changelog: Feature: Added MesonDeps as a new generator to create an extra file with all the GNU flags from all the dependencies. Meson build-helper will add that one (if exists) to complement the created one by MesonToolchain.
Docs: conan-io/docs#2654
Closes: #10683 #11397 #11398

Motivation: Dependencies which are defining only GNU flags, MesonToolchain will never get anything from their build environments because it needs those flags to initialize its own instance, so right now, it's possible to work-around it but it's a bit hard. This PR is proposing that alternative but, for sure, it's open to being discussed.

ret = NewCppInfo()
for dep in deps:
dep_cppinfo = dep.cpp_info.aggregated_components()
# In case we have components, aggregate them, we do not support isolated
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what exactly does "isolated" target mean?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've only used the functions that were already there. There's nothing new here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it doesn't answer my question...

return[dep for dep in reversed(deps.values())]


def get_gnu_deps_flags(conanfile):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a free function probably doen't belong to AutoToolsDeps generator, it should be somewhere else in conan.tools?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic was already here, so I've kept it here as well. I don't think that it has to be in Conan tools but I'm not saying that this is the better place or even if we want it. By the record, the final import is from conan.tools.gnu import get_gnu_deps_flags so I guess it makes sense... Let's discuss! 😄


def generate(self):
# Get GNU flags from all the dependencies
cflags, cxxflags, cpp_flags, libs, ldflags = get_gnu_deps_flags(self)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps, we need some universal interface (object) that could be returned from or accepted by various tools (build helpers).
how about some NamedTuple or struct?

ldflags.extend(flags.lib_paths)

# set the rpath in Macos so that the library are found in the configure step
if conanfile.settings.get_safe("os") == "Macos":
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's weird why is it only Macos?

Copy link
Contributor

@lasote lasote left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about the toolchain being populated with the dependencies.
I need some clarification because I've read the issues associated. Still, I'm unsure about what would happen if the workarounds that were introduced here are moved to a MesonDeps generator that is based on the AutotoolsDeps? I think it should work right? Why introduce in the toolchain the information about the deps? The Meson tool, when run, will load first the launcher for the environment. am I missing something?

@franramirez688
Copy link
Contributor Author

moved to a MesonDeps generator that is based on the AutotoolsDeps?

Yeah, I think I'm going to try a MesonDeps instead of this. I think it's going to be much cleaner.
Thanks for the feedback!

@SSE4
Copy link
Contributor

SSE4 commented Jul 4, 2022

Yeah, I think I'm going to try a MesonDeps instead of this. I think it's going to be much cleaner. Thanks for the feedback!

I can't find anything about MesonDeps, neither in the codebase, nor in the documentation. do you have a link?

@franramirez688
Copy link
Contributor Author

I can't find anything about MesonDeps, neither in the codebase, nor in the documentation. do you have a link?

Sure you cannot because that's a new generator. It's not created yet. I'm going to study if it's feasible or not and then, update the PR.

for include_path in include_paths if include_path]

def _format_library_paths(self, library_paths):
if not library_paths:
return []
# FIXME: Missing support for subsystems
pattern = "-LIBPATH:%s" if is_msvc(self._conanfile) else "-L%s"
pattern = "/LIBPATH:%s" if is_msvc(self._conanfile) else "-L%s"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what exactly was a bug?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SSE4 Now, the Meson test is passing because of this change. Anyway, as you already know, the Meson bug is still there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was the -LIBPATH: as valid compile options, wasn't it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes. just in case, for link.exe both shoud be legal:

On the command line, an option consists of an option specifier, either a dash (-) or a forward slash (/), followed by the name of the option. 

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyway, if they're valid both of them, then, let's use the forward slash. What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, I have no objections. I'd prefer the way it works with meson.

self.cpp_args = []
self.cpp_link_args = []

# TODO: Add all this logic to GnuDepsFlags? Distinguish between GnuFlags and GnuDepsFlags?
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this POC is accepted, then I'll propose a refactor of the actual GnuDepsFlags.

  • GnuDepsFlags -> GnuFlags
  • (new) GnuDepsFlags getting the GNU flags for all the dependencies

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it might be too mind blowing (for users), let's not mulltiply entities and use Occam's razor
e.g. we already have too many disputes on what cmake generator to use everywhere, and it's hard enough to explain

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean. I'm not thinking of a new generator. GnuDepsFlags is mostly used as an internal helper class and, apart from that, its name is saying Deps but it's not managing any deps, so, what I'm saying is to do this refactor for internal purpose. Users should not be affected at all.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GnuDepsFlags will not be exposed to users, it is internal

else:
cmd += ' --native-file "{}"'.format(native)
if has_deps_flags:
cmd += ' --native-file "{}"'.format(deps_flags)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but it overrides, isn't it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it's not. They are being added as an extended part of the MesonToolchain:

    c_args = {{c_args}} + preprocessor_definitions + c_args
    c_link_args = {{c_link_args}} + c_link_args
    cpp_args = {{cpp_args}} + preprocessor_definitions + cpp_args
    cpp_link_args = {{cpp_link_args}} + cpp_link_args

So, the only part that is being overridden, it's the first definition of the constants:

    [constants]
    ........
    c_args = []
    c_link_args = []
    cpp_args = []
    cpp_link_args = []

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure this won't be breaking. The values from multiple machine files override each other, only last file wins. If MesonDeps adds some flags, and MesonToolchain too, they will remove the previously defined one. I don't think the idiom c_args = {{c_args}} + preprocessor_definitions + c_args will work. Am I misunderstanding something?
Most likely a test that covers this is necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is not working so. AutotoolDeps, as MesonDeps, is getting the flags from all the dependencies altogether so I'm creating only one file, the conan_meson_deps_flags.ini. It's not created a file per dependency.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And, the test is already there for sure. That test is not passing without those deps flags. I can try to debug something from the log or try to print anything else.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not a problem of one file per dependency. It will be the conan_meson_deps_flags.ini, being overriden by the conan_meston_toolchain.ini file values for those cppflags, etc.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO this complicates local flow significantly. now, if one wants to replicate conan buid exactly, will have to type something like --native-file conan_meson_deps_flags1.ini --native-file conan_meson_deps_fags2.ini ... --native-file conan_meson_native.ini, and it has to be in the correct order (besides the fact it's a long command line). I would just write everything into conan_meson_native.ini to simplify the workflow and reduce a chance of human error.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, you'll only have a single file for all the deps: --native-file conan_meson_deps_flags.ini, and that's it. Have a look at the last test that I've added.

else:
cmd += ' --native-file "{}"'.format(native)
if has_deps_flags:
cmd += ' --native-file "{}"'.format(deps_flags)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure this won't be breaking. The values from multiple machine files override each other, only last file wins. If MesonDeps adds some flags, and MesonToolchain too, they will remove the previously defined one. I don't think the idiom c_args = {{c_args}} + preprocessor_definitions + c_args will work. Am I misunderstanding something?
Most likely a test that covers this is necessary.

@@ -60,15 +59,14 @@ def _format_frameworks(self, frameworks, is_path=False):
def _format_include_paths(self, include_paths):
if not include_paths:
return []
# FIXME: Missing support for subsystems
return ["-I%s" % (self._adjust_path(include_path))
pattern = "/I%s" if is_msvc(self._conanfile) else "-I%s"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? In theory VS also admits -I without problems. Maybe it is a bit more compatible if this is used by some other build tool, like autotools + cl.exe?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it admits both but Meson is failing because of an internal bug on its side. So this change is making life easier for Meson users and works with VS.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if it's more compatible with tools (e.g. meson), let's switch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants