From 5bc83e67d73d9bf296362ae21d09cea41f723496 Mon Sep 17 00:00:00 2001 From: Francisco Ramirez de Anton Date: Tue, 5 Jul 2022 11:35:35 +0200 Subject: [PATCH] Fixed bad CL flags and created new MesonDeps (based on AutotoolsDeps) --- conan/tools/gnu/gnudeps_flags.py | 8 +- conan/tools/meson/__init__.py | 3 +- conan/tools/meson/meson.py | 11 +- conan/tools/meson/mesondeps.py | 105 ++++++++++++++++++ conan/tools/meson/toolchain.py | 12 +- conans/client/generators/__init__.py | 6 +- .../meson/test_meson_and_gnu_deps_flags.py | 17 +-- 7 files changed, 135 insertions(+), 27 deletions(-) create mode 100644 conan/tools/meson/mesondeps.py diff --git a/conan/tools/gnu/gnudeps_flags.py b/conan/tools/gnu/gnudeps_flags.py index 7342543297d..2546c7831db 100644 --- a/conan/tools/gnu/gnudeps_flags.py +++ b/conan/tools/gnu/gnudeps_flags.py @@ -48,7 +48,6 @@ def _format_frameworks(self, frameworks, is_path=False): os_ = self._conanfile.settings.get_safe("os") if not frameworks or not is_apple_os(os_): return [] - # FIXME: Missing support for subsystems compiler = self._conanfile.settings.get_safe("compiler") if str(compiler) not in self._GCC_LIKE: return [] @@ -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" + return [pattern % (self._adjust_path(include_path)) 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" return [pattern % self._adjust_path(library_path) for library_path in library_paths if library_path] diff --git a/conan/tools/meson/__init__.py b/conan/tools/meson/__init__.py index 9f317238a9c..b1fe7d9b9a9 100644 --- a/conan/tools/meson/__init__.py +++ b/conan/tools/meson/__init__.py @@ -1,3 +1,4 @@ -from conan.tools.meson.toolchain import MesonToolchain from conan.tools.meson.meson import Meson +from conan.tools.meson.mesondeps import MesonDeps +from conan.tools.meson.toolchain import MesonToolchain diff --git a/conan/tools/meson/meson.py b/conan/tools/meson/meson.py index 1285bab4769..1b467ba357a 100644 --- a/conan/tools/meson/meson.py +++ b/conan/tools/meson/meson.py @@ -1,7 +1,8 @@ import os from conan.tools.build import build_jobs -from conan.tools.meson import MesonToolchain +from conan.tools.meson.toolchain import MesonToolchain +from conan.tools.meson.mesondeps import MesonDeps class Meson(object): @@ -15,10 +16,18 @@ def configure(self, reconfigure=False): generators_folder = self._conanfile.generators_folder cross = os.path.join(generators_folder, MesonToolchain.cross_filename) native = os.path.join(generators_folder, MesonToolchain.native_filename) + deps_flags = os.path.join(generators_folder, MesonDeps.filename) # extra machine files layer + has_deps_flags = os.path.exists(deps_flags) + if os.path.exists(cross): cmd += ' --cross-file "{}"'.format(cross) + if has_deps_flags: + cmd += ' --cross-file "{}"'.format(deps_flags) else: cmd += ' --native-file "{}"'.format(native) + if has_deps_flags: + cmd += ' --native-file "{}"'.format(deps_flags) + cmd += ' "{}" "{}"'.format(build_folder, source_folder) if self._conanfile.package_folder: cmd += ' -Dprefix="{}"'.format(self._conanfile.package_folder) diff --git a/conan/tools/meson/mesondeps.py b/conan/tools/meson/mesondeps.py new file mode 100644 index 00000000000..aece7306eed --- /dev/null +++ b/conan/tools/meson/mesondeps.py @@ -0,0 +1,105 @@ +import textwrap + +from jinja2 import Template + +from conan.tools.gnu.gnudeps_flags import GnuDepsFlags +from conan.tools.meson.helpers import to_meson_value +from conans.model.new_build_info import NewCppInfo +from conans.util.files import save + + +class MesonDeps(object): + """Generator that manages all the GNU flags from all the dependencies""" + + filename = "conan_meson_deps_flags.ini" + + _meson_file_template = textwrap.dedent(""" + [constants] + c_args = {{c_args}} + c_link_args = {{c_link_args}} + cpp_args = {{cpp_args}} + cpp_link_args = {{cpp_link_args}} + """) + + def __init__(self, conanfile): + self._conanfile = conanfile + self._ordered_deps = [] + # constants + self.c_args = [] + self.c_link_args = [] + self.cpp_args = [] + self.cpp_link_args = [] + + # TODO: Add all this logic to GnuDepsFlags? Distinguish between GnuFlags and GnuDepsFlags? + @property + def ordered_deps(self): + if not self._ordered_deps: + deps = self._conanfile.dependencies.host.topological_sort + self._ordered_deps = [dep for dep in reversed(deps.values())] + return self._ordered_deps + + def _get_cpp_info(self): + ret = NewCppInfo() + for dep in self.ordered_deps: + dep_cppinfo = dep.cpp_info.aggregated_components() + # In case we have components, aggregate them, we do not support isolated + # "targets" with autotools + ret.merge(dep_cppinfo) + return ret + + def _rpaths_flags(self): + flags = [] + for dep in self.ordered_deps: + flags.extend(["-Wl,-rpath -Wl,{}".format(libdir) for libdir in dep.cpp_info.libdirs + if dep.options.get_safe("shared", False)]) + return flags + + def get_gnu_flags(self): + flags = GnuDepsFlags(self._conanfile, self._get_cpp_info()) + + # cpp_flags + cpp_flags = [] + cpp_flags.extend(flags.include_paths) + cpp_flags.extend(flags.defines) + + # Ldflags + ldflags = flags.sharedlinkflags + ldflags.extend(flags.exelinkflags) + ldflags.extend(flags.frameworks) + ldflags.extend(flags.framework_paths) + ldflags.extend(flags.lib_paths) + + # set the rpath in Macos so that the library are found in the configure step + if self._conanfile.settings.get_safe("os") == "Macos": + ldflags.extend(self._rpaths_flags()) + + # libs + libs = flags.libs + libs.extend(flags.system_libs) + + # cflags + cflags = flags.cflags + cxxflags = flags.cxxflags + return cflags, cxxflags, cpp_flags, ldflags, libs + + def _context(self): + cflags, cxxflags, cpp_flags, ldflags, _ = self.get_gnu_flags() + self.c_args.extend(cflags + cpp_flags) + self.cpp_args.extend(cxxflags + cpp_flags) + self.c_link_args.extend(ldflags) + self.cpp_link_args.extend(ldflags) + + return { + "c_args": to_meson_value(self.c_args), + "c_link_args": to_meson_value(self.c_link_args), + "cpp_args": to_meson_value(self.cpp_args), + "cpp_link_args": to_meson_value(self.cpp_link_args), + } + + def _content(self): + context = self._context() + content = Template(self._meson_file_template).render(context) + return content + + def generate(self): + save(self.filename, self._content()) diff --git a/conan/tools/meson/toolchain.py b/conan/tools/meson/toolchain.py index cbedd32c220..4a14b534272 100644 --- a/conan/tools/meson/toolchain.py +++ b/conan/tools/meson/toolchain.py @@ -26,6 +26,10 @@ class MesonToolchain(object): [constants] preprocessor_definitions = [{% for it, value in preprocessor_definitions.items() -%} '-D{{ it }}="{{ value}}"'{%- if not loop.last %}, {% endif %}{% endfor %}] + c_args = [] + c_link_args = [] + cpp_args = [] + cpp_link_args = [] [project options] {% for it, value in project_options.items() -%} @@ -52,10 +56,10 @@ class MesonToolchain(object): {% if b_staticpic %}b_staticpic = {{b_staticpic}}{% endif %} {% if cpp_std %}cpp_std = '{{cpp_std}}' {% endif %} {% if backend %}backend = '{{backend}}' {% endif %} - c_args = {{c_args}} + preprocessor_definitions - c_link_args = {{c_link_args}} - cpp_args = {{cpp_args}} + preprocessor_definitions - cpp_link_args = {{cpp_link_args}} + 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 {% if pkg_config_path %}pkg_config_path = '{{pkg_config_path}}'{% endif %} {% for context, values in cross_build.items() %} diff --git a/conans/client/generators/__init__.py b/conans/client/generators/__init__.py index 9c76dd41b43..246af0a5112 100644 --- a/conans/client/generators/__init__.py +++ b/conans/client/generators/__init__.py @@ -72,7 +72,8 @@ def __init__(self): "MesonToolchain", "MSBuildDeps", "QbsToolchain", "msbuild", "VirtualRunEnv", "VirtualBuildEnv", "AutotoolsDeps", "AutotoolsToolchain", "BazelDeps", "BazelToolchain", "PkgConfigDeps", - "VCVars", "IntelCC", "XcodeDeps", "PremakeDeps", "XcodeToolchain"] + "VCVars", "IntelCC", "XcodeDeps", "PremakeDeps", "XcodeToolchain", + "MesonDeps"] def add(self, name, generator_class, custom=False): if name not in self._generators or custom: @@ -113,6 +114,9 @@ def _new_generator(self, generator_name, output): elif generator_name == "MesonToolchain": from conan.tools.meson import MesonToolchain return MesonToolchain + elif generator_name == "MesonDeps": + from conan.tools.meson import MesonDeps + return MesonDeps elif generator_name in ("MSBuildDeps", "msbuild"): from conan.tools.microsoft import MSBuildDeps return MSBuildDeps diff --git a/conans/test/functional/toolchains/meson/test_meson_and_gnu_deps_flags.py b/conans/test/functional/toolchains/meson/test_meson_and_gnu_deps_flags.py index f802f62e758..1e99d4fa922 100644 --- a/conans/test/functional/toolchains/meson/test_meson_and_gnu_deps_flags.py +++ b/conans/test/functional/toolchains/meson/test_meson_and_gnu_deps_flags.py @@ -15,29 +15,16 @@ def test_mesontoolchain_using_gnu_deps_flags(self): conanfile_py = textwrap.dedent(""" from conan import ConanFile - from conan.tools.meson import Meson, MesonToolchain - from conan.tools.gnu import get_gnu_deps_flags - + from conan.tools.meson import Meson class App(ConanFile): settings = "os", "arch", "compiler", "build_type" requires = "hello/0.1" + generators = "MesonDeps", "MesonToolchain" def layout(self): self.folders.build = "build" - def generate(self): - # Get GNU flags from all the dependencies - cflags, cxxflags, cpp_flags, libs, ldflags = get_gnu_deps_flags(self) - - tc = MesonToolchain(self) - # Extend flags to MesonToolchain - tc.c_args.extend(cpp_flags) - tc.cpp_args.extend(cpp_flags) - tc.c_link_args.extend(ldflags) - tc.cpp_link_args.extend(ldflags) - tc.generate() - def build(self): meson = Meson(self) meson.configure()