✨ feat: Windows .bat support + settings64 env setup for Xilinx tools
Tool discovery:
- On Windows, scan .bat files in addition to .exe
(Xilinx Windows tools use .bat wrappers, not .exe)
- Prefer .exe over .bat when both exist (same version dir)
Environment setup:
- _find_settings_script(): walk up from bin/ to find settings64.sh/.bat
- build_tool_command(): wrap Linux tool invocation with 'source settings64.sh'
Windows .bat wrappers handle env internally, no extra wrapping needed
- reboot_manager.py now uses build_tool_command() for proper env
Example output (Linux):
build_tool_command('/data/xilinx/Vitis/2023.2/bin/xsct', 'script.tcl')
→ ['bash', '-c', 'source .../settings64.sh && .../xsct script.tcl']
This commit is contained in:
@@ -231,8 +231,9 @@ exit
|
|||||||
if callback:
|
if callback:
|
||||||
callback("progress", "Running JTAG system reset...")
|
callback("progress", "Running JTAG system reset...")
|
||||||
|
|
||||||
|
from vitis_checker import build_tool_command
|
||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
[xsct, tcl_path],
|
build_tool_command(xsct, tcl_path),
|
||||||
capture_output=True,
|
capture_output=True,
|
||||||
text=True,
|
text=True,
|
||||||
timeout=30,
|
timeout=30,
|
||||||
|
|||||||
+63
-1
@@ -110,6 +110,7 @@ def _scan_xilinx_root(
|
|||||||
"""Scan xilinx_root for all installed versions of a tool.
|
"""Scan xilinx_root for all installed versions of a tool.
|
||||||
|
|
||||||
Searches under Vitis/*/bin/ and Vivado/*/bin/ for the executable.
|
Searches under Vitis/*/bin/ and Vivado/*/bin/ for the executable.
|
||||||
|
On Windows also checks .bat wrappers in addition to .exe.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
xilinx_root: Xilinx root directory (e.g., /data/xilinx, C:/Xilinx).
|
xilinx_root: Xilinx root directory (e.g., /data/xilinx, C:/Xilinx).
|
||||||
@@ -124,6 +125,11 @@ def _scan_xilinx_root(
|
|||||||
if not xr.is_dir():
|
if not xr.is_dir():
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
# On Windows, also try .bat extension (Xilinx tools use .bat wrappers)
|
||||||
|
suffixes = [exec_suffix]
|
||||||
|
if exec_suffix == ".exe":
|
||||||
|
suffixes.append(".bat")
|
||||||
|
|
||||||
for product in _PRODUCT_DIRS:
|
for product in _PRODUCT_DIRS:
|
||||||
pdir = xr / product
|
pdir = xr / product
|
||||||
if not pdir.is_dir():
|
if not pdir.is_dir():
|
||||||
@@ -135,11 +141,13 @@ def _scan_xilinx_root(
|
|||||||
for ver_dir in entries:
|
for ver_dir in entries:
|
||||||
if not ver_dir.is_dir():
|
if not ver_dir.is_dir():
|
||||||
continue
|
continue
|
||||||
candidate = ver_dir / "bin" / f"{exec_name}{exec_suffix}"
|
for sfx in suffixes:
|
||||||
|
candidate = ver_dir / "bin" / f"{exec_name}{sfx}"
|
||||||
if candidate.is_file():
|
if candidate.is_file():
|
||||||
v = _parse_version_tuple(ver_dir.name)
|
v = _parse_version_tuple(ver_dir.name)
|
||||||
if v != (0,):
|
if v != (0,):
|
||||||
results.append((v, candidate, product))
|
results.append((v, candidate, product))
|
||||||
|
break # Found for this version dir
|
||||||
# Sort newest first (descending version tuple)
|
# Sort newest first (descending version tuple)
|
||||||
results.sort(key=lambda x: x[0], reverse=True)
|
results.sort(key=lambda x: x[0], reverse=True)
|
||||||
return results
|
return results
|
||||||
@@ -237,6 +245,60 @@ def get_all_found_versions(
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
# ── Environment setup ────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
||||||
|
def _find_settings_script(tool_path: str) -> str | None:
|
||||||
|
"""Find the settings64 script for a Xilinx tool's version directory.
|
||||||
|
|
||||||
|
Walks up from the tool's bin/ directory looking for
|
||||||
|
settings64.sh (Linux) or settings64.bat (Windows).
|
||||||
|
|
||||||
|
Args:
|
||||||
|
tool_path: Absolute path to a Xilinx tool executable.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Path to settings64 script, or None if not found.
|
||||||
|
"""
|
||||||
|
p = Path(tool_path).resolve()
|
||||||
|
for parent in p.parents:
|
||||||
|
for name in ("settings64.sh", "settings64.bat"):
|
||||||
|
candidate = parent / name
|
||||||
|
if candidate.is_file():
|
||||||
|
return str(candidate)
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def build_tool_command(tool_path: str, *args: str) -> list[str]:
|
||||||
|
"""Build a subprocess-safe command with Xilinx environment setup.
|
||||||
|
|
||||||
|
On Linux: sources settings64.sh before running the tool.
|
||||||
|
On Windows: .bat wrappers handle environment internally.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
tool_path: Path to the Xilinx tool executable.
|
||||||
|
*args: Arguments to pass to the tool.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Command list suitable for subprocess.run().
|
||||||
|
"""
|
||||||
|
import shlex
|
||||||
|
|
||||||
|
system = platform.system().lower()
|
||||||
|
|
||||||
|
# Windows: .bat wrappers set up their own environment
|
||||||
|
if system == "windows":
|
||||||
|
return [tool_path, *args]
|
||||||
|
|
||||||
|
# Linux: find settings64.sh and source it before running
|
||||||
|
settings = _find_settings_script(tool_path)
|
||||||
|
if not settings:
|
||||||
|
return [tool_path, *args]
|
||||||
|
|
||||||
|
quoted = " ".join(shlex.quote(a) for a in [tool_path, *args])
|
||||||
|
return ["bash", "-c", f"source {shlex.quote(settings)} && {quoted}"]
|
||||||
|
|
||||||
|
|
||||||
# ── Public path getters ──────────────────────────────────────────────
|
# ── Public path getters ──────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user