Skip to content

Commit

Permalink
WIP out-of-treee build
Browse files Browse the repository at this point in the history
out-of-tree builds allow multiple configurations to be built
simultaneously from one source tree. Each build configuration exists in
a separate builddir, and the srcdir contains no configuration, object
files or build artifacts.

In an autotools project which uses automake, the Makefiles are object
files, ie they are generated specifically for a particular
configuration.

When building an autotools project out-of-tree, the workspace is the
srcdir, and does not contain a Makefile. instead, the Makefile is in
$makeDirectory which is the builddir.

This commit cleans up the detection of makefile location that is done in
the extension so that the correct makefile is found, even if it lives
out-of-tree/out-of-workspace, has a name other than Makefile/makefile,
an whether or not a file named Makefile also exists in the srcdir.

WIP because something doesn't work and I don't know how to debug (HELP
wanted):

- if a file named "Makefile" also exists in srcdir, the extension
  functions correctly.
- if a file named "Makefile" does NOT exist in the srcdir, but only in
  builddir (as is typical), the extension is asynchronously deactivated
  after doing all the dry-run work.

The deactivation is not expected, it is a result of a $srcdir/Makefile not
existing, but the debugger does not pause the Extension Development Host
when the deactivate() method is called. Instead, the Extension
Development Host quickly reloads before I have a chance to examine the
callstack. The callstack is of course cleared when the Host reloads.

There must be a way to diagnose exactly why deactivate() is called, but
I don't know how.
  • Loading branch information
drok committed Oct 13, 2023
1 parent ba69555 commit 619073e
Showing 1 changed file with 64 additions and 37 deletions.
101 changes: 64 additions & 37 deletions src/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -699,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 @@ -755,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 @@ -808,7 +835,7 @@ export async function getCommandForConfiguration(configuration: string | undefin
}
}

if (!util.checkFileExistsSync(util.resolvePathToRoot(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

0 comments on commit 619073e

Please sign in to comment.