Skip to content

Commit e03fcd9

Browse files
committed
Avoid infinite dry-run loop with automake projects
The top makefile in projects that use autotools and automake contains a rule to remake the makefile itself when the configuration changes (configure.ac). Even when dry-running, GNU make regenerates the makefile, in a bid to generate a 'correct' dry-run output. VScode needs to add --always-make in order to get a complete view of the dry-run. Without it, it would only get the commands needed for outdated targets. These two behaviours combined cause a naive 'make --dry-run --always-make' to continuously remake the Makefile. In order to avoid this infinite loop, make must be instructed as in the "Remaking Makefiles" man page, to avoid remaking the makefile. This is done by adding two options: --assume-old=Makefile, and Makefile (ie, target). Make requires the Makefile to be explicitly specified as target, otherwise it ignores the --assume-old=Makefile option. Furthermore, Makefiles generated by automake cause the top invocation to be a recursive sub-make invocation. On recursive makes, make itself calls submake without passing the --assume-old option, thus breaking the combo required for the sub-make to avoid remaking the makefile. As a result, automake Makefiles need one more workaround. The --assume-old option must be manually passed to sub-make via the AM_MAKEFLAGS, which is always appended to sub-make's command line. This commit implements the above incantation to enable automake Makefiles to be dry-run without an infinite loop. Additionally, the makefilePath, makeDirectory, updatedMakefilePath and updatedMakeDirectory variables are made to store the respective setting, rather then re-purposing them to store the corresponding resolved, absolute paths. makefilePath cannot be undefined because for dry-running the name of the makefile must always be supplied on the make commandline.
1 parent aeb59ee commit e03fcd9

3 files changed

Lines changed: 18 additions & 18 deletions

File tree

package.nls.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"makefile-tools.configuration.makefile.makePath.description": "The path to the make tool",
2424
"makefile-tools.configuration.makefile.configurations.description": "The user defined makefile configurations",
2525
"makefile-tools.configuration.makefile.configurations.name.description": "The name of the makefile configuration",
26-
"makefile-tools.configuration.makefile.configurations.makefilePath.description": "File path to the makefile",
26+
"makefile-tools.configuration.makefile.configurations.makefilePath.description": "File path to the makefile. Defaults to 'Makefile'",
2727
"makefile-tools.configuration.makefile.configurations.makePath.description": "File path to the make command",
2828
"makefile-tools.configuration.makefile.configurations.makeDirectory.description": "Folder path passed to make via the -C switch",
2929
"makefile-tools.configuration.makefile.configurations.makeArgs.description": "Arguments to pass to the make command",

src/configuration.ts

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -194,35 +194,37 @@ async function readMakePath(): Promise<void> {
194194
}
195195
}
196196

197-
let makefilePath: string | undefined;
198-
export function getMakefilePath(): string | undefined { return makefilePath; }
199-
export function setMakefilePath(path: string): void { makefilePath = path; }
197+
let makefilePath: string = "Makefile";
198+
export function getMakefilePath(): string { return makefilePath; }
199+
export function setMakefilePath(path: string = "Makefile"): void { makefilePath = path; }
200200
// Read the full path to the makefile if defined in settings.
201201
// It represents a default to look for if no other makefile is already provided
202202
// in makefile.configurations.makefilePath.
203203
// TODO: validate and integrate with "-f [Makefile]" passed in makefile.configurations.makeArgs.
204204
async function readMakefilePath(): Promise<void> {
205-
makefilePath = await util.getExpandedSetting<string>("makefilePath");
206-
if (!makefilePath) {
205+
let makefilePathSetting: string | undefined = await util.getExpandedSetting<string>("makefilePath");
206+
if (!makefilePathSetting) {
207207
logger.message("No path to the makefile is defined in the settings file.");
208+
setMakefilePath();
208209
} else {
209-
makefilePath = util.resolvePathToRoot(makefilePath);
210+
setMakefilePath(makefilePathSetting);
210211
}
211212
}
212213

213214
let makeDirectory: string | undefined;
214215
export function getMakeDirectory(): string | undefined { return makeDirectory; }
215-
export function setMakeDirectory(dir: string): void { makeDirectory = dir; }
216+
export function setMakeDirectory(dir: string = ''): void { makeDirectory = dir; }
216217
// Read the make working directory path if defined in settings.
217218
// It represents a default to look for if no other makeDirectory is already provided
218219
// in makefile.configurations.makeDirectory.
219220
// TODO: validate and integrate with "-C [DIR_PATH]" passed in makefile.configurations.makeArgs.
220221
async function readMakeDirectory(): Promise<void> {
221-
makeDirectory = await util.getExpandedSetting<string>("makeDirectory");
222-
if (!makeDirectory) {
222+
let makeDirectorySetting: string | undefined = await util.getExpandedSetting<string>("makeDirectory");
223+
if (!makeDirectorySetting) {
223224
logger.message("No folder path to the makefile is defined in the settings file.");
225+
setMakeDirectory();
224226
} else {
225-
makeDirectory = util.resolvePathToRoot(makeDirectory);
227+
setMakeDirectory(makeDirectorySetting);
226228
}
227229
}
228230

@@ -806,7 +808,7 @@ export async function getCommandForConfiguration(configuration: string | undefin
806808
}
807809
}
808810

809-
if (!util.checkFileExistsSync(configurationMakefile)) {
811+
if (!util.checkFileExistsSync(util.resolvePathToRoot(configurationMakefile))) {
810812
logger.message("The makefile entry point was not found. " +
811813
"Make sure it exists at the location defined by makefile.makefilePath, makefile.configurations[].makefilePath, " +
812814
"makefile.makeDirectory, makefile.configurations[].makeDirectory" +
@@ -1305,9 +1307,6 @@ export async function initFromSettings(activation: boolean = false): Promise<voi
13051307

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

13201319
subKey = "makeDirectory";
13211320
let updatedMakeDirectory : string | undefined = await util.getExpandedSetting<string>(subKey);
1322-
if (updatedMakeDirectory) {
1323-
updatedMakeDirectory = util.resolvePathToRoot(updatedMakeDirectory);
1324-
}
13251321
if (updatedMakeDirectory !== makeDirectory) {
13261322
// A change in makefile.makeDirectory should trigger an IntelliSense update
13271323
// only if the extension is not currently reading from a build log.

src/make.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,11 @@ export async function generateParseContent(progress: vscode.Progress<{}>,
467467
makeArgs.push("--question");
468468
logger.messageNoCR("Generating targets information with command: ");
469469
} else {
470+
const makefilePath :string = configuration.getMakefilePath();
470471
makeArgs.push("--dry-run");
472+
makeArgs.push(`--assume-old=${makefilePath}`);
473+
makeArgs.push(makefilePath);
474+
makeArgs.push("AM_MAKEFLAGS=--assume-old=Makefile Makefile");
471475

472476
// If this is not a clean configure, remove --always-make from the arguments list.
473477
// We need to have --always-make in makefile.dryrunSwitches and remove it for not clean configure

0 commit comments

Comments
 (0)