diff --git a/packages/dsp-mod-debug/dss_script/dss-launcher.bat b/packages/dsp-mod-debug/dss_script/dss-launcher.bat index 4dc705f..7e898ae 100644 --- a/packages/dsp-mod-debug/dss_script/dss-launcher.bat +++ b/packages/dsp-mod-debug/dss_script/dss-launcher.bat @@ -8,9 +8,6 @@ if defined ENV_SCRIPT_DIR ( set "SCRIPT_DIR=%~dp0" ) -rem Ensure the script directory ends with a trailing backslash for reliable path joins -if not "%SCRIPT_DIR:~-1%"=="\" set "SCRIPT_DIR=%SCRIPT_DIR%\" - rem DSS script and config paths set "DSS_WRAPPER=%SCRIPT_DIR%dss-wrapper.js" set "DSS_CONFIG=%SCRIPT_DIR%dss-config.json" @@ -21,46 +18,26 @@ if not exist "%DSS_WRAPPER%" ( exit /b 1 ) -rem Parse DSS path (prefer bundled runtime script, then environment variable, then default) -if exist "%SCRIPT_DIR%setdssenv.bat" ( - set "DSS_CMD=%SCRIPT_DIR%setdssenv.bat" - echo [DSSLauncher] Using bundled runtime setdssenv.bat: %DSS_CMD% -) else if exist "%SCRIPT_DIR%..\setdssenv.bat" ( - set "DSS_CMD=%SCRIPT_DIR%..\setdssenv.bat" - echo [DSSLauncher] Using parent runtime setdssenv.bat: %DSS_CMD% -) else if exist "%SCRIPT_DIR%..\..\setdssenv.bat" ( - set "DSS_CMD=%SCRIPT_DIR%..\..\setdssenv.bat" - echo [DSSLauncher] Using grandparent runtime setdssenv.bat: %DSS_CMD% -) else if defined DSS_BAT ( +rem Parse DSS path (prefer environment variable) +if defined DSS_BAT ( set "DSS_CMD=%DSS_BAT%" echo [DSSLauncher] Using DSS_BAT from environment: %DSS_BAT% -) else if defined CCS_PATH ( - set "DSS_CMD=%CCS_PATH%\ccs_base\scripting\examples\TestServer\setdssenv.bat" - echo [DSSLauncher] Using CCS_PATH to locate DSS: %CCS_PATH% ) else ( - set "DSS_CMD=dss.bat" - echo [DSSLauncher] Using default dss.bat from PATH + echo [DSSLauncher] ERROR: DSS_BAT not set. Please set DSS_BAT environment variable. + exit /b 1 ) rem Verify DSS_CMD -if /i "%DSS_CMD%"=="dss.bat" ( - where dss.bat >nul 2>nul - if errorlevel 1 ( - echo [DSSLauncher] ERROR: dss.bat not found in PATH. Please set DSS_BAT or CCS_PATH environment variable. - exit /b 1 - ) -) else ( - if not exist "%DSS_CMD%" ( - echo [DSSLauncher] ERROR: DSS script not found: %DSS_CMD% - exit /b 1 - ) +if not exist "%DSS_CMD%" ( + echo [DSSLauncher] ERROR: DSS script not found: %DSS_CMD% + exit /b 1 ) echo [DSSLauncher] DSS command: %DSS_CMD% echo [DSSLauncher] Wrapper script: %DSS_WRAPPER% echo [DSSLauncher] Config file: %DSS_CONFIG% -rem Setup DSS environment +rem Setup DSS environment (setdssenv.bat) call "%DSS_CMD%" if errorlevel 1 ( echo [DSSLauncher] ERROR: Failed to setup DSS environment using: %DSS_CMD% @@ -69,17 +46,28 @@ if errorlevel 1 ( echo [DSSLauncher] DSS environment initialized. Starting wrapper script... -rem Run DSS wrapper script -if exist "%SCRIPT_DIR%dss.bat" ( - call "%SCRIPT_DIR%dss.bat" "%DSS_WRAPPER%" -) else if exist "%SCRIPT_DIR%..\dss.bat" ( - call "%SCRIPT_DIR%..\dss.bat" "%DSS_WRAPPER%" -) else if exist "%SCRIPT_DIR%..\..\dss.bat" ( - call "%SCRIPT_DIR%..\..\dss.bat" "%DSS_WRAPPER%" +rem Find and run dss.bat (from same directory as setdssenv.bat) +set "DSS_EXE=" +for %%i in ("%DSS_CMD%") do set "DSS_CMD_DIR=%%~dpi" +if exist "!DSS_CMD_DIR!dss.bat" ( + set "DSS_EXE=!DSS_CMD_DIR!dss.bat" ) else ( - dss "%DSS_WRAPPER%" + where dss.bat >nul 2>nul + if not errorlevel 1 ( + for /f "delims=" %%i in ('where dss.bat') do ( + if not defined DSS_EXE set "DSS_EXE=%%i" + ) + ) ) +if not defined DSS_EXE ( + echo [DSSLauncher] ERROR: dss.bat not found + exit /b 1 +) + +echo [DSSLauncher] Using dss.bat: %DSS_EXE% +"%DSS_EXE%" "%DSS_WRAPPER%" + set EXIT_CODE=%errorlevel% echo [DSSLauncher] DSS process exited with code %EXIT_CODE% diff --git a/packages/dsp-mod-debug/dss_script/setdssenv.bat b/packages/dsp-mod-debug/dss_script/setdssenv.bat new file mode 100644 index 0000000..36d99dc --- /dev/null +++ b/packages/dsp-mod-debug/dss_script/setdssenv.bat @@ -0,0 +1,12 @@ +@echo off + +REM setpath.bat + +REM Scripting Root - use absolute path for ccs_base/scripting +set "SCRPITING_ROOT=C:\ccs\ccs_base\scripting" + +echo [DSSEnv] %SCRPITING_ROOT% + +REM add locations of dss.bat and loadti to PATH +set PATH=%PATH%;%SCRPITING_ROOT%\bin;%SCRPITING_ROOT%\examples\loadti +set PERL5LIB=%PERL5LIB%;%SCRPITING_ROOT%\examples\TestServer diff --git a/packages/dsp-mod-debug/src/dssDebugProvider.ts b/packages/dsp-mod-debug/src/dssDebugProvider.ts index bd8954d..44cd7e4 100644 --- a/packages/dsp-mod-debug/src/dssDebugProvider.ts +++ b/packages/dsp-mod-debug/src/dssDebugProvider.ts @@ -14,38 +14,6 @@ import * as path from 'path'; import * as fs from 'fs'; import * as os from 'os'; import { execSync } from 'child_process'; -import { findBasicRoot } from './basicRoot'; - -const extensionRoot = path.resolve(__dirname, '..'); -const getBuiltinBasicRoot = () => findBasicRoot(extensionRoot); - -function resolveBuiltinToolchainPath(toolName: string, fallbackDir?: string): string | undefined { - const basicRoot = getBuiltinBasicRoot(); - if (!basicRoot) { - return undefined; - } - - const toolchainCandidates = [ - path.join(basicRoot, toolName), - path.join(basicRoot, 'ti-cgt-c6000_8.2.2', 'bin', toolName), - path.join(basicRoot, 'ti-cgt-arm_5.2.2', 'bin', toolName) - ]; - - for (const candidate of toolchainCandidates) { - if (fs.existsSync(candidate)) { - return candidate; - } - } - - if (fallbackDir) { - const fallbackCandidate = path.join(fallbackDir, toolName); - if (fs.existsSync(fallbackCandidate)) { - return fallbackCandidate; - } - } - - return undefined; -} /** * 源码路径映射规则 @@ -61,7 +29,8 @@ export interface SourceMapRule { * CCS 环境配置 */ export interface CCSConfig { - ccsPath: string; + dssPath: string; + toolsRoot: string; dssBatPath: string; dis6xPath: string; ofd6xPath: string; @@ -71,20 +40,6 @@ export interface CCSConfig { /** * DSS 调试配置提供者 */ -function resolveRuntimeRootFromBuiltinBasic(): string | undefined { - const basicRoot = getBuiltinBasicRoot(); - if (!basicRoot) { - return undefined; - } - - const dssRoot = path.join(basicRoot, 'ccs_base'); - if (fs.existsSync(dssRoot)) { - return dssRoot; - } - - return undefined; -} - export class DSSDebugProvider implements vscode.DebugConfigurationProvider { /** @@ -107,7 +62,7 @@ export class DSSDebugProvider implements vscode.DebugConfigurationProvider { // 解析 CCS 环境配置 const ccsConfig = await this.resolveCCSEnvironment({ - ccsPath: settings.get('ccsPath') || config.ccsPath, + dssPath: settings.get('dssPath') || config.dssPath, dssBatPath: settings.get('dssBatPath') || config.dssBatPath, dis6xPath: settings.get('dis6xPath') || config.disasm?.dis6xPath, ofd6xPath: settings.get('ofd6xPath') || config.disasm?.ofd6xPath @@ -122,7 +77,6 @@ export class DSSDebugProvider implements vscode.DebugConfigurationProvider { config.dssBatPath = ccsConfig.dssBatPath; config.dis6xPath = ccsConfig.dis6xPath; config.ofd6xPath = ccsConfig.ofd6xPath; - config.runtimeRoot = config.runtimeRoot || resolveRuntimeRootFromBuiltinBasic(); // 处理反汇编配置 config.disasm = config.disasm || {}; @@ -140,14 +94,26 @@ export class DSSDebugProvider implements vscode.DebugConfigurationProvider { } /** - * 解析 CCS 环境配置 - * 所有路径从 .basic 目录解析,不依赖 CCS 安装。 + * 解析 DSS 环境配置 */ async resolveCCSEnvironment(userConfig: Partial): Promise { - const tools = this.resolveToolPaths('', userConfig); + // 1. 检测 DSS 安装路径 + const dssPath = userConfig.dssPath || await this.detectDSSInstallation(); + + if (!dssPath) { + throw new Error('无法检测到 DSS调试器 安装路径'); + } + + // 2. 解析工具路径(.basic 目录) + const basicRoot = await this.detectBasicRoot(); + if (!basicRoot) { + throw new Error('无法检测到 .basic 目录'); + } + const tools = this.resolveToolPaths(dssPath, basicRoot, userConfig); return { - ccsPath: '', + dssPath: dssPath, + toolsRoot: basicRoot, dssBatPath: userConfig.dssBatPath || tools.dssBatPath, dis6xPath: userConfig.dis6xPath || tools.dis6xPath, ofd6xPath: userConfig.ofd6xPath || tools.ofd6xPath, @@ -156,53 +122,68 @@ export class DSSDebugProvider implements vscode.DebugConfigurationProvider { } /** - * 自动检测 CCS 安装路径 + * 自动检测 .basic 目录 + * 通过 DspCoreApi 的 resolveBasicPath 获取 */ - async detectCCSInstallation(): Promise { - // 1. 检查 .basic 目录下的 bundled runtime(优先) - const basicRoot = getBuiltinBasicRoot(); - if (basicRoot) { - const dssDir = path.join(basicRoot, 'dss'); - if (fs.existsSync(dssDir)) { - return basicRoot; + async detectBasicRoot(): Promise { + try { + // 优先通过内部命令获取 + const internalApi = await vscode.commands.executeCommand('dsp.internal.getCoreApi'); + if (internalApi?.resolveBasicPath) { + return internalApi.resolveBasicPath(); } + } catch { + // 内部命令不存在,回退到扩展导出 } - // 2. 检查环境变量 - const envPath = process.env.CCS_PATH || process.env.CCS_INSTALL_DIR || process.env.CCS_ROOT; - if (envPath && fs.existsSync(envPath)) { - return envPath; - } - - // 3. Windows 注册表检测 - if (process.platform === 'win32') { - const regPaths = [ - 'HKLM\\SOFTWARE\\Texas Instruments\\Code Composer Studio', - 'HKLM\\SOFTWARE\\WOW6432Node\\Texas Instruments\\Code Composer Studio', - 'HKCU\\SOFTWARE\\Texas Instruments\\Code Composer Studio' - ]; - - for (const regPath of regPaths) { - try { - const result = execSync(`reg query "${regPath}" /v InstallLocation 2>nul`, { - encoding: 'utf8', - timeout: 5000 - }); - const match = result.match(/InstallLocation\s+REG_SZ\s+(.+)/i); - if (match && match[1]) { - const installPath = match[1].trim(); - if (fs.existsSync(installPath)) { - return installPath; - } - } - } catch { - // 忽略错误,继续尝试下一个路径 + try { + const ext = vscode.extensions.getExtension('yhftide.dsp-core'); + if (ext) { + if (!ext.isActive) { + await ext.activate(); + } + const api = ext.exports; + if (api?.resolveBasicPath) { + return api.resolveBasicPath(); } } + } catch { + // 扩展不可用 } - // 3. 常见安装路径回退 - const commonPaths = this.getCommonCCSPaths(); + return undefined; + } + + /** + * 查找 DSS 根目录 + * @returns DSS 根目录路径,如果未找到则返回 undefined + */ + private findDSSRoot(): string | undefined { + const extensionPath = path.resolve(__dirname, '..', '..'); + const candidates = [ + path.join(extensionPath, ), + path.join(extensionPath, '..'), + path.join(extensionPath, '..', '..'), + path.join(extensionPath, '..', '..', '..'), + ]; + + for (const candidate of candidates) { + // 打印到输出面板 + console.log(`[DSSDebugProvider] Checking for .basic directory at: ${candidate}`); + if (fs.existsSync(candidate) && fs.existsSync(path.join(candidate, 'dss'))) { + return candidate; + } + } + + return undefined; + } + + /** + * 自动检测 DSS调试器 安装路径 + */ + async detectDSSInstallation(): Promise { + + const commonPaths = await this.getCommonDSSPaths(); for (const p of commonPaths) { if (fs.existsSync(p)) { return p; @@ -213,42 +194,38 @@ export class DSSDebugProvider implements vscode.DebugConfigurationProvider { } /** - * 获取常见的 CCS 安装路径 + * 获取常见的 DSS调试器 安装路径 */ - private getCommonCCSPaths(): string[] { - const homeDir = os.homedir(); + private async getCommonDSSPaths(): Promise { const platform = process.platform; if (platform === 'win32') { - return [ - 'C:\\ti\\ccsv7', - path.join(homeDir, 'ti', 'ccsv7') - ]; - } else if (platform === 'linux') { - return [ - '/opt/ti/ccsv7', - path.join(homeDir, 'ti', 'ccsv7') - ]; + const paths: string[] = []; + if (paths.length === 0) { + const fallbackRoot = this.findDSSRoot(); + if (fallbackRoot) { + paths.push(fallbackRoot); + } + } + + return paths; } return []; } /** - * 解析 CCS 工具路径 + * 解析工具路径 + * @param dssRoot DSS 根目录(setdssenv.bat 所在位置) + * @param toolsRoot Tools 根目录(.basic,编译器所在位置) */ resolveToolPaths( - ccsPath: string, + dssRoot: string, + toolsRoot: string, userConfig?: Partial ): { dssBatPath: string; dis6xPath: string; ofd6xPath: string; compilerVersion?: string } { - // 先尝试从内置 .basic 目录解析工具链与运行时 - const basicRoot = getBuiltinBasicRoot(); - const builtinDssBatPath = basicRoot ? path.join(basicRoot, 'ccs_base', 'setdssenv.bat') : undefined; - const builtinDis6xPath = resolveBuiltinToolchainPath('dis6x.exe'); - const builtinOfd6xPath = resolveBuiltinToolchainPath('ofd6x.exe'); - - // 查找编译器版本目录 - const compilerDir = path.join(ccsPath, 'tools', 'compiler'); + // 查找编译器版本目录(在 toolsRoot 下) + let compilerDir = toolsRoot; let compilerVersion: string | undefined; if (fs.existsSync(compilerDir)) { @@ -262,21 +239,14 @@ export class DSSDebugProvider implements vscode.DebugConfigurationProvider { } } - // 构建 DSS 路径 - const dssBatPath = userConfig?.dssBatPath || builtinDssBatPath || ''; + // 构建 DSS 路径(在 dssRoot 下) + const dssBatPath = userConfig?.dssBatPath || + path.join(dssRoot, 'dss', 'setdssenv.bat'); // 构建工具路径 let dis6xPath = userConfig?.dis6xPath || ''; let ofd6xPath = userConfig?.ofd6xPath || ''; - if (!dis6xPath) { - dis6xPath = builtinDis6xPath || ''; - } - - if (!ofd6xPath) { - ofd6xPath = builtinOfd6xPath || ''; - } - if (compilerVersion && !dis6xPath) { dis6xPath = path.join(compilerDir, compilerVersion, 'bin', 'dis6x.exe'); if (!fs.existsSync(dis6xPath)) { @@ -308,13 +278,13 @@ export class DSSDebugProvider implements vscode.DebugConfigurationProvider { try { const settings = vscode.workspace.getConfiguration('dsp.debug.dss'); const ccsConfig = await this.resolveCCSEnvironment({ - ccsPath: settings.get('ccsPath'), + dssPath: settings.get('dssPath'), dssBatPath: settings.get('dssBatPath'), dis6xPath: settings.get('dis6xPath'), ofd6xPath: settings.get('ofd6xPath') }); - messages.push(`✓ CCS 路径: ${ccsConfig.ccsPath}`); + messages.push(`✓ CCS 路径: ${ccsConfig.dssPath}`); if (fs.existsSync(ccsConfig.dssBatPath)) { messages.push(`✓ DSS 路径: ${ccsConfig.dssBatPath}`); @@ -393,7 +363,7 @@ export class DSSDebugProvider implements vscode.DebugConfigurationProvider { if (builtinLibrarySources && fs.existsSync(builtinLibrarySources)) { // 内置库源码目录结构: builtinLibrarySources//... rules.push({ - compilePath: ccsConfig.ccsPath + '\\tools\\compiler', + compilePath: ccsConfig.toolsRoot + '\\tools\\compiler', localPath: builtinLibrarySources, enabled: true }); @@ -404,17 +374,13 @@ export class DSSDebugProvider implements vscode.DebugConfigurationProvider { // 这样可以识别系统库源码(如 RTS 库) if (ccsConfig.compilerVersion) { const compilerPath = path.join( - ccsConfig.ccsPath, - 'tools', - 'compiler', + ccsConfig.toolsRoot, ccsConfig.compilerVersion ); // 检查是否有对应的内置源码 const builtinSourcePath = path.join( - ccsConfig.ccsPath, - 'tools', - 'compiler', + ccsConfig.toolsRoot, ccsConfig.compilerVersion, 'lib', 'src' @@ -427,6 +393,19 @@ export class DSSDebugProvider implements vscode.DebugConfigurationProvider { enabled: true }); } + + // 添加编译器内部构建路径的后缀匹配规则 + // 编译器源码路径可能是 /tmp/scratch/build_jenkins/.../lib-internal/src/boot.c + // 随编译器版本变化,但 lib-internal/src 后缀稳定 + const libInternalSrc = path.join(ccsConfig.toolsRoot, ccsConfig.compilerVersion, 'lib', 'src'); + if (fs.existsSync(libInternalSrc)) { + rules.push({ + compilePath: 'lib-internal/src', + localPath: libInternalSrc, + enabled: true, + suffixMatch: true + }); + } } return rules;