mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-06 17:26:01 +02:00
Add a directory tracker to the CBS Makefile builder (#1071)
Messages such as "make: Entering directory" are now processed so that the scanner info builder knows the correct full path to use for build. Without this code calls to ToolChain.getResourcesFromCommand() would pass in the wrong directory and resources could not be reliably calculated. With the incorrect calculation the scanner info does not get applied to the file correctly and the file cannot be indexed reliably.
This commit is contained in:
parent
3fc221a349
commit
0e5338966d
1 changed files with 83 additions and 0 deletions
|
@ -11,12 +11,16 @@
|
|||
package org.eclipse.cdt.core.build;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Stack;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.ConsoleOutputStream;
|
||||
|
@ -70,6 +74,7 @@ public class StandardBuildConfiguration extends CBuildConfiguration {
|
|||
private String cleanCommand = DEFAULT_CLEAN_COMMAND;
|
||||
private IContainer buildContainer;
|
||||
private IEnvironmentVariable[] envVars;
|
||||
private Stack<String> directoryStack = new Stack<>();
|
||||
|
||||
public StandardBuildConfiguration(IBuildConfiguration config, String name) throws CoreException {
|
||||
super(config, name);
|
||||
|
@ -361,4 +366,82 @@ public class StandardBuildConfiguration extends CBuildConfiguration {
|
|||
}
|
||||
}
|
||||
|
||||
private abstract class DirectoryPatternParser {
|
||||
private final Pattern pattern;
|
||||
|
||||
public DirectoryPatternParser(String regex) {
|
||||
this.pattern = Pattern.compile(regex);
|
||||
}
|
||||
|
||||
public void processLine(String line) {
|
||||
Matcher matcher = pattern.matcher(line);
|
||||
if (matcher.find()) {
|
||||
recordDirectoryChange(matcher);
|
||||
}
|
||||
}
|
||||
|
||||
abstract protected void recordDirectoryChange(Matcher matcher);
|
||||
}
|
||||
|
||||
private final List<DirectoryPatternParser> enteringDirectoryPatterns = List.of( //
|
||||
//
|
||||
new DirectoryPatternParser("make\\[(.*)\\]: Entering directory [`'](.*)'") { //$NON-NLS-1$
|
||||
@Override
|
||||
protected void recordDirectoryChange(Matcher matcher) {
|
||||
int level;
|
||||
try {
|
||||
level = Integer.valueOf(matcher.group(1)).intValue();
|
||||
} catch (NumberFormatException e) {
|
||||
level = 0;
|
||||
}
|
||||
String dir = matcher.group(2);
|
||||
/*
|
||||
* Sometimes make screws up the output, so "leave" events can't be seen. Double-check
|
||||
* level here.
|
||||
*/
|
||||
int parseLevel = directoryStack.size();
|
||||
for (; level < parseLevel; level++) {
|
||||
if (!directoryStack.empty()) {
|
||||
directoryStack.pop();
|
||||
}
|
||||
}
|
||||
directoryStack.push(dir);
|
||||
}
|
||||
},
|
||||
|
||||
// This is emitted by GNU make using options -w or --print-directory.
|
||||
new DirectoryPatternParser("make: Entering directory [`'](.*)'") { //$NON-NLS-1$
|
||||
@Override
|
||||
protected void recordDirectoryChange(Matcher matcher) {
|
||||
String dir = matcher.group(1);
|
||||
directoryStack.push(dir);
|
||||
}
|
||||
},
|
||||
|
||||
//
|
||||
new DirectoryPatternParser("make(\\[.*\\])?: Leaving directory") { //$NON-NLS-1$
|
||||
@Override
|
||||
protected void recordDirectoryChange(Matcher matcher) {
|
||||
if (!directoryStack.empty()) {
|
||||
directoryStack.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
@Override
|
||||
public boolean processLine(String line) {
|
||||
enteringDirectoryPatterns.forEach(p -> p.processLine(line));
|
||||
return super.processLine(line);
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getBuildDirectoryURI() throws CoreException {
|
||||
if (!directoryStack.isEmpty()) {
|
||||
return Path.of(directoryStack.peek()).toUri();
|
||||
} else {
|
||||
return super.getBuildDirectoryURI();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue