Skip to content

Commit db001db

Browse files
authored
Merge pull request #511 from kanami09/fix/keil-export
改进“导出为 Keil 项目“功能
2 parents 972ed86 + 354dd40 commit db001db

File tree

5 files changed

+54
-29
lines changed

5 files changed

+54
-29
lines changed

eide.code-workspace

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@
66
],
77
"settings": {
88
"search.useIgnoreFiles": false,
9-
"typescript.tsdk": "node_modules\\typescript\\lib"
9+
"js/ts.tsdk.path": "node_modules/typescript/lib"
1010
}
11-
}
11+
}

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/EIDEProject.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3414,7 +3414,7 @@ $(OUT_DIR):
34143414

34153415
protected abstract create(option: CreateOptions): File;
34163416

3417-
abstract ExportToKeilProject(): File | undefined;
3417+
abstract ExportToKeilProject(saveFile?: File): File | undefined;
34183418

34193419
static NewProject(workspaceState: vscode.Memento): AbstractProject {
34203420
return new EIDEProject(workspaceState);
@@ -3813,7 +3813,7 @@ class EIDEProject extends AbstractProject {
38133813
return baseInfo.workspaceFile;
38143814
}
38153815

3816-
ExportToKeilProject(): File | undefined {
3816+
ExportToKeilProject(saveFile?: File): File | undefined {
38173817

38183818
let keilFile: File;
38193819

@@ -3826,8 +3826,8 @@ class EIDEProject extends AbstractProject {
38263826
const keilSuffix = prjConfig.type === 'C51' ? 'uvproj' : 'uvprojx';
38273827
const suffixFilter = [new RegExp('\\.' + keilSuffix + '$', 'i')];
38283828

3829-
// local keil file
3830-
const localKeilFile = File.fromArray([this.GetRootDir().path, `${prjConfig.name}.${keilSuffix}`]);
3829+
// use user-specified save path, or fall back to project root
3830+
const localKeilFile = saveFile ?? File.fromArray([this.GetRootDir().path, `${prjConfig.name}.${keilSuffix}`]);
38313831

38323832
// get from project root folder
38333833
if (localKeilFile.IsFile()) {
@@ -3860,7 +3860,7 @@ class EIDEProject extends AbstractProject {
38603860
halFiles = halFiles.concat(group.files);
38613861
} else {
38623862
fileGroups.push(<FileGroup>{
3863-
name: File.ToUnixPath(<string>rePath).toUpperCase(),
3863+
name: File.ToUnixPath(<string>rePath),
38643864
files: group.files,
38653865
disabled: group.disabled
38663866
});
@@ -3892,10 +3892,13 @@ class EIDEProject extends AbstractProject {
38923892
// rm empty file groups for MDK
38933893
fileGroups = fileGroups.filter(g => g.files.length > 0);
38943894

3895+
const outDir = saveFile ? new File(NodePath.dirname(saveFile.path)) : this.GetRootDir();
3896+
const outName = saveFile ? saveFile.noSuffixName : localKeilFile.noSuffixName;
3897+
38953898
// set keil xml
3896-
keilParser.SetKeilXml(this, fileGroups, cDevice);
3899+
keilParser.SetKeilXml(this, fileGroups, outDir, cDevice);
38973900

3898-
return keilParser.Save(this.GetRootDir(), localKeilFile.noSuffixName);
3901+
return keilParser.Save(outDir, outName);
38993902
}
39003903

39013904
//////////////////////////////// overrride ///////////////////////////////////

src/EIDEProjectExplorer.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4203,7 +4203,7 @@ export class ProjectExplorer implements CustomConfigurationProvider {
42034203
}
42044204
}
42054205

4206-
ExportKeilXml(prjItem: ProjTreeItem) {
4206+
async ExportKeilXml(prjItem: ProjTreeItem) {
42074207
try {
42084208
const prj = this.getProjectByTreeItem(prjItem);
42094209
if (!prj)
@@ -4221,7 +4221,26 @@ export class ProjectExplorer implements CustomConfigurationProvider {
42214221
return;
42224222
}
42234223

4224-
const xmlFile = prj.ExportToKeilProject();
4224+
const prjConfig = prj.GetConfiguration().config;
4225+
const keilSuffix = prjConfig.type === 'C51' ? 'uvproj' : 'uvprojx';
4226+
const defaultUri = vscode.Uri.file(NodePath.join(prj.GetRootDir().path, `${prjConfig.name}.${keilSuffix}`));
4227+
4228+
const uri = await vscode.window.showSaveDialog({
4229+
defaultUri: defaultUri,
4230+
filters: { 'Keil Project': [keilSuffix] }
4231+
});
4232+
if (!uri) return;
4233+
4234+
// warn if the chosen save path is on a different drive from the project root;
4235+
// in that case, cross-drive paths cannot be made relative and will be written as absolute paths
4236+
const saveDrive = NodePath.parse(uri.fsPath).root.toLowerCase();
4237+
const prjDrive = NodePath.parse(prj.GetRootDir().path).root.toLowerCase();
4238+
if (saveDrive !== prjDrive) {
4239+
GlobalEvent.emit('msg', newMessage('Warning',
4240+
`导出路径 (${saveDrive}) 与项目根目录 (${prjDrive}) 不在同一驱动器,此行为可能导致移动或复制项目后 Keil 无法正确识别文件。`));
4241+
}
4242+
4243+
const xmlFile = prj.ExportToKeilProject(new File(uri.fsPath));
42254244

42264245
if (xmlFile) {
42274246
GlobalEvent.emit('msg', newMessage('Info', export_keil_xml_ok + prj.toRelativePath(xmlFile.path)));

src/KeilXmlParser.ts

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ export abstract class KeilParser<T> {
306306

307307
abstract ParseData(): KeilParserResult<T>[];
308308

309-
abstract SetKeilXml(prj: AbstractProject, fileGroups: FileGroup[], deviceInfo?: CurrentDevice): void;
309+
abstract SetKeilXml(prj: AbstractProject, fileGroups: FileGroup[], keilOutputDir: File, deviceInfo?: CurrentDevice): void;
310310
}
311311

312312
//----
@@ -504,7 +504,7 @@ class C51Parser extends KeilParser<KeilC51Option> {
504504
}
505505
}
506506

507-
SetKeilXml(prj: AbstractProject, fileGroups: FileGroup[], deviceInfo?: CurrentDevice): void {
507+
SetKeilXml(prj: AbstractProject, fileGroups: FileGroup[], keilOutputDir: File, deviceInfo?: CurrentDevice): void {
508508

509509
const prjConfig: ProjectConfiguration<any> = prj.GetConfiguration();
510510
const target = this.doc.Project.Targets.Target[0];
@@ -534,14 +534,15 @@ class C51Parser extends KeilParser<KeilC51Option> {
534534
target.TargetOption.TargetCommonOption.Device = devName;
535535
target.TargetOption.TargetCommonOption.Vendor = vendor;
536536

537-
const outFolder = File.normalize(prjConfig.config.outDir);
538-
target.TargetOption.TargetCommonOption.OutputDirectory = `.\\${outFolder}\\Keil\\`;
539-
target.TargetOption.TargetCommonOption.ListingPath = `.\\${outFolder}\\Keil\\`;
537+
const outFolderAbs = prj.ToAbsolutePath(prjConfig.config.outDir);
538+
const outFolder = File.ToLocalPath(keilOutputDir.ToRelativePath(outFolderAbs) || outFolderAbs);
539+
target.TargetOption.TargetCommonOption.OutputDirectory = `${outFolder}\\Keil\\`;
540+
target.TargetOption.TargetCommonOption.ListingPath = `${outFolder}\\Keil\\`;
540541
target.TargetOption.TargetCommonOption.OutputName = target.TargetName;
541542

542543
target.TargetOption.Target51.C51.VariousControls.IncludePath = mergedDep.incList
543544
.map(s => prj.resolveEnvVar(s))
544-
.map(inc => File.ToLocalPath(prj.toRelativePath(inc)))
545+
.map(inc => { const abs = File.isAbsolute(inc) ? inc : prj.ToAbsolutePath(inc); return File.ToLocalPath(keilOutputDir.ToRelativePath(abs) || abs); })
545546
.join(';');
546547

547548
target.TargetOption.Target51.C51.VariousControls.Define = mergedDep.defineList.join(",");
@@ -563,7 +564,7 @@ class C51Parser extends KeilParser<KeilC51Option> {
563564
const fileElement = {
564565
FileName: _f.file.name,
565566
FileType: this.getFileType(_f.file).toString(),
566-
FilePath: prj.ToRelativePath(_f.file.path) || _f.file.path
567+
FilePath: File.ToLocalPath(keilOutputDir.ToRelativePath(_f.file.path) || _f.file.path)
567568
};
568569

569570
this.setFileDisableFlag(fileElement, _f.disabled);
@@ -1169,7 +1170,7 @@ class ARMParser extends KeilParser<KeilARMOption> {
11691170
return result;
11701171
}
11711172

1172-
private setOption(targetOptionObj: any, prj: AbstractProject) {
1173+
private setOption(targetOptionObj: any, prj: AbstractProject, keilOutputDir: File) {
11731174

11741175
const armAdsObj = targetOptionObj.TargetArmAds;
11751176
const prjConfig = <ProjectConfiguration<ArmBaseCompileData>>prj.GetConfiguration();
@@ -1213,7 +1214,7 @@ class ARMParser extends KeilParser<KeilARMOption> {
12131214
LDads.umfTarg = config.useCustomScatterFile ? '0' : '1';
12141215
if (config.scatterFilePath) {
12151216
const absPath = prj.ToAbsolutePath(config.scatterFilePath);
1216-
LDads.ScatterFile = this.ToRelativePath(absPath);
1217+
LDads.ScatterFile = File.ToLocalPath(keilOutputDir.ToRelativePath(absPath) || absPath);
12171218
} else {
12181219
LDads.ScatterFile = '';
12191220
}
@@ -1317,7 +1318,7 @@ class ARMParser extends KeilParser<KeilARMOption> {
13171318
}
13181319
}
13191320

1320-
SetKeilXml(prj: AbstractProject, fileGroups: FileGroup[], deviceInfo?: CurrentDevice): void {
1321+
SetKeilXml(prj: AbstractProject, fileGroups: FileGroup[], keilOutputDir: File, deviceInfo?: CurrentDevice): void {
13211322

13221323
const prjConfig: ProjectConfiguration<any> = prj.GetConfiguration();
13231324
const target = this.doc.Project.Targets.Target[0];
@@ -1366,17 +1367,19 @@ class ARMParser extends KeilParser<KeilARMOption> {
13661367
}
13671368

13681369
target.TargetName = prjConfig.config.name;
1370+
target.uAC6 = prj.getToolchain().name === 'AC6' ? '1' : '0';
13691371
target.TargetOption.TargetCommonOption.Device = devName;
13701372
target.TargetOption.TargetCommonOption.Vendor = vendor;
13711373

1372-
const outFolder = File.normalize(prjConfig.config.outDir);
1373-
target.TargetOption.TargetCommonOption.OutputDirectory = `.\\${outFolder}\\Keil\\`;
1374-
target.TargetOption.TargetCommonOption.ListingPath = `.\\${outFolder}\\Keil\\`;
1374+
const outFolderAbs = prj.ToAbsolutePath(prjConfig.config.outDir);
1375+
const outFolder = File.ToLocalPath(keilOutputDir.ToRelativePath(outFolderAbs) || outFolderAbs);
1376+
target.TargetOption.TargetCommonOption.OutputDirectory = `${outFolder}\\Keil\\`;
1377+
target.TargetOption.TargetCommonOption.ListingPath = `${outFolder}\\Keil\\`;
13751378
target.TargetOption.TargetCommonOption.OutputName = target.TargetName;
13761379

13771380
target.TargetOption.TargetArmAds.Cads.VariousControls.IncludePath = mergedDep.incList
13781381
.map(s => prj.resolveEnvVar(s))
1379-
.map(inc => File.ToLocalPath(prj.toRelativePath(inc)))
1382+
.map(inc => { const abs = File.isAbsolute(inc) ? inc : prj.ToAbsolutePath(inc); return File.ToLocalPath(keilOutputDir.ToRelativePath(abs) || abs); })
13801383
.join(';');
13811384

13821385
target.TargetOption.TargetArmAds.Cads.VariousControls.Define = mergedDep.defineList.join(","); // C/CPP
@@ -1387,7 +1390,7 @@ class ARMParser extends KeilParser<KeilARMOption> {
13871390
target.TargetOption.TargetArmAds.Aads.VariousControls.Define = defines.join(","); // ASM
13881391
}
13891392

1390-
this.setOption(target.TargetOption, prj);
1393+
this.setOption(target.TargetOption, prj, keilOutputDir);
13911394

13921395
const nGroups: any[] = [];
13931396

@@ -1404,7 +1407,7 @@ class ARMParser extends KeilParser<KeilARMOption> {
14041407
const fileElement = {
14051408
FileName: _f.file.name,
14061409
FileType: this.getFileType(_f.file).toString(),
1407-
FilePath: prj.ToRelativePath(_f.file.path) || _f.file.path
1410+
FilePath: File.ToLocalPath(keilOutputDir.ToRelativePath(_f.file.path) || _f.file.path)
14081411
};
14091412

14101413
this.setFileDisableFlag(fileElement, _f.disabled);

0 commit comments

Comments
 (0)