diff --git a/conan/internal/internal_tools.py b/conan/internal/internal_tools.py index 03a4cc0c01b..195b65a7647 100644 --- a/conan/internal/internal_tools.py +++ b/conan/internal/internal_tools.py @@ -16,3 +16,9 @@ def is_universal_arch(settings_value, valid_definitions): valid_macos_values = [val for val in valid_definitions if ("arm" in val or "x86" in val)] return all(part in valid_macos_values for part in parts) + + +def raise_on_universal_arch(conanfile): + if is_universal_arch(conanfile.settings.get_safe("arch"), + conanfile.settings.possible_values().get("arch")): + raise ConanException("Universal binaries not supported by toolchain.") diff --git a/conan/tools/gnu/autotoolstoolchain.py b/conan/tools/gnu/autotoolstoolchain.py index 71ec02001be..e106367c047 100644 --- a/conan/tools/gnu/autotoolstoolchain.py +++ b/conan/tools/gnu/autotoolstoolchain.py @@ -1,4 +1,5 @@ from conan.internal import check_duplicated_generator +from conan.internal.internal_tools import raise_on_universal_arch from conan.tools.apple.apple import apple_min_version_flag, is_apple_os, to_apple_arch, apple_sdk_path from conan.tools.apple.apple import get_apple_sdk_fullname from conan.tools.build import cmd_args_to_string, save_toolchain_args @@ -24,6 +25,8 @@ def __init__(self, conanfile, namespace=None, prefix="/"): helper so that it reads the information from the proper file. :param prefix: Folder to use for ``--prefix`` argument ("/" by default). """ + raise_on_universal_arch(conanfile) + self._conanfile = conanfile self._namespace = namespace self._prefix = prefix diff --git a/conan/tools/google/toolchain.py b/conan/tools/google/toolchain.py index 17a7470ce51..b9684bec714 100644 --- a/conan/tools/google/toolchain.py +++ b/conan/tools/google/toolchain.py @@ -26,6 +26,7 @@ from jinja2 import Template from conan.internal import check_duplicated_generator +from conan.internal.internal_tools import raise_on_universal_arch from conan.tools.apple import to_apple_arch, is_apple_os from conan.tools.build.cross_building import cross_building from conan.tools.build.flags import cppstd_flag @@ -63,6 +64,8 @@ def __init__(self, conanfile): """ :param conanfile: ``< ConanFile object >`` The current recipe object. Always use ``self``. """ + raise_on_universal_arch(conanfile) + self._conanfile = conanfile # Bazel build parameters diff --git a/conan/tools/meson/toolchain.py b/conan/tools/meson/toolchain.py index 86d5491d5d1..d1c2ac0c1be 100644 --- a/conan/tools/meson/toolchain.py +++ b/conan/tools/meson/toolchain.py @@ -5,6 +5,7 @@ from conan.errors import ConanException from conan.internal import check_duplicated_generator +from conan.internal.internal_tools import raise_on_universal_arch from conan.tools.apple.apple import to_apple_arch, is_apple_os, apple_min_version_flag, \ apple_sdk_path, get_apple_sdk_fullname from conan.tools.build.cross_building import cross_building @@ -93,6 +94,7 @@ def __init__(self, conanfile, backend=None): :param conanfile: ``< ConanFile object >`` The current recipe object. Always use ``self``. :param backend: ``str`` ``backend`` Meson variable value. By default, ``ninja``. """ + 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) diff --git a/conans/test/integration/toolchains/test_raise_on_universal_binaries.py b/conans/test/integration/toolchains/test_raise_on_universal_binaries.py new file mode 100644 index 00000000000..552424a652a --- /dev/null +++ b/conans/test/integration/toolchains/test_raise_on_universal_binaries.py @@ -0,0 +1,15 @@ +from parameterized import parameterized + +from conans.test.assets.genconanfile import GenConanfile +from conans.test.utils.tools import TestClient + + +@parameterized.expand(["AutotoolsToolchain", "MesonToolchain", "BazelToolchain"]) +def test_create_universal_binary(toolchain): + client = TestClient() + conanfile = (GenConanfile().with_settings("os", "arch", "compiler", "build_type").with_generator(toolchain)) + client.save({"conanfile.py": conanfile}) + + client.run('create . --name=foo --version=1.0 -s="arch=armv8|armv8.3|x86_64"', + assert_error=True) + assert f"Error in generator '{toolchain}': Universal binaries not supported by toolchain." in client.out diff --git a/conans/test/utils/mocks.py b/conans/test/utils/mocks.py index db0d9f39370..cb538224bb1 100644 --- a/conans/test/utils/mocks.py +++ b/conans/test/utils/mocks.py @@ -1,3 +1,4 @@ +from collections import defaultdict from io import StringIO from conan import ConanFile @@ -62,6 +63,9 @@ def __getattr__(self, name): def rm_safe(self, name): self.values.pop(name, None) + def possible_values(self): + return defaultdict(lambda: []) + class MockCppInfo(object): def __init__(self):