diff --git a/aqt/archives.py b/aqt/archives.py index 5bef0f92..3b715b80 100644 --- a/aqt/archives.py +++ b/aqt/archives.py @@ -380,17 +380,27 @@ def _get_archives_base(self, name, target_packages): os_name = self.os_name if self.os_name == "windows": os_name += "_x86" - elif os_name != "linux_arm64" and os_name != "all_os": + elif os_name != "linux_arm64" and os_name != "all_os" and os_name != "windows_arm64": os_name += "_x64" if self.target == "android" and self.version >= Version("6.7.0"): os_name = "all_os" - os_target_folder = posixpath.join( - "online/qtsdkrepository", - os_name, - self.target, - # tools_ifw/ - name, - ) + # + if os_name in ("windows_x86", "windows_arm64") and self.version >= Version("6.8.0"): + os_target_folder = posixpath.join( + "online/qtsdkrepository", + os_name, + self.target, + name, + name, + ) + else: + os_target_folder = posixpath.join( + "online/qtsdkrepository", + os_name, + self.target, + # tools_ifw/ + name, + ) update_xml_url = posixpath.join(os_target_folder, "Updates.xml") update_xml_text = self._download_update_xml(update_xml_url) self._parse_update_xml(os_target_folder, update_xml_text, target_packages) diff --git a/aqt/installer.py b/aqt/installer.py index 46b8ccea..bfd09a64 100644 --- a/aqt/installer.py +++ b/aqt/installer.py @@ -280,6 +280,8 @@ def _set_arch(arch: Optional[str], os_name: str, target: str, qt_version_or_spec return "android" except ValueError: pass + elif os_name == "windows_arm64" and target == "desktop": + return "windows_msvc2022_arm64" raise CliInputError("Please supply a target architecture.", should_show_help=True) def _check_mirror(self, mirror): @@ -747,7 +749,9 @@ def _set_install_qt_parser(self, install_qt_parser, *, is_legacy: bool): def _set_install_tool_parser(self, install_tool_parser, *, is_legacy: bool): install_tool_parser.set_defaults(func=self.run_install_tool, is_legacy=is_legacy) - install_tool_parser.add_argument("host", choices=["linux", "linux_arm64", "mac", "windows"], help="host os name") + install_tool_parser.add_argument( + "host", choices=["linux", "linux_arm64", "mac", "windows", "windows_arm64"], help="host os name" + ) if not is_legacy: install_tool_parser.add_argument( "target", @@ -804,7 +808,9 @@ def make_parser_sde(cmd: str, desc: str, is_legacy: bool, action, is_add_kde: bo def make_parser_list_sde(cmd: str, desc: str, cmd_type: str): parser = subparsers.add_parser(cmd, description=desc) - parser.add_argument("host", choices=["linux", "linux_arm64", "mac", "windows"], help="host os name") + parser.add_argument( + "host", choices=["linux", "linux_arm64", "mac", "windows", "windows_arm64"], help="host os name" + ) parser.add_argument( "qt_version_spec", metavar="(VERSION | SPECIFICATION)", @@ -852,7 +858,9 @@ def _make_list_qt_parser(self, subparsers: argparse._SubParsersAction): "$ aqt list-qt mac desktop --archives 5.9.0 clang_64 # list archives in base Qt installation\n" "$ aqt list-qt mac desktop --archives 5.14.0 clang_64 debug_info # list archives in debug_info module\n", ) - list_parser.add_argument("host", choices=["linux", "linux_arm64", "mac", "windows"], help="host os name") + list_parser.add_argument( + "host", choices=["linux", "linux_arm64", "mac", "windows", "windows_arm64"], help="host os name" + ) list_parser.add_argument( "target", nargs="?", @@ -936,7 +944,9 @@ def _make_list_tool_parser(self, subparsers: argparse._SubParsersAction): "$ aqt list-tool mac desktop tools_ifw --long # print tool variant names with metadata for QtIFW\n" "$ aqt list-tool mac desktop ifw --long # print tool variant names with metadata for QtIFW\n", ) - list_parser.add_argument("host", choices=["linux", "linux_arm64", "mac", "windows"], help="host os name") + list_parser.add_argument( + "host", choices=["linux", "linux_arm64", "mac", "windows", "windows_arm64"], help="host os name" + ) list_parser.add_argument( "target", nargs="?", @@ -1023,7 +1033,9 @@ def _set_common_arguments(self, subparser, *, is_legacy: bool, is_target_depreca """ if is_legacy: subparser.add_argument("qt_version", help='Qt version in the format of "5.X.Y"') - subparser.add_argument("host", choices=["linux", "linux_arm64", "mac", "windows"], help="host os name") + subparser.add_argument( + "host", choices=["linux", "linux_arm64", "mac", "windows", "windows_arm64"], help="host os name" + ) if is_target_deprecated: subparser.add_argument( "target", diff --git a/aqt/metadata.py b/aqt/metadata.py index 003ff613..2d488ccb 100644 --- a/aqt/metadata.py +++ b/aqt/metadata.py @@ -199,9 +199,10 @@ def get_semantic_version(qt_ver: str, is_preview: bool) -> Optional[Version]: class ArchiveId: CATEGORIES = ("tools", "qt") - HOSTS = ("windows", "mac", "linux", "linux_arm64", "all_os") + HOSTS = ("windows", "windows_arm64", "mac", "linux", "linux_arm64", "all_os") TARGETS_FOR_HOST = { "windows": ["android", "desktop", "winrt"], + "windows_arm64": ["desktop"], "mac": ["android", "desktop", "ios"], "linux": ["android", "desktop"], "linux_arm64": ["desktop"], @@ -233,17 +234,29 @@ def is_tools(self) -> bool: def to_url(self) -> str: return "online/qtsdkrepository/{os}{arch}/{target}/".format( os=self.host, - arch=("_x86" if self.host == "windows" else ("" if self.host in ("linux_arm64", "all_os") else "_x64")), + arch=( + "_x86" + if self.host == "windows" + else ("" if self.host in ("linux_arm64", "all_os", "windows_arm64") else "_x64") + ), target=self.target, ) - def to_folder(self, qt_version_no_dots: str, extension: Optional[str] = None) -> str: - return "{category}{major}_{ver}{ext}".format( - category=self.category, - major=qt_version_no_dots[0], - ver=qt_version_no_dots, - ext="_" + extension if extension else "", - ) + def to_folder(self, version: Version, qt_version_no_dots: str, extension: Optional[str] = None) -> str: + if version >= Version("6.8.0"): + return "{category}{major}_{ver}/{category}{major}_{ver}{ext}".format( + category=self.category, + major=qt_version_no_dots[0], + ver=qt_version_no_dots, + ext="_" + extension if extension else "", + ) + else: + return "{category}{major}_{ver}{ext}".format( + category=self.category, + major=qt_version_no_dots[0], + ver=qt_version_no_dots, + ext="_" + extension if extension else "", + ) def all_extensions(self, version: Version) -> List[str]: if self.target == "desktop" and QtRepoProperty.is_in_wasm_range(self.host, version): @@ -611,8 +624,9 @@ def fetch_arches(self, version: Version) -> List[str]: qt_ver_str = self._get_qt_version_str(version) for extension in self.archive_id.all_extensions(version): modules: Dict[str, Dict[str, str]] = {} + folder = self.archive_id.to_folder(version, qt_ver_str, extension) try: - modules = self._fetch_module_metadata(self.archive_id.to_folder(qt_ver_str, extension)) + modules = self._fetch_module_metadata(folder) except ArchiveDownloadError as e: if extension == "": raise @@ -810,7 +824,7 @@ def fetch_modules(self, version: Version, arch: str) -> List[str]: qt_ver_str = self._get_qt_version_str(version) # Example: re.compile(r"^(preview\.)?qt\.(qt5\.)?590\.(.+)$") pattern = re.compile(r"^(preview\.)?qt\.(qt" + str(version.major) + r"\.)?" + qt_ver_str + r"\.(.+)$") - modules_meta = self._fetch_module_metadata(self.archive_id.to_folder(qt_ver_str, extension)) + modules_meta = self._fetch_module_metadata(self.archive_id.to_folder(version, qt_ver_str, extension)) def to_module_arch(name: str) -> Tuple[Optional[str], Optional[str]]: _match = pattern.match(name) @@ -856,7 +870,7 @@ def fetch_long_modules(self, version: Version, arch: str) -> ModuleData: def matches_arch(element: Element) -> bool: return bool(pattern.match(MetadataFactory.require_text(element, "Name"))) - modules_meta = self._fetch_module_metadata(self.archive_id.to_folder(qt_ver_str, extension), matches_arch) + modules_meta = self._fetch_module_metadata(self.archive_id.to_folder(version, qt_ver_str, extension), matches_arch) m: Dict[str, Dict[str, str]] = {} for key, value in modules_meta.items(): match = pattern.match(key) @@ -874,7 +888,7 @@ def fetch_modules_sde(self, cmd_type: str, version: Version) -> List[str]: "qt", ), "Internal misuse of fetch_modules_sde" qt_ver_str = self._get_qt_version_str(version) - modules_meta = self._fetch_module_metadata(self.archive_id.to_folder(qt_ver_str, "src_doc_examples")) + modules_meta = self._fetch_module_metadata(self.archive_id.to_folder(version, qt_ver_str, "src_doc_examples")) # pattern: Match all names "qt.qt5.12345.doc.(\w+) pattern = re.compile(r"^qt\.(qt" + str(version.major) + r"\.)?" + qt_ver_str + r"\." + cmd_type + r"\.(.+)$") @@ -913,7 +927,7 @@ def no_modules(element: Element) -> bool: predicate = no_modules if not modules else all_modules if "all" in modules else specify_modules try: mod_metadata = self._fetch_module_metadata( - self.archive_id.to_folder(qt_version_str, extension), predicate=predicate + self.archive_id.to_folder(version, qt_version_str, extension), predicate=predicate ) except (AttributeError, ValueError) as e: raise ArchiveListError(f"Downloaded metadata is corrupted. {e}") from e @@ -948,7 +962,10 @@ def fetch_default_desktop_arch(self, version: Version, is_msvc: bool = False) -> elif self.archive_id.host == "mac": return "clang_64" elif self.archive_id.host == "windows" and is_msvc: - return "win64_msvc2019_64" + if version >= Version("6.8.0"): + return "win64_msvc2022_64" + else: + return "win64_msvc2019_64" arches = [arch for arch in self.fetch_arches(version) if QtRepoProperty.MINGW_ARCH_PATTERN.match(arch)] selected_arch = QtRepoProperty.select_default_mingw(arches, is_dir=False) if not selected_arch: diff --git a/docs/cli.rst b/docs/cli.rst index 5104d5a5..635590b3 100644 --- a/docs/cli.rst +++ b/docs/cli.rst @@ -502,7 +502,7 @@ There are various combinations to accept according to Qt version. .. describe:: host - linux, linux_arm64, windows or mac. The operating system on which the Qt development tools will run. + linux, linux_arm64, windows, windows_arm64, all_os, or mac. The operating system on which the Qt development tools will run. .. describe:: target @@ -539,7 +539,9 @@ There are various combinations to accept according to Qt version. * clang_64 for mac desktop - * win64_msvc2019_64, win64_msvc2017_64, win64_msvc2015_64, win32_msvc2015, win32_mingw53 for windows desktop + * win64_msvc2022_64, win64_mingw, win64_llvm_mingw, win64_msvc2019_64, win64_msvc2019_arm64, win64_msvc2017_64, win64_msvc2015_64, win32_msvc2015, win32_mingw53 for windows desktop + + * win64_msvc2022_arm64 for windows_arm64 desktop * android_armv7, android_arm64_v8a, android_x86, android_x86_64 for android