Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDoug Schaefer2017-09-28 00:27:40 +0000
committerDoug Schaefer2017-09-28 17:42:58 +0000
commit5228d193004a8001632385127f5b45a3a5243f7e (patch)
tree58b418f969732f94b12054aa58bba475e579bbd2 /build/org.eclipse.cdt.build.gcc.core
parent80dc8d9c2517e738be2e16a6f98375266259bd0d (diff)
downloadorg.eclipse.cdt-5228d193004a8001632385127f5b45a3a5243f7e.tar.gz
org.eclipse.cdt-5228d193004a8001632385127f5b45a3a5243f7e.tar.xz
org.eclipse.cdt-5228d193004a8001632385127f5b45a3a5243f7e.zip
UI for adding toolchains for Core Build. New Generic Target Wizard.
Provide a way to add new toolchains. Also start of UI to allow for reordering them to help with toolchain selection for targets. New Generic Target Wizard for the new wizard2 extension point for the Launch Bar Target UI. Change-Id: I60635ab27dad5b69df72c339337473183dcf711a
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