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

WIP - Fix out of tree build #517

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
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
45 changes: 2 additions & 43 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,44 +37,7 @@
"Other"
],
"activationEvents": [
"onCommand:makefile.setBuildConfiguration",
"onCommand:makefile.getConfiguration",
"onCommand:makefile.setBuildTarget",
"onCommand:makefile.getBuildTarget",
"onCommand:makefile.buildTarget",
"onCommand:makefile.buildCleanTarget",
"onCommand:makefile.buildAll",
"onCommand:makefile.buildCleanAll",
"onCommand:makefile.setLaunchConfiguration",
"onCommand:makefile.launchDebug",
"onCommand:makefile.launchRun",
"onCommand:makefile.launchTargetPath",
"onCommand:makefile.getLaunchTargetPath",
"onCommand:makefile.launchTargetFileName",
"onCommand:makefile.getLaunchTargetFileName",
"onCommand:makefile.getLaunchTargetDirectory",
"onCommand:makefile.getLaunchTargetArgs",
"onCommand:makefile.getLaunchTargetArgsConcat",
"onCommand:makefile.makeBaseDirectory",
"onCommand:makefile.configure",
"onCommand:makefile.cleanConfigure",
"onCommand:makefile.preConfigure",
"onCommand:makefile.postConfigure",
"onCommand:makefile.outline.setBuildConfiguration",
"onCommand:makefile.outline.setBuildTarget",
"onCommand:makefile.outline.buildTarget",
"onCommand:makefile.outline.buildCleanTarget",
"onCommand:makefile.outline.setLaunchConfiguration",
"onCommand:makefile.outline.launchDebug",
"onCommand:makefile.outline.launchRun",
"onCommand:makefile.outline.configure",
"onCommand:makefile.outline.cleanConfigure",
"onCommand:makefile.outline.preConfigure",
"onCommand:makefile.outline.postConfigure",
"onCommand:makefile.resetState",
"workspaceContains:**/makefile",
"workspaceContains:**/Makefile",
"workspaceContains:**/GNUmakefile"
"*"
],
"main": "./out/src/extension.js",
"contributes": {
Expand Down Expand Up @@ -606,10 +569,6 @@
"command": "makefile.launchRun",
"when": "makefile:localRunFeature"
},
{
"command": "makefile.setBuildConfiguration",
"when": "makefile:fullFeatureSet"
},
{
drok marked this conversation as resolved.
Show resolved Hide resolved
"command": "makefile.setBuildTarget",
"when": "makefile:fullFeatureSet"
Expand Down Expand Up @@ -718,7 +677,7 @@
},
{
"command": "makefile.outline.setBuildConfiguration",
"when": "makefile:fullFeatureSet && view == makefile.outline && viewItem =~ /nodeType=configuration/",
"when": "view == makefile.outline && viewItem =~ /nodeType=configuration/",
"group": "inline@1"
},
{
Expand Down
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
147 changes: 84 additions & 63 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 @@ -697,39 +699,82 @@ export async function getCommandForConfiguration(configuration: string | undefin
configurationMakeCommand += ".exe";
}

// Add the working directory path via the -C switch.
// makefile.configurations.makeDirectory overwrites makefile.makeDirectory.
let makeDirectoryUsed: string | undefined = makefileConfiguration?.makeDirectory ? util.resolvePathToRoot(makefileConfiguration?.makeDirectory) : makeDirectory;
if (makeDirectoryUsed) {
configurationMakeArgs.push("-C");
configurationMakeArgs.push(`${makeDirectoryUsed}`);
configurationMakefile = makeDirectoryUsed;
}

// Add the makefile path via the -f make switch.
// The make file is in makeDirectory or in the workspace directory,
// and is named "Makefile" or "makefile".
// makefile.configurations.makefilePath overwrites makefile.makefilePath.
configurationMakefile = makefileConfiguration?.makefilePath ? util.resolvePathToRoot(makefileConfiguration?.makefilePath) : makefilePath;
if (configurationMakefile) {
// check if the makefile path is a directory. If so, try adding `Makefile` or `makefile`
if (util.checkDirectoryExistsSync(configurationMakefile)) {
let makeFileTest: string = path.join(configurationMakefile, "Makefile");
if (!util.checkFileExistsSync(makeFileTest)) {
makeFileTest = path.join(configurationMakefile, "makefile");
let makeFileTest: string | undefined;
// filename of makefile relative to makeDirectory
let relativeMakefile: string | undefined;
let makefileExists : boolean = false;
if (makeDirectoryUsed) {
// check if the makefile path is a directory. If so, try adding
// the configuration makefilePath, then the makefilePath, then `Makefile` or `makefile`
if (util.checkDirectoryExistsSync(makeDirectoryUsed)) {
if (makefileConfiguration?.makefilePath) {
makeFileTest = path.join(makeDirectoryUsed, makefileConfiguration?.makefilePath);
relativeMakefile = makefileConfiguration?.makefilePath;
makefileExists = util.checkFileExistsSync(util.resolvePathToRoot(makeFileTest));
if (!makefileExists) {
makeFileTest = makefilePath;
relativeMakefile = util.resolvePathToRoot(makeFileTest);
makefileExists = util.checkFileExistsSync(util.resolvePathToRoot(makeFileTest));
}
}

// if we found the makefile in the directory, set the `configurationMakefile` to the found file path.
if (util.checkFileExistsSync(makeFileTest)) {
configurationMakefile = makeFileTest;
if (!makefileExists) {
makeFileTest = path.join(makeDirectoryUsed, makefilePath);
relativeMakefile = makefilePath;
makefileExists = util.checkFileExistsSync(util.resolvePathToRoot(makeFileTest));
if (!makefileExists) {
if (makefilePath != "Makefile") {
relativeMakefile = "Makefile";
makeFileTest = path.join(makeDirectoryUsed, relativeMakefile);
makefileExists = util.checkFileExistsSync(util.resolvePathToRoot(makeFileTest));
}
if (!makefileExists) {
relativeMakefile = "makefile";
makeFileTest = path.join(makeDirectoryUsed, relativeMakefile);
makefileExists = util.checkFileExistsSync(util.resolvePathToRoot(makeFileTest));
}
}
}
}
}
if (!makefileExists) {
if (!makeDirectoryUsed && makefileConfiguration?.makefilePath) {
relativeMakefile = makefileConfiguration?.makefilePath;
makeFileTest = makefileConfiguration?.makefilePath;
makefileExists = util.checkFileExistsSync(util.resolvePathToRoot(makeFileTest));
}
}
if (!makefileExists) {
makeFileTest = makefilePath;
relativeMakefile = makefilePath;
makefileExists = util.checkFileExistsSync(util.resolvePathToRoot(makeFileTest));
}

// if we found the makefile in the directory, set the `configurationMakefile` to the found file path.
if (makefileExists) {
configurationMakefile = relativeMakefile;
configurationMakeArgs.push("-f");
configurationMakeArgs.push(`${configurationMakefile}`);
configurationMakeArgs.push(`${relativeMakefile}`);
setMakefilePath(relativeMakefile);
setConfigurationMakefile(makeFileTest);
// Need to rethink this (GitHub 59).
// Some repos don't work when we automatically add -C, others don't work when we don't.
// configurationMakeArgs.push("-C");
// configurationMakeArgs.push(path.parse(configurationMakefile).dir);
}

// Add the working directory path via the -C switch.
// makefile.configurations.makeDirectory overwrites makefile.makeDirectory.
let makeDirectoryUsed: string | undefined = makefileConfiguration?.makeDirectory ? util.resolvePathToRoot(makefileConfiguration?.makeDirectory) : makeDirectory;
if (makeDirectoryUsed) {
configurationMakeArgs.push("-C");
configurationMakeArgs.push(`${makeDirectoryUsed}`);
}

// Make sure we append "makefile.configurations[].makeArgs" last, in case the developer wants to overwrite any arguments that the extension
// deduces from the settings. Additionally, for -f/-C, resolve path to root.
if (makefileConfiguration?.makeArgs) {
Expand All @@ -753,22 +798,6 @@ export async function getCommandForConfiguration(configuration: string | undefin
logger.message(`Deduced command '${configurationMakeCommand} ${configurationMakeArgs.join(" ")}' for configuration "${configuration}"`);
}

// Check for makefile path on disk: we search first for any makefile specified via the makefilePath setting,
// then via the makeDirectory setting and then in the root of the workspace. On linux/mac, it often is 'Makefile', so verify that we default to the right filename.
if (!configurationMakefile) {
if (makeDirectoryUsed) {
configurationMakefile = util.resolvePathToRoot(path.join(makeDirectoryUsed, "Makefile"));
if (!util.checkFileExistsSync(configurationMakefile)) {
configurationMakefile = util.resolvePathToRoot(path.join(makeDirectoryUsed, "makefile"));
}
} else {
configurationMakefile = util.resolvePathToRoot("./Makefile");
if (!util.checkFileExistsSync(configurationMakefile)) {
configurationMakefile = util.resolvePathToRoot("./makefile");
}
}
}

// Validation and warnings about properly defining the makefile and make tool.
// These are not needed if the current configuration reads from a build log instead of dry-run output.
let buildLog: string | undefined = getConfigurationBuildLog();
Expand Down Expand Up @@ -806,7 +835,7 @@ export async function getCommandForConfiguration(configuration: string | undefin
}
}

if (!util.checkFileExistsSync(configurationMakefile)) {
if (!makefileExists) {
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 +965,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
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 +1334,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 +1345,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());
Copy link
Contributor

Choose a reason for hiding this comment

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

I see why you moved makeArgs.push(currentAll) to later below... but what about "all" in case of "forTargets"? You did not do that intentionally? When "forTargets" is true, we need a slightly different set of args passed to "make" and if not correct we don't identify correctly all available targets. We need "all" in that case and with your change I don't see where we make sure we add "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.

Recall that in #217, "all" does not work for target discovery.

Removing "all" as an explicit target means make will work on the .DEFAULT_GOAL, whatever that happens to be (should be "all" in most or all autotools projects, but it can be something else, like "sub-make" in #217

This won't fix 217, because in that example the wrapper makefile has no ability to recurse, but it will avoid an unnecesary error ("target 'all' does not exist" in cases like #217). Adding 'all' to this command does nothing, as far as I can see.

Was "all" added for some specific purpose, where the implicit target was not better?


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
Loading