diff --git a/builder/main.py b/builder/main.py index 42ef0c93c..1c8a3e554 100644 --- a/builder/main.py +++ b/builder/main.py @@ -257,21 +257,51 @@ def _get_installed_uv_packages(): def install_esptool(env): """ Install esptool from package folder "tool-esptoolpy" using uv package manager. + Also determines the path to the esptool executable binary. Args: env: SCons environment object Returns: - bool: True if successful, False otherwise + str: Path to esptool executable, or 'esptool' as fallback """ + def _get_esptool_executable_path(python_exe): + """ + Get the path to the esptool executable binary. + + Args: + python_exe (str): Path to Python executable + + Returns: + str: Path to esptool executable + """ + if not python_exe or not os.path.isfile(python_exe): + return 'esptool' # Fallback + + python_dir = os.path.dirname(python_exe) + + if sys.platform == "win32": + scripts_dir = os.path.join(python_dir, "Scripts") + esptool_exe = os.path.join(scripts_dir, "esptool.exe") + else: + scripts_dir = os.path.join(python_dir) + esptool_exe = os.path.join(scripts_dir, "esptool") + + if os.path.isfile(esptool_exe): + return esptool_exe + + return 'esptool' + try: subprocess.check_call( [env.subst("$PYTHONEXE"), "-c", "import esptool"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, - env=os.environ # Use modified environment with custom PYTHONPATH + env=os.environ ) - return True + python_exe = env.subst("$PYTHONEXE") + esptool_binary_path = _get_esptool_executable_path(python_exe) + return esptool_binary_path except (subprocess.CalledProcessError, FileNotFoundError): pass @@ -282,18 +312,22 @@ def install_esptool(env): "uv", "pip", "install", "--quiet", f"--python={env.subst('$PYTHONEXE')}", "-e", esptool_repo_path - ], env=os.environ) # Use modified environment with custom PYTHONPATH - return True + ], env=os.environ) + + python_exe = env.subst("$PYTHONEXE") + esptool_binary_path = _get_esptool_executable_path(python_exe) + return esptool_binary_path + except subprocess.CalledProcessError as e: print(f"Warning: Failed to install esptool: {e}") - return False + return 'esptool' # Fallback - return False + return 'esptool' # Fallback # Install Python dependencies and esptool install_python_deps() -install_esptool(env) +esptool_binary_path = install_esptool(env) def BeforeUpload(target, source, env): @@ -675,6 +709,13 @@ def switch_off_ldf(): if "INTEGRATION_EXTRA_DATA" not in env: env["INTEGRATION_EXTRA_DATA"] = {} +# Take care of possible whitespaces in path +objcopy_value = ( + f'"{esptool_binary_path}"' + if ' ' in esptool_binary_path + else esptool_binary_path +) + # Configure build tools and environment variables env.Replace( __get_board_boot_mode=_get_board_boot_mode, @@ -704,7 +745,7 @@ def switch_off_ldf(): "bin", "%s-elf-gdb" % toolchain_arch, ), - OBJCOPY='esptool', + OBJCOPY=objcopy_value, RANLIB="%s-elf-gcc-ranlib" % toolchain_arch, SIZETOOL="%s-elf-size" % toolchain_arch, ARFLAGS=["rc"],