From 9b56b852a0a6f1fe612d721bfb785819c16d61ca Mon Sep 17 00:00:00 2001 From: Francisco Ramirez de Anton Date: Fri, 12 Apr 2024 13:20:38 +0200 Subject: [PATCH 1/7] Added native attribute to MesonToolchain. Adapted the whole Meson mechanism --- conan/tools/meson/meson.py | 24 ++-- conan/tools/meson/toolchain.py | 137 ++++++++++++++------ conans/client/graph/profile_node_definer.py | 5 + conans/model/conan_file.py | 1 - 4 files changed, 112 insertions(+), 55 deletions(-) diff --git a/conan/tools/meson/meson.py b/conan/tools/meson/meson.py index 13541bc431a..3003f93192a 100644 --- a/conan/tools/meson/meson.py +++ b/conan/tools/meson/meson.py @@ -29,24 +29,22 @@ def configure(self, reconfigure=False): " Removing in Conan 2.x.", warn_tag="deprecated") source_folder = self._conanfile.source_folder build_folder = self._conanfile.build_folder - cmd = "meson setup" generators_folder = self._conanfile.generators_folder cross = os.path.join(generators_folder, MesonToolchain.cross_filename) native = os.path.join(generators_folder, MesonToolchain.native_filename) - meson_filenames = [] - if os.path.exists(cross): - cmd_param = " --cross-file" - meson_filenames.append(cross) - else: - cmd_param = " --native-file" - meson_filenames.append(native) - + is_cross_build = os.path.exists(cross) machine_files = self._conanfile.conf.get("tools.meson.mesontoolchain:extra_machine_files", default=[], check_type=list) - if machine_files: - meson_filenames.extend(machine_files) - - cmd += "".join([f'{cmd_param} "{meson_option}"' for meson_option in meson_filenames]) + cmd = "meson setup " + if is_cross_build: + machine_files.insert(0, cross) + cmd += "".join([f'--cross-file "{file}"' for file in machine_files]) + if os.path.exists(native): + if not is_cross_build: # machine files are only appended to the cross or the native one + machine_files.insert(0, native) + cmd += "".join([f'--native-file "{file}"' for file in machine_files]) + else: # extra native file for cross-building scenarios + cmd += f' --native-file "{native}"' cmd += ' "{}" "{}"'.format(build_folder, source_folder) # Issue related: https://github.com/mesonbuild/meson/issues/12880 cmd += ' --prefix=/' # this must be an absolute path, otherwise, meson complains diff --git a/conan/tools/meson/toolchain.py b/conan/tools/meson/toolchain.py index 80f13338750..5a1038ea3f2 100644 --- a/conan/tools/meson/toolchain.py +++ b/conan/tools/meson/toolchain.py @@ -1,7 +1,7 @@ import os import textwrap -from jinja2 import Template +from jinja2 import Template, StrictUndefined from conan.errors import ConanException from conan.internal import check_duplicated_generator @@ -20,11 +20,10 @@ class MesonToolchain(object): """ MesonToolchain generator """ - native_filename = "conan_meson_native.ini" cross_filename = "conan_meson_cross.ini" - _meson_file_template = textwrap.dedent(""" + _meson_file_template = textwrap.dedent("""\ [properties] {% for it, value in properties.items() -%} {{it}} = {{value}} @@ -49,33 +48,76 @@ class MesonToolchain(object): {% endfor %} [binaries] - {% if c %}c = {{c}}{% endif %} - {% if cpp %}cpp = {{cpp}}{% endif %} - {% if ld %}ld = {{ld}}{% endif %} + {% if c %} + c = {{c}} + {% endif %} + {% if cpp %} + cpp = {{cpp}} + {% endif %} + {% if ld %} + ld = {{ld}} + {% endif %} {% if is_apple_system %} - {% if objc %}objc = '{{objc}}'{% endif %} - {% if objcpp %}objcpp = '{{objcpp}}'{% endif %} + {% if objc %} + objc = '{{objc}}' + {% endif %} + {% if objcpp %} + objcpp = '{{objcpp}}' + {% endif %} + {% endif %} + {% if c_ld %} + c_ld = '{{c_ld}}' + {% endif %} + {% if cpp_ld %} + cpp_ld = '{{cpp_ld}}' + {% endif %} + {% if ar %} + ar = '{{ar}}' + {% endif %} + {% if strip %} + strip = '{{strip}}' + {% endif %} + {% if as %} + as = '{{as}}' + {% endif %} + {% if windres %} + windres = '{{windres}}' + {% endif %} + {% if pkgconfig %} + pkgconfig = '{{pkgconfig}}' + {% endif %} + {% if pkgconfig %} + pkg-config = '{{pkgconfig}}' {% endif %} - {% if c_ld %}c_ld = '{{c_ld}}'{% endif %} - {% if cpp_ld %}cpp_ld = '{{cpp_ld}}'{% endif %} - {% if ar %}ar = '{{ar}}'{% endif %} - {% if strip %}strip = '{{strip}}'{% endif %} - {% if as %}as = '{{as}}'{% endif %} - {% if windres %}windres = '{{windres}}'{% endif %} - {% if pkgconfig %}pkgconfig = '{{pkgconfig}}'{% endif %} - {% if pkgconfig %}pkg-config = '{{pkgconfig}}'{% endif %} [built-in options] - {% if buildtype %}buildtype = '{{buildtype}}'{% endif %} - {% if debug %}debug = {{debug}}{% endif %} - {% if default_library %}default_library = '{{default_library}}'{% endif %} - {% if b_vscrt %}b_vscrt = '{{b_vscrt}}' {% endif %} - {% if b_ndebug %}b_ndebug = {{b_ndebug}}{% endif %} - {% if b_staticpic %}b_staticpic = {{b_staticpic}}{% endif %} - {% if cpp_std %}cpp_std = '{{cpp_std}}' {% endif %} - {% if backend %}backend = '{{backend}}' {% endif %} - {% if pkg_config_path %}pkg_config_path = '{{pkg_config_path}}'{% endif %} - {% if build_pkg_config_path %}build.pkg_config_path = '{{build_pkg_config_path}}'{% endif %} + {% if buildtype %} + buildtype = '{{buildtype}}' + {% endif %} + {% if default_library %} + default_library = '{{default_library}}' + {% endif %} + {% if b_vscrt %} + b_vscrt = '{{b_vscrt}}' + {% endif %} + {% if b_ndebug %} + b_ndebug = {{b_ndebug}} + {% endif %} + {% if b_staticpic %} + b_staticpic = {{b_staticpic}} + {% endif %} + {% if cpp_std %} + cpp_std = '{{cpp_std}}' + {% endif %} + {% if backend %} + backend = '{{backend}}' + {% endif %} + {% if pkg_config_path %} + pkg_config_path = '{{pkg_config_path}}' + {% endif %} + {% if build_pkg_config_path %} + build.pkg_config_path = '{{build_pkg_config_path}}' + {% endif %} # C/C++ arguments c_args = {{c_args}} + preprocessor_definitions c_link_args = {{c_link_args}} @@ -98,7 +140,7 @@ class MesonToolchain(object): {% endfor %} """) - def __init__(self, conanfile, backend=None): + def __init__(self, conanfile, backend=None, native=False): """ :param conanfile: ``< ConanFile object >`` The current recipe object. Always use ``self``. :param backend: ``str`` ``backend`` Meson variable value. By default, ``ninja``. @@ -107,6 +149,8 @@ def __init__(self, conanfile, backend=None): self._conanfile = conanfile self._os = self._conanfile.settings.get_safe("os") self._is_apple_system = is_apple_os(self._conanfile) + self._native = native + self._conanfile_conf = self._conanfile.conf_build if native else self._conanfile.conf # Values are kept as Python built-ins so users can modify them more easily, and they are # only converted to Meson file syntax for rendering @@ -168,7 +212,7 @@ def __init__(self, conanfile, backend=None): self.cross_build = {} default_comp = "" default_comp_cpp = "" - if cross_building(conanfile, skip_x64_x86=True): + if native is False and cross_building(conanfile, skip_x64_x86=True): os_host = conanfile.settings.get_safe("os") arch_host = conanfile.settings.get_safe("arch") os_build = conanfile.settings_build.get_safe('os') @@ -197,10 +241,11 @@ def __init__(self, conanfile, backend=None): default_comp_cpp = "cl" # Read configuration for compilers - compilers_by_conf = self._conanfile.conf.get("tools.build:compiler_executables", default={}, + compilers_by_conf = self._conanfile_conf.get("tools.build:compiler_executables", default={}, check_type=dict) # Read the VirtualBuildEnv to update the variables - build_env = VirtualBuildEnv(self._conanfile, auto_generate=True).vars() + build_env = self._conanfile.buildenv_build.vars(self._conanfile) if native else ( + VirtualBuildEnv(self._conanfile, auto_generate=True).vars()) #: Sets the Meson ``c`` variable, defaulting to the ``CC`` build environment value. #: If provided as a blank-separated string, it will be transformed into a list. #: Otherwise, it remains a single string. @@ -232,7 +277,7 @@ def __init__(self, conanfile, backend=None): self.windres = build_env.get("WINDRES") #: Defines the Meson ``pkgconfig`` variable. Defaulted to ``PKG_CONFIG`` #: build environment value - self.pkgconfig = (self._conanfile.conf.get("tools.gnu:pkg_config", check_type=str) or + self.pkgconfig = (self._conanfile_conf.get("tools.gnu:pkg_config", check_type=str) or build_env.get("PKG_CONFIG")) #: Defines the Meson ``c_args`` variable. Defaulted to ``CFLAGS`` build environment value self.c_args = self._get_env_list(build_env.get("CFLAGS", [])) @@ -266,7 +311,8 @@ def __init__(self, conanfile, backend=None): self.objcpp_link_args = [] self._resolve_apple_flags_and_variables(build_env, compilers_by_conf) - self._resolve_android_cross_compilation() + if native is False: + self._resolve_android_cross_compilation() def _get_default_dirs(self): """ @@ -325,7 +371,7 @@ def _resolve_android_cross_compilation(self): if not self.cross_build or not self.cross_build["host"]["system"] == "android": return - ndk_path = self._conanfile.conf.get("tools.android:ndk_path") + ndk_path = self._conanfile_conf.get("tools.android:ndk_path") if not ndk_path: raise ConanException("You must provide a NDK path. Use 'tools.android:ndk_path' " "configuration field.") @@ -346,11 +392,11 @@ def _resolve_android_cross_compilation(self): def _get_extra_flags(self): # Now, it's time to get all the flags defined by the user - cxxflags = self._conanfile.conf.get("tools.build:cxxflags", default=[], check_type=list) - cflags = self._conanfile.conf.get("tools.build:cflags", default=[], check_type=list) - sharedlinkflags = self._conanfile.conf.get("tools.build:sharedlinkflags", default=[], check_type=list) - exelinkflags = self._conanfile.conf.get("tools.build:exelinkflags", default=[], check_type=list) - linker_scripts = self._conanfile.conf.get("tools.build:linker_scripts", default=[], check_type=list) + cxxflags = self._conanfile_conf.get("tools.build:cxxflags", default=[], check_type=list) + cflags = self._conanfile_conf.get("tools.build:cflags", default=[], check_type=list) + sharedlinkflags = self._conanfile_conf.get("tools.build:sharedlinkflags", default=[], check_type=list) + exelinkflags = self._conanfile_conf.get("tools.build:exelinkflags", default=[], check_type=list) + linker_scripts = self._conanfile_conf.get("tools.build:linker_scripts", default=[], check_type=list) linker_script_flags = ['-T"' + linker_script + '"' for linker_script in linker_scripts] defines = [f"-D{d}" for d in self._conanfile.conf.get("tools.build:defines", default=[], check_type=list)] return { @@ -450,6 +496,15 @@ def _sanitize_format(v): "is_apple_system": self._is_apple_system } + @property + def _filename(self): + if self.cross_build and self._native: + return self.native_filename + elif self.cross_build: + return self.cross_filename + else: + return self.native_filename + @property def _content(self): """ @@ -458,7 +513,8 @@ def _content(self): :return: ``str`` whole Meson context content. """ context = self._context() - content = Template(self._meson_file_template).render(context) + content = Template(self._meson_file_template, trim_blocks=True, lstrip_blocks=True, + undefined=StrictUndefined).render(context) return content def generate(self): @@ -468,7 +524,6 @@ def generate(self): If Windows OS, it will be created a ``conanvcvars.bat`` as well. """ check_duplicated_generator(self, self._conanfile) - filename = self.native_filename if not self.cross_build else self.cross_filename - save(filename, self._content) + save(self._filename, self._content) # FIXME: Should we check the OS and compiler to call VCVars? VCVars(self._conanfile).generate() diff --git a/conans/client/graph/profile_node_definer.py b/conans/client/graph/profile_node_definer.py index 548c4596e22..2b905ef0c64 100644 --- a/conans/client/graph/profile_node_definer.py +++ b/conans/client/graph/profile_node_definer.py @@ -26,8 +26,13 @@ def initialize_conanfile_profile(conanfile, profile_build, profile_host, base_co settings_build = _per_package_settings(conanfile, profile_build, ref) if is_build_require or base_context == CONTEXT_BUILD: _initialize_conanfile(conanfile, profile_build, settings_build.copy(), ref) + conanfile.buildenv_build = None + conanfile.conf_build = None else: _initialize_conanfile(conanfile, profile_host, settings_host, ref) + # Host profile with some build profile information + conanfile.buildenv_build = profile_build.buildenv.get_profile_env(ref, conanfile._conan_is_consumer) + conanfile.conf_build = profile_build.conf.get_conanfile_conf(ref, conanfile._conan_is_consumer) conanfile.settings_build = settings_build conanfile.settings_target = None diff --git a/conans/model/conan_file.py b/conans/model/conan_file.py index 554d0938afa..03118d2365a 100644 --- a/conans/model/conan_file.py +++ b/conans/model/conan_file.py @@ -9,7 +9,6 @@ from conans.model.dependencies import ConanFileDependencies from conans.model.layout import Folders, Infos, Layouts from conans.model.options import Options - from conans.model.requires import Requirements from conans.model.settings import Settings From 7e19fe438d4324e05c2dc17cc4be669d543246ab Mon Sep 17 00:00:00 2001 From: Francisco Ramirez de Anton Date: Fri, 12 Apr 2024 13:47:50 +0200 Subject: [PATCH 2/7] Added functional test --- .../meson/test_meson_native_attribute.py | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 conans/test/functional/toolchains/meson/test_meson_native_attribute.py diff --git a/conans/test/functional/toolchains/meson/test_meson_native_attribute.py b/conans/test/functional/toolchains/meson/test_meson_native_attribute.py new file mode 100644 index 00000000000..a87615c6c83 --- /dev/null +++ b/conans/test/functional/toolchains/meson/test_meson_native_attribute.py @@ -0,0 +1,94 @@ +import os +import platform +import textwrap + +import pytest + +from conan.tools.apple.apple import _to_apple_arch, XCRun +from conans.test.assets.sources import gen_function_cpp, gen_function_h +from conans.test.utils.mocks import ConanFileMock +from conans.test.utils.tools import TestClient +from conans.util.runners import conan_run + + +@pytest.mark.tool("meson") +@pytest.mark.skipif(platform.system() != "Darwin", reason="requires OSX") +def test_apple_meson_toolchain_cross_compiling(): + arch = 'armv8' if platform.machine() == "x86_64" else "x86_64" + profile = textwrap.dedent(f""" + [settings] + os = Macos + arch = {arch} + compiler = apple-clang + compiler.version = 12.0 + compiler.libcxx = libc++ + """) + conanfile_py = textwrap.dedent(""" + from conan import ConanFile + from conan.tools.meson import Meson, MesonToolchain + from conan.tools.build import cross_building + + class App(ConanFile): + settings = "os", "arch", "compiler", "build_type" + options = {"shared": [True, False], "fPIC": [True, False]} + default_options = {"shared": False, "fPIC": True} + + def layout(self): + self.folders.build = "build" + + def config_options(self): + if self.settings.os == "Windows": + self.options.rm_safe("fPIC") + + def configure(self): + if self.options.shared: + self.options.rm_safe("fPIC") + + def generate(self): + tc = MesonToolchain(self) + tc.generate() + # Forcing to create the native context too + if cross_building(self): + tc = MesonToolchain(self, native=True) + tc.generate() + + def build(self): + meson = Meson(self) + meson.configure() + meson.build() + """) + meson_build = textwrap.dedent(""" + project('tutorial', 'cpp') + hello = library('hello', 'hello.cpp') + # Even cross-building the library, we want to create an executable using only the native context + executable('mygen', 'mygen.cpp', native: true) + """) + my_gen_cpp = textwrap.dedent(""" + #include + int main() { + std::cout << "Hello World!"; + return 0; + } + """) + hello_h = gen_function_h(name="hello") + hello_cpp = gen_function_cpp(name="hello") + client = TestClient() + client.save({"conanfile.py": conanfile_py, + "meson.build": meson_build, + "hello.h": hello_h, + "hello.cpp": hello_cpp, + "mygen.cpp": my_gen_cpp, + "profile_host": profile}) + client.run("build . --profile:build=default --profile:host=profile_host") + libhello = os.path.join(client.current_folder, "build", "libhello.a") + assert os.path.isfile(libhello) is True + # Now, ensuring that we can run the mygen executable + mygen = os.path.join(client.current_folder, "build", "mygen") + client.run_command(f"'{mygen}'") + assert "Hello" in client.out + # Extra check for lib arch + conanfile = ConanFileMock({}, runner=conan_run) + xcrun = XCRun(conanfile) + lipo = xcrun.find('lipo') + client.run_command('"%s" -info "%s"' % (lipo, libhello)) + assert "architecture: %s" % _to_apple_arch(arch) in client.out From 02f1cc3be4a3d8993c2dcf417be57106011ecb95 Mon Sep 17 00:00:00 2001 From: Francisco Ramirez de Anton Date: Fri, 12 Apr 2024 16:56:59 +0200 Subject: [PATCH 3/7] Added integration test --- conan/tools/meson/toolchain.py | 18 ++-- .../toolchains/meson/test_mesontoolchain.py | 99 +++++++++++++++++++ 2 files changed, 109 insertions(+), 8 deletions(-) diff --git a/conan/tools/meson/toolchain.py b/conan/tools/meson/toolchain.py index 5a1038ea3f2..91d654538e3 100644 --- a/conan/tools/meson/toolchain.py +++ b/conan/tools/meson/toolchain.py @@ -147,11 +147,13 @@ def __init__(self, conanfile, backend=None, native=False): """ raise_on_universal_arch(conanfile) self._conanfile = conanfile - self._os = self._conanfile.settings.get_safe("os") - self._is_apple_system = is_apple_os(self._conanfile) self._native = native + self._is_cross_building = cross_building(conanfile, skip_x64_x86=True) + if not self._is_cross_building and native: + raise ConanException("You can only pass native=True if you're cross-building, " + "otherwise, it could cause unexpected results.") + self._is_apple_system = is_apple_os(self._conanfile) self._conanfile_conf = self._conanfile.conf_build if native else self._conanfile.conf - # Values are kept as Python built-ins so users can modify them more easily, and they are # only converted to Meson file syntax for rendering # priority: first user conf, then recipe, last one is default "ninja" @@ -212,7 +214,7 @@ def __init__(self, conanfile, backend=None, native=False): self.cross_build = {} default_comp = "" default_comp_cpp = "" - if native is False and cross_building(conanfile, skip_x64_x86=True): + if native is False and self._is_cross_building: os_host = conanfile.settings.get_safe("os") arch_host = conanfile.settings.get_safe("arch") os_build = conanfile.settings_build.get_safe('os') @@ -355,7 +357,7 @@ def _resolve_apple_flags_and_variables(self, build_env, compilers_by_conf): return # Calculating the main Apple flags min_flag, arch_flag, isysroot_flag = ( - resolve_apple_flags(self._conanfile, is_cross_building=bool(self.cross_build))) + resolve_apple_flags(self._conanfile, is_cross_building=self._is_cross_building)) self.apple_arch_flag = arch_flag.split() if arch_flag else [] self.apple_isysroot_flag = isysroot_flag.split() if isysroot_flag else [] self.apple_min_version_flag = [apple_min_version_flag(self._conanfile)] @@ -368,7 +370,7 @@ def _resolve_apple_flags_and_variables(self, build_env, compilers_by_conf): self.objcpp_link_args = self._get_env_list(build_env.get('LDFLAGS', [])) def _resolve_android_cross_compilation(self): - if not self.cross_build or not self.cross_build["host"]["system"] == "android": + if not self._is_cross_building or not self.cross_build["host"]["system"] == "android": return ndk_path = self._conanfile_conf.get("tools.android:ndk_path") @@ -498,9 +500,9 @@ def _sanitize_format(v): @property def _filename(self): - if self.cross_build and self._native: + if self._is_cross_building and self._native: return self.native_filename - elif self.cross_build: + elif self._is_cross_building: return self.cross_filename else: return self.native_filename diff --git a/conans/test/integration/toolchains/meson/test_mesontoolchain.py b/conans/test/integration/toolchains/meson/test_mesontoolchain.py index 740cb931de7..21bd02c59de 100644 --- a/conans/test/integration/toolchains/meson/test_mesontoolchain.py +++ b/conans/test/integration/toolchains/meson/test_mesontoolchain.py @@ -4,6 +4,7 @@ import pytest +from conan.tools.files import load from conan.tools.meson import MesonToolchain from conans.test.utils.tools import TestClient @@ -418,3 +419,101 @@ def generate(self): assert "option2 = 'disabled'" in content assert "option3 = 'enabled'" in content assert "option4 = 'disabled'" in content + + +def test_native_attribute(): + """ + Tests that native file only has the build context (not as a build require) content. + """ + host = textwrap.dedent(""" + [settings] + arch=armv8 + build_type=Release + compiler=gcc + compiler.cppstd=gnu17 + compiler.libcxx=libstdc++11 + compiler.version=11 + os=Linux + + [buildenv] + STRIP=False + PKG_CONFIG=/usr/bin/pkg-config + + [conf] + tools.build:compiler_executables={"c": "gcc", "cpp": "g++"} + """) + build = textwrap.dedent(""" + [settings] + os=Linux + arch=x86_64 + compiler=clang + compiler.version=12 + compiler.libcxx=libc++ + compiler.cppstd=11 + + [buildenv] + STRIP=True + PKG_CONFIG=/usr/lib/meson/pkgconfig + + [conf] + tools.build:compiler_executables={"c": "clang", "cpp": "clang++"} + """) + client = TestClient() + conanfile = textwrap.dedent(""" + from conan import ConanFile + from conan.tools.meson import MesonToolchain + class Pkg(ConanFile): + settings = "os", "compiler", "arch", "build_type" + def generate(self): + tc = MesonToolchain(self) + tc.generate() + # We're cross-building, no need to check it + tc = MesonToolchain(self, native=True) + tc.generate() + """) + client.save({"host": host, + "build": build, + "conanfile.py": conanfile}) + client.run("install . -pr:h host -pr:b build") + native_content = load(None, os.path.join(client.current_folder, MesonToolchain.native_filename)) + cross_content = load(None, os.path.join(client.current_folder, MesonToolchain.cross_filename)) + expected_native = textwrap.dedent(""" + [binaries] + c = 'clang' + cpp = 'clang++' + strip = 'True' + pkgconfig = '/usr/lib/meson/pkgconfig' + pkg-config = '/usr/lib/meson/pkgconfig' + """) + expected_cross = textwrap.dedent(""" + [binaries] + c = 'gcc' + cpp = 'g++' + strip = 'False' + pkgconfig = '/usr/bin/pkg-config' + pkg-config = '/usr/bin/pkg-config' + """) + assert expected_native in native_content + assert "[host_machine]" not in native_content + assert "[build_machine]" not in native_content + assert expected_cross in cross_content + assert "[build_machine]" in cross_content + assert "[host_machine]" in cross_content + + +def test_native_attribute_error(): + client = TestClient() + conanfile = textwrap.dedent(""" + from conan import ConanFile + from conan.tools.meson import MesonToolchain + class Pkg(ConanFile): + settings = "os", "compiler", "arch", "build_type" + def generate(self): + tc = MesonToolchain(self) + tc.generate() + tc = MesonToolchain(self, native=True) + tc.generate() + """) + client.save({"conanfile.py": conanfile}) + client.run("install .", assert_error=True) + assert "You can only pass native=True if you're cross-building" in client.out From e6da471915110aac04e503209dc2a637fd5c6a8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Ram=C3=ADrez?= Date: Mon, 29 Apr 2024 14:59:46 +0200 Subject: [PATCH 4/7] Update conans/test/functional/toolchains/meson/test_meson_native_attribute.py Co-authored-by: James --- .../toolchains/meson/test_meson_native_attribute.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/conans/test/functional/toolchains/meson/test_meson_native_attribute.py b/conans/test/functional/toolchains/meson/test_meson_native_attribute.py index a87615c6c83..18538ce1f7f 100644 --- a/conans/test/functional/toolchains/meson/test_meson_native_attribute.py +++ b/conans/test/functional/toolchains/meson/test_meson_native_attribute.py @@ -63,12 +63,7 @@ def build(self): # Even cross-building the library, we want to create an executable using only the native context executable('mygen', 'mygen.cpp', native: true) """) - my_gen_cpp = textwrap.dedent(""" - #include - int main() { - std::cout << "Hello World!"; - return 0; - } + my_gen_cpp = gen_function_cpp(name="main") """) hello_h = gen_function_h(name="hello") hello_cpp = gen_function_cpp(name="hello") From 8b3ff0716f4f38cc775464168279852f0387969b Mon Sep 17 00:00:00 2001 From: Francisco Ramirez de Anton Date: Tue, 30 Apr 2024 08:15:29 +0200 Subject: [PATCH 5/7] typo --- .../functional/toolchains/meson/test_meson_native_attribute.py | 1 - 1 file changed, 1 deletion(-) diff --git a/conans/test/functional/toolchains/meson/test_meson_native_attribute.py b/conans/test/functional/toolchains/meson/test_meson_native_attribute.py index 18538ce1f7f..09046dd6d38 100644 --- a/conans/test/functional/toolchains/meson/test_meson_native_attribute.py +++ b/conans/test/functional/toolchains/meson/test_meson_native_attribute.py @@ -64,7 +64,6 @@ def build(self): executable('mygen', 'mygen.cpp', native: true) """) my_gen_cpp = gen_function_cpp(name="main") - """) hello_h = gen_function_h(name="hello") hello_cpp = gen_function_cpp(name="hello") client = TestClient() From e3391b2531178b733649b88ac7ff82be27b85e73 Mon Sep 17 00:00:00 2001 From: Francisco Ramirez de Anton Date: Tue, 30 Apr 2024 15:53:06 +0200 Subject: [PATCH 6/7] Get back to cross_build check --- conan/tools/meson/toolchain.py | 18 +++++++------- .../meson/test_meson_native_attribute.py | 24 +++++++++++++------ 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/conan/tools/meson/toolchain.py b/conan/tools/meson/toolchain.py index 91d654538e3..2339536f05f 100644 --- a/conan/tools/meson/toolchain.py +++ b/conan/tools/meson/toolchain.py @@ -148,10 +148,6 @@ def __init__(self, conanfile, backend=None, native=False): raise_on_universal_arch(conanfile) self._conanfile = conanfile self._native = native - self._is_cross_building = cross_building(conanfile, skip_x64_x86=True) - if not self._is_cross_building and native: - raise ConanException("You can only pass native=True if you're cross-building, " - "otherwise, it could cause unexpected results.") self._is_apple_system = is_apple_os(self._conanfile) self._conanfile_conf = self._conanfile.conf_build if native else self._conanfile.conf # Values are kept as Python built-ins so users can modify them more easily, and they are @@ -209,12 +205,11 @@ def __init__(self, conanfile, backend=None, native=False): # Issue: https://github.com/conan-io/conan/issues/14935 self.build_pkg_config_path = None self.libcxx, self.gcc_cxx11_abi = libcxx_flags(self._conanfile) - #: Dict-like object with the build, host, and target as the Meson machine context self.cross_build = {} default_comp = "" default_comp_cpp = "" - if native is False and self._is_cross_building: + if native is False and cross_building(conanfile, skip_x64_x86=True): os_host = conanfile.settings.get_safe("os") arch_host = conanfile.settings.get_safe("arch") os_build = conanfile.settings_build.get_safe('os') @@ -238,6 +233,9 @@ def __init__(self, conanfile, backend=None, native=False): default_comp = "gcc" default_comp_cpp = "g++" + if self.cross_build and native: + raise ConanException("You can only pass native=True if you're cross-building, " + "otherwise, it could cause unexpected results.") if "Visual" in compiler or compiler == "msvc": default_comp = "cl" default_comp_cpp = "cl" @@ -357,7 +355,7 @@ def _resolve_apple_flags_and_variables(self, build_env, compilers_by_conf): return # Calculating the main Apple flags min_flag, arch_flag, isysroot_flag = ( - resolve_apple_flags(self._conanfile, is_cross_building=self._is_cross_building)) + resolve_apple_flags(self._conanfile, is_cross_building=self.cross_build)) self.apple_arch_flag = arch_flag.split() if arch_flag else [] self.apple_isysroot_flag = isysroot_flag.split() if isysroot_flag else [] self.apple_min_version_flag = [apple_min_version_flag(self._conanfile)] @@ -370,7 +368,7 @@ def _resolve_apple_flags_and_variables(self, build_env, compilers_by_conf): self.objcpp_link_args = self._get_env_list(build_env.get('LDFLAGS', [])) def _resolve_android_cross_compilation(self): - if not self._is_cross_building or not self.cross_build["host"]["system"] == "android": + if not self.cross_build or not self.cross_build["host"]["system"] == "android": return ndk_path = self._conanfile_conf.get("tools.android:ndk_path") @@ -500,9 +498,9 @@ def _sanitize_format(v): @property def _filename(self): - if self._is_cross_building and self._native: + if self.cross_build and self._native: return self.native_filename - elif self._is_cross_building: + elif self.cross_build: return self.cross_filename else: return self.native_filename diff --git a/conans/test/functional/toolchains/meson/test_meson_native_attribute.py b/conans/test/functional/toolchains/meson/test_meson_native_attribute.py index 09046dd6d38..a35c12861f7 100644 --- a/conans/test/functional/toolchains/meson/test_meson_native_attribute.py +++ b/conans/test/functional/toolchains/meson/test_meson_native_attribute.py @@ -14,13 +14,22 @@ @pytest.mark.tool("meson") @pytest.mark.skipif(platform.system() != "Darwin", reason="requires OSX") def test_apple_meson_toolchain_cross_compiling(): - arch = 'armv8' if platform.machine() == "x86_64" else "x86_64" + arch_host = 'armv8' if platform.machine() == "x86_64" else "x86_64" + arch_build = 'armv8' if platform.machine() != "x86_64" else "x86_64" profile = textwrap.dedent(f""" [settings] os = Macos - arch = {arch} + arch = {arch_host} compiler = apple-clang - compiler.version = 12.0 + compiler.version = 13.0 + compiler.libcxx = libc++ + """) + profile_build = textwrap.dedent(f""" + [settings] + os = Macos + arch = {arch_build} + compiler = apple-clang + compiler.version = 13.0 compiler.libcxx = libc++ """) conanfile_py = textwrap.dedent(""" @@ -72,17 +81,18 @@ def build(self): "hello.h": hello_h, "hello.cpp": hello_cpp, "mygen.cpp": my_gen_cpp, - "profile_host": profile}) - client.run("build . --profile:build=default --profile:host=profile_host") + "profile_host": profile, + "profile_build": profile_build}) + client.run("build . --profile:build=profile_build --profile:host=profile_host") libhello = os.path.join(client.current_folder, "build", "libhello.a") assert os.path.isfile(libhello) is True # Now, ensuring that we can run the mygen executable mygen = os.path.join(client.current_folder, "build", "mygen") client.run_command(f"'{mygen}'") - assert "Hello" in client.out + assert "Release!" in client.out # Extra check for lib arch conanfile = ConanFileMock({}, runner=conan_run) xcrun = XCRun(conanfile) lipo = xcrun.find('lipo') client.run_command('"%s" -info "%s"' % (lipo, libhello)) - assert "architecture: %s" % _to_apple_arch(arch) in client.out + assert "architecture: %s" % _to_apple_arch(arch_host) in client.out From cc595cf01f0c99f46a6bc598beb35e26bed236bc Mon Sep 17 00:00:00 2001 From: Francisco Ramirez de Anton Date: Tue, 30 Apr 2024 18:00:11 +0200 Subject: [PATCH 7/7] Fixed if-else condition if native --- conan/tools/meson/toolchain.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/conan/tools/meson/toolchain.py b/conan/tools/meson/toolchain.py index 2339536f05f..586e9afbc1d 100644 --- a/conan/tools/meson/toolchain.py +++ b/conan/tools/meson/toolchain.py @@ -149,6 +149,10 @@ def __init__(self, conanfile, backend=None, native=False): self._conanfile = conanfile self._native = native self._is_apple_system = is_apple_os(self._conanfile) + is_cross_building = cross_building(conanfile, skip_x64_x86=True) + if not is_cross_building and native: + raise ConanException("You can only pass native=True if you're cross-building, " + "otherwise, it could cause unexpected results.") self._conanfile_conf = self._conanfile.conf_build if native else self._conanfile.conf # Values are kept as Python built-ins so users can modify them more easily, and they are # only converted to Meson file syntax for rendering @@ -209,7 +213,7 @@ def __init__(self, conanfile, backend=None, native=False): self.cross_build = {} default_comp = "" default_comp_cpp = "" - if native is False and cross_building(conanfile, skip_x64_x86=True): + if native is False and is_cross_building: os_host = conanfile.settings.get_safe("os") arch_host = conanfile.settings.get_safe("arch") os_build = conanfile.settings_build.get_safe('os') @@ -233,9 +237,6 @@ def __init__(self, conanfile, backend=None, native=False): default_comp = "gcc" default_comp_cpp = "g++" - if self.cross_build and native: - raise ConanException("You can only pass native=True if you're cross-building, " - "otherwise, it could cause unexpected results.") if "Visual" in compiler or compiler == "msvc": default_comp = "cl" default_comp_cpp = "cl"