From 2c5c1e11d81e0d7fa09427e6082e55649a564732 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E6=96=87=E5=B3=B0?= Date: Mon, 8 Jun 2026 20:06:57 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=BC=96=E8=AF=91=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- package-lock.json | 4 +-- package.json | 2 +- src/compiler.ts | 81 ++++++++++++++++++++++++++++++++++------------- 4 files changed, 63 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 6fe3128..d4377e9 100644 --- a/README.md +++ b/README.md @@ -181,7 +181,7 @@ VS Code C/C++ IntelliSense 可能无法识别这些寄存器。插件会自动 工程目录\build\ ``` -为了兼容官方工具链,插件会先让 `c.exe` 按官方风格输出到工程根目录的小写文件名前缀,例如 `ft61e132a.hex`,编译成功后再复制为配置输出目录中的工程名文件,例如 `build\FT61E132A.hex`。 +为了兼容官方工具链,插件会先让 `c.exe` 按官方风格输出到工程根目录的小写文件名前缀,例如 `ft61e132a.hex`,编译成功后再把所有编译生成/更新的产物移动到配置输出目录,例如 `build\FT61E132A.hex`、`build\FT61E132A.map`、`build\FT61E132A.lst`、`build\button.p1` 等。 也可以设置为绝对路径,例如: diff --git a/package-lock.json b/package-lock.json index 2c5a9bb..85f99fa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "fmd-c-compiler", - "version": "0.2.13", + "version": "0.2.15", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "fmd-c-compiler", - "version": "0.2.13", + "version": "0.2.15", "devDependencies": { "@types/node": "^20.0.0", "@types/vscode": "^1.85.0", diff --git a/package.json b/package.json index 9507b45..3743036 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "publisher": "kevinngmanfong", "displayName": "FMD C Compiler", "description": "FMD/FT61FC6X 系列 MCU 编译器支持(C.exe 工具链)", - "version": "0.2.13", + "version": "0.2.15", "license": "MIT", "icon": "resources/icon.png", "engines": { diff --git a/src/compiler.ts b/src/compiler.ts index aae9e29..4912aad 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -136,9 +136,8 @@ export class FmdCompiler { this.outputChannel.appendLine(''); this.outputChannel.appendLine('========== 编译成功 =========='); - this.copyCompilerArtifacts(compilerArtifacts, artifacts); - this.logArtifact(artifacts.hexFile); - this.logArtifact(artifacts.binFile); + this.moveCompilerArtifacts(projectDir, compilerArtifacts, artifacts); + this.logBuildArtifacts(artifacts.outputDir); vscode.window.showInformationMessage('FMD: 编译成功 ✓'); return { success: true, exitCode, artifacts }; @@ -222,20 +221,27 @@ export class FmdCompiler { return; } - const cleanExts = ['.obj', '.p1', '.pre', '.d', '.lpp', '.cmf', '.sym', '.map', '.rlf', '.sdb', '.asm']; + const cleanExts = ['.as', '.asm', '.bin', '.cmf', '.cof', '.d', '.hex', '.hxl', '.lpp', '.lst', '.map', '.obj', '.p1', '.pre', '.rlf', '.sdb', '.sym']; let count = 0; try { - const files = fs.readdirSync(projectDir); - for (const f of files) { - const ext = path.extname(f).toLowerCase(); - if (cleanExts.includes(ext)) { - fs.unlinkSync(path.join(projectDir, f)); - count++; + const cfg = getConfig(); + const outputDir = this.resolveOutputDir(projectDir, cfg.outputDir); + for (const dir of Array.from(new Set([projectDir, outputDir]))) { + if (!fs.existsSync(dir)) { + continue; + } + const files = fs.readdirSync(dir); + for (const f of files) { + const ext = path.extname(f).toLowerCase(); + if (cleanExts.includes(ext)) { + fs.unlinkSync(path.join(dir, f)); + count++; + } } } - this.outputChannel.appendLine(`[FMD] 清理完成,删除 ${count} 个中间文件`); - vscode.window.showInformationMessage(`FMD: 清理完成,删除 ${count} 个中间文件`); + this.outputChannel.appendLine(`[FMD] 清理完成,删除 ${count} 个编译产物`); + vscode.window.showInformationMessage(`FMD: 清理完成,删除 ${count} 个编译产物`); } catch (err) { vscode.window.showErrorMessage(`FMD 清理失败: ${err}`); } @@ -271,22 +277,44 @@ export class FmdCompiler { return path.isAbsolute(outputDir) ? outputDir : path.join(projectDir, outputDir); } - private copyCompilerArtifacts(from: FmdOutputArtifacts, to: FmdOutputArtifacts): void { + private moveCompilerArtifacts(projectDir: string, from: FmdOutputArtifacts, to: FmdOutputArtifacts): void { fs.mkdirSync(to.outputDir, { recursive: true }); - const pairs = [ - [from.hexFile, to.hexFile], - [from.binFile, to.binFile], - ]; + const artifactExts = new Set([ + '.as', '.asm', '.bin', '.cmf', '.cof', '.d', '.hex', '.hxl', '.lpp', + '.lst', '.map', '.obj', '.p1', '.pre', '.rlf', '.sdb', '.sym', + ]); - for (const [source, target] of pairs) { - if (source === target || !fs.existsSync(source)) { + for (const file of fs.readdirSync(projectDir)) { + const source = path.join(projectDir, file); + if (!fs.statSync(source).isFile()) { continue; } + + const ext = path.extname(file).toLowerCase(); + if (!artifactExts.has(ext)) { + continue; + } + + const targetName = this.getOutputArtifactName(file, from.projectName, to.projectName); + const target = path.join(to.outputDir, targetName); + if (source === target) { + continue; + } + fs.copyFileSync(source, target); - this.outputChannel.appendLine(`复制输出: ${source} -> ${target}`); + fs.unlinkSync(source); + this.outputChannel.appendLine(`移动输出: ${source} -> ${target}`); } } + private getOutputArtifactName(fileName: string, compilerProjectName: string, outputProjectName: string): string { + const base = path.basename(fileName, path.extname(fileName)); + const ext = path.extname(fileName); + return base.toLowerCase() === compilerProjectName.toLowerCase() + ? outputProjectName + ext.toLowerCase() + : fileName; + } + private resolveCompilerChip(projectDir: string, projectName: string, projectChip: string, compilerPath: string): string { const historicalChip = this.readMachineTypeFromMap(projectDir, projectName); if (historicalChip && this.checkCompilerChipSupport(compilerPath, historicalChip).supported) { @@ -515,8 +543,17 @@ export class FmdCompiler { })); } - private logArtifact(filePath: string): void { - if (fs.existsSync(filePath)) { + private logBuildArtifacts(outputDir: string): void { + if (!fs.existsSync(outputDir)) { + return; + } + + this.outputChannel.appendLine(`输出目录: ${outputDir}`); + for (const file of fs.readdirSync(outputDir)) { + const filePath = path.join(outputDir, file); + if (!fs.statSync(filePath).isFile()) { + continue; + } const stat = fs.statSync(filePath); this.outputChannel.appendLine(`输出: ${filePath} (${stat.size} 字节)`); }