Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuildConfiguration.java')
-rw-r--r--core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuildConfiguration.java261
1 files changed, 82 insertions, 179 deletions
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuildConfiguration.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuildConfiguration.java
index d0b6c275aa6..039e1a4518b 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuildConfiguration.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuildConfiguration.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2015, 2019 QNX Software Systems and others.
+ * Copyright (c) 2015, 2022 QNX Software Systems and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -10,16 +10,10 @@
*******************************************************************************/
package org.eclipse.cdt.core.build;
-import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.lang.reflect.Type;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
@@ -28,16 +22,17 @@ import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
-import java.util.Properties;
import java.util.Map.Entry;
+import java.util.Properties;
import java.util.Set;
+import java.util.stream.Collectors;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.CommandLauncherManager;
+import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.cdt.core.IConsoleParser;
import org.eclipse.cdt.core.IConsoleParser2;
import org.eclipse.cdt.core.IMarkerGenerator;
@@ -61,12 +56,14 @@ import org.eclipse.cdt.core.parser.ExtendedScannerInfo;
import org.eclipse.cdt.core.parser.IExtendedScannerInfo;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.core.parser.IScannerInfoChangeListener;
-import org.eclipse.cdt.core.parser.IncludeExportPatterns;
import org.eclipse.cdt.core.resources.IConsole;
+import org.eclipse.cdt.internal.core.BuildRunnerHelper;
+import org.eclipse.cdt.internal.core.ConsoleOutputSniffer;
import org.eclipse.cdt.internal.core.build.Messages;
import org.eclipse.cdt.internal.core.model.BinaryRunner;
import org.eclipse.cdt.internal.core.model.CModelManager;
-import org.eclipse.cdt.internal.core.parser.ParserSettings2;
+import org.eclipse.cdt.internal.core.scannerinfo.ExtendedScannerInfoSerializer;
+import org.eclipse.cdt.internal.core.scannerinfo.IExtendedScannerInfoDeserializer;
import org.eclipse.cdt.utils.CommandLineUtil;
import org.eclipse.cdt.utils.spawner.EnvironmentReader;
import org.eclipse.core.filesystem.URIUtil;
@@ -92,12 +89,6 @@ import org.osgi.service.prefs.Preferences;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonDeserializationContext;
-import com.google.gson.JsonDeserializer;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParseException;
/**
* Root class for CDT build configurations. Provides access to the build
@@ -124,6 +115,8 @@ public abstract class CBuildConfiguration extends PlatformObject implements ICBu
private final Map<IResource, List<IScannerInfoChangeListener>> scannerInfoListeners = new HashMap<>();
private ScannerInfoCache scannerInfoCache;
+ private ICommandLauncher launcher;
+
protected CBuildConfiguration(IBuildConfiguration config, String name) throws CoreException {
this.config = config;
this.name = name;
@@ -496,7 +489,8 @@ public abstract class CBuildConfiguration extends PlatformObject implements ICBu
.write(String.format(Messages.CBuildConfiguration_CommandNotFound, commands.get(0)));
return null;
}
- commands.set(0, commandPath.toString());
+ IPath cmd = new org.eclipse.core.runtime.Path(commandPath.toString());
+ List<String> args = commands.subList(1, commands.size());
// check if includes have been removed/refreshed and scanner info refresh is needed
boolean needRefresh = CommandLauncherManager.getInstance().checkIfIncludesChanged(this);
@@ -505,18 +499,28 @@ public abstract class CBuildConfiguration extends PlatformObject implements ICBu
t.setProperty(NEED_REFRESH, Boolean.valueOf(needRefresh).toString());
}
- ProcessBuilder processBuilder = new ProcessBuilder(commands).directory(buildDirectory.toFile());
- // Override environment variables
- Map<String, String> environment = processBuilder.environment();
+ // Generate environment block before launching process
+ launcher = CommandLauncherManager.getInstance().getCommandLauncher(this);
+ Properties envProps = launcher.getEnvironment();
+ HashMap<String, String> environment = envProps.entrySet().stream()
+ .collect(Collectors.toMap(e -> String.valueOf(e.getKey()), e -> String.valueOf(e.getValue()),
+ (prev, next) -> next, HashMap::new));
for (IEnvironmentVariable envVar : envVars) {
environment.put(envVar.getName(), envVar.getValue());
}
setBuildEnvironment(environment);
- process = processBuilder.start();
+ launcher.setProject(getProject());
+ process = launcher.execute(cmd, args.toArray(new String[0]), BuildRunnerHelper.envMapToEnvp(environment),
+ buildDirectory, monitor);
}
return process;
}
+ /**
+ * @return The exit code of the build process.
+ *
+ * @deprecated use {@link #watchProcess(IConsole, IProgressMonitor)} or {@link #watchProcess(IConsoleParser[], IProgressMonitor)} instead
+ */
@Deprecated
protected int watchProcess(Process process, IConsoleParser[] consoleParsers, IConsole console)
throws CoreException {
@@ -528,110 +532,42 @@ public abstract class CBuildConfiguration extends PlatformObject implements ICBu
}
/**
+ * @return The exit code of the build process.
* @since 6.4
+ *
+ * @deprecated use {@link #watchProcess(IConsole, IProgressMonitor)} instead and pass in a monitor
*/
+ @Deprecated
protected int watchProcess(Process process, IConsole console) throws CoreException {
- Thread t1 = new ReaderThread(process.getInputStream(), console.getOutputStream());
- t1.start();
- Thread t2 = new ReaderThread(process.getErrorStream(), console.getErrorStream());
- t2.start();
- try {
- int rc = process.waitFor();
- // Allow reader threads the chance to process all output to console
- while (t1.isAlive()) {
- Thread.sleep(100);
- }
- while (t2.isAlive()) {
- Thread.sleep(100);
- }
- return rc;
- } catch (InterruptedException e) {
- CCorePlugin.log(e);
- return -1;
- }
+ return watchProcess(console, new NullProgressMonitor());
}
/**
+ * @return The exit code of the build process.
+ * @since 7.5
+ */
+ protected int watchProcess(IConsole console, IProgressMonitor monitor) throws CoreException {
+ return launcher.waitAndRead(console.getInfoStream(), console.getErrorStream(), monitor);
+ }
+
+ /**
+ * @return The exit code of the build process.
* @since 6.4
+ *
+ * @deprecated use {@link #watchProcess(IConsoleParser[], IProgressMonitor)} instead and pass in a monitor
*/
+ @Deprecated
protected int watchProcess(Process process, IConsoleParser[] consoleParsers) throws CoreException {
- Thread t1 = new ReaderThread(this, process.getInputStream(), consoleParsers);
- t1.start();
- Thread t2 = new ReaderThread(this, process.getErrorStream(), consoleParsers);
- t2.start();
- try {
- int rc = process.waitFor();
- // Allow reader threads the chance to process all output to console
- while (t1.isAlive()) {
- Thread.sleep(100);
- }
- while (t2.isAlive()) {
- Thread.sleep(100);
- }
- return rc;
- } catch (InterruptedException e) {
- CCorePlugin.log(e);
- return -1;
- }
+ return watchProcess(consoleParsers, new NullProgressMonitor());
}
- private static class ReaderThread extends Thread {
- CBuildConfiguration config;
- private final BufferedReader in;
- private final IConsoleParser[] consoleParsers;
- private final PrintStream out;
-
- public ReaderThread(CBuildConfiguration config, InputStream in, IConsoleParser[] consoleParsers) {
- this.config = config;
- this.in = new BufferedReader(new InputStreamReader(in));
- this.out = null;
- this.consoleParsers = consoleParsers;
- }
-
- public ReaderThread(InputStream in, OutputStream out) {
- this.in = new BufferedReader(new InputStreamReader(in));
- this.out = new PrintStream(out);
- this.consoleParsers = null;
- this.config = null;
- }
-
- @Override
- public void run() {
- List<Job> jobList = new ArrayList<>();
- try {
- for (String line = in.readLine(); line != null; line = in.readLine()) {
- if (consoleParsers != null) {
- for (IConsoleParser consoleParser : consoleParsers) {
- // Synchronize to avoid interleaving of lines
- synchronized (consoleParser) {
- // if we have an IConsoleParser2, use the processLine method that
- // takes a job list (Container Build support)
- if (consoleParser instanceof IConsoleParser2) {
- ((IConsoleParser2) consoleParser).processLine(line, jobList);
- } else {
- consoleParser.processLine(line);
- }
- }
- }
- }
- if (out != null) {
- out.println(line);
- }
- }
- for (Job j : jobList) {
- try {
- j.join();
- } catch (InterruptedException e) {
- // ignore
- }
- }
- if (config != null) {
- config.shutdown();
- }
- } catch (IOException e) {
- CCorePlugin.log(e);
- }
- }
+ /**
+ * @return The exit code of the build process.
+ * @since 7.5
+ */
+ protected int watchProcess(IConsoleParser[] consoleParsers, IProgressMonitor monitor) throws CoreException {
+ ConsoleOutputSniffer sniffer = new ConsoleOutputSniffer(consoleParsers);
+ return launcher.waitAndRead(sniffer.getOutputStream(), sniffer.getErrorStream(), monitor);
}
private File getScannerInfoCacheFile() {
@@ -639,63 +575,6 @@ public abstract class CBuildConfiguration extends PlatformObject implements ICBu
.append(getProject().getName()).append(name + ".json").toFile(); //$NON-NLS-1$
}
- private static class IExtendedScannerInfoCreator implements JsonDeserializer<IExtendedScannerInfo> {
- @Override
- public IExtendedScannerInfo deserialize(JsonElement element, Type arg1, JsonDeserializationContext arg2)
- throws JsonParseException {
- JsonObject infoObj = element.getAsJsonObject();
-
- Map<String, String> definedSymbols = null;
- if (infoObj.has("definedSymbols")) { //$NON-NLS-1$
- JsonObject definedSymbolsObj = infoObj.get("definedSymbols").getAsJsonObject(); //$NON-NLS-1$
- definedSymbols = new HashMap<>();
- for (Entry<String, JsonElement> entry : definedSymbolsObj.entrySet()) {
- definedSymbols.put(entry.getKey(), entry.getValue().getAsString());
- }
- }
-
- String[] includePaths = null;
- if (infoObj.has("includePaths")) { //$NON-NLS-1$
- JsonArray includePathsArray = infoObj.get("includePaths").getAsJsonArray(); //$NON-NLS-1$
- List<String> includePathsList = new ArrayList<>(includePathsArray.size());
- for (Iterator<JsonElement> i = includePathsArray.iterator(); i.hasNext();) {
- includePathsList.add(i.next().getAsString());
- }
- includePaths = includePathsList.toArray(new String[includePathsList.size()]);
- }
-
- IncludeExportPatterns includeExportPatterns = null;
- if (infoObj.has("includeExportPatterns")) { //$NON-NLS-1$
- JsonObject includeExportPatternsObj = infoObj.get("includeExportPatterns").getAsJsonObject(); //$NON-NLS-1$
- String exportPattern = null;
- if (includeExportPatternsObj.has("includeExportPattern")) { //$NON-NLS-1$
- exportPattern = includeExportPatternsObj.get("includeExportPattern") //$NON-NLS-1$
- .getAsJsonObject().get("pattern").getAsString(); //$NON-NLS-1$
- }
-
- String beginExportsPattern = null;
- if (includeExportPatternsObj.has("includeBeginExportPattern")) { //$NON-NLS-1$
- beginExportsPattern = includeExportPatternsObj.get("includeBeginExportPattern") //$NON-NLS-1$
- .getAsJsonObject().get("pattern").getAsString(); //$NON-NLS-1$
- }
-
- String endExportsPattern = null;
- if (includeExportPatternsObj.has("includeEndExportPattern")) { //$NON-NLS-1$
- endExportsPattern = includeExportPatternsObj.get("includeEndExportPattern") //$NON-NLS-1$
- .getAsJsonObject().get("pattern").getAsString(); //$NON-NLS-1$
- }
-
- includeExportPatterns = new IncludeExportPatterns(exportPattern, beginExportsPattern,
- endExportsPattern);
- }
-
- ExtendedScannerInfo info = new ExtendedScannerInfo(definedSymbols, includePaths);
- info.setIncludeExportPatterns(includeExportPatterns);
- info.setParserSettings(new ParserSettings2());
- return info;
- }
- }
-
/**
* @since 6.1
*/
@@ -705,15 +584,14 @@ public abstract class CBuildConfiguration extends PlatformObject implements ICBu
File cacheFile = getScannerInfoCacheFile();
if (cacheFile.exists()) {
try (FileReader reader = new FileReader(cacheFile)) {
- GsonBuilder gsonBuilder = new GsonBuilder();
- gsonBuilder.registerTypeAdapter(IExtendedScannerInfo.class, new IExtendedScannerInfoCreator());
- Gson gson = gsonBuilder.create();
+ Gson gson = createGson();
scannerInfoCache = gson.fromJson(reader, ScannerInfoCache.class);
} catch (IOException e) {
CCorePlugin.log(e);
- scannerInfoCache = new ScannerInfoCache();
}
- } else {
+ }
+
+ if (scannerInfoCache == null) {
scannerInfoCache = new ScannerInfoCache();
}
scannerInfoCache.initCache();
@@ -721,6 +599,14 @@ public abstract class CBuildConfiguration extends PlatformObject implements ICBu
}
}
+ private Gson createGson() {
+ GsonBuilder gsonBuilder = new GsonBuilder();
+ gsonBuilder.registerTypeAdapter(IExtendedScannerInfo.class, new IExtendedScannerInfoDeserializer());
+ gsonBuilder.registerTypeAdapter(ExtendedScannerInfo.class, new ExtendedScannerInfoSerializer());
+ Gson gson = gsonBuilder.create();
+ return gson;
+ }
+
/**
* @since 6.1
*/
@@ -736,7 +622,7 @@ public abstract class CBuildConfiguration extends PlatformObject implements ICBu
}
try (FileWriter writer = new FileWriter(getScannerInfoCacheFile())) {
- Gson gson = new Gson();
+ Gson gson = createGson();
synchronized (scannerInfoLock) {
gson.toJson(scannerInfoCache, writer);
}
@@ -787,7 +673,24 @@ public abstract class CBuildConfiguration extends PlatformObject implements ICBu
synchronized (scannerInfoLock) {
info = scannerInfoCache.getScannerInfo(resource);
}
- if (info == null || info.getIncludePaths().length == 0) {
+ // Following is a kludge to fix Bug 579668 whereby sometimes a timing
+ // bug occurs and scanner info for a project that specifies a container target
+ // has not initialized the include paths correctly to point to copied includes
+ // from the image target. We check to see if org.eclipse.cdt.docker.launcher is
+ // found in the include paths which is the .plugin directory where we copy headers
+ // to in the .metadata folder.
+ boolean needsFixing = false;
+ if (info != null && info.getIncludePaths().length > 0 && toolChain != null
+ && toolChain.getId().startsWith("gcc-img-sha")) { //$NON-NLS-1$
+ needsFixing = true;
+ for (String includePath : info.getIncludePaths()) {
+ if (includePath.contains("org.eclipse.cdt.docker.launcher")) { //$NON-NLS-1$
+ needsFixing = false;
+ break;
+ }
+ }
+ }
+ if (info == null || info.getIncludePaths().length == 0 || needsFixing) {
ICElement celement = CCorePlugin.getDefault().getCoreModel().create(resource);
if (celement instanceof ITranslationUnit) {
try {

Back to the top