Skip to content
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

[VSC-1409] Add check for missing compile_commands.json in IDF projects #1271

Open
wants to merge 5 commits 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
4 changes: 3 additions & 1 deletion l10n/bundle.l10n.es.json
Original file line number Diff line number Diff line change
Expand Up @@ -186,5 +186,7 @@
"Execute Custom Task": "Ejecutar tarea personalizada",
"Wait for ESP-IDF build or flash to finish": "Espere a que finalice la compilación o la actualización de ESP-IDF",
"Target {0} Set Successfully.": "Objetivo {0} configurado con éxito.",
"Unknown error occurred while setting IDF target.": "Ocurrió un error desconocido al configurar el objetivo IDF."
"Unknown error occurred while setting IDF target.": "Ocurrió un error desconocido al configurar el objetivo IDF.",
"compile_commands.json is missing. This may cause errors with code analysis extensions.": "Falta compile_commands.json. Esto puede causar errores con las extensiones de análisis de código.",
"Generate compile_commands.json": "Generar compile_commands.json"
}
4 changes: 3 additions & 1 deletion l10n/bundle.l10n.pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -186,5 +186,7 @@
"Execute Custom Task": "Executar tarefa personalizada",
"Wait for ESP-IDF build or flash to finish": "Aguarde a conclusão da compilação ou flash do ESP-IDF",
"Target {0} Set Successfully.": "Alvo {0} definido com sucesso.",
"Unknown error occurred while setting IDF target.": "Ocorreu um erro desconhecido ao definir o alvo IDF."
"Unknown error occurred while setting IDF target.": "Ocorreu um erro desconhecido ao definir o alvo IDF.",
"compile_commands.json is missing. This may cause errors with code analysis extensions.": "O arquivo compile_commands.json está faltando. Isso pode causar erros com extensões de análise de código.",
"Generate compile_commands.json": "Gerar compile_commands.json"
}
4 changes: 3 additions & 1 deletion l10n/bundle.l10n.ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -186,5 +186,7 @@
"Execute Custom Task": "Выполнить пользовательскую задачу",
"Wait for ESP-IDF build or flash to finish": "Подождите завершения сборки или прошивки ESP-IDF.",
"Target {0} Set Successfully.": "Цель {0} успешно установлена.",
"Unknown error occurred while setting IDF target.": "Произошла неизвестная ошибка при установке цели IDF."
"Unknown error occurred while setting IDF target.": "Произошла неизвестная ошибка при установке цели IDF.",
"compile_commands.json is missing. This may cause errors with code analysis extensions.": "Отсутствует файл compile_commands.json. Это может вызвать ошибки в работе расширений для анализа кода.",
"Generate compile_commands.json": "Создать compile_commands.json"
}
4 changes: 3 additions & 1 deletion l10n/bundle.l10n.zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -186,5 +186,7 @@
"Execute Custom Task": "执行自定义任务",
"Wait for ESP-IDF build or flash to finish": "等待 ESP-IDF 构建或刷新完成",
"Target {0} Set Successfully.": "目标 {0} 设置成功",
"Unknown error occurred while setting IDF target.": "设置 IDF 目标时发生未知错误"
"Unknown error occurred while setting IDF target.": "设置 IDF 目标时发生未知错误",
"compile_commands.json is missing. This may cause errors with code analysis extensions.": "缺少 compile_commands.json 文件。这可能会导致代码分析扩展出错。",
"Generate compile_commands.json": "生成 compile_commands.json"
}
26 changes: 6 additions & 20 deletions src/build/buildTask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import * as vscode from "vscode";
import * as idfConf from "../idfConfiguration";
import {
appendIdfAndToolsToPath,
compareVersion,
getEspIdfFromCMake,
getSDKConfigFilePath,
isBinInPath,
Expand Down Expand Up @@ -119,7 +118,6 @@ export class BuildTask {
if (!cmakeCacheExists) {
const espIdfVersion = await getEspIdfFromCMake(this.idfPathDir);
let defaultCompilerArgs;
const useEqualSign = compareVersion(espIdfVersion, "4.4") >= 0;
if (espIdfVersion === "x.x") {
Logger.warn(
"Could not determine ESP-IDF version. Using default compiler arguments for the latest known version."
Expand All @@ -129,12 +127,6 @@ export class BuildTask {
"-DPYTHON_DEPS_CHECKED=1",
"-DESP_PLATFORM=1",
];
} else if (useEqualSign) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rebase is removing changes from #1266 which are implemented in master.

Please update.

defaultCompilerArgs = [
"-G=Ninja",
"-DPYTHON_DEPS_CHECKED=1",
"-DESP_PLATFORM=1",
];
} else {
defaultCompilerArgs = [
"-G",
Expand All @@ -153,19 +145,11 @@ export class BuildTask {
}
let buildPathArgsIndex = compilerArgs.indexOf("-B");
if (buildPathArgsIndex !== -1) {
compilerArgs.splice(buildPathArgsIndex, useEqualSign ? 1 : 2);
}
if (useEqualSign) {
compilerArgs.push(`-B=${this.buildDirPath}`);
} else {
compilerArgs.push("-B", this.buildDirPath);
compilerArgs.splice(buildPathArgsIndex, 2);
}
compilerArgs.push("-B", this.buildDirPath);
if (compilerArgs.indexOf("-S") === -1) {
if (useEqualSign) {
compilerArgs.push(`-S=${this.currentWorkspace.fsPath}`);
} else {
compilerArgs.push("-S", this.currentWorkspace.fsPath);
}
compilerArgs.push("-S", this.currentWorkspace.fsPath);
}

const sdkconfigFile = await getSDKConfigFilePath(this.currentWorkspace);
Expand Down Expand Up @@ -261,7 +245,9 @@ export class BuildTask {
this.currentWorkspace
) as string;

const adapterTargetName = await getIdfTargetFromSdkconfig(this.currentWorkspace);
const adapterTargetName = await getIdfTargetFromSdkconfig(
this.currentWorkspace
);
const showTaskOutput =
notificationMode === idfConf.NotificationMode.All ||
notificationMode === idfConf.NotificationMode.Output
Expand Down
12 changes: 3 additions & 9 deletions src/espIdf/reconfigure/task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
workspace,
} from "vscode";
import { NotificationMode, readParameter } from "../../idfConfiguration";
import { appendIdfAndToolsToPath, compareVersion, getEspIdfFromCMake, getSDKConfigFilePath } from "../../utils";
import { appendIdfAndToolsToPath, getSDKConfigFilePath } from "../../utils";
import { join } from "path";
import { TaskManager } from "../../taskManager";
import { getVirtualEnvPythonPath } from "../../pythonManager";
Expand Down Expand Up @@ -65,18 +65,12 @@ export class IdfReconfigureTask {

const idfPy = join(this.idfPathDir, "tools", "idf.py");
const reconfigureArgs = [idfPy];
const espIdfVersion = await getEspIdfFromCMake(this.idfPathDir);
const useEqualSign = compareVersion(espIdfVersion, "4.4") >= 0;

let buildPathArgsIndex = reconfigureArgs.indexOf("-B");
if (buildPathArgsIndex !== -1) {
reconfigureArgs.splice(buildPathArgsIndex, useEqualSign ? 1 : 2);
}
if (useEqualSign) {
reconfigureArgs.push(`-B=${this.buildDirPath}`);
} else {
reconfigureArgs.push("-B", this.buildDirPath);
reconfigureArgs.splice(buildPathArgsIndex, 2);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here removing changes in master from #1266

}
reconfigureArgs.push("-B", this.buildDirPath);

const sdkconfigFile = await getSDKConfigFilePath(this.curWorkspace);
if (reconfigureArgs.indexOf("SDKCONFIG") === -1) {
Expand Down
166 changes: 104 additions & 62 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import { ExamplesPlanel } from "./examples/ExamplesPanel";
import * as idfConf from "./idfConfiguration";
import { Logger } from "./logger/logger";
import { OutputChannel } from "./logger/outputChannel";
import { showInfoNotificationWithAction } from "./logger/utils";
import * as utils from "./utils";
import { PreCheck } from "./utils";
import {
Expand Down Expand Up @@ -391,77 +392,81 @@ export async function activate(context: vscode.ExtensionContext) {
binTimestampEventFunc
);
context.subscriptions.push(buildWatcherCreateDisposable);

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes from 394 to 469 are not related to the PR proposal solution. While I think is good to add this to context subscription disposable array, the amount of changes are not necessary.

Please update to remove these changes.

vscode.workspace.onDidChangeWorkspaceFolders(async (e) => {
if (PreCheck.isWorkspaceFolderOpen()) {
for (const ws of e.removed) {
if (workspaceRoot && ws.uri === workspaceRoot) {
workspaceRoot = initSelectedWorkspace(statusBarItems["workspace"]);
await getIdfTargetFromSdkconfig(
workspaceRoot,
statusBarItems["target"]
);
if (statusBarItems && statusBarItems["port"]) {
statusBarItems["port"].text =
`$(${commandDictionary[CommandKeys.SelectSerialPort].iconId}) ` +
idfConf.readParameter("idf.port", workspaceRoot);
}
if (statusBarItems["projectConf"]) {
statusBarItems["projectConf"].dispose();
statusBarItems["projectConf"] = undefined;
const selectedConfig = ESP.ProjectConfiguration.store.get<string>(
ESP.ProjectConfiguration.SELECTED_CONFIG
context.subscriptions.push(
vscode.workspace.onDidChangeWorkspaceFolders(async (e) => {
if (PreCheck.isWorkspaceFolderOpen()) {
for (const ws of e.removed) {
if (workspaceRoot && ws.uri === workspaceRoot) {
workspaceRoot = initSelectedWorkspace(statusBarItems["workspace"]);
await getIdfTargetFromSdkconfig(
workspaceRoot,
statusBarItems["target"]
);
ESP.ProjectConfiguration.store.clear(selectedConfig);
ESP.ProjectConfiguration.store.clear(
ESP.ProjectConfiguration.SELECTED_CONFIG
if (statusBarItems && statusBarItems["port"]) {
statusBarItems["port"].text =
`$(${
commandDictionary[CommandKeys.SelectSerialPort].iconId
}) ` + idfConf.readParameter("idf.port", workspaceRoot);
}
if (statusBarItems["projectConf"]) {
statusBarItems["projectConf"].dispose();
statusBarItems["projectConf"] = undefined;
const selectedConfig = ESP.ProjectConfiguration.store.get<string>(
ESP.ProjectConfiguration.SELECTED_CONFIG
);
ESP.ProjectConfiguration.store.clear(selectedConfig);
ESP.ProjectConfiguration.store.clear(
ESP.ProjectConfiguration.SELECTED_CONFIG
);
}
const currentIdfSetup = await getCurrentIdfSetup(
workspaceRoot,
false
);
if (statusBarItems["currentIdfVersion"]) {
statusBarItems["currentIdfVersion"].text = currentIdfSetup.isValid
? `$(${
commandDictionary[CommandKeys.SelectCurrentIdfVersion]
.iconId
}) ESP-IDF v${currentIdfSetup.version}`
: `$(${
commandDictionary[CommandKeys.SelectCurrentIdfVersion]
.iconId
}) ESP-IDF InvalidSetup`;
}
const coverageOptions = getCoverageOptions(workspaceRoot);
covRenderer = new CoverageRenderer(workspaceRoot, coverageOptions);
break;
}
const currentIdfSetup = await getCurrentIdfSetup(
}
if (typeof workspaceRoot === undefined) {
workspaceRoot = initSelectedWorkspace(statusBarItems["workspace"]);
await getIdfTargetFromSdkconfig(
workspaceRoot,
false
statusBarItems["target"]
);
if (statusBarItems["currentIdfVersion"]) {
statusBarItems["currentIdfVersion"].text = currentIdfSetup.isValid
? `$(${
commandDictionary[CommandKeys.SelectCurrentIdfVersion].iconId
}) ESP-IDF v${currentIdfSetup.version}`
: `$(${
commandDictionary[CommandKeys.SelectCurrentIdfVersion].iconId
}) ESP-IDF InvalidSetup`;
}
const coverageOptions = getCoverageOptions(workspaceRoot);
covRenderer = new CoverageRenderer(workspaceRoot, coverageOptions);
break;
}
const buildDirPath = idfConf.readParameter(
"idf.buildPath",
workspaceRoot
) as string;
const projectName = await getProjectName(buildDirPath);
const projectElfFile = `${path.join(buildDirPath, projectName)}.elf`;
const debugAdapterConfig = {
currentWorkspace: workspaceRoot,
elfFile: projectElfFile,
} as IDebugAdapterConfig;
debugAdapterManager.configureAdapter(debugAdapterConfig);
const openOCDConfig: IOpenOCDConfig = {
workspace: workspaceRoot,
} as IOpenOCDConfig;
openOCDManager.configureServer(openOCDConfig);
}
if (typeof workspaceRoot === undefined) {
workspaceRoot = initSelectedWorkspace(statusBarItems["workspace"]);
await getIdfTargetFromSdkconfig(
workspaceRoot,
statusBarItems["target"]
);
const coverageOptions = getCoverageOptions(workspaceRoot);
covRenderer = new CoverageRenderer(workspaceRoot, coverageOptions);
}
const buildDirPath = idfConf.readParameter(
"idf.buildPath",
workspaceRoot
) as string;
const projectName = await getProjectName(buildDirPath);
const projectElfFile = `${path.join(buildDirPath, projectName)}.elf`;
const debugAdapterConfig = {
currentWorkspace: workspaceRoot,
elfFile: projectElfFile,
} as IDebugAdapterConfig;
debugAdapterManager.configureAdapter(debugAdapterConfig);
const openOCDConfig: IOpenOCDConfig = {
workspace: workspaceRoot,
} as IOpenOCDConfig;
openOCDManager.configureServer(openOCDConfig);
}
ConfserverProcess.dispose();
});
ConfserverProcess.dispose();
})
);

vscode.debug.onDidTerminateDebugSession((e) => {
if (isOpenOCDLaunchedByDebug && !isDebugRestarted) {
Expand Down Expand Up @@ -3666,6 +3671,43 @@ export async function activate(context: vscode.ExtensionContext) {
new HintHoverProvider(treeDataProvider)
)
);
checkAndNotifyMissingCompileCommands();
}

function checkAndNotifyMissingCompileCommands() {
if (vscode.workspace.workspaceFolders) {
vscode.workspace.workspaceFolders.forEach(async (folder) => {
try {
const isIdfProject = utils.checkIsProjectCmakeLists(folder.uri.fsPath);
if (isIdfProject) {
const buildDirPath = idfConf.readParameter(
"idf.buildPath",
workspaceRoot
) as string;
const compileCommandsPath = path.join(
radurentea marked this conversation as resolved.
Show resolved Hide resolved
buildDirPath,
"compile_commands.json"
);
const compileCommandsExists = await pathExists(compileCommandsPath);

if (!compileCommandsExists) {
showInfoNotificationWithAction(
vscode.l10n.t(
"compile_commands.json is missing. This may cause errors with code analysis extensions."
),
vscode.l10n.t("Generate compile_commands.json"),
() => vscode.commands.executeCommand("espIdf.idfReconfigureTask")
);
}
}
} catch (error) {
const msg = error.message
? error.message
: "Error checking for compile_commands.json file.";
Logger.error(msg, error, "extension compileCommandsExists");
}
});
}
}

async function getFrameworksPickItems() {
Expand Down
25 changes: 25 additions & 0 deletions src/logger/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import * as vscode from "vscode";

type NotificationAction = () => Thenable<unknown> | Promise<void> | void;

/**
* Shows an information notification with a button that executes a custom action when clicked.
* @param {string} infoMessage - The information message to display.
* @param {string} buttonLabel - The label for the button.
* @param {NotificationAction} action - The action to perform when the button is clicked.
* @returns {Promise<void>} - A promise that resolves when the notification is shown and handled.
*/
export async function showInfoNotificationWithAction(
infoMessage: string,
buttonLabel: string,
action: NotificationAction
): Promise<void> {
const selectedOption = await vscode.window.showInformationMessage(
infoMessage,
buttonLabel
);

if (selectedOption === buttonLabel) {
await Promise.resolve(action());
}
}