diff --git a/conans/client/build/cmake_flags.py b/conans/client/build/cmake_flags.py index fbc937108f2..5d29c626300 100644 --- a/conans/client/build/cmake_flags.py +++ b/conans/client/build/cmake_flags.py @@ -174,6 +174,61 @@ def _get_cpp_standard_vars(self): definitions["CONAN_STD_CXX_FLAG"] = cppstd_flag(self._conanfile.settings) return definitions + @staticmethod + def _cmake_system_name(os_, cmake_version): + apple_system_name = "Darwin" if cmake_version and Version(cmake_version) < Version( + "3.14") or not cmake_version else None + cmake_system_name_map = {"Macos": "Darwin", + "iOS": apple_system_name or "iOS", + "tvOS": apple_system_name or "tvOS", + "watchOS": apple_system_name or "watchOS", + "Neutrino": "QNX", + "": "Generic", + None: "Generic"} + return cmake_system_name_map.get(os_, os_) + + @staticmethod + def _cmake_system_processor(os_, arch): + if os_ in ["Windows", "WindowsStore", "WindowsCE"]: + # Windows: PROCESSOR_ARCHITECTURE + # https://docs.microsoft.com/en-us/windows/win32/winprog64/wow64-implementation-details + cmake_system_processor_map = {"x86_64": "AMD64", + "x86": "x86", + "ia64": "IA64", + "armv5hf": "ARM", + "armv6": "ARM", + "armv7": "ARM", + "armv7hf": "ARM", + "armv7s": "ARM", + "armv7k": "ARM", + "armv8": "ARM64", + "armv8_32": "ARM64", + "armv8.3": "ARM64"} + else: + cmake_system_processor_map = {"x86_64": "x86_64", + "x86": "i386", + "ia64": "ia64", + "armv5hf": "arm", + "armv6": "arm", + "armv7": "arm", + "armv7hf": "arm", + "armv7s": "arm", + "armv7k": "arm", + "armv8": "aarch64", + "armv8_32": "aarch64", + "armv8.3": "aarch64", + "sparc": "sparc", + "sparcv9": "sparc64", + "s390": "s390", + "s390x": "s390x", + "mips": "mips", + "mips64": "mips64", + "ppc32be": "pcc", + "ppc32": "ppcle", + "ppc64le": "ppc64le", + "ppc64": "ppc64"} + return cmake_system_processor_map.get(arch, arch) + def _cmake_cross_build_defines(self, cmake_version): os_ = self._ss("os") arch = self._ss("arch") @@ -184,7 +239,7 @@ def _cmake_cross_build_defines(self, cmake_version): env_sn = {"False": False, "True": True, "": None}.get(env_sn, env_sn) cmake_system_name = env_sn or self._forced_cmake_system_name - os_build, _, _, _ = get_cross_building_settings(self._conanfile) + os_build, arch_build, _, _ = get_cross_building_settings(self._conanfile) compiler = self._ss("compiler") libcxx = self._ss("compiler.libcxx") @@ -206,16 +261,8 @@ def _cmake_cross_build_defines(self, cmake_version): else: # detect if we are cross building and the system name and version skip_x64_x86 = os_ in ['Windows', 'Linux', 'SunOS', 'AIX'] if cross_building(self._conanfile, skip_x64_x86=skip_x64_x86): # We are cross building - apple_system_name = "Darwin" if cmake_version and Version(cmake_version) < Version( - "3.14") or not cmake_version else None - cmake_system_name_map = {"Macos": "Darwin", - "iOS": apple_system_name or "iOS", - "tvOS": apple_system_name or "tvOS", - "watchOS": apple_system_name or "watchOS", - "Neutrino": "QNX", - "": "Generic", - None: "Generic"} - definitions["CMAKE_SYSTEM_NAME"] = cmake_system_name_map.get(os_, os_) + definitions["CMAKE_SYSTEM_NAME"] = self._cmake_system_name(os_, cmake_version) + definitions["CMAKE_SYSTEM_PROCESSOR"] = self._cmake_system_processor(os_, arch) if os_ver: definitions["CMAKE_SYSTEM_VERSION"] = os_ver diff --git a/conans/test/unittests/client/build/cmake_test.py b/conans/test/unittests/client/build/cmake_test.py index b16939e278c..4f6121eb732 100644 --- a/conans/test/unittests/client/build/cmake_test.py +++ b/conans/test/unittests/client/build/cmake_test.py @@ -495,7 +495,9 @@ def quote_var(var): with tools.chdir(self.tempdir): linux_stuff = "" if platform.system() != "Linux": - linux_stuff = '-DCMAKE_SYSTEM_NAME="Linux" -DCMAKE_SYSROOT="/path/to/sysroot" ' + linux_stuff = '-DCMAKE_SYSTEM_NAME="Linux" ' \ + '-DCMAKE_SYSTEM_PROCESSOR="i386" ' \ + '-DCMAKE_SYSROOT="/path/to/sysroot" ' generator = "MinGW Makefiles" if platform.system() == "Windows" else "Unix Makefiles" flags = '{} -DCONAN_COMPILER="gcc" ' \ @@ -670,8 +672,21 @@ def check(text, build_config, generator=None, set_cmake_flags=False): cross = "" skip_x64_x86 = the_os in ['Windows', 'Linux'] if cmake_system_name and cross_building(conanfile, skip_x64_x86=skip_x64_x86): - cross = ("-DCMAKE_SYSTEM_NAME=\"%s\" %s-DCMAKE_SYSROOT=\"/path/to/sysroot\" " - % ({"Macos": "Darwin"}.get(the_os, the_os), cross_ver)) + if the_os in ["WindowsStore", "WindowsCE", "Windows"]: + arch_map = {"armv8": "ARM64", + "armv7": "ARM", + "x86": "x86", + "x86_64": "AMD64"} + else: + arch_map = {"armv8": "aarch64", + "armv7": "arm", + "x86": "i386", + "x86_64": "x86_64", + "sparcv9": "sparc64"} + cross = ("-DCMAKE_SYSTEM_NAME=\"%s\" " + "-DCMAKE_SYSTEM_PROCESSOR=\"%s\" " + "%s-DCMAKE_SYSROOT=\"/path/to/sysroot\" " + % ({"Macos": "Darwin"}.get(the_os, the_os), arch_map.get(arch, arch), cross_ver)) cmake = CMake(conanfile, generator=generator, cmake_system_name=cmake_system_name, set_cmake_flags=set_cmake_flags) new_text = text.replace("-DCONAN_IN_LOCAL_CACHE", "%s-DCONAN_IN_LOCAL_CACHE" % cross) @@ -807,6 +822,7 @@ def check(text, build_config, generator=None, set_cmake_flags=False): '-DCMAKE_EXPORT_NO_PACKAGE_REGISTRY="ON" -DCONAN_EXPORTED="1" -Wno-dev' % cmakegen, "") + settings.arch = "sparc" settings.compiler = "Visual Studio" settings.compiler.version = "12" settings.os = "WindowsStore" @@ -868,7 +884,9 @@ def test_deleted_os(self): cmake = CMake(conanfile) generator = "Unix" if platform.system() != "Windows" else "MinGW" - cross = ("-DCMAKE_SYSTEM_NAME=\"Linux\" -DCMAKE_SYSROOT=\"/path/to/sysroot\" " + cross = ("-DCMAKE_SYSTEM_NAME=\"Linux\" " + "-DCMAKE_SYSTEM_PROCESSOR=\"x86_64\" " + "-DCMAKE_SYSROOT=\"/path/to/sysroot\" " if platform.system() != "Linux" else "") self.assertEqual('-G "%s Makefiles" %s-DCONAN_IN_LOCAL_CACHE="OFF" ' '-DCONAN_COMPILER="gcc" ' @@ -967,6 +985,7 @@ def test_convenient_functions(self): cmake = CMake(conanfile) cross = '-DCMAKE_SYSTEM_NAME="Android"' \ + ' -DCMAKE_SYSTEM_PROCESSOR="arm"' \ ' -DCMAKE_SYSTEM_VERSION="{0}"' \ ' -DCMAKE_SYSROOT="/path/to/sysroot"' \ ' -DCMAKE_ANDROID_ARCH_ABI="armeabi-v7a"' \ @@ -1606,6 +1625,29 @@ def test_cmake_vs_arch(self): self.assertIn('-G "Visual Studio 15 2017 Win64"', cmake.command_line) self.assertIn('-T "v141,host=x64"', cmake.command_line) + @parameterized.expand([('Linux', 'armv7', 'Linux', 'arm'), + ('Linux', 'armv8', 'Linux', 'aarch64'), + ('FreeBSD', 'x86', 'FreeBSD', 'i386'), + ('SunOS', 'sparcv9', 'SunOS', 'sparc64'), + ('Windows', 'x86', 'Windows', 'x86'), + ('Windows', 'x86_64', 'Windows', 'AMD64'), + ('Windows', 'armv7', 'Windows', 'ARM'), + ('Windows', 'armv8', 'Windows', 'ARM64'), + ]) + def test_cmake_system_processor(self, os_, arch_, system_name, system_processor): + settings = Settings.loads(get_default_settings_yml()) + settings.os = os_ + settings.arch = arch_ + settings.os_build = "Linux" + settings.arch_build = "x86_64" + + conanfile = ConanFileMock() + conanfile.settings = settings + + cmake = CMake(conanfile) + self.assertEqual(cmake.definitions["CMAKE_SYSTEM_NAME"], system_name) + self.assertEqual(cmake.definitions["CMAKE_SYSTEM_PROCESSOR"], system_processor) + def test_skip_test(self): conf = ConfDefinition() conf.loads("tools.build:skip_test=1") @@ -1615,3 +1657,4 @@ def test_skip_test(self): cmake = CMake(conanfile, generator="Unix Makefiles") cmake.test() self.assertIsNone(conanfile.command) +