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

Fix infinite loop when --dry-running autoconf projects. #500

Open
wants to merge 2 commits into
base: main
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
2 changes: 1 addition & 1 deletion package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"makefile-tools.configuration.makefile.makePath.description": "The path to the make tool",
"makefile-tools.configuration.makefile.configurations.description": "The user defined makefile configurations",
"makefile-tools.configuration.makefile.configurations.name.description": "The name of the makefile configuration",
"makefile-tools.configuration.makefile.configurations.makefilePath.description": "File path to the makefile",
"makefile-tools.configuration.makefile.configurations.makefilePath.description": "File path to the makefile. Defaults to 'Makefile'",
"makefile-tools.configuration.makefile.configurations.makePath.description": "File path to the make command",
"makefile-tools.configuration.makefile.configurations.makeDirectory.description": "Folder path passed to make via the -C switch",
"makefile-tools.configuration.makefile.configurations.makeArgs.description": "Arguments to pass to the make command",
Expand Down
48 changes: 21 additions & 27 deletions src/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,35 +194,37 @@ async function readMakePath(): Promise<void> {
}
}

let makefilePath: string | undefined;
export function getMakefilePath(): string | undefined { return makefilePath; }
export function setMakefilePath(path: string): void { makefilePath = path; }
let makefilePath: string = "Makefile";
export function getMakefilePath(): string { return makefilePath; }
export function setMakefilePath(path: string = "Makefile"): void { makefilePath = path; }
// Read the full path to the makefile if defined in settings.
// It represents a default to look for if no other makefile is already provided
// in makefile.configurations.makefilePath.
// TODO: validate and integrate with "-f [Makefile]" passed in makefile.configurations.makeArgs.
async function readMakefilePath(): Promise<void> {
makefilePath = await util.getExpandedSetting<string>("makefilePath");
if (!makefilePath) {
let makefilePathSetting: string | undefined = await util.getExpandedSetting<string>("makefilePath");
if (!makefilePathSetting) {
logger.message("No path to the makefile is defined in the settings file.");
setMakefilePath();
} else {
makefilePath = util.resolvePathToRoot(makefilePath);
setMakefilePath(makefilePathSetting);
}
}

let makeDirectory: string | undefined;
export function getMakeDirectory(): string | undefined { return makeDirectory; }
export function setMakeDirectory(dir: string): void { makeDirectory = dir; }
export function setMakeDirectory(dir: string = ''): void { makeDirectory = dir; }
// Read the make working directory path if defined in settings.
// It represents a default to look for if no other makeDirectory is already provided
// in makefile.configurations.makeDirectory.
// TODO: validate and integrate with "-C [DIR_PATH]" passed in makefile.configurations.makeArgs.
async function readMakeDirectory(): Promise<void> {
makeDirectory = await util.getExpandedSetting<string>("makeDirectory");
if (!makeDirectory) {
let makeDirectorySetting: string | undefined = await util.getExpandedSetting<string>("makeDirectory");
if (!makeDirectorySetting) {
logger.message("No folder path to the makefile is defined in the settings file.");
setMakeDirectory();
} else {
makeDirectory = util.resolvePathToRoot(makeDirectory);
setMakeDirectory(makeDirectorySetting);
}
}

Expand Down Expand Up @@ -806,7 +808,7 @@ export async function getCommandForConfiguration(configuration: string | undefin
}
}

if (!util.checkFileExistsSync(configurationMakefile)) {
if (!util.checkFileExistsSync(util.resolvePathToRoot(configurationMakefile))) {
logger.message("The makefile entry point was not found. " +
"Make sure it exists at the location defined by makefile.makefilePath, makefile.configurations[].makefilePath, " +
"makefile.makeDirectory, makefile.configurations[].makeDirectory" +
Expand Down Expand Up @@ -936,24 +938,22 @@ export async function readMakefileConfigurations(): Promise<void> {
// Last target picked from the set of targets that are run by the makefiles
// when building for the current configuration.
// Saved into the settings storage. Also reflected in the configuration status bar button
let currentTarget: string | undefined;
export function getCurrentTarget(): string | undefined { return currentTarget; }
export function setCurrentTarget(target: string | undefined): void { currentTarget = target; }
// Assume the well-known "all" target for the default goal
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure. Before this change, if the user does not specify a build target, we invoke "make" (eventually with other args, coming via other switches) but no target mentioned which will result in "make" looking only at the first (if I understand correctly). Now for such scenario suddenly "make" would build "all" even if the user did not specify "all".

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The issue is that in order to avoid the infinite loop, you must add Makefile as a target, no matter what. Giving no other target is not an option, because make would not attempt to build anything, there would be no compilers invoked, and thus no useful information to be parsed (defines and includes).

The target "all" is assumed all over the code, so that's why I thought it's already baked in. If you want to do it more correctly, you'd have to call make twice. The first time with --print-data-base --dry-run --assume-old=Makefile Makefile, from which you'd extract the .DEFAULT_GOAL variable, and the second time with --dry-run --assume-old=Makefile Makefile ${.DEFAULT_GOAL} - then no assumptions are made about the default target, and you get useful tool invocations from the 2nd --dry-run.

In fact, the output of the first run would be useful to extract the targets in the current directory. (so you'd get the targets first, then the tool invocations)

let currentTarget: string = "all";
export function getCurrentTarget(): string { return currentTarget; }
// Set the current target, or 'all' if none was given
export function setCurrentTarget(target: string = "all"): void { currentTarget = target; }

// Read current target from workspace state, update status bar item
function readCurrentTarget(): void {
let buildTarget : string | undefined = extension.getState().buildTarget;
setCurrentTarget(buildTarget);
if (!buildTarget) {
logger.message("No target defined in the workspace state. Assuming 'Default'.");
statusBar.setTarget("Default");
// If no particular target is defined in settings, use 'Default' for the button
// but keep the variable empty, to not append it to the make command.
currentTarget = "";
logger.message(`No target defined in the workspace state. Assuming '${currentTarget}'.`);
} else {
currentTarget = buildTarget;
logger.message(`Reading current build target "${currentTarget}" from the workspace state.`);
statusBar.setTarget(currentTarget);
}
statusBar.setTarget(currentTarget);
}

let configureOnOpen: boolean | undefined;
Expand Down Expand Up @@ -1307,9 +1307,6 @@ export async function initFromSettings(activation: boolean = false): Promise<voi

subKey = "makefilePath";
let updatedMakefilePath : string | undefined = await util.getExpandedSetting<string>(subKey);
if (updatedMakefilePath) {
updatedMakefilePath = util.resolvePathToRoot(updatedMakefilePath);
}
if (updatedMakefilePath !== makefilePath) {
// A change in makefile.makefilePath should trigger an IntelliSense update
// only if the extension is not currently reading from a build log.
Expand All @@ -1321,9 +1318,6 @@ export async function initFromSettings(activation: boolean = false): Promise<voi

subKey = "makeDirectory";
let updatedMakeDirectory : string | undefined = await util.getExpandedSetting<string>(subKey);
if (updatedMakeDirectory) {
updatedMakeDirectory = util.resolvePathToRoot(updatedMakeDirectory);
}
if (updatedMakeDirectory !== makeDirectory) {
// A change in makefile.makeDirectory should trigger an IntelliSense update
// only if the extension is not currently reading from a build log.
Expand Down
18 changes: 7 additions & 11 deletions src/make.ts
Original file line number Diff line number Diff line change
Expand Up @@ -446,17 +446,6 @@ export async function generateParseContent(progress: vscode.Progress<{}>,
// Continue with the make dryrun invocation
let makeArgs: string[] = [];

// Prepend the target to the arguments given in the makefile.configurations object,
// unless we want to parse for the full set of available targets.
if (forTargets) {
makeArgs.push("all");
} else {
let currentTarget: string | undefined = configuration.getCurrentTarget();
if (currentTarget) {
makeArgs.push(currentTarget);
}
}

// Include all the make arguments defined in makefile.configurations.makeArgs
makeArgs = makeArgs.concat(configuration.getConfigurationMakeArgs());

Expand All @@ -478,7 +467,11 @@ export async function generateParseContent(progress: vscode.Progress<{}>,
makeArgs.push("--question");
logger.messageNoCR("Generating targets information with command: ");
} else {
const makefilePath :string = configuration.getMakefilePath();
makeArgs.push("--dry-run");
makeArgs.push(`--assume-old=${makefilePath}`);
makeArgs.push(makefilePath);
makeArgs.push("AM_MAKEFLAGS=--assume-old=Makefile Makefile");

// If this is not a clean configure, remove --always-make from the arguments list.
// We need to have --always-make in makefile.dryrunSwitches and remove it for not clean configure
Expand All @@ -492,6 +485,9 @@ export async function generateParseContent(progress: vscode.Progress<{}>,
}
});

// Append the target to the arguments given in the makefile.configurations object
makeArgs.push(configuration.getCurrentTarget());

logger.messageNoCR(`Generating ${getConfigureIsInBackground() ? "in the background a new " : ""}configuration cache with command: `);
}

Expand Down
8 changes: 0 additions & 8 deletions src/test/fakeSuite/extension.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ suite('Fake dryrun parsing', /*async*/() => {
await vscode.workspace.getConfiguration("makefile").update("launchConfigurations", undefined);
configuration.setCurrentLaunchConfiguration(undefined);
configuration.setCurrentMakefileConfiguration("Default");
configuration.setCurrentTarget(undefined);
configuration.initFromState();
await configuration.initFromSettings();

Expand Down Expand Up @@ -118,7 +117,6 @@ suite('Fake dryrun parsing', /*async*/() => {
await vscode.workspace.getConfiguration("makefile").update("launchConfigurations", undefined);
configuration.setCurrentLaunchConfiguration(undefined);
configuration.setCurrentMakefileConfiguration("Default");
configuration.setCurrentTarget(undefined);
configuration.initFromState();
await configuration.initFromSettings();

Expand Down Expand Up @@ -173,7 +171,6 @@ suite('Fake dryrun parsing', /*async*/() => {
await vscode.workspace.getConfiguration("makefile").update("launchConfigurations", undefined);
configuration.setCurrentLaunchConfiguration(undefined);
configuration.setCurrentMakefileConfiguration("Default");
configuration.setCurrentTarget(undefined);
configuration.initFromState();
await configuration.initFromSettings();

Expand Down Expand Up @@ -250,7 +247,6 @@ suite('Fake dryrun parsing', /*async*/() => {
await vscode.workspace.getConfiguration("makefile").update("launchConfigurations", undefined);
configuration.setCurrentLaunchConfiguration(undefined);
configuration.setCurrentMakefileConfiguration("Default");
configuration.setCurrentTarget(undefined);
configuration.initFromState();
await configuration.initFromSettings();

Expand Down Expand Up @@ -312,7 +308,6 @@ suite('Fake dryrun parsing', /*async*/() => {
await vscode.workspace.getConfiguration("makefile").update("launchConfigurations", undefined);
configuration.setCurrentLaunchConfiguration(undefined);
configuration.setCurrentMakefileConfiguration("Default");
configuration.setCurrentTarget(undefined);
configuration.initFromState();
await configuration.initFromSettings();

Expand Down Expand Up @@ -374,7 +369,6 @@ suite('Fake dryrun parsing', /*async*/() => {
await vscode.workspace.getConfiguration("makefile").update("launchConfigurations", undefined);
configuration.setCurrentLaunchConfiguration(undefined);
configuration.setCurrentMakefileConfiguration("Default");
configuration.setCurrentTarget(undefined);
configuration.initFromState();
await configuration.initFromSettings();

Expand Down Expand Up @@ -434,7 +428,6 @@ suite('Fake dryrun parsing', /*async*/() => {
await vscode.workspace.getConfiguration("makefile").update("launchConfigurations", undefined);
configuration.setCurrentLaunchConfiguration(undefined);
configuration.setCurrentMakefileConfiguration("Default");
configuration.setCurrentTarget(undefined);
configuration.initFromState();
await configuration.initFromSettings();

Expand Down Expand Up @@ -476,7 +469,6 @@ suite('Fake dryrun parsing', /*async*/() => {
await vscode.workspace.getConfiguration("makefile").update("launchConfigurations", undefined);
configuration.setCurrentLaunchConfiguration(undefined);
configuration.setCurrentMakefileConfiguration("Default");
configuration.setCurrentTarget(undefined);
configuration.initFromState();
await configuration.initFromSettings();

Expand Down
Loading