From 3c88b7176ddf055057cfb98585f0523440b3f622 Mon Sep 17 00:00:00 2001 From: Fu Hanxi Date: Wed, 22 Jul 2026 13:31:52 +0200 Subject: [PATCH] ci(windows): fix fetch submodule path issue --- tools/ci/python_packages/gitlab_api.py | 27 ++++++++++++++++++++------ tools/cmake/component.cmake | 24 +++++++++++------------ 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/tools/ci/python_packages/gitlab_api.py b/tools/ci/python_packages/gitlab_api.py index caa856aba0f..57fa1832775 100644 --- a/tools/ci/python_packages/gitlab_api.py +++ b/tools/ci/python_packages/gitlab_api.py @@ -1,6 +1,7 @@ # SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Apache-2.0 import argparse +import copy import logging import os import re @@ -257,18 +258,32 @@ class Gitlab: return self.decompress_archive(temp_file.name, destination) + @staticmethod + def _to_win32_long_path(path: str) -> str: + normalized_path = os.path.normpath(os.path.abspath(path)) + if normalized_path.startswith('\\\\?\\'): + return normalized_path + if normalized_path.startswith('\\\\'): + return '\\\\?\\UNC\\' + normalized_path[2:] + return '\\\\?\\' + normalized_path + @staticmethod def decompress_archive(path: str, destination: str) -> str: full_destination = os.path.abspath(destination) - # By default max path length is set to 260 characters - # Prefix `\\?\` extends it to 32,767 characters - if sys.platform == 'win32': - full_destination = '\\\\?\\' + full_destination try: with tarfile.open(path, 'r') as archive_file: - root_name = archive_file.getnames()[0] - archive_file.extractall(full_destination) + members = archive_file.getmembers() + root_name = members[0].name + if sys.platform == 'win32': + # tarfile keeps archive member names in POSIX form. Normalize them before + # combining with a long-path-prefixed destination to avoid invalid mixed separators. + full_destination = Gitlab._to_win32_long_path(full_destination) + members = [copy.copy(member) for member in members] + for member in members: + member.name = member.name.replace('/', '\\') + member.linkname = member.linkname.replace('/', '\\') + archive_file.extractall(full_destination, members=members) except tarfile.TarError as e: logging.error(f'Error while decompressing archive {path}') raise e diff --git a/tools/cmake/component.cmake b/tools/cmake/component.cmake index c269d6837d9..5f7eeabb467 100644 --- a/tools/cmake/component.cmake +++ b/tools/cmake/component.cmake @@ -97,9 +97,9 @@ endmacro() # function(__component_dir_quick_check var component_dir) set(res 1) - get_filename_component(abs_dir ${component_dir} ABSOLUTE) + get_filename_component(abs_dir "${component_dir}" ABSOLUTE) - get_filename_component(base_dir ${abs_dir} NAME) + get_filename_component(base_dir "${abs_dir}" NAME) string(SUBSTRING "${base_dir}" 0 1 first_char) # Check the component directory contains a CMakeLists.txt file @@ -148,8 +148,8 @@ function(__component_add component_dir prefix component_source) # so later in the build, these component targets actually contain the properties meant for the # corresponding component library. idf_build_get_property(component_targets __COMPONENT_TARGETS) - get_filename_component(abs_dir ${component_dir} ABSOLUTE) - get_filename_component(base_dir ${abs_dir} NAME) + get_filename_component(abs_dir "${component_dir}" ABSOLUTE) + get_filename_component(base_dir "${abs_dir}" NAME) if(NOT EXISTS "${abs_dir}/CMakeLists.txt") message(FATAL_ERROR "Directory '${component_dir}' does not contain a component.") @@ -276,15 +276,15 @@ macro(__component_add_sources sources) message(WARNING "SRCS and SRC_DIRS are both specified; ignoring SRC_DIRS.") endif() foreach(src ${__SRCS}) - get_filename_component(src "${src}" ABSOLUTE BASE_DIR ${COMPONENT_DIR}) - list(APPEND sources ${src}) + get_filename_component(src "${src}" ABSOLUTE BASE_DIR "${COMPONENT_DIR}") + list(APPEND sources "${src}") endforeach() else() if(__SRC_DIRS) foreach(dir ${__SRC_DIRS}) - get_filename_component(abs_dir ${dir} ABSOLUTE BASE_DIR ${COMPONENT_DIR}) + get_filename_component(abs_dir "${dir}" ABSOLUTE BASE_DIR "${COMPONENT_DIR}") - if(NOT IS_DIRECTORY ${abs_dir}) + if(NOT IS_DIRECTORY "${abs_dir}") message(FATAL_ERROR "SRC_DIRS entry '${dir}' does not exist.") endif() @@ -293,7 +293,7 @@ macro(__component_add_sources sources) if(dir_sources) foreach(src ${dir_sources}) - get_filename_component(src "${src}" ABSOLUTE BASE_DIR ${COMPONENT_DIR}) + get_filename_component(src "${src}" ABSOLUTE BASE_DIR "${COMPONENT_DIR}") list(APPEND sources "${src}") endforeach() else() @@ -315,11 +315,11 @@ endmacro() macro(__component_add_include_dirs lib dirs type) foreach(dir ${dirs}) - get_filename_component(_dir ${dir} ABSOLUTE BASE_DIR ${CMAKE_CURRENT_LIST_DIR}) - if(NOT IS_DIRECTORY ${_dir}) + get_filename_component(_dir "${dir}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_LIST_DIR}") + if(NOT IS_DIRECTORY "${_dir}") message(FATAL_ERROR "Include directory '${_dir}' is not a directory.") endif() - target_include_directories(${lib} ${type} ${_dir}) + target_include_directories(${lib} ${type} "${_dir}") endforeach() endmacro()