Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'build/org.eclipse.cdt.build.gcc.core')
-rw-r--r--build/org.eclipse.cdt.build.gcc.core/META-INF/MANIFEST.MF3
-rw-r--r--build/org.eclipse.cdt.build.gcc.core/plugin.xml4
-rw-r--r--build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/GCCToolChain.java249
-rw-r--r--build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/GCCUserToolChainProvider.java219
-rw-r--r--build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/Activator.java6
-rw-r--r--build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/GCCPathToolChainProvider.java104
-rw-r--r--build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/Messages.java25
-rw-r--r--build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/messages.properties11
8 files changed, 477 insertions, 144 deletions
diff --git a/build/org.eclipse.cdt.build.gcc.core/META-INF/MANIFEST.MF b/build/org.eclipse.cdt.build.gcc.core/META-INF/MANIFEST.MF
index 07c5abe6db2..182b4d4d518 100644
--- a/build/org.eclipse.cdt.build.gcc.core/META-INF/MANIFEST.MF
+++ b/build/org.eclipse.cdt.build.gcc.core/META-INF/MANIFEST.MF
@@ -7,7 +7,8 @@ Bundle-Activator: org.eclipse.cdt.build.gcc.core.internal.Activator
Bundle-Vendor: Eclipse CDT
Require-Bundle: org.eclipse.core.runtime,
org.eclipse.core.resources;bundle-version="3.10.0",
- org.eclipse.cdt.core;bundle-version="5.12.0"
+ org.eclipse.cdt.core;bundle-version="5.12.0",
+ com.google.gson
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ActivationPolicy: lazy
Export-Package: org.eclipse.cdt.build.gcc.core
diff --git a/build/org.eclipse.cdt.build.gcc.core/plugin.xml b/build/org.eclipse.cdt.build.gcc.core/plugin.xml
index 596c7623f67..036b2b8f894 100644
--- a/build/org.eclipse.cdt.build.gcc.core/plugin.xml
+++ b/build/org.eclipse.cdt.build.gcc.core/plugin.xml
@@ -11,6 +11,10 @@
class="org.eclipse.cdt.build.gcc.core.internal.Msys2ToolChainProvider"
id="org.eclipse.cdt.build.gcc.core.msys2Provider">
</provider>
+ <provider
+ class="org.eclipse.cdt.build.gcc.core.GCCUserToolChainProvider"
+ id="org.eclipse.cdt.build.gcc.core.provider.user">
+ </provider>
</extension>
</plugin>
diff --git a/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/GCCToolChain.java b/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/GCCToolChain.java
index 51373ff7d84..f5cd6b21b64 100644
--- a/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/GCCToolChain.java
+++ b/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/GCCToolChain.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2015 QNX Software Systems and others.
+ * Copyright (c) 2015, 2017 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -16,10 +16,10 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -45,23 +45,21 @@ import org.eclipse.core.runtime.PlatformObject;
/**
* The GCC toolchain. This is the base class for all GCC toolchains. It
- * represents GCC as found on the user's PATH. It can be overriden to change
+ * represents GCC as found on the user's PATH. It can be overridden to change
* environment variable settings.
*/
public class GCCToolChain extends PlatformObject implements IToolChain {
private final IToolChainProvider provider;
private final String id;
- private final String version;
- private final String name;
- private final Path[] path;
- private final String prefix;
+ private final Path path;
private final IEnvironmentVariable pathVar;
private final IEnvironmentVariable[] envVars;
private final Map<String, String> properties = new HashMap<>();
+
+ private String cCommand;
+ private String cppCommand;
private String[] commands;
- private String[] cCommands;
- private String[] cppCommands;
public GCCToolChain(IToolChainProvider provider, String id, String version) {
this(provider, id, version, null, null);
@@ -74,12 +72,8 @@ public class GCCToolChain extends PlatformObject implements IToolChain {
public GCCToolChain(IToolChainProvider provider, String id, String version, Path[] path, String prefix) {
this.provider = provider;
this.id = id;
- this.version = version;
- this.name = id + " - " + version; //$NON-NLS-1$
- this.path = path;
- this.prefix = prefix != null ? prefix : ""; //$NON-NLS-1$
- if (path != null) {
+ if (path != null && path.length > 0) {
StringBuilder pathString = new StringBuilder();
for (int i = 0; i < path.length; ++i) {
pathString.append(path[i].toString());
@@ -87,15 +81,67 @@ public class GCCToolChain extends PlatformObject implements IToolChain {
pathString.append(File.pathSeparator);
}
}
- pathVar = new EnvironmentVariable("PATH", pathString.toString(), IEnvironmentVariable.ENVVAR_PREPEND, //$NON-NLS-1$
+ this.path = path[0];
+ this.pathVar = new EnvironmentVariable("PATH", pathString.toString(), IEnvironmentVariable.ENVVAR_PREPEND, //$NON-NLS-1$
File.pathSeparator);
- envVars = new IEnvironmentVariable[] { pathVar };
+ this.envVars = new IEnvironmentVariable[] { pathVar };
} else {
- pathVar = null;
- envVars = new IEnvironmentVariable[0];
+ this.path = null;
+ this.pathVar = null;
+ this.envVars = new IEnvironmentVariable[0];
}
}
+ public GCCToolChain(IToolChainProvider provider, Path pathToToolChain, String arch,
+ IEnvironmentVariable[] envVars) {
+ this.provider = provider;
+ this.path = pathToToolChain;
+
+ // We include arch in the id since a compiler can support multiple arches.
+ StringBuilder idBuilder = new StringBuilder("gcc-"); //$NON-NLS-1$
+ if (arch != null) {
+ idBuilder.append(arch);
+ }
+ idBuilder.append('-');
+ idBuilder.append(pathToToolChain.toString());
+ this.id = idBuilder.toString();
+
+ IEnvironmentVariable pathVar = null;
+ if (envVars != null) {
+ for (IEnvironmentVariable envVar : envVars) {
+ if (envVar.getName().equalsIgnoreCase("PATH")) { //$NON-NLS-1$
+ pathVar = envVar;
+ }
+ }
+ }
+
+ if (pathVar == null) {
+ // Make one with the directory containing out tool
+ String name;
+ // if (System.getenv("Path") != null) { //$NON-NLS-1$
+ // name = "Path"; //$NON-NLS-1$
+ // } else {
+ name = "PATH"; //$NON-NLS-1$
+ // }
+ pathVar = new EnvironmentVariable(name, this.path.getParent().toString(),
+ IEnvironmentVariable.ENVVAR_PREPEND, File.pathSeparator);
+ if (envVars == null) {
+ envVars = new IEnvironmentVariable[] { pathVar };
+ } else {
+ IEnvironmentVariable[] newVars = new IEnvironmentVariable[envVars.length + 1];
+ System.arraycopy(envVars, 0, newVars, 0, envVars.length);
+ newVars[envVars.length] = pathVar;
+ envVars = newVars;
+ }
+ }
+ this.pathVar = pathVar;
+ this.envVars = envVars;
+ }
+
+ public Path getPath() {
+ return path;
+ }
+
@Override
public IToolChainProvider getProvider() {
return provider;
@@ -108,12 +154,30 @@ public class GCCToolChain extends PlatformObject implements IToolChain {
@Override
public String getVersion() {
- return version;
+ return ""; //$NON-NLS-1$
}
@Override
public String getName() {
- return name;
+ StringBuilder name = new StringBuilder("GCC"); //$NON-NLS-1$
+ String os = getProperty(ATTR_OS);
+ if (os != null) {
+ name.append(' ');
+ name.append(os);
+ }
+
+ String arch = getProperty(ATTR_ARCH);
+ if (arch != null) {
+ name.append(' ');
+ name.append(arch);
+ }
+
+ if (path != null) {
+ name.append(' ');
+ name.append(path.toString());
+ }
+
+ return name.toString();
}
@Override
@@ -122,18 +186,24 @@ public class GCCToolChain extends PlatformObject implements IToolChain {
if (value != null) {
return value;
}
-
+
// By default, we're a local GCC
switch (key) {
case ATTR_OS:
return Platform.getOS();
case ATTR_ARCH:
- return Platform.getOSArch();
+ if (Platform.getOS().equals(getProperty(ATTR_OS))) {
+ return Platform.getOSArch();
+ }
}
-
+
return null;
}
+ public Map<String, String> getProperties() {
+ return properties;
+ }
+
@Override
public void setProperty(String key, String value) {
properties.put(key, value);
@@ -359,7 +429,7 @@ public class GCCToolChain extends PlatformObject implements IToolChain {
@Override
public IEnvironmentVariable getVariable(String name) {
- if (path != null && name.equals("PATH")) { //$NON-NLS-1$
+ if (pathVar != null && (name.equals("PATH") || name.equals("Path"))) { //$NON-NLS-1$ //$NON-NLS-2$
return pathVar;
}
return null;
@@ -377,20 +447,11 @@ public class GCCToolChain extends PlatformObject implements IToolChain {
}
if (Platform.getOS().equals(Platform.OS_WIN32)) {
- if (!command.toString().endsWith(".exe")) { //$NON-NLS-1$
+ if (!command.toString().endsWith(".exe") && !command.toString().endsWith(".bat")) { //$NON-NLS-1$ //$NON-NLS-2$
command = Paths.get(command.toString() + ".exe"); //$NON-NLS-1$
}
}
- if (path != null) {
- for (Path p : path) {
- Path c = p.resolve(command);
- if (Files.isExecutable(c)) {
- return c;
- }
- }
- }
-
// Look for it in the path environment var
IEnvironmentVariable myPath = getVariable("PATH"); //$NON-NLS-1$
String path = myPath != null ? myPath.getValue() : System.getenv("PATH"); //$NON-NLS-1$
@@ -405,44 +466,35 @@ public class GCCToolChain extends PlatformObject implements IToolChain {
return null;
}
- private boolean isLocal() {
- return Platform.getOS().equals(properties.get(ATTR_OS))
- && Platform.getOSArch().equals(properties.get(ATTR_ARCH));
+ private void initCompileCommands() {
+ if (commands == null) {
+ cCommand = path.getFileName().toString();
+ cppCommand = null;
+ if (cCommand.contains("gcc")) { //$NON-NLS-1$
+ cppCommand = cCommand.replace("gcc", "g++"); //$NON-NLS-1$ //$NON-NLS-2$
+ commands = new String[] { cCommand, cppCommand };
+ } else if (cCommand.contains("clang")) { //$NON-NLS-1$
+ cppCommand = cCommand.replace("clang", "clang++"); //$NON-NLS-1$ //$NON-NLS-2$
+ commands = new String[] { cCommand, cppCommand };
+ } else {
+ commands = new String[] { cCommand };
+ }
+ }
}
@Override
public String[] getCompileCommands() {
- if (commands == null) {
- boolean local = isLocal();
-
- List<String> cCommandsList = new ArrayList<>(Arrays.asList(prefix + "gcc", prefix + "clang", prefix + "cc")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- if (local) {
- cCommandsList.addAll(Arrays.asList("gcc", "clang", "cc")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- }
- cCommands = cCommandsList.toArray(new String[cCommandsList.size()]);
-
- List<String> cppCommandsList = new ArrayList<>(Arrays.asList(prefix + "g++", prefix + "clang++", prefix + "c++")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- if (local) {
- cppCommandsList.addAll(Arrays.asList("g++", "clang++", "c++")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- }
- cppCommands = cppCommandsList.toArray(new String[cppCommandsList.size()]);
-
- List<String> commandsList = new ArrayList<>(cCommandsList);
- commandsList.addAll(cppCommandsList);
- commands = commandsList.toArray(new String[commandsList.size()]);
- }
+ initCompileCommands();
return commands;
}
@Override
public String[] getCompileCommands(ILanguage language) {
- if (commands == null) {
- getCompileCommands();
- }
+ initCompileCommands();
if (GPPLanguage.ID.equals(language.getId())) {
- return cppCommands;
+ return new String[] { cppCommand != null ? cppCommand : cCommand };
} else if (GCCLanguage.ID.equals(language.getId())) {
- return cCommands;
+ return new String[] { cCommand };
} else {
return new String[0];
}
@@ -498,4 +550,79 @@ public class GCCToolChain extends PlatformObject implements IToolChain {
return newCommand;
}
+ public static class GCCInfo {
+ private static final Pattern versionPattern = Pattern.compile(".*(gcc|LLVM) version .*"); //$NON-NLS-1$
+ private static final Pattern targetPattern = Pattern.compile("Target: (.*)"); //$NON-NLS-1$
+
+ public String target;
+ public String version;
+
+ public GCCInfo(String command) throws IOException {
+ this(command, null);
+ }
+
+ public GCCInfo(String command, Map<String, String> env) throws IOException {
+ ProcessBuilder builder = new ProcessBuilder(new String[] { command, "-v" }).redirectErrorStream(true); //$NON-NLS-1$
+ if (env != null) {
+ Map<String, String> procEnv = builder.environment();
+ for (Entry<String, String> entry : env.entrySet()) {
+ if ("PATH".equals(entry.getKey())) { //$NON-NLS-1$
+ // prepend the path
+ String path = entry.getValue() + File.pathSeparator + procEnv.get("PATH"); //$NON-NLS-1$
+ procEnv.put("PATH", path); //$NON-NLS-1$
+ } else {
+ // replace
+ procEnv.put(entry.getKey(), entry.getValue());
+ }
+ }
+ }
+ Process proc = builder.start();
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()))) {
+ for (String line = reader.readLine(); line != null; line = reader.readLine()) {
+ Matcher versionMatcher = versionPattern.matcher(line);
+ if (versionMatcher.matches()) {
+ version = line.trim();
+ continue;
+ }
+ Matcher targetMatcher = targetPattern.matcher(line);
+ if (targetMatcher.matches()) {
+ target = targetMatcher.group(1);
+ continue;
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ GCCInfo other = (GCCInfo) obj;
+ if (target == null) {
+ if (other.target != null)
+ return false;
+ } else if (!target.equals(other.target))
+ return false;
+ if (version == null) {
+ if (other.version != null)
+ return false;
+ } else if (!version.equals(other.version))
+ return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((target == null) ? 0 : target.hashCode());
+ result = prime * result + ((version == null) ? 0 : version.hashCode());
+ return result;
+ }
+
+ }
}
diff --git a/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/GCCUserToolChainProvider.java b/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/GCCUserToolChainProvider.java
new file mode 100644
index 00000000000..b7b25e9d993
--- /dev/null
+++ b/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/GCCUserToolChainProvider.java
@@ -0,0 +1,219 @@
+/*******************************************************************************
+ * Copyright (c) 2017 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.cdt.build.gcc.core;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.cdt.build.gcc.core.internal.Activator;
+import org.eclipse.cdt.build.gcc.core.internal.Messages;
+import org.eclipse.cdt.core.build.IToolChain;
+import org.eclipse.cdt.core.build.IToolChainManager;
+import org.eclipse.cdt.core.build.IUserToolChainProvider;
+import org.eclipse.cdt.core.envvar.EnvironmentVariable;
+import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+
+public class GCCUserToolChainProvider implements IUserToolChainProvider {
+
+ public static final String PROVIDER_ID = "org.eclipse.cdt.build.gcc.core.provider.user"; //$NON-NLS-1$
+
+ private static final String ARCH = "arch"; //$NON-NLS-1$
+ private static final String DELIMITER = "delimiter"; //$NON-NLS-1$
+ private static final String ENVIRONMENT = "environment"; //$NON-NLS-1$
+ private static final String ID = "id"; //$NON-NLS-1$
+ private static final String NAME = "name"; //$NON-NLS-1$
+ private static final String OPERATION = "operation"; //$NON-NLS-1$
+ private static final String PATH = "path"; //$NON-NLS-1$
+ private static final String PROPERTIES = "properties"; //$NON-NLS-1$
+ private static final String VALUE = "value"; //$NON-NLS-1$
+
+ private IToolChainManager manager;
+ private JsonArray toolChains;
+
+ @Override
+ public String getId() {
+ return PROVIDER_ID;
+ }
+
+ private File getJsonFile() {
+ return Activator.getPlugin().getStateLocation().append("toolchains.json").toFile(); //$NON-NLS-1$
+ }
+
+ @Override
+ public void init(IToolChainManager manager) throws CoreException {
+ this.manager = manager;
+
+ // Load up the magic JSON file which contains our toolchain defs
+ try {
+ File jsonFile = getJsonFile();
+ if (jsonFile.exists()) {
+ toolChains = new JsonParser().parse(new FileReader(jsonFile)).getAsJsonArray();
+ for (JsonElement element : toolChains) {
+ JsonObject tc = element.getAsJsonObject();
+ String arch;
+ if (tc.has(ARCH)) {
+ arch = tc.get(ARCH).getAsString();
+ } else {
+ arch = null;
+ }
+ Path path = Paths.get(tc.get(PATH).getAsString());
+ IEnvironmentVariable[] envvars = null;
+ if (tc.has(ENVIRONMENT)) {
+ List<IEnvironmentVariable> envlist = new ArrayList<>();
+ for (JsonElement var : tc.get(ENVIRONMENT).getAsJsonArray()) {
+ JsonObject varobj = var.getAsJsonObject();
+ String name = varobj.get(NAME).getAsString();
+ int operation = varobj.get(OPERATION).getAsInt();
+ String value = null;
+ if (varobj.has(VALUE)) {
+ value = varobj.get(VALUE).getAsString();
+ }
+ String delimiter = null;
+ if (varobj.has(DELIMITER)) {
+ delimiter = varobj.get(DELIMITER).getAsString();
+ }
+ envlist.add(new EnvironmentVariable(name, value, operation, delimiter));
+ }
+ envvars = envlist.toArray(new IEnvironmentVariable[0]);
+ }
+
+ GCCToolChain gcc = new GCCToolChain(this, path, arch, envvars);
+ if (tc.has(PROPERTIES)) {
+ for (JsonElement prop : tc.get(PROPERTIES).getAsJsonArray()) {
+ JsonObject propobj = prop.getAsJsonObject();
+ gcc.setProperty(propobj.get(NAME).getAsString(), propobj.get(VALUE).getAsString());
+ }
+ }
+ manager.addToolChain(gcc);
+ }
+ }
+ } catch (IOException | IllegalStateException e) {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), Messages.GCCUserToolChainProvider_Loading, e));
+ }
+ }
+
+ @Override
+ public void addToolChain(IToolChain toolChain) throws CoreException {
+ if (!(toolChain instanceof GCCToolChain)) {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), Messages.GCCUserToolChainProvider_NotOurs));
+ }
+
+ GCCToolChain gcc = (GCCToolChain) toolChain;
+
+ // Persist the toolchain
+ if (toolChains == null) {
+ toolChains = new JsonArray();
+ }
+
+ JsonObject newtc = new JsonObject();
+ toolChains.add(newtc);
+
+ newtc.addProperty(ID, gcc.getId());
+ newtc.addProperty(ARCH, gcc.getProperty(IToolChain.ATTR_ARCH));
+ newtc.addProperty(PATH, gcc.getPath().toString());
+
+ Map<String, String> properties = gcc.getProperties();
+ if (properties != null && !properties.isEmpty()) {
+ JsonArray props = new JsonArray();
+ newtc.add(PROPERTIES, props);
+ for (Entry<String, String> entry : gcc.getProperties().entrySet()) {
+ JsonObject prop = new JsonObject();
+ props.add(prop);
+ prop.addProperty(NAME, entry.getKey());
+ prop.addProperty(VALUE, entry.getValue());
+ }
+ }
+
+ IEnvironmentVariable[] envvars = gcc.getVariables();
+ if (envvars != null && envvars.length > 0) {
+ JsonArray env = new JsonArray();
+ newtc.add(ENVIRONMENT, env);
+ for (IEnvironmentVariable var : gcc.getVariables()) {
+ JsonObject envvar = new JsonObject();
+ env.add(envvar);
+
+ envvar.addProperty(NAME, var.getName());
+ envvar.addProperty(OPERATION, var.getOperation());
+ String value = var.getValue();
+ if (value != null) {
+ envvar.addProperty(VALUE, value);
+ }
+
+ String delimiter = var.getDelimiter();
+ if (delimiter != null) {
+ envvar.addProperty(DELIMITER, delimiter);
+ }
+ }
+ }
+
+ try {
+ saveJsonFile();
+ } catch (IOException e) {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), Messages.GCCUserToolChainProvider_Saving, e));
+ }
+
+ manager.addToolChain(toolChain);
+ }
+
+ @Override
+ public void removeToolChain(IToolChain toolChain) throws CoreException {
+ if (toolChains != null) {
+ String id = toolChain.getId();
+ JsonArray copy = new JsonArray();
+ copy.addAll(toolChains);
+ for (JsonElement element : copy) {
+ JsonObject tc = element.getAsJsonObject();
+ if (id.equals(tc.get(ID).getAsString())) {
+ toolChains.remove(element);
+ }
+ }
+
+ try {
+ saveJsonFile();
+ } catch (IOException e) {
+ throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), Messages.GCCUserToolChainProvider_Saving1, e));
+ }
+ }
+ manager.removeToolChain(toolChain);
+ }
+
+ @Override
+ public IToolChain getToolChain(String id) throws CoreException {
+ Collection<IToolChain> tcs = manager.getToolChains(PROVIDER_ID, id);
+ if (tcs.isEmpty()) {
+ return null;
+ } else {
+ return tcs.iterator().next();
+ }
+ }
+
+ private void saveJsonFile() throws IOException {
+ try (Writer writer = new FileWriter(getJsonFile())) {
+ writer.write(new Gson().toJson(toolChains));
+ }
+ }
+}
diff --git a/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/Activator.java b/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/Activator.java
index c9f26e7d2d9..d50a8b19fdb 100644
--- a/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/Activator.java
+++ b/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/Activator.java
@@ -18,10 +18,12 @@ public class Activator extends Plugin {
private static Plugin plugin;
+ @Override
public void start(BundleContext bundleContext) throws Exception {
plugin = this;
}
+ @Override
public void stop(BundleContext bundleContext) throws Exception {
plugin = null;
}
@@ -48,4 +50,8 @@ public class Activator extends Plugin {
return ref != null ? context.getService(ref) : null;
}
+ public static Plugin getPlugin() {
+ return plugin;
+ }
+
}
diff --git a/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/GCCPathToolChainProvider.java b/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/GCCPathToolChainProvider.java
index 11944cbca88..d44607af45b 100644
--- a/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/GCCPathToolChainProvider.java
+++ b/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/GCCPathToolChainProvider.java
@@ -7,17 +7,13 @@
*******************************************************************************/
package org.eclipse.cdt.build.gcc.core.internal;
-import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
-import java.io.InputStreamReader;
-import java.nio.file.Path;
-import java.util.HashSet;
-import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.cdt.build.gcc.core.GCCToolChain;
+import org.eclipse.cdt.build.gcc.core.GCCToolChain.GCCInfo;
import org.eclipse.cdt.core.build.IToolChain;
import org.eclipse.cdt.core.build.IToolChainManager;
import org.eclipse.cdt.core.build.IToolChainProvider;
@@ -28,12 +24,9 @@ import org.eclipse.core.runtime.Platform;
*/
public class GCCPathToolChainProvider implements IToolChainProvider {
- private static final String ID = "org.eclipse.cdt.build.gcc.core.gccPathProvider"; //$NON-NLS-1$
+ public static final String ID = "org.eclipse.cdt.build.gcc.core.gccPathProvider"; //$NON-NLS-1$
- private static final Pattern gppPattern = Pattern.compile("(.*-)?(g\\+\\+|clang\\+\\+)"); //$NON-NLS-1$
- private static final Pattern gccPattern = Pattern.compile("(.*-)?(gcc|clang)"); //$NON-NLS-1$
- private static final Pattern versionPattern = Pattern.compile(".*(gcc|LLVM) version .*"); //$NON-NLS-1$
- private static final Pattern targetPattern = Pattern.compile("Target: (.*)"); //$NON-NLS-1$
+ private static final Pattern gccPattern = Pattern.compile("(.*-)?((gcc|clang)(\\.exe)?)"); //$NON-NLS-1$
@Override
public String getId() {
@@ -42,86 +35,33 @@ public class GCCPathToolChainProvider implements IToolChainProvider {
@Override
public void init(IToolChainManager manager) {
- Set<String> names = new HashSet<>();
-
String path = System.getenv("PATH"); //$NON-NLS-1$
for (String dirStr : path.split(File.pathSeparator)) {
File dir = new File(dirStr);
if (dir.isDirectory()) {
- for (String file : dir.list()) {
- String prefix = null;
- boolean hasAltCmd = false;
-
- Matcher matcher = gccPattern.matcher(file);
+ for (File file : dir.listFiles()) {
+ Matcher matcher = gccPattern.matcher(file.getName());
if (matcher.matches()) {
- prefix = matcher.group(1);
- String cmd = matcher.group(2);
- String altFile = prefix + (cmd.startsWith("g") ? "g++" : "clang++"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- File altCmd = new File(dir, altFile);
- hasAltCmd = altCmd.exists() && altCmd.canExecute();
- }
- else {
- matcher = gppPattern.matcher(file);
- if (matcher.matches()) {
- prefix = matcher.group(1);
- String cmd = matcher.group(2);
- String altFile = prefix + (cmd.startsWith("g") ? "gcc" : "clang"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- File altCmd = new File(dir, altFile);
- hasAltCmd = altCmd.exists() && altCmd.canExecute();
- }
- }
- if (prefix != null && hasAltCmd) {
- String command = dirStr + File.separatorChar + file;
try {
- Process proc = new ProcessBuilder(new String[] { command, "-v" }).redirectErrorStream(true) //$NON-NLS-1$
- .start();
- String version = null;
- String target = null;
- try (BufferedReader reader = new BufferedReader(
- new InputStreamReader(proc.getInputStream()))) {
- for (String line = reader.readLine(); line != null; line = reader.readLine()) {
- Matcher versionMatcher = versionPattern.matcher(line);
- if (versionMatcher.matches()) {
- version = line.trim();
- continue;
- }
- Matcher targetMatcher = targetPattern.matcher(line);
- if (targetMatcher.matches()) {
- target = targetMatcher.group(1);
- continue;
- }
- }
- }
- if (target != null && version != null) {
- String name = target + " - " + version; //$NON-NLS-1$
- if (!names.contains(name)) {
- names.add(name);
- GCCToolChain toolChain = new GCCToolChain(this, target, version,
- new Path[] { dir.toPath() }, prefix);
- String[] tuple = target.split("-"); //$NON-NLS-1$
- if (tuple.length > 2) {
- // Arch
- if ("x86_64".equals(tuple[0])) { //$NON-NLS-1$
- toolChain.setProperty(IToolChain.ATTR_ARCH, tuple[0]);
- } else {
- toolChain.setProperty(IToolChain.ATTR_ARCH, "x86"); // default //$NON-NLS-1$
- }
+ GCCInfo info = new GCCInfo(file.toString());
+ if (info.target != null && info.version != null) {
+ String[] tuple = info.target.split("-"); //$NON-NLS-1$
+ if (tuple.length > 2) {
+ GCCToolChain gcc = new GCCToolChain(this, file.toPath(), tuple[0], null);
- // OS
- switch (tuple[1]) {
- case "w64": //$NON-NLS-1$
- toolChain.setProperty(IToolChain.ATTR_OS, Platform.OS_WIN32);
- break;
- case "linux": //$NON-NLS-1$
- toolChain.setProperty(IToolChain.ATTR_OS, Platform.OS_LINUX);
- break;
- case "apple": //$NON-NLS-1$
- toolChain.setProperty(IToolChain.ATTR_OS, Platform.OS_MACOSX);
- break;
- }
+ // OS
+ switch (tuple[1]) {
+ case "w64": //$NON-NLS-1$
+ gcc.setProperty(IToolChain.ATTR_OS, Platform.OS_WIN32);
+ break;
+ case "linux": //$NON-NLS-1$
+ gcc.setProperty(IToolChain.ATTR_OS, Platform.OS_LINUX);
+ break;
+ case "apple": //$NON-NLS-1$
+ gcc.setProperty(IToolChain.ATTR_OS, Platform.OS_MACOSX);
+ break;
}
- toolChain.setProperty(IToolChain.ATTR_PACKAGE, "system"); //$NON-NLS-1$
- manager.addToolChain(toolChain);
+ manager.addToolChain(gcc);
}
}
} catch (IOException e) {
diff --git a/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/Messages.java b/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/Messages.java
new file mode 100644
index 00000000000..a4018d3fc24
--- /dev/null
+++ b/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/Messages.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2017 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.cdt.build.gcc.core.internal;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.cdt.build.gcc.core.internal.messages"; //$NON-NLS-1$
+ public static String GCCUserToolChainProvider_Loading;
+ public static String GCCUserToolChainProvider_NotOurs;
+ public static String GCCUserToolChainProvider_Saving;
+ public static String GCCUserToolChainProvider_Saving1;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/messages.properties b/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/messages.properties
new file mode 100644
index 00000000000..baaae03267d
--- /dev/null
+++ b/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/messages.properties
@@ -0,0 +1,11 @@
+################################################################################
+# Copyright (c) 2017 QNX Software Systems and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+################################################################################
+GCCUserToolChainProvider_Loading=Loading toolchains file
+GCCUserToolChainProvider_NotOurs=Not our toolchain
+GCCUserToolChainProvider_Saving=Saving toolchains file
+GCCUserToolChainProvider_Saving1=Saving toolchains file

Back to the top