Skip to content

Commit b8699d3

Browse files
authored
Merge pull request #261 from github0null/dev
v3.13.2023060401 revision
2 parents fd46f18 + 56ef42d commit b8699d3

File tree

9 files changed

+219
-120
lines changed

9 files changed

+219
-120
lines changed

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,26 @@ All notable version changes will be recorded in this file.
66

77
***
88

9+
### [v3.13.2023060401] revision
10+
11+
**Fix**:
12+
- `Incorrect GCC Options`: Move gcc '--specs=xxx' options to 'global' region. [issue](https://github.com/github0null/eide/issues/259)
13+
14+
**Optimize**:
15+
- `Source Exclude List`: Allow use Env Variables in exclude path string.
16+
- `Eclipse Project Importer`: Optimize eclipse project parser, allow resolve virtual folder and folder link.
17+
- `Armcc Options`: Remove duplicate option 'optimize-for-time' for AC5
18+
19+
***
20+
21+
### [v3.13.2023060101] revision
22+
23+
**Optimize**:
24+
- `Source Exclude List`: Allow use Env Variables in exclude path string.
25+
- `Eclipse Project Importer`: Optimize eclipse project parser, allow resolve virtual folder and folder link.
26+
27+
***
28+
929
### [v3.13.0] update
1030

1131
**New**:

lang/arm.v5.verify.json

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -170,15 +170,6 @@
170170
"-Otime (for code time)"
171171
]
172172
},
173-
"optimize-for-time": {
174-
"markdownDescription": "Optimize for time",
175-
"description.zh-cn": "Optimize for time",
176-
"type": "boolean",
177-
"enum": [
178-
true,
179-
false
180-
]
181-
},
182173
"one-elf-section-per-function": {
183174
"markdownDescription": "One ELF Section per Function",
184175
"type": "boolean",

lang/arm.v6.verify.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@
200200
]
201201
},
202202
"link-time-optimization": {
203-
"markdownDescription": "Link Time Optimization",
203+
"markdownDescription": "Link Time Optimization (LTO)",
204204
"type": "boolean"
205205
},
206206
"one-elf-section-per-function": {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
"homepage": "https://em-ide.com",
3939
"license": "MIT",
4040
"description": "A mcu development environment for 8051/AVR/STM8/Cortex-M/MIPS/RISC-V",
41-
"version": "3.13.0",
41+
"version": "3.13.2023060401",
4242
"preview": false,
4343
"engines": {
4444
"vscode": "^1.67.0"

res/data/models/unix/arm.v5.model.json

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -182,13 +182,6 @@
182182
"level-speed": "-Otime"
183183
}
184184
},
185-
"optimize-for-time": {
186-
"type": "selectable",
187-
"command": {
188-
"true": "-Otime",
189-
"false": ""
190-
}
191-
},
192185
"one-elf-section-per-function": {
193186
"type": "selectable",
194187
"command": {
@@ -283,13 +276,6 @@
283276
"level-speed": "-Otime"
284277
}
285278
},
286-
"optimize-for-time": {
287-
"type": "selectable",
288-
"command": {
289-
"true": "-Otime",
290-
"false": ""
291-
}
292-
},
293279
"one-elf-section-per-function": {
294280
"type": "selectable",
295281
"command": {

res/data/models/win32/arm.v5.model.json

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -182,13 +182,6 @@
182182
"level-speed": "-Otime"
183183
}
184184
},
185-
"optimize-for-time": {
186-
"type": "selectable",
187-
"command": {
188-
"true": "-Otime",
189-
"false": ""
190-
}
191-
},
192185
"one-elf-section-per-function": {
193186
"type": "selectable",
194187
"command": {
@@ -283,13 +276,6 @@
283276
"level-speed": "-Otime"
284277
}
285278
},
286-
"optimize-for-time": {
287-
"type": "selectable",
288-
"command": {
289-
"true": "-Otime",
290-
"false": ""
291-
}
292-
},
293279
"one-elf-section-per-function": {
294280
"type": "selectable",
295281
"command": {

src/EIDEProject.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1542,7 +1542,7 @@ export abstract class AbstractProject implements CustomConfigurationProvider, Pr
15421542
//--
15431543

15441544
isExcluded(path: string): boolean {
1545-
const excList = this.GetConfiguration().config.excludeList;
1545+
const excList = this.GetConfiguration().config.excludeList.map((excpath) => this.resolveEnvVar(excpath));
15461546
const rePath = this.toRelativePath(path);
15471547
return excList.findIndex(excluded => rePath === excluded || rePath.startsWith(`${excluded}/`)) !== -1;
15481548
}

src/EclipseProjectParser.ts

Lines changed: 143 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ import * as NodePath from 'path';
33
import * as os from 'os';
44
import * as xml2js from 'xml2js';
55
import { VirtualFolder } from './EIDETypeDefine';
6-
import { VirtualSource } from './EIDEProject';
6+
import { VirtualSource, AbstractProject } from './EIDEProject';
77
import { isArray } from 'util';
88
import { ArrayDelRepetition } from '../lib/node-utility/Utility';
9+
import { File } from '../lib/node-utility/File';
910

1011
export type EclipseProjectType = 'arm' | 'sdcc' | 'riscv' | 'gcc';
1112

@@ -104,6 +105,10 @@ export async function parseEclipseProject(cprojectPath: string): Promise<Eclipse
104105
let cprjDom = (await xml2js.parseStringPromise(
105106
fs.readFileSync(cprojectPath).toString()))['cproject'];
106107

108+
const cprojectDir = new File(NodePath.dirname(cprojectPath));
109+
110+
const SRC_FILE_FILTER = AbstractProject.getSourceFileFilterWithoutObj().concat(AbstractProject.headerFilter);
111+
107112
const PROJ_INFO: EclipseProjectInfo = {
108113
name: _prjDom.name[0].replace(/\s+/g, '_'),
109114
type: 'gcc',
@@ -122,6 +127,10 @@ export async function parseEclipseProject(cprojectPath: string): Promise<Eclipse
122127
if (!node) throw new Error(`not found: '<storageModule moduleId="org.eclipse.cdt.core.settings">'`);
123128
cprjDom = node;
124129

130+
const root_virtualsrcs: string[] = [];
131+
const root_srcdirs: string[] = [];
132+
const eclipseTargetList: string[] = [];
133+
125134
// parse all project targets
126135
for (const ccfg of toArray(cprjDom['cconfiguration'])) {
127136

@@ -147,6 +156,8 @@ export async function parseEclipseProject(cprojectPath: string): Promise<Eclipse
147156

148157
cTarget = cTarget['configuration'][0];
149158

159+
eclipseTargetList.push(cTarget.$['name']);
160+
150161
const tInfo: EclipseProjectTarget = {
151162
name: cTarget.$['name'].replace(/\s+/g, '_'),
152163
excList: [],
@@ -252,11 +263,24 @@ export async function parseEclipseProject(cprojectPath: string): Promise<Eclipse
252263
}
253264

254265
if (cTarget.sourceEntries) {
266+
255267
toArray(cTarget.sourceEntries[0].entry).forEach(e => {
256268

257269
//<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="src" />
258270
if (<string>e.$['kind'] == 'sourcePath') {
259-
PROJ_INFO.sourceEntries.push(formatFilePath(e.$['name']));
271+
const srcdir = formatFilePath(e.$['name']);
272+
if (srcdir == '.' || srcdir == '') {
273+
const srcs = cprojectDir.GetList(SRC_FILE_FILTER, [/^[^\.].+/]);
274+
srcs.forEach(src => {
275+
if (src.IsFile()) {
276+
root_virtualsrcs.push(src.name);
277+
} else {
278+
root_srcdirs.push(src.name);
279+
}
280+
});
281+
} else {
282+
root_srcdirs.push(srcdir);
283+
}
260284
}
261285

262286
(<string>e.$['excluding'] || '')
@@ -268,10 +292,24 @@ export async function parseEclipseProject(cprojectPath: string): Promise<Eclipse
268292
}
269293
}
270294

295+
// setup root sources
296+
ArrayDelRepetition(root_virtualsrcs).forEach(srcpath => {
297+
PROJ_INFO.virtualSource.files.push({ path: srcpath });
298+
});
299+
ArrayDelRepetition(root_srcdirs).forEach(srcdir => {
300+
if (eclipseTargetList.includes(srcdir)) return; // skip eclipse build dir
301+
PROJ_INFO.sourceEntries.push(srcdir);
302+
});
303+
271304
const getVirtualFolder = (rePath: string) => {
272305

273-
rePath = rePath.trim().replace(/^\//, '').replace(/^\.\/?/, '');
274-
if (rePath == '') return PROJ_INFO.virtualSource;
306+
rePath = rePath.trim()
307+
.replace(/^\//, '')
308+
.replace(/\/+$/, '')
309+
.replace(/^\.\/?/, '');
310+
311+
if (rePath == '' || rePath == '.')
312+
return PROJ_INFO.virtualSource;
275313

276314
let curFolder = PROJ_INFO.virtualSource;
277315
let pathList = rePath.split(/\\|\//).reverse();
@@ -296,23 +334,76 @@ export async function parseEclipseProject(cprojectPath: string): Promise<Eclipse
296334
return curFolder;
297335
};
298336

337+
const virtualRootList: string[] = [];
338+
const virtualRootMap: { [vpath: string]: string } = {};
339+
299340
// parse external source
300341
if (_prjDom.linkedResources) {
301342
toArray(_prjDom.linkedResources[0].link).forEach(link => {
302-
if (link.type[0] != '1') return; // skip folder
303-
const vPath = link.name[0].trim();
304-
if (vPath == '') return;
305-
const vFolder = getVirtualFolder(NodePath.dirname(vPath));
306-
const locations = link.locationURI || link.location;
307-
if (!Array.isArray(locations)) return;
308-
vFolder.files.push({ path: formatFilePath(locations[0]) });
343+
if (link.type[0] == '1') { // virtual file
344+
const vPath = link.name[0].trim();
345+
if (vPath == '') return;
346+
const vFolder = getVirtualFolder(NodePath.dirname(vPath));
347+
const locations = link.locationURI || link.location;
348+
if (!Array.isArray(locations)) return;
349+
vFolder.files.push({ path: formatFilePath(locations[0]) });
350+
} else if (link.type[0] == '2') { // virtual folder
351+
const vpath = link.name[0].trim();
352+
const locations: string = link.locationURI || link.location;
353+
if (!Array.isArray(locations)) return;
354+
const location: string = locations[0];
355+
if (typeof location != 'string') return;
356+
virtualRootList.push(vpath);
357+
const rootdirpath_ = formatFilePath(location);
358+
let rootdirfullpath = rootdirpath_;
359+
if (!File.isAbsolute(rootdirpath_)) rootdirfullpath = `${cprojectDir.path}/${rootdirpath_}`;
360+
let vFolder = getVirtualFolder(vpath); // add this folder
361+
if (File.IsDir(rootdirfullpath)) {
362+
virtualRootMap[vpath] = File.ToUnixPath(rootdirpath_);
363+
const files = new File(rootdirfullpath).GetAll(SRC_FILE_FILTER, File.EXCLUDE_ALL_FILTER);
364+
const srcRootDir = new File(rootdirfullpath);
365+
files.forEach(f => {
366+
let subvpath = vpath;
367+
const dirname = srcRootDir.ToRelativePath(f.dir);
368+
if (dirname && dirname != '.') subvpath += '/' + dirname;
369+
vFolder = getVirtualFolder(subvpath);
370+
vFolder.files.push({ path: cprojectDir.ToRelativePath(f.path) || f.path });
371+
});
372+
}
373+
}
309374
});
310375
}
311376

377+
const completeVirtualPaths = (pathlist: string[]): string[] => {
378+
return pathlist.map(p => {
379+
if (virtualRootList.includes(p) || virtualRootList.some(e => p.startsWith(e + '/'))) {
380+
return `${VirtualSource.rootName}/${p}`;
381+
} else {
382+
return p;
383+
}
384+
});
385+
};
386+
387+
const resolveVirtualPaths = (pathlist: string[]): string[] => {
388+
return pathlist.map(p => {
389+
for (const rootpath of virtualRootList) {
390+
if ((rootpath == p || p.startsWith(rootpath + '/')) && virtualRootMap[rootpath]) {
391+
return p.replace(rootpath, virtualRootMap[rootpath]);
392+
}
393+
}
394+
return p;
395+
});
396+
};
397+
312398
// del repeat args for every targets
313399
for (const target of PROJ_INFO.targets) {
314400

315-
target.excList = ArrayDelRepetition(target.excList);
401+
// add prefix for virtual exclude paths
402+
target.excList = completeVirtualPaths(ArrayDelRepetition(target.excList));
403+
404+
// resolve virtual include paths
405+
target.globalArgs.cIncDirs = resolveVirtualPaths(target.globalArgs.cIncDirs);
406+
target.globalArgs.sIncDirs = resolveVirtualPaths(target.globalArgs.sIncDirs);
316407

317408
for (const key in target.globalArgs) {
318409
const obj: any = target.globalArgs;
@@ -336,9 +427,6 @@ export async function parseEclipseProject(cprojectPath: string): Promise<Eclipse
336427

337428
function parseToolOption(optionObj: any): { type: string, val: string[] } | undefined {
338429

339-
if (optionObj.$['valueType'] == undefined)
340-
return;
341-
342430
if (optionObj.$['id']) {
343431
// skip output args
344432
if (['.converthex', '.convertbin', '.convert']
@@ -351,13 +439,13 @@ function parseToolOption(optionObj: any): { type: string, val: string[] } | unde
351439

352440
const VALUE_NAME: string = optionObj.$['name'] || '';
353441
const VALUE_VAL: string = optionObj.$['value'] || '';
354-
const VALUE_TYPE: string = optionObj.$['valueType'];
442+
const VALUE_TYPE: string | undefined = optionObj.$['valueType'];
355443

356-
let makeResult = (value: string | string[]): { type: string, val: string[] } | undefined => {
444+
let makeResult = (value: string | string[], typ?: string): { type: string, val: string[] } | undefined => {
357445
if (value == '') return undefined;
358446
if (isArray(value) && value.length == 0) return undefined;
359447
return {
360-
type: VALUE_TYPE,
448+
type: typ || VALUE_TYPE || '',
361449
val: isArray(value) ? value : [value]
362450
};
363451
};
@@ -371,6 +459,43 @@ function parseToolOption(optionObj: any): { type: string, val: string[] } | unde
371459
return fmt + arg;
372460
}
373461

462+
//
463+
// match by name
464+
//
465+
466+
// <Language Standard> = option.std.gnu99
467+
if (/Language Standard/i.test(VALUE_NAME)) {
468+
const m = /std\.(\w+)/.exec(VALUE_VAL);
469+
if (m && m.length > 1) {
470+
const langStd = m[1];
471+
return makeResult(`-std=${langStd}`, 'string');
472+
}
473+
}
474+
475+
if (VALUE_NAME.includes('(-D)')) {
476+
const li: string[] = [];
477+
toArray(optionObj.listOptionValue).forEach(item => li.push(item.$['value']));
478+
return makeResult(li, 'definedSymbols');
479+
}
480+
481+
if (VALUE_NAME.includes('(-I)')) {
482+
const li: string[] = [];
483+
toArray(optionObj.listOptionValue).forEach(item => {
484+
let p = formatFilePath(item.$['value']);
485+
if (p == '..') p = '.';
486+
if (p.startsWith('../')) p = p.substr(3); // for eclipse, include path is base 'Debug' folder
487+
li.push(p);
488+
});
489+
return makeResult(li, 'includePath');
490+
}
491+
492+
//
493+
// match by type
494+
//
495+
496+
if (VALUE_TYPE == undefined)
497+
return;
498+
374499
if (VALUE_TYPE == 'boolean') {
375500
if (VALUE_VAL == 'true') {
376501
const mRes = /\((\-.+)\)/.exec(VALUE_NAME);

0 commit comments

Comments
 (0)