Skip to content

[feature]增加ap的vscode runner #69

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 79 additions & 49 deletions src/env/index.ts
Original file line number Diff line number Diff line change
@@ -1,48 +1,58 @@
import LISA from '@listenai/lisa_core';
import { Bundle, Flasher } from '@lisa-env/type';
import { Binary } from '@binary/type';
import { delimiter, join } from 'path';
import { uniq, defaults } from 'lodash';
import { pathExists, readJson, outputJson, remove } from 'fs-extra';
import LISA from "@listenai/lisa_core";
import { Bundle, Flasher } from "@lisa-env/type";
import { Binary } from "@binary/type";
import { delimiter, join } from "path";
import { uniq, defaults } from "lodash";
import { pathExists, readJson, outputJson, remove } from "fs-extra";

import { KEY_OF_PATH, SYSTEM_PATHS, makePath, splitPath } from '../utils/path';
import typedImport from '../utils/typedImport';
import { KEY_OF_PATH, SYSTEM_PATHS, makePath, splitPath } from "../utils/path";
import typedImport from "../utils/typedImport";

import { PLUGIN_HOME, get } from './config';
import { PLUGIN_HOME, get } from "./config";

export const PACKAGE_HOME = join(PLUGIN_HOME, 'packages');
const PACKAGE_MODULES_DIR = join(PACKAGE_HOME, 'node_modules');
export const PACKAGE_HOME = join(PLUGIN_HOME, "packages");
const PACKAGE_MODULES_DIR = join(PACKAGE_HOME, "node_modules");

const CONFIG_DIR = join(PLUGIN_HOME, 'config');
const WEST_CONFIG_GLOBAL = join(CONFIG_DIR, 'westconfig');
const CONFIG_DIR = join(PLUGIN_HOME, "config");
const WEST_CONFIG_GLOBAL = join(CONFIG_DIR, "westconfig");

const ENV_CACHE_DIR = join(PLUGIN_HOME, 'envs');
const ENV_CACHE_DIR = join(PLUGIN_HOME, "envs");

const PIP_INDEX_URL = process.env.PIP_INDEX_URL || 'https://pypi.tuna.tsinghua.edu.cn/simple';
const PIP_INDEX_URL =
process.env.PIP_INDEX_URL || "https://pypi.tuna.tsinghua.edu.cn/simple";

const BUILTIN_BINARIES = [
'../venv',
'@binary/cmake',
'@binary/dtc',
'@binary/gperf',
'@binary/mklfs',
'@binary/ninja',
'@binary/protoc',
'@binary/xz',
"../venv",
"@binary/cmake",
"@binary/dtc",
"@binary/gperf",
"@binary/mklfs",
"@binary/ninja",
"@binary/protoc",
"@binary/xz",
];

export async function getEnv(override?: string): Promise<Record<string, string>> {
const escape = (name: string) => name.replaceAll('/', '_').replaceAll('\\', '_');
const cacheName = override ? `cache_${escape(override)}.json` : 'cache.json';
export async function getEnv(
override?: string
): Promise<Record<string, string>> {
const escape = (name: string) =>
name.replaceAll("/", "_").replaceAll("\\", "_");
const cacheName = override ? `cache_${escape(override)}.json` : "cache.json";
const cacheFile = join(ENV_CACHE_DIR, cacheName);
if (await pathExists(cacheFile)) {
const env = await readJson(cacheFile);
Object.assign(env, makePath([...splitPath(env[KEY_OF_PATH]), ...SYSTEM_PATHS]));
Object.assign(
env,
makePath([...splitPath(env[KEY_OF_PATH]), ...SYSTEM_PATHS])
);
return env;
} else {
const env = await makeEnv(override);
await outputJson(cacheFile, env);
Object.assign(env, makePath([...splitPath(env[KEY_OF_PATH]), ...SYSTEM_PATHS]));
Object.assign(
env,
makePath([...splitPath(env[KEY_OF_PATH]), ...SYSTEM_PATHS])
);
return env;
}
}
Expand All @@ -51,8 +61,10 @@ export async function invalidateEnv(): Promise<void> {
await remove(ENV_CACHE_DIR);
}

export async function getFlasher(override?: string): Promise<Flasher | undefined> {
const envs = await get('env') || [];
export async function getFlasher(
override?: string
): Promise<Flasher | undefined> {
const envs = (await get("env")) || [];
if (override) envs.unshift(override);
const bundles = await loadBundles(uniq(envs));
if (bundles.length == 0) return undefined;
Expand All @@ -62,21 +74,29 @@ export async function getFlasher(override?: string): Promise<Flasher | undefined
export async function loadBundles(envs?: string[]): Promise<Bundle[]> {
if (!envs) return [];
try {
return await Promise.all(envs.map(name => typedImport<Bundle>(`${PACKAGE_MODULES_DIR}/@lisa-env/${name}`)));
return await Promise.all(
envs.map((name) =>
typedImport<Bundle>(`${PACKAGE_MODULES_DIR}/@lisa-env/${name}`)
)
);
} catch (e) {
return [];
}
}

export async function loadBinaries(bundles?: Bundle[]): Promise<Record<string, Binary>> {
export async function loadBinaries(
bundles?: Bundle[]
): Promise<Record<string, Binary>> {
const binaries: Record<string, Binary> = {};
for (const name of BUILTIN_BINARIES) {
const unprefixedName = name.split('/').slice(1).join('/');
const unprefixedName = name.split("/").slice(1).join("/");
binaries[unprefixedName] = await typedImport<Binary>(name);
}
for (const bundle of bundles || []) {
for (const name of bundle.binaries || []) {
binaries[name] = await typedImport<Binary>(`${PACKAGE_MODULES_DIR}/@binary/${name}`);
binaries[name] = await typedImport<Binary>(
`${PACKAGE_MODULES_DIR}/@binary/${name}`
);
}
}
return binaries;
Expand All @@ -87,7 +107,7 @@ async function makeEnv(override?: string): Promise<Record<string, string>> {
const binaries: string[] = [];
const libraries: string[] = [];

const envs = await get('env') || [];
const envs = (await get("env")) || [];
if (override) envs.unshift(override);
const bundles = await loadBundles(uniq(envs));

Expand All @@ -101,9 +121,9 @@ async function makeEnv(override?: string): Promise<Record<string, string>> {
}
}

const sdk = await get('sdk');
const sdk = await get("sdk");
if (sdk) {
env['ZEPHYR_BASE'] = sdk;
env["ZEPHYR_BASE"] = sdk;
}

Object.assign(env, {
Expand All @@ -121,29 +141,39 @@ async function makeEnv(override?: string): Promise<Record<string, string>> {

Object.assign(env, makePath(binaries));

if (libraries.length > 0 && process.platform == 'linux') {
if (libraries.length > 0 && process.platform == "linux") {
const { LD_LIBRARY_PATH } = process.env;
env['LD_LIBRARY_PATH'] = [
env["LD_LIBRARY_PATH"] = [
...libraries,
...LD_LIBRARY_PATH ? LD_LIBRARY_PATH.split(delimiter) : [],
...(LD_LIBRARY_PATH ? LD_LIBRARY_PATH.split(delimiter) : []),
].join(delimiter);
}

if (process.platform == 'linux') {
if (process.platform == "linux") {
try {
const dirs: string[] = [];
const { stdout } = await LISA.cmd('infocmp', ['-D'], { shell: true });
LISA.application.debug('infocmp -D', stdout);
for (const dir of stdout.split('\n')) {
if (dir && await pathExists(dir)) {
const { stdout } = await LISA.cmd("infocmp", ["-D"], { shell: true });
LISA.application.debug("infocmp -D", stdout);
for (const dir of stdout.split("\n")) {
if (dir && (await pathExists(dir))) {
dirs.push(dir);
}
}
env['TERMINFO_DIRS'] = dirs.join(delimiter);
LISA.application.debug('TERMINFO_DIRS', env['TERMINFO_DIRS']);
} catch (e) {
}
env["TERMINFO_DIRS"] = dirs.join(delimiter);
LISA.application.debug("TERMINFO_DIRS", env["TERMINFO_DIRS"]);
} catch (e) {}
}

return env;
}

export async function getBinarie(name: string): Promise<any> {
const envs = (await get("env")) || [];
const bundles = await loadBundles(uniq(envs));
const binaries = await loadBinaries(bundles);
for (const binary of Object.keys(binaries)) {
if (name === binary.toString()) {
return binaries[binary];
}
}
}
148 changes: 96 additions & 52 deletions src/tasks/initVs.ts
Original file line number Diff line number Diff line change
@@ -1,64 +1,108 @@
import { LisaType, job } from '../utils/lisa_ex';
import { join, resolve } from 'path';
import { LisaType, job } from "../utils/lisa_ex";
import { join, resolve } from "path";
import {
readFile, copy, writeFile, readJson, pathExists, writeJson
} from 'fs-extra';
readFile,
copy,
writeFile,
readJson,
pathExists,
remove,
rename,
mkdir,
} from "fs-extra";

import { getEnv } from '../env';
import { get } from '../env/config';
import parseArgs from '../utils/parseArgs';
import { testLog } from '../utils/testLog';
import { getEnv, getBinarie } from "../env";
import { get } from "../env/config";
import parseArgs from "../utils/parseArgs";
import { testLog } from "../utils/testLog";
import { platform } from "os";

export default ({ application, cmd }: LisaType) => {

job('init-vs', {
title: '生成vscode debug runner',
job("init-vs", {
title: "生成vscode debug runner",
async task(ctx, task) {
const { args, printHelp } = parseArgs(application.argv, {
'env': { arg: 'name', help: '指定编译环境' },
});
const current = await get('env');
const availableSdks = ["csk6-dsp", "csk6"];
const current = await get("env");
const env = await getEnv();
let XTENSA_TOOL: string = '';
if (!args['env']) {
if (!current) {
throw new Error(`需要设置 编译环境 (lisa zep use-env [path])`);
} else if (!current.includes('csk6-dsp')) {
throw new Error(`暂不支持其他SDK`);
}
} else if (args['env'] !== 'csk6-dsp') {
let XTENSA_TOOL: string = "";
let JLINK_TOOL: string = "";
let JLinkGDBServerCL: string = "";
if (platform() !== "win32") {
throw new Error("该命令暂只支持在 windows 下执行");
}
const { args } = parseArgs(application.argv, {
env: { arg: "name", help: "生成vscode debug runner" },
});
if (!current) {
throw new Error(`需要设置 编译环境 (lisa zep use-env [path])`);
}
if (!args["env"]) {
throw new Error(`需要指定编译环境 (--env [env])`);
} else if (!availableSdks.includes(args["env"])) {
throw new Error(`暂不支持其他SDK`);
}

const XTENSA_SYSTEM = env.XTENSA_SYSTEM;
if (!XTENSA_SYSTEM) {
throw new Error(`需要设置 XTENSA_SYSTEM`);
} else {
XTENSA_TOOL = join(XTENSA_SYSTEM.split('venus_hifi4')[0], 'XtensaTools/bin/xt-gdb.exe')
if (!(await pathExists(XTENSA_TOOL))) {
throw new Error(`xt-gdb不存在: ${XTENSA_TOOL}`);
if (args["env"] === "csk6-dsp") {
const XTENSA_SYSTEM = env.XTENSA_SYSTEM;
if (!XTENSA_SYSTEM) {
throw new Error(`需要设置 XTENSA_SYSTEM`);
} else {
XTENSA_TOOL = join(
XTENSA_SYSTEM.split("venus_hifi4")[0],
"XtensaTools/bin/xt-gdb.exe"
);
if (!(await pathExists(XTENSA_TOOL))) {
throw new Error(`xt-gdb不存在: ${XTENSA_TOOL}`);
}
}
}
if (args["env"] === "csk6") {
const JLINK = await getBinarie("jlink-venus");
JLINK_TOOL = JLINK && JLINK.homeDir;
if (!JLINK_TOOL || !(await pathExists(JLINK_TOOL))) {
throw new Error(`需要设置 jlink-venus`);
} else {
JLinkGDBServerCL = join(JLINK.homeDir, "JLinkGDBServerCL.exe");
if (!(await pathExists(JLinkGDBServerCL))) {
throw new Error(`缺少必要文件:${JLinkGDBServerCL}`);
}
}
}
const jlinkSNcode = ctx.jlinkSNcode || await task.prompt({
type: 'input',
name: 'value',
message: '请输入jlink 的 `SN` 码',
initial: '.',
})
ctx.jlinkSNcode = jlinkSNcode;
const targetDir = join(process.cwd(), '.vscode');
const formDir = join(__dirname, '..', '..', 'vscode');
await copy(formDir, targetDir);
const configFIle = join(targetDir, 'xt-ocd-config.xml');
const Launchfile = join(targetDir, 'launch.json');
const configFileStr = await readFile(configFIle, 'utf8');
const result = configFileStr.replace(/###usbser###/g, jlinkSNcode);
await writeFile(configFIle, result, 'utf-8');
const launchJson = await readJson(Launchfile);
launchJson.configurations[0].linux.miDebuggerPath = XTENSA_TOOL || '';
await writeFile(Launchfile, JSON.stringify(launchJson, null, "\t"));
testLog(task, '成功')
const targetDir = join(process.cwd(), ".vscode");
const formDir = join(__dirname, "..", "..", "vscode");
const Launchfile = join(formDir, `launch_${args["env"]}.json`);
await remove(targetDir);
if (args["env"] === "csk6-dsp") {
const jlinkSNcode =
ctx.jlinkSNcode ||
(await task.prompt({
type: "input",
name: "value",
message: "请输入jlink 的 `SN` 码",
initial: ".",
}));
ctx.jlinkSNcode = jlinkSNcode;
await mkdir(targetDir);
const configFIle = join(formDir, "xt-ocd-config.xml");
const configFileStr = await readFile(configFIle, "utf8");
const result = configFileStr.replace(/###usbser###/g, jlinkSNcode);
await writeFile(join(targetDir, "xt-ocd-config.xml"), result, "utf-8");
const launchJson = await readJson(Launchfile);
launchJson.configurations[0].linux.miDebuggerPath = XTENSA_TOOL || "";
await writeFile(
join(targetDir, `launch.json`),
JSON.stringify(launchJson, null, "\t")
);
} else {
await mkdir(targetDir);
const launchJson = await readJson(Launchfile);
launchJson.configurations[0].serverpath = JLinkGDBServerCL || "";
launchJson.configurations[0].armToolchainPath = JLINK_TOOL || "";
await writeFile(
join(targetDir, `launch.json`),
JSON.stringify(launchJson, null, "\t")
);
}
testLog(task, "成功");
},

});
}
};
File renamed without changes.
Loading