mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-25 01:45:33 +02:00
Modernize Arduino plug-ins. Adjust APIs to suite.
Change-Id: Ic877c8f0992874e647d4b464502165d7bd3ebe0e
This commit is contained in:
parent
b2300cbcfe
commit
7139dc2f1e
60 changed files with 1264 additions and 1864 deletions
|
@ -1,20 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?eclipse version="3.4"?>
|
||||
<plugin>
|
||||
<extension
|
||||
point="org.eclipse.cdt.core.toolChainType">
|
||||
<toolChainType
|
||||
class="org.eclipse.cdt.build.gcc.core.GCCToolChainType"
|
||||
id="org.eclipse.cdt.build.gcc">
|
||||
</toolChainType>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.cdt.core.toolChainProvider">
|
||||
<provider
|
||||
class="org.eclipse.cdt.build.gcc.core.internal.GCCPathToolChainProvider">
|
||||
class="org.eclipse.cdt.build.gcc.core.internal.GCCPathToolChainProvider"
|
||||
id="org.eclipse.cdt.build.gcc.core.gccPathProvider">
|
||||
</provider>
|
||||
<provider
|
||||
class="org.eclipse.cdt.build.gcc.core.internal.Msys2ToolChainProvider">
|
||||
class="org.eclipse.cdt.build.gcc.core.internal.Msys2ToolChainProvider"
|
||||
id="org.eclipse.cdt.build.gcc.core.msys2Provider">
|
||||
</provider>
|
||||
</extension>
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ import java.util.regex.Pattern;
|
|||
import org.eclipse.cdt.build.gcc.core.internal.Activator;
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.build.IToolChain;
|
||||
import org.eclipse.cdt.core.build.IToolChainType;
|
||||
import org.eclipse.cdt.core.build.IToolChainProvider;
|
||||
import org.eclipse.cdt.core.envvar.EnvironmentVariable;
|
||||
import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
|
||||
import org.eclipse.cdt.core.parser.ExtendedScannerInfo;
|
||||
|
@ -41,45 +41,47 @@ import org.eclipse.core.runtime.Platform;
|
|||
import org.eclipse.core.runtime.PlatformObject;
|
||||
|
||||
/**
|
||||
* The GCC toolchain. Placing it in cdt.core for now.
|
||||
*
|
||||
* TODO move to it's own plug-in.
|
||||
*
|
||||
* @since 5.12
|
||||
* 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 environment variable settings.
|
||||
*/
|
||||
public class GCCToolChain extends PlatformObject implements IToolChain {
|
||||
|
||||
private final IToolChainType type;
|
||||
private final IToolChainProvider provider;
|
||||
private final String name;
|
||||
private final String command;
|
||||
private String version;
|
||||
private String target;
|
||||
private Path path;
|
||||
private IEnvironmentVariable pathVar;
|
||||
private IEnvironmentVariable[] envVars;
|
||||
private final Path path;
|
||||
private final String prefix;
|
||||
private final IEnvironmentVariable pathVar;
|
||||
private final IEnvironmentVariable[] envVars;
|
||||
|
||||
public GCCToolChain(IToolChainType type, Path path, String command) {
|
||||
this.type = type;
|
||||
this.command = command;
|
||||
getVersion(path.resolve(command).toString());
|
||||
this.name = command + '-' + version;
|
||||
this.path = path;
|
||||
protected String[] compileCommands;
|
||||
|
||||
pathVar = new EnvironmentVariable("PATH", path.toString(), IEnvironmentVariable.ENVVAR_PREPEND, //$NON-NLS-1$
|
||||
File.pathSeparator);
|
||||
envVars = new IEnvironmentVariable[] { pathVar };
|
||||
public GCCToolChain(IToolChainProvider provider, String name) {
|
||||
this(provider, name, null, null);
|
||||
}
|
||||
|
||||
protected GCCToolChain(IToolChainType type, String name, String command) {
|
||||
this.type = type;
|
||||
public GCCToolChain(IToolChainProvider provider, String name, Path path) {
|
||||
this(provider, name, path, null);
|
||||
}
|
||||
|
||||
public GCCToolChain(IToolChainProvider provider, String name, Path path, String prefix) {
|
||||
this.provider = provider;
|
||||
this.name = name;
|
||||
this.command = command;
|
||||
// TODO need to pull the other info out of preferences
|
||||
this.path = path;
|
||||
this.prefix = prefix;
|
||||
|
||||
if (path != null) {
|
||||
pathVar = new EnvironmentVariable("PATH", path.toString(), IEnvironmentVariable.ENVVAR_PREPEND, //$NON-NLS-1$
|
||||
File.pathSeparator);
|
||||
envVars = new IEnvironmentVariable[] { pathVar };
|
||||
} else {
|
||||
pathVar = null;
|
||||
envVars = new IEnvironmentVariable[0];
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IToolChainType getType() {
|
||||
return type;
|
||||
public IToolChainProvider getProvider() {
|
||||
return provider;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -89,8 +91,7 @@ public class GCCToolChain extends PlatformObject implements IToolChain {
|
|||
|
||||
@Override
|
||||
public String getProperty(String key) {
|
||||
// TODO for now assume it's a local gcc
|
||||
// Later use the target, especially to find out arch
|
||||
// this class represents a local toolchain
|
||||
switch (key) {
|
||||
case ATTR_OS:
|
||||
return Platform.getOS();
|
||||
|
@ -100,36 +101,6 @@ public class GCCToolChain extends PlatformObject implements IToolChain {
|
|||
return null;
|
||||
}
|
||||
|
||||
private static Pattern versionPattern = Pattern.compile(".*(gcc|LLVM) version .*"); //$NON-NLS-1$
|
||||
private static Pattern targetPattern = Pattern.compile("Target: (.*)"); //$NON-NLS-1$
|
||||
|
||||
private void getVersion(String command) {
|
||||
try {
|
||||
Process proc = new ProcessBuilder(new String[] { command, "-v" }).redirectErrorStream(true) //$NON-NLS-1$
|
||||
.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Activator.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
protected void addDiscoveryOptions(List<String> command) {
|
||||
command.add("-E"); //$NON-NLS-1$
|
||||
command.add("-P"); //$NON-NLS-1$
|
||||
|
@ -142,12 +113,12 @@ public class GCCToolChain extends PlatformObject implements IToolChain {
|
|||
IExtendedScannerInfo baseScannerInfo, IResource resource, URI buildDirectoryURI) {
|
||||
try {
|
||||
Path buildDirectory = Paths.get(buildDirectoryURI);
|
||||
|
||||
|
||||
List<String> commandLine = new ArrayList<>();
|
||||
if (command.isAbsolute()) {
|
||||
commandLine.add(command.toString());
|
||||
} else {
|
||||
commandLine.add(path.resolve(command).toString());
|
||||
commandLine.add(getCommandPath(command).toString());
|
||||
}
|
||||
|
||||
if (baseScannerInfo != null && baseScannerInfo.getIncludePaths() != null) {
|
||||
|
@ -160,12 +131,18 @@ public class GCCToolChain extends PlatformObject implements IToolChain {
|
|||
commandLine.addAll(Arrays.asList(args));
|
||||
|
||||
// Change output to stdout
|
||||
boolean haveOut = false;
|
||||
for (int i = 0; i < commandLine.size() - 1; ++i) {
|
||||
if (commandLine.get(i).equals("-o")) { //$NON-NLS-1$
|
||||
commandLine.set(i + 1, "-"); //$NON-NLS-1$
|
||||
haveOut = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!haveOut) {
|
||||
commandLine.add("-o"); //$NON-NLS-1$
|
||||
commandLine.add("-"); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
// Change source file to a tmp file (needs to be empty)
|
||||
Path tmpFile = null;
|
||||
|
@ -259,7 +236,7 @@ public class GCCToolChain extends PlatformObject implements IToolChain {
|
|||
|
||||
@Override
|
||||
public IEnvironmentVariable getVariable(String name) {
|
||||
if (pathVar.getName().equals(name)) {
|
||||
if (path != null && name.equals("PATH")) { //$NON-NLS-1$
|
||||
return pathVar;
|
||||
}
|
||||
return null;
|
||||
|
@ -271,30 +248,46 @@ public class GCCToolChain extends PlatformObject implements IToolChain {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Path getCommandPath(String command) {
|
||||
return path.resolve(command);
|
||||
public Path getCommandPath(Path command) {
|
||||
if (command.isAbsolute()) {
|
||||
return command;
|
||||
}
|
||||
|
||||
if (path != null) {
|
||||
return path.resolve(command);
|
||||
}
|
||||
|
||||
// Look for it in the path environment var
|
||||
String path = System.getenv("PATH"); //$NON-NLS-1$
|
||||
for (String entry : path.split(File.pathSeparator)) {
|
||||
Path entryPath = Paths.get(entry);
|
||||
Path cmdPath = entryPath.resolve(command);
|
||||
if (Files.isExecutable(cmdPath)) {
|
||||
return cmdPath;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getCompileCommands() {
|
||||
if (compileCommands == null) {
|
||||
List<String> cmds = new ArrayList<>();
|
||||
for (String cmd : new String[] { "gcc", "g++", "clang", "clang++" }) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
||||
cmd = prefix != null ? cmd : prefix + cmd;
|
||||
Path cmdPath = getCommandPath(Paths.get(cmd));
|
||||
if (cmdPath != null) {
|
||||
cmds.add(cmd);
|
||||
}
|
||||
}
|
||||
compileCommands = cmds.toArray(new String[compileCommands.length]);
|
||||
}
|
||||
return compileCommands;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IResource[] getResourcesFromCommand(String[] cmd, URI buildDirectoryURI) {
|
||||
// Make sure this is our command
|
||||
boolean found = false;
|
||||
for (String arg : cmd) {
|
||||
if (arg.startsWith("-")) { //$NON-NLS-1$
|
||||
break;
|
||||
}
|
||||
Path cmdPath = Paths.get(arg);
|
||||
if (cmdPath.getFileName().toString().equals(command)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
// not our command
|
||||
return null;
|
||||
}
|
||||
|
||||
// Start at the back looking for arguments
|
||||
List<IResource> resources = new ArrayList<>();
|
||||
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
|
||||
|
@ -308,7 +301,7 @@ public class GCCToolChain extends PlatformObject implements IToolChain {
|
|||
resources.add(resource);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return resources.toArray(new IResource[resources.size()]);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015 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 org.eclipse.cdt.core.build.IToolChain;
|
||||
import org.eclipse.cdt.core.build.IToolChainType;
|
||||
|
||||
public class GCCToolChainType implements IToolChainType {
|
||||
|
||||
public static final String ID = "org.eclipse.cdt.build.gcc"; //$NON-NLS-1$
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IToolChain getToolChain(String name) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -11,98 +11,53 @@ import java.io.BufferedReader;
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
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.GCCToolChainType;
|
||||
import org.eclipse.cdt.core.build.IToolChain;
|
||||
import org.eclipse.cdt.core.build.IToolChainManager;
|
||||
import org.eclipse.cdt.core.build.IToolChainProvider;
|
||||
import org.eclipse.cdt.core.build.IToolChainType;
|
||||
|
||||
/**
|
||||
* Finds gcc and clang on the path.
|
||||
*/
|
||||
public class GCCPathToolChainProvider implements IToolChainProvider {
|
||||
|
||||
private static Pattern gccPattern = Pattern.compile("(.*-)?(gcc|g\\+\\+|clang|clang\\+\\+)(-[0-9].*)?"); //$NON-NLS-1$
|
||||
private static final String ID = "org.eclipse.cdt.build.gcc.core.gccPathProvider"; //$NON-NLS-1$
|
||||
|
||||
private static final Pattern gccPattern = Pattern.compile("(.*-)?(gcc|g\\+\\+|clang|clang\\+\\+)"); //$NON-NLS-1$
|
||||
|
||||
@Override
|
||||
public Collection<IToolChain> getToolChains() {
|
||||
IToolChainManager manager = Activator.getService(IToolChainManager.class);
|
||||
IToolChainType type = null;
|
||||
|
||||
List<IToolChain> toolChains = new ArrayList<>();
|
||||
|
||||
String path = null;
|
||||
for (Entry<String, String> entry : System.getenv().entrySet()) {
|
||||
if (entry.getKey().equalsIgnoreCase("PATH")) { //$NON-NLS-1$
|
||||
path = entry.getValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (path != null) {
|
||||
Map<String, List<String>> installs = new HashMap<>();
|
||||
|
||||
for (String dirStr : path.split(File.pathSeparator)) {
|
||||
File dir = new File(dirStr);
|
||||
if (dir.isDirectory()) {
|
||||
for (String file : dir.list()) {
|
||||
Matcher matcher = gccPattern.matcher(file);
|
||||
if (matcher.matches()) {
|
||||
String prefix = matcher.group(1);
|
||||
String suffix = matcher.group(3);
|
||||
String command = dirStr + File.separatorChar + file;
|
||||
String version = getVersion(command);
|
||||
if (version != null) {
|
||||
List<String> commands = installs.get(version);
|
||||
if (commands == null) {
|
||||
commands = new ArrayList<>();
|
||||
installs.put(version, commands);
|
||||
}
|
||||
commands.add(command);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Entry<String, List<String>> entry : installs.entrySet()) {
|
||||
String version = entry.getKey();
|
||||
String searchStr;
|
||||
if (version.contains("LLVM")) {
|
||||
searchStr = "clang++";
|
||||
} else {
|
||||
searchStr = "g++";
|
||||
}
|
||||
|
||||
for (String command : entry.getValue()) {
|
||||
if (command.contains(searchStr)) {
|
||||
if (type == null) {
|
||||
type = manager.getToolChainType(GCCToolChainType.ID);
|
||||
}
|
||||
Path commandPath = Paths.get(command);
|
||||
toolChains.add(
|
||||
new GCCToolChain(type, commandPath.getParent(), commandPath.getFileName().toString()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return toolChains;
|
||||
public String getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(IToolChainManager manager) {
|
||||
Set<String> versions = 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()) {
|
||||
Matcher matcher = gccPattern.matcher(file);
|
||||
if (matcher.matches()) {
|
||||
String prefix = matcher.group(1);
|
||||
String command = dirStr + File.separatorChar + file;
|
||||
String version = getVersion(command);
|
||||
if (version != null && !versions.contains(version)) {
|
||||
versions.add(version);
|
||||
manager.addToolChain(new GCCToolChain(this, version, dir.toPath(), prefix));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Pattern versionPattern = Pattern.compile(".*(gcc|LLVM) version .*"); //$NON-NLS-1$
|
||||
private static Pattern targetPattern = Pattern.compile("Target: (.*)"); //$NON-NLS-1$
|
||||
|
||||
|
|
|
@ -9,30 +9,28 @@ package org.eclipse.cdt.build.gcc.core.internal;
|
|||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.build.gcc.core.GCCToolChain;
|
||||
import org.eclipse.cdt.build.gcc.core.GCCToolChainType;
|
||||
import org.eclipse.cdt.core.build.IToolChain;
|
||||
import org.eclipse.cdt.core.build.IToolChainManager;
|
||||
import org.eclipse.cdt.core.build.IToolChainProvider;
|
||||
import org.eclipse.cdt.core.build.IToolChainType;
|
||||
import org.eclipse.cdt.utils.WindowsRegistry;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
|
||||
public class Msys2ToolChainProvider implements IToolChainProvider {
|
||||
|
||||
private static final String ID = "org.eclipse.cdt.build.gcc.core.msys2Provider"; //$NON-NLS-1$
|
||||
|
||||
@Override
|
||||
public Collection<IToolChain> getToolChains() {
|
||||
public String getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(IToolChainManager manager) {
|
||||
if (Platform.getOS().equals(Platform.OS_WIN32)) {
|
||||
WindowsRegistry registry = WindowsRegistry.getRegistry();
|
||||
String uninstallKey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; //$NON-NLS-1$
|
||||
String subkey;
|
||||
List<IToolChain> toolChains = null;
|
||||
IToolChainType type = null;
|
||||
for (int i = 0; (subkey = registry.getCurrentUserKeyName(uninstallKey, i)) != null; i++) {
|
||||
String compKey = uninstallKey + '\\' + subkey;
|
||||
String displayName = registry.getCurrentUserValue(compKey, "DisplayName"); //$NON-NLS-1$
|
||||
|
@ -40,24 +38,11 @@ public class Msys2ToolChainProvider implements IToolChainProvider {
|
|||
String installLocation = registry.getCurrentUserValue(compKey, "InstallLocation"); //$NON-NLS-1$
|
||||
Path gccPath = Paths.get(installLocation + "\\mingw64\\bin\\gcc.exe"); //$NON-NLS-1$
|
||||
if (Files.exists(gccPath)) {
|
||||
if (toolChains == null) {
|
||||
toolChains = new ArrayList<>();
|
||||
}
|
||||
if (type == null) {
|
||||
type = Activator.getService(IToolChainManager.class).getToolChainType(GCCToolChainType.ID);
|
||||
}
|
||||
toolChains.add(
|
||||
new GCCToolChain(type, gccPath.getParent(), gccPath.getFileName().toString()));
|
||||
manager.addToolChain(new GCCToolChain(this, "msys2.x86_64", gccPath.getParent())); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (toolChains != null) {
|
||||
return toolChains;
|
||||
}
|
||||
}
|
||||
// default
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -35,7 +35,8 @@ public class CMakeBuildConfiguration extends CBuildConfiguration {
|
|||
}
|
||||
|
||||
public CMakeBuildConfiguration(IBuildConfiguration config, String name, IToolChain toolChain) {
|
||||
super(config, name, toolChain);
|
||||
super(config, name);
|
||||
setToolChain(toolChain);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -685,7 +685,6 @@
|
|||
<extension-point id="ProblemMarkerFilter" name="%problemMarkerFilter.name" schema="schema/ProblemMarkerFilter.exsd"/>
|
||||
<extension-point id="buildConfigProvider" name="buildConfigProvider" schema="schema/buildConfigProvider.exsd"/>
|
||||
<extension-point id="toolChainProvider" name="Tool Chain Provider" schema="schema/toolChainProvider.exsd"/>
|
||||
<extension-point id="toolChainType" name="Tool Chain Type" schema="schema/toolChainType.exsd"/>
|
||||
|
||||
<extension
|
||||
point="org.eclipse.cdt.core.templateProcessTypes">
|
||||
|
|
|
@ -1,102 +1,109 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!-- Schema file written by PDE -->
|
||||
<schema targetNamespace="org.eclipse.cdt.core" xmlns="http://www.w3.org/2001/XMLSchema">
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.schema plugin="org.eclipse.cdt.core" id="ToolChainProvider" name="Tool Chain Provider"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
A toolchain provider provides automatically discovered toolchains when requested. Providers have enablement to make sure they aren't called unless there's a good chance they have toolchains to offer.
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<element name="extension">
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.element />
|
||||
</appInfo>
|
||||
</annotation>
|
||||
<complexType>
|
||||
<sequence minOccurs="1" maxOccurs="unbounded">
|
||||
<element ref="provider"/>
|
||||
</sequence>
|
||||
<attribute name="point" type="string" use="required">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
</annotation>
|
||||
</attribute>
|
||||
<attribute name="id" type="string">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
</annotation>
|
||||
</attribute>
|
||||
<attribute name="name" type="string">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
<appInfo>
|
||||
<meta.attribute translatable="true"/>
|
||||
</appInfo>
|
||||
</annotation>
|
||||
</attribute>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name="provider">
|
||||
<complexType>
|
||||
<attribute name="class" type="string" use="required">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
<appInfo>
|
||||
<meta.attribute kind="java" basedOn=":org.eclipse.cdt.core.build.IToolChainProvider"/>
|
||||
</appInfo>
|
||||
</annotation>
|
||||
</attribute>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.section type="since"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
[Enter the first release in which this extension point appears.]
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.section type="examples"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
[Enter extension point usage example here.]
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.section type="apiinfo"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
[Enter API information here.]
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.section type="implementation"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
[Enter information about supplied implementation of this extension point.]
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
|
||||
</schema>
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!-- Schema file written by PDE -->
|
||||
<schema targetNamespace="org.eclipse.cdt.core" xmlns="http://www.w3.org/2001/XMLSchema">
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.schema plugin="org.eclipse.cdt.core" id="ToolChainProvider" name="Tool Chain Provider"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
A toolchain provider provides automatically discovered toolchains when requested. Providers have enablement to make sure they aren't called unless there's a good chance they have toolchains to offer.
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<element name="extension">
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.element />
|
||||
</appInfo>
|
||||
</annotation>
|
||||
<complexType>
|
||||
<sequence minOccurs="1" maxOccurs="unbounded">
|
||||
<element ref="provider"/>
|
||||
</sequence>
|
||||
<attribute name="point" type="string" use="required">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
</annotation>
|
||||
</attribute>
|
||||
<attribute name="id" type="string">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
</annotation>
|
||||
</attribute>
|
||||
<attribute name="name" type="string">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
<appInfo>
|
||||
<meta.attribute translatable="true"/>
|
||||
</appInfo>
|
||||
</annotation>
|
||||
</attribute>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name="provider">
|
||||
<complexType>
|
||||
<attribute name="id" type="string" use="required">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
</annotation>
|
||||
</attribute>
|
||||
<attribute name="class" type="string" use="required">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
<appInfo>
|
||||
<meta.attribute kind="java" basedOn=":org.eclipse.cdt.core.build.IToolChainProvider"/>
|
||||
</appInfo>
|
||||
</annotation>
|
||||
</attribute>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.section type="since"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
[Enter the first release in which this extension point appears.]
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.section type="examples"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
[Enter extension point usage example here.]
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.section type="apiinfo"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
[Enter API information here.]
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.section type="implementation"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
[Enter information about supplied implementation of this extension point.]
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
|
||||
</schema>
|
||||
|
|
|
@ -1,127 +0,0 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!-- Schema file written by PDE -->
|
||||
<schema targetNamespace="org.eclipse.cdt.core" xmlns="http://www.w3.org/2001/XMLSchema">
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.schema plugin="org.eclipse.cdt.core" id="ToolChainType" name="Tool Chain Type"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
Defines toolchain type extensions. Toolchain types provide toolchain objects for a given type of toolchain. They are passed properties that are stored for the toolchain.
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<element name="extension">
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.element />
|
||||
</appInfo>
|
||||
</annotation>
|
||||
<complexType>
|
||||
<sequence minOccurs="1" maxOccurs="unbounded">
|
||||
<element ref="toolChainType"/>
|
||||
</sequence>
|
||||
<attribute name="point" type="string" use="required">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
</annotation>
|
||||
</attribute>
|
||||
<attribute name="id" type="string">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
</annotation>
|
||||
</attribute>
|
||||
<attribute name="name" type="string">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
<appInfo>
|
||||
<meta.attribute translatable="true"/>
|
||||
</appInfo>
|
||||
</annotation>
|
||||
</attribute>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name="toolChainType">
|
||||
<complexType>
|
||||
<sequence minOccurs="0" maxOccurs="unbounded">
|
||||
<element ref="targetType"/>
|
||||
</sequence>
|
||||
<attribute name="id" type="string" use="required">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
</annotation>
|
||||
</attribute>
|
||||
<attribute name="class" type="string" use="required">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
<appInfo>
|
||||
<meta.attribute kind="java" basedOn=":org.eclipse.cdt.core.build.IToolChainType"/>
|
||||
</appInfo>
|
||||
</annotation>
|
||||
</attribute>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name="targetType">
|
||||
<complexType>
|
||||
<attribute name="id" type="string" use="required">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
<appInfo>
|
||||
<meta.attribute kind="identifier" basedOn="org.eclipse.launchbar.core.launchTargetTypes/launchTargetType/@id"/>
|
||||
</appInfo>
|
||||
</annotation>
|
||||
</attribute>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.section type="since"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
[Enter the first release in which this extension point appears.]
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.section type="examples"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
[Enter extension point usage example here.]
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.section type="apiinfo"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
[Enter API information here.]
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.section type="implementation"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
[Enter information about supplied implementation of this extension point.]
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
|
||||
</schema>
|
|
@ -439,7 +439,7 @@ public class CCorePlugin extends Plugin {
|
|||
* @see #setOptions
|
||||
*/
|
||||
public static HashMap<String, String> getDefaultOptions() {
|
||||
HashMap<String, String> defaultOptions = new HashMap<String, String>(10);
|
||||
HashMap<String, String> defaultOptions = new HashMap<>(10);
|
||||
|
||||
// see #initializeDefaultPluginPreferences() for changing default
|
||||
// settings
|
||||
|
@ -502,7 +502,7 @@ public class CCorePlugin extends Plugin {
|
|||
* @see CCorePlugin#getDefaultOptions
|
||||
*/
|
||||
public static HashMap<String, String> getOptions() {
|
||||
HashMap<String, String> options = new HashMap<String, String>(10);
|
||||
HashMap<String, String> options = new HashMap<>(10);
|
||||
|
||||
// see #initializeDefaultPluginPreferences() for changing default
|
||||
// settings
|
||||
|
@ -728,7 +728,7 @@ public class CCorePlugin extends Plugin {
|
|||
ICDescriptor cdesc = getCProjectDescription(project, false);
|
||||
ICExtensionReference[] cextensions = cdesc.get(BINARY_PARSER_UNIQ_ID, true);
|
||||
if (cextensions.length > 0) {
|
||||
ArrayList<IBinaryParser> list = new ArrayList<IBinaryParser>(cextensions.length);
|
||||
ArrayList<IBinaryParser> list = new ArrayList<>(cextensions.length);
|
||||
for (ICExtensionReference ref : cextensions) {
|
||||
IBinaryParser parser = null;
|
||||
try {
|
||||
|
@ -1538,11 +1538,15 @@ public class CCorePlugin extends Plugin {
|
|||
* @noreference This method is not intended to be referenced by clients.
|
||||
*/
|
||||
public static void log(Throwable e) {
|
||||
String msg = e.getMessage();
|
||||
if (msg == null) {
|
||||
log("Error", e); //$NON-NLS-1$
|
||||
if (e instanceof CoreException) {
|
||||
log(((CoreException) e).getStatus());
|
||||
} else {
|
||||
log("Error: " + msg, e); //$NON-NLS-1$
|
||||
String msg = e.getMessage();
|
||||
if (msg == null) {
|
||||
log("Error", e); //$NON-NLS-1$
|
||||
} else {
|
||||
log("Error: " + msg, e); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,9 @@ import org.eclipse.cdt.core.ProblemMarkerInfo;
|
|||
import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
|
||||
import org.eclipse.cdt.core.model.CoreModel;
|
||||
import org.eclipse.cdt.core.model.ICModelMarker;
|
||||
import org.eclipse.cdt.core.model.ICProject;
|
||||
import org.eclipse.cdt.core.model.IOutputEntry;
|
||||
import org.eclipse.cdt.core.model.IPathEntry;
|
||||
import org.eclipse.cdt.core.parser.IExtendedScannerInfo;
|
||||
import org.eclipse.cdt.core.parser.IScannerInfo;
|
||||
import org.eclipse.cdt.core.parser.IScannerInfoChangeListener;
|
||||
|
@ -67,37 +70,11 @@ public abstract class CBuildConfiguration extends PlatformObject
|
|||
|
||||
private final String name;
|
||||
private final IBuildConfiguration config;
|
||||
private final IToolChain toolChain;
|
||||
private IToolChain toolChain;
|
||||
|
||||
protected CBuildConfiguration(IBuildConfiguration config, String name) {
|
||||
this.config = config;
|
||||
this.name = name;
|
||||
|
||||
// Load toolchain from prefs
|
||||
Preferences settings = getSettings();
|
||||
String typeId = settings.get(TOOLCHAIN_TYPE, ""); //$NON-NLS-1$
|
||||
String id = settings.get(TOOLCHAIN_NAME, ""); //$NON-NLS-1$
|
||||
IToolChainManager toolChainManager = CCorePlugin.getService(IToolChainManager.class);
|
||||
toolChain = !id.isEmpty() ? toolChainManager.getToolChain(typeId, id) : null;
|
||||
|
||||
if (toolChain == null) {
|
||||
CCorePlugin.log(String.format("Toolchain missing for config: %s", config.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
protected CBuildConfiguration(IBuildConfiguration config, String name, IToolChain toolChain) {
|
||||
this.config = config;
|
||||
this.name = name;
|
||||
|
||||
this.toolChain = toolChain;
|
||||
Preferences settings = getSettings();
|
||||
settings.put(TOOLCHAIN_TYPE, toolChain.getType().getId());
|
||||
settings.put(TOOLCHAIN_NAME, toolChain.getName());
|
||||
try {
|
||||
settings.flush();
|
||||
} catch (BackingStoreException e) {
|
||||
CCorePlugin.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -124,7 +101,16 @@ public abstract class CBuildConfiguration extends PlatformObject
|
|||
IFolder buildFolder = buildRootFolder.getFolder(name);
|
||||
if (!buildFolder.exists()) {
|
||||
buildFolder.create(true, true, new NullProgressMonitor());
|
||||
buildFolder.setDerived(true, null);
|
||||
ICProject cproject = CoreModel.getDefault().create(getProject());
|
||||
IOutputEntry output = CoreModel.newOutputEntry(buildFolder.getFullPath());
|
||||
IPathEntry[] oldEntries = cproject.getRawPathEntries();
|
||||
IPathEntry[] newEntries = new IPathEntry[oldEntries.length + 1];
|
||||
System.arraycopy(oldEntries, 0, newEntries, 0, oldEntries.length);
|
||||
newEntries[oldEntries.length] = output;
|
||||
cproject.setRawPathEntries(newEntries, null);
|
||||
}
|
||||
|
||||
return buildFolder;
|
||||
}
|
||||
|
||||
|
@ -136,7 +122,7 @@ public abstract class CBuildConfiguration extends PlatformObject
|
|||
return Paths.get(getBuildDirectoryURI());
|
||||
}
|
||||
|
||||
protected void setBuildEnvironment(Map<String, String> env) {
|
||||
public void setBuildEnvironment(Map<String, String> env) {
|
||||
CCorePlugin.getDefault().getBuildEnvironmentManager().setEnvironment(env, config, true);
|
||||
}
|
||||
|
||||
|
@ -158,10 +144,35 @@ public abstract class CBuildConfiguration extends PlatformObject
|
|||
}
|
||||
|
||||
@Override
|
||||
public IToolChain getToolChain() {
|
||||
public IToolChain getToolChain() throws CoreException {
|
||||
if (toolChain == null) {
|
||||
Preferences settings = getSettings();
|
||||
String typeId = settings.get(TOOLCHAIN_TYPE, ""); //$NON-NLS-1$
|
||||
String id = settings.get(TOOLCHAIN_NAME, ""); //$NON-NLS-1$
|
||||
IToolChainManager toolChainManager = CCorePlugin.getService(IToolChainManager.class);
|
||||
toolChain = toolChainManager.getToolChain(typeId, id);
|
||||
|
||||
if (toolChain == null) {
|
||||
CCorePlugin.log(String.format("Toolchain missing for config: %s", config.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
return toolChain;
|
||||
}
|
||||
|
||||
protected void setToolChain(IToolChain toolChain) {
|
||||
this.toolChain = toolChain;
|
||||
|
||||
Preferences settings = getSettings();
|
||||
settings.put(TOOLCHAIN_TYPE, toolChain.getProvider().getId());
|
||||
settings.put(TOOLCHAIN_NAME, toolChain.getName());
|
||||
try {
|
||||
settings.flush();
|
||||
} catch (BackingStoreException e) {
|
||||
CCorePlugin.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IEnvironmentVariable getVariable(String name) {
|
||||
// By default, none
|
||||
|
@ -346,7 +357,7 @@ public abstract class CBuildConfiguration extends PlatformObject
|
|||
cheaterInfo = new HashMap<>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public IScannerInfo getScannerInformation(IResource resource) {
|
||||
initScannerInfo();
|
||||
|
@ -358,8 +369,29 @@ public abstract class CBuildConfiguration extends PlatformObject
|
|||
// TODO smarter line parsing to deal with quoted arguments
|
||||
String[] command = line.split("\\s+"); //$NON-NLS-1$
|
||||
|
||||
// Make sure it's a compile command
|
||||
boolean found = false;
|
||||
String[] compileCommands = toolChain.getCompileCommands();
|
||||
for (String arg : command) {
|
||||
if (arg.startsWith("-")) { //$NON-NLS-1$
|
||||
// option found, missed our command
|
||||
break;
|
||||
}
|
||||
|
||||
for (String cc : compileCommands) {
|
||||
if (arg.equals(cc)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
IResource[] resources = getToolChain().getResourcesFromCommand(command, getBuildDirectoryURI());
|
||||
IResource[] resources = toolChain.getResourcesFromCommand(command, getBuildDirectoryURI());
|
||||
if (resources != null) {
|
||||
for (IResource resource : resources) {
|
||||
initScannerInfo();
|
||||
|
|
|
@ -34,18 +34,18 @@ public interface ICBuildConfiguration extends IAdaptable, IScannerInfoProvider {
|
|||
*
|
||||
* @return resources build configuration
|
||||
*/
|
||||
IBuildConfiguration getBuildConfiguration();
|
||||
IBuildConfiguration getBuildConfiguration() throws CoreException;
|
||||
|
||||
/**
|
||||
* Build Configurations are configurations for a given toolchain.
|
||||
*
|
||||
* @return the toolchain for this build configuration
|
||||
*/
|
||||
IToolChain getToolChain();
|
||||
IToolChain getToolChain() throws CoreException;
|
||||
|
||||
IEnvironmentVariable getVariable(String name);
|
||||
IEnvironmentVariable getVariable(String name) throws CoreException;
|
||||
|
||||
IEnvironmentVariable[] getVariables();
|
||||
IEnvironmentVariable[] getVariables() throws CoreException;
|
||||
|
||||
IProject[] build(int kind, Map<String, String> args, IConsole console, IProgressMonitor monitor) throws CoreException;
|
||||
|
||||
|
|
|
@ -35,6 +35,8 @@ public interface ICBuildConfigurationManager {
|
|||
IBuildConfiguration createBuildConfiguration(ICBuildConfigurationProvider provider, IProject project,
|
||||
String configName, IProgressMonitor monitor) throws CoreException;
|
||||
|
||||
IBuildConfiguration getBuildConfiguration(ICBuildConfigurationProvider provider, IProject project, String configName) throws CoreException;
|
||||
|
||||
/**
|
||||
* Called by providers to add new build configurations as they are created.
|
||||
*
|
||||
|
@ -52,8 +54,8 @@ public interface ICBuildConfigurationManager {
|
|||
* @param buildConfig
|
||||
* @return the matching CDT build configuration
|
||||
*/
|
||||
ICBuildConfiguration getBuildConfiguration(IBuildConfiguration buildConfig);
|
||||
|
||||
ICBuildConfiguration getBuildConfiguration(IBuildConfiguration buildConfig) throws CoreException;
|
||||
|
||||
ICBuildConfiguration getDefaultBuildConfiguration(IProject project) throws CoreException;
|
||||
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ public interface ICBuildConfigurationProvider {
|
|||
* @param config
|
||||
* @return CDT build configuration for the Platform build configuration
|
||||
*/
|
||||
ICBuildConfiguration getCBuildConfiguration(IBuildConfiguration config, String name);
|
||||
ICBuildConfiguration getCBuildConfiguration(IBuildConfiguration config, String name) throws CoreException;
|
||||
|
||||
/**
|
||||
* Returns a default C build configuration for a given project if any.
|
||||
|
|
|
@ -28,7 +28,7 @@ public interface IToolChain extends IAdaptable {
|
|||
static final String ATTR_OS = "os"; //$NON-NLS-1$
|
||||
static final String ATTR_ARCH = "arch"; //$NON-NLS-1$
|
||||
|
||||
IToolChainType getType();
|
||||
IToolChainProvider getProvider();
|
||||
|
||||
String getName();
|
||||
|
||||
|
@ -52,8 +52,10 @@ public interface IToolChain extends IAdaptable {
|
|||
|
||||
String[] getErrorParserIds();
|
||||
|
||||
Path getCommandPath(String command);
|
||||
Path getCommandPath(Path command);
|
||||
|
||||
String[] getCompileCommands();
|
||||
|
||||
IResource[] getResourcesFromCommand(String[] command, URI buildDirectoryURI);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@ package org.eclipse.cdt.core.build;
|
|||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
/**
|
||||
* The global toolchain manager. Accessed as an OSGi service.
|
||||
*
|
||||
|
@ -17,9 +19,11 @@ import java.util.Map;
|
|||
*/
|
||||
public interface IToolChainManager {
|
||||
|
||||
IToolChainType getToolChainType(String id);
|
||||
|
||||
IToolChain getToolChain(String typeId, String name);
|
||||
IToolChainProvider getProvider(String providerId) throws CoreException;
|
||||
|
||||
IToolChain getToolChain(String providerId, String name) throws CoreException;
|
||||
|
||||
Collection<IToolChain> getToolChains(String providerId) throws CoreException;
|
||||
|
||||
/**
|
||||
* Returns the list of toolchains that have the given properties.
|
||||
|
@ -28,6 +32,10 @@ public interface IToolChainManager {
|
|||
* properties of the toolchains
|
||||
* @return the qualified toolchains
|
||||
*/
|
||||
Collection<IToolChain> getToolChainsMatching(Map<String, String> properties);
|
||||
Collection<IToolChain> getToolChainsMatching(Map<String, String> properties) throws CoreException;
|
||||
|
||||
void addToolChain(IToolChain toolChain);
|
||||
|
||||
void removeToolChain(IToolChain toolChain);
|
||||
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.build;
|
||||
|
||||
import java.util.Collection;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
/**
|
||||
* A provider of toolchains. Registered with the toolChainProvider extension
|
||||
|
@ -17,6 +17,34 @@ import java.util.Collection;
|
|||
*/
|
||||
public interface IToolChainProvider {
|
||||
|
||||
Collection<IToolChain> getToolChains();
|
||||
/**
|
||||
* Returns the id for this provider.
|
||||
*
|
||||
* @return id
|
||||
*/
|
||||
String getId();
|
||||
|
||||
/**
|
||||
* Initialize the list of toolchains.
|
||||
*
|
||||
* @param manager handle on manager to add or remove them
|
||||
*/
|
||||
default void init(IToolChainManager manager) throws CoreException {
|
||||
// By default, toolchains are created on demand
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the manager to dynamically create the named toolchain.
|
||||
*
|
||||
* @param name
|
||||
* the name of the toolchain
|
||||
* @param properties
|
||||
* the persisted settings for the toolchain
|
||||
* @return the toolchain initialized with the settings.
|
||||
*/
|
||||
default IToolChain getToolChain(String name) throws CoreException {
|
||||
// By default, assumes all toolchains were added at init time.
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015 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.core.build;
|
||||
|
||||
/**
|
||||
* A type of toolchain.
|
||||
*
|
||||
* @since 6.0
|
||||
*/
|
||||
public interface IToolChainType {
|
||||
|
||||
String getId();
|
||||
|
||||
/**
|
||||
* Called by the toolchain to inflate the toolchain from the user preference
|
||||
* store.
|
||||
*
|
||||
* @param name
|
||||
* the name of the toolchain
|
||||
* @param properties
|
||||
* the persisted settings for the toolchain
|
||||
* @return the toolchain initialized with the settings.
|
||||
*/
|
||||
IToolChain getToolChain(String name);
|
||||
|
||||
}
|
|
@ -11,6 +11,7 @@ import org.eclipse.cdt.core.CCorePlugin;
|
|||
import org.eclipse.cdt.core.build.ICBuildConfiguration;
|
||||
import org.eclipse.cdt.core.build.ICBuildConfigurationManager;
|
||||
import org.eclipse.core.resources.IBuildConfiguration;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IAdapterFactory;
|
||||
|
||||
public class CBuildConfigAdapterFactory implements IAdapterFactory {
|
||||
|
@ -23,7 +24,11 @@ public class CBuildConfigAdapterFactory implements IAdapterFactory {
|
|||
if (ICBuildConfiguration.class.equals(adapterType)
|
||||
&& adaptableObject instanceof IBuildConfiguration) {
|
||||
IBuildConfiguration config = (IBuildConfiguration) adaptableObject;
|
||||
return (T) manager.getBuildConfiguration(config);
|
||||
try {
|
||||
return (T) manager.getBuildConfiguration(config);
|
||||
} catch (CoreException e) {
|
||||
CCorePlugin.log(e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -139,7 +139,7 @@ public class CBuildConfigurationManager implements ICBuildConfigurationManager,
|
|||
}
|
||||
|
||||
@Override
|
||||
public ICBuildConfiguration getBuildConfiguration(IBuildConfiguration buildConfig) {
|
||||
public ICBuildConfiguration getBuildConfiguration(IBuildConfiguration buildConfig) throws CoreException {
|
||||
initProviders();
|
||||
synchronized (configs) {
|
||||
ICBuildConfiguration config = configs.get(buildConfig);
|
||||
|
@ -160,6 +160,13 @@ public class CBuildConfigurationManager implements ICBuildConfigurationManager,
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBuildConfiguration getBuildConfiguration(ICBuildConfigurationProvider provider, IProject project,
|
||||
String configName) throws CoreException {
|
||||
String name = provider.getId() + '/' + configName;
|
||||
return project.getBuildConfig(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICBuildConfiguration getDefaultBuildConfiguration(IProject project) throws CoreException {
|
||||
initProviders();
|
||||
|
|
|
@ -9,6 +9,7 @@ package org.eclipse.cdt.internal.core.build;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -17,7 +18,6 @@ import org.eclipse.cdt.core.CCorePlugin;
|
|||
import org.eclipse.cdt.core.build.IToolChain;
|
||||
import org.eclipse.cdt.core.build.IToolChainManager;
|
||||
import org.eclipse.cdt.core.build.IToolChainProvider;
|
||||
import org.eclipse.cdt.core.build.IToolChainType;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IConfigurationElement;
|
||||
import org.eclipse.core.runtime.IExtensionPoint;
|
||||
|
@ -26,41 +26,33 @@ import org.eclipse.core.runtime.Platform;
|
|||
|
||||
public class ToolChainManager implements IToolChainManager {
|
||||
|
||||
private Map<String, IConfigurationElement> typeElements;
|
||||
private Map<String, IToolChainType> types;
|
||||
private Map<String, IConfigurationElement> providerElements;
|
||||
private Map<String, IToolChainProvider> providers;
|
||||
private Map<String, Map<String, IToolChain>> toolChains;
|
||||
|
||||
private void init() {
|
||||
if (typeElements == null) {
|
||||
typeElements = new HashMap<>();
|
||||
types = new HashMap<>();
|
||||
if (providerElements == null) {
|
||||
providerElements = new HashMap<>();
|
||||
providers = new HashMap<>();
|
||||
|
||||
// Load the types
|
||||
IExtensionRegistry registry = Platform.getExtensionRegistry();
|
||||
IExtensionPoint typesPoint = registry.getExtensionPoint(CCorePlugin.PLUGIN_ID + ".toolChainType"); //$NON-NLS-1$
|
||||
IExtensionPoint typesPoint = registry
|
||||
.getExtensionPoint(CCorePlugin.PLUGIN_ID + ".toolChainProvider"); //$NON-NLS-1$
|
||||
for (IConfigurationElement element : typesPoint.getConfigurationElements()) {
|
||||
String id = element.getAttribute("id"); //$NON-NLS-1$
|
||||
typeElements.put(id, element);
|
||||
providerElements.put(id, element);
|
||||
}
|
||||
|
||||
// Load the discovered toolchains
|
||||
toolChains = new HashMap<>();
|
||||
IExtensionPoint providersPoint = registry
|
||||
.getExtensionPoint(CCorePlugin.PLUGIN_ID + ".toolChainProvider"); //$NON-NLS-1$
|
||||
for (IConfigurationElement element : providersPoint.getConfigurationElements()) {
|
||||
for (IConfigurationElement element : providerElements.values()) {
|
||||
// TODO check for enablement
|
||||
try {
|
||||
IToolChainProvider provider = (IToolChainProvider) element
|
||||
.createExecutableExtension("class"); //$NON-NLS-1$
|
||||
for (IToolChain toolChain : provider.getToolChains()) {
|
||||
String typeId = toolChain.getType().getId();
|
||||
Map<String, IToolChain> tcs = toolChains.get(typeId);
|
||||
if (tcs == null) {
|
||||
tcs = new HashMap<>();
|
||||
toolChains.put(typeId, tcs);
|
||||
}
|
||||
tcs.put(toolChain.getName(), toolChain);
|
||||
}
|
||||
providers.put(element.getAttribute("id"), provider); //$NON-NLS-1$
|
||||
provider.init(this);
|
||||
} catch (CoreException e) {
|
||||
CCorePlugin.log(e);
|
||||
}
|
||||
|
@ -69,28 +61,65 @@ public class ToolChainManager implements IToolChainManager {
|
|||
}
|
||||
|
||||
@Override
|
||||
public IToolChainType getToolChainType(String id) {
|
||||
public void addToolChain(IToolChain toolChain) {
|
||||
String providerId = toolChain.getProvider().getId();
|
||||
Map<String, IToolChain> provider = toolChains.get(providerId);
|
||||
if (provider == null) {
|
||||
provider = new HashMap<>();
|
||||
toolChains.put(providerId, provider);
|
||||
}
|
||||
provider.put(toolChain.getName(), toolChain);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeToolChain(IToolChain toolChain) {
|
||||
String providerId = toolChain.getProvider().getId();
|
||||
Map<String, IToolChain> provider = toolChains.get(providerId);
|
||||
if (provider != null) {
|
||||
provider.remove(toolChain.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IToolChainProvider getProvider(String providerId) throws CoreException {
|
||||
init();
|
||||
IToolChainType type = types.get(id);
|
||||
if (type == null) {
|
||||
IConfigurationElement element = typeElements.get(id);
|
||||
IToolChainProvider provider = providers.get(providerId);
|
||||
if (provider == null) {
|
||||
IConfigurationElement element = providerElements.get(providerId);
|
||||
if (element != null) {
|
||||
try {
|
||||
type = (IToolChainType) element.createExecutableExtension("class"); //$NON-NLS-1$
|
||||
types.put(id, type);
|
||||
} catch (CoreException e) {
|
||||
CCorePlugin.log(e);
|
||||
}
|
||||
provider = (IToolChainProvider) element.createExecutableExtension("class"); //$NON-NLS-1$
|
||||
providers.put(providerId, provider);
|
||||
}
|
||||
}
|
||||
return type;
|
||||
return provider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IToolChain getToolChain(String typeId, String name) {
|
||||
public IToolChain getToolChain(String providerId, String name) throws CoreException {
|
||||
init();
|
||||
Map<String, IToolChain> tcs = toolChains.get(typeId);
|
||||
return tcs != null ? tcs.get(name) : null;
|
||||
Map<String, IToolChain> provider = toolChains.get(providerId);
|
||||
if (provider != null) {
|
||||
IToolChain toolChain = provider.get(name);
|
||||
if (toolChain != null) {
|
||||
return toolChain;
|
||||
}
|
||||
}
|
||||
|
||||
// Try the provider
|
||||
IToolChainProvider realProvider = providers.get(providerId);
|
||||
if (realProvider != null) {
|
||||
IToolChain toolChain = realProvider.getToolChain(name);
|
||||
if (toolChain != null) {
|
||||
if (provider == null) {
|
||||
provider = new HashMap<>();
|
||||
toolChains.put(providerId, provider);
|
||||
}
|
||||
provider.put(name, toolChain);
|
||||
return toolChain;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -111,4 +140,15 @@ public class ToolChainManager implements IToolChainManager {
|
|||
return tcs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<IToolChain> getToolChains(String providerId) {
|
||||
init();
|
||||
Map<String, IToolChain> provider = toolChains.get(providerId);
|
||||
if (provider != null) {
|
||||
return Collections.unmodifiableCollection(provider.values());
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,9 +7,11 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.envvar;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.build.ICBuildConfiguration;
|
||||
import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
|
||||
import org.eclipse.core.resources.IBuildConfiguration;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
public class BuildConfigEnvironmentSupplier implements ICoreEnvironmentVariableSupplier {
|
||||
|
||||
|
@ -19,7 +21,12 @@ public class BuildConfigEnvironmentSupplier implements ICoreEnvironmentVariableS
|
|||
ICBuildConfiguration cconfig = ((IBuildConfiguration) context)
|
||||
.getAdapter(ICBuildConfiguration.class);
|
||||
if (cconfig != null) {
|
||||
return cconfig.getVariable(name);
|
||||
try {
|
||||
return cconfig.getVariable(name);
|
||||
} catch (CoreException e) {
|
||||
CCorePlugin.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
@ -31,7 +38,12 @@ public class BuildConfigEnvironmentSupplier implements ICoreEnvironmentVariableS
|
|||
ICBuildConfiguration cconfig = ((IBuildConfiguration) context)
|
||||
.getAdapter(ICBuildConfiguration.class);
|
||||
if (cconfig != null) {
|
||||
return cconfig.getVariables();
|
||||
try {
|
||||
return cconfig.getVariables();
|
||||
} catch (CoreException e) {
|
||||
CCorePlugin.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -7,10 +7,12 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.envvar;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.build.ICBuildConfiguration;
|
||||
import org.eclipse.cdt.core.build.IToolChain;
|
||||
import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
|
||||
import org.eclipse.core.resources.IBuildConfiguration;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
public class ToolChainEnvironmentSupplier implements ICoreEnvironmentVariableSupplier {
|
||||
|
||||
|
@ -20,9 +22,14 @@ public class ToolChainEnvironmentSupplier implements ICoreEnvironmentVariableSup
|
|||
ICBuildConfiguration config = ((IBuildConfiguration) context)
|
||||
.getAdapter(ICBuildConfiguration.class);
|
||||
if (config != null) {
|
||||
IToolChain toolChain = config.getToolChain();
|
||||
if (toolChain != null) {
|
||||
return toolChain.getVariable(name);
|
||||
try {
|
||||
IToolChain toolChain = config.getToolChain();
|
||||
if (toolChain != null) {
|
||||
return toolChain.getVariable(name);
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
CCorePlugin.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,9 +42,14 @@ public class ToolChainEnvironmentSupplier implements ICoreEnvironmentVariableSup
|
|||
ICBuildConfiguration config = ((IBuildConfiguration) context)
|
||||
.getAdapter(ICBuildConfiguration.class);
|
||||
if (config != null) {
|
||||
IToolChain toolChain = config.getToolChain();
|
||||
if (toolChain != null) {
|
||||
return toolChain.getVariables();
|
||||
try {
|
||||
IToolChain toolChain = config.getToolChain();
|
||||
if (toolChain != null) {
|
||||
return toolChain.getVariables();
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
CCorePlugin.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -192,7 +192,8 @@
|
|||
<extension
|
||||
point="org.eclipse.cdt.core.toolChainProvider">
|
||||
<provider
|
||||
class="org.eclipse.cdt.qt.core.QtMinGWToolChainProvider">
|
||||
class="org.eclipse.cdt.qt.core.QtMinGWToolChainProvider"
|
||||
id="org.eclipse.cdt.qt.core.qtMinGWProvider">
|
||||
</provider>
|
||||
</extension>
|
||||
<extension
|
||||
|
|
|
@ -74,7 +74,8 @@ public class QtBuildConfiguration extends CBuildConfiguration implements ICBuild
|
|||
QtBuildConfiguration(IBuildConfiguration config, String name, IToolChain toolChain, IQtInstall qtInstall,
|
||||
String launchMode)
|
||||
throws CoreException {
|
||||
super(config, name, toolChain);
|
||||
super(config, name);
|
||||
setToolChain(toolChain);
|
||||
this.qtInstall = qtInstall;
|
||||
this.launchMode = launchMode;
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
package org.eclipse.cdt.internal.qt.core.launch;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import org.eclipse.cdt.core.build.IToolChain;
|
||||
|
@ -64,7 +65,7 @@ public class QtLocalDebugLaunchConfigDelegate extends QtLaunchConfigurationDeleg
|
|||
IQtBuildConfiguration qtBuildConfig = getQtBuildConfiguration(configuration, mode, target, monitor);
|
||||
|
||||
IToolChain toolChain = qtBuildConfig.getToolChain();
|
||||
gdbLaunch.setGDBPath(toolChain.getCommandPath("gdb").toString()); //$NON-NLS-1$
|
||||
gdbLaunch.setGDBPath(toolChain.getCommandPath(Paths.get("gdb")).toString()); //$NON-NLS-1$
|
||||
String gdbVersion = gdbLaunch.getGDBVersion();
|
||||
|
||||
Path exeFile = qtBuildConfig.getProgramPath();
|
||||
|
|
|
@ -28,6 +28,10 @@ import org.osgi.framework.Bundle;
|
|||
|
||||
public class QtProjectGenerator extends FMProjectGenerator {
|
||||
|
||||
public QtProjectGenerator(String manifestPath) {
|
||||
super(manifestPath);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initProjectDescription(IProjectDescription description) {
|
||||
description
|
||||
|
@ -39,7 +43,7 @@ public class QtProjectGenerator extends FMProjectGenerator {
|
|||
public Bundle getSourceBundle() {
|
||||
return Activator.getDefault().getBundle();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void generate(Map<String, Object> model, IProgressMonitor monitor) throws CoreException {
|
||||
super.generate(model, monitor);
|
||||
|
|
|
@ -60,7 +60,7 @@ public abstract class QtLaunchConfigurationDelegate extends LaunchConfigurationT
|
|||
properties.put(IToolChain.ATTR_ARCH, arch);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected IQtBuildConfiguration getQtBuildConfiguration(ILaunchConfiguration configuration, String mode,
|
||||
ILaunchTarget target, IProgressMonitor monitor) throws CoreException {
|
||||
// Find the Qt build config
|
||||
|
@ -72,10 +72,13 @@ public abstract class QtLaunchConfigurationDelegate extends LaunchConfigurationT
|
|||
// Find the toolchains that support this target
|
||||
Map<String, String> properties = new HashMap<>();
|
||||
populateToolChainProperties(target, properties);
|
||||
|
||||
|
||||
IToolChainManager toolChainManager = Activator.getService(IToolChainManager.class);
|
||||
for (IToolChain toolChain : toolChainManager.getToolChainsMatching(properties)) {
|
||||
IQtBuildConfiguration qtConfig = provider.createConfiguration(project, toolChain, mode, monitor);
|
||||
IQtBuildConfiguration qtConfig = provider.getConfiguration(project, toolChain, mode, monitor);
|
||||
if (qtConfig == null) {
|
||||
qtConfig = provider.createConfiguration(project, toolChain, mode, monitor);
|
||||
}
|
||||
if (qtConfig != null) {
|
||||
return qtConfig;
|
||||
}
|
||||
|
|
|
@ -11,29 +11,30 @@ import java.io.IOException;
|
|||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.cdt.build.gcc.core.GCCToolChain;
|
||||
import org.eclipse.cdt.build.gcc.core.GCCToolChainType;
|
||||
import org.eclipse.cdt.core.build.IToolChain;
|
||||
import org.eclipse.cdt.core.build.IToolChainManager;
|
||||
import org.eclipse.cdt.core.build.IToolChainProvider;
|
||||
import org.eclipse.cdt.core.build.IToolChainType;
|
||||
import org.eclipse.cdt.internal.qt.core.Activator;
|
||||
import org.eclipse.cdt.utils.WindowsRegistry;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
|
||||
public class QtMinGWToolChainProvider implements IToolChainProvider {
|
||||
|
||||
private static final String ID = "org.eclipse.cdt.qt.core.qtMinGWProvider"; //$NON-NLS-1$
|
||||
|
||||
@Override
|
||||
public Collection<IToolChain> getToolChains() {
|
||||
public String getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(IToolChainManager manager) throws CoreException {
|
||||
if (Platform.getOS().equals(Platform.OS_WIN32)) {
|
||||
WindowsRegistry registry = WindowsRegistry.getRegistry();
|
||||
String uninstallKey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; //$NON-NLS-1$
|
||||
String subkey;
|
||||
IToolChainType type = Activator.getService(IToolChainManager.class).getToolChainType(GCCToolChainType.ID);
|
||||
for (int i = 0; (subkey = registry.getCurrentUserKeyName(uninstallKey, i)) != null; i++) {
|
||||
String compKey = uninstallKey + '\\' + subkey;
|
||||
String displayName = registry.getCurrentUserValue(compKey, "DisplayName"); //$NON-NLS-1$
|
||||
|
@ -41,18 +42,16 @@ public class QtMinGWToolChainProvider implements IToolChainProvider {
|
|||
String installLocation = registry.getCurrentUserValue(compKey, "InstallLocation"); //$NON-NLS-1$
|
||||
Path gcc = Paths.get("\\bin\\gcc.exe"); //$NON-NLS-1$
|
||||
try {
|
||||
return Files.walk(Paths.get(installLocation).resolve("Tools"), 1) //$NON-NLS-1$
|
||||
Files.walk(Paths.get(installLocation).resolve("Tools"), 1) //$NON-NLS-1$
|
||||
.filter((path) -> Files.exists(path.resolve(gcc)))
|
||||
.map((path) -> new GCCToolChain(type, path.resolve("bin"), "gcc.exe")) //$NON-NLS-1$ //$NON-NLS-2$
|
||||
.collect(Collectors.toList());
|
||||
.map((path) -> new GCCToolChain(this, "qt.mingw", path.resolve("bin"))) //$NON-NLS-1$ //$NON-NLS-2$
|
||||
.forEach(toolChain -> manager.addToolChain(toolChain));
|
||||
} catch (IOException e) {
|
||||
Activator.log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// default
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,75 +7,11 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.qt.ui.wizards;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.internal.qt.core.project.QtProjectGenerator;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.jobs.ISchedulingRule;
|
||||
import org.eclipse.jface.dialogs.Dialog;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.ui.actions.WorkspaceModifyOperation;
|
||||
import org.eclipse.ui.dialogs.WizardNewProjectCreationPage;
|
||||
import org.eclipse.ui.wizards.newresource.BasicNewResourceWizard;
|
||||
|
||||
public class HelloWorldWizard extends BasicNewResourceWizard {
|
||||
|
||||
private WizardNewProjectCreationPage mainPage;
|
||||
public class HelloWorldWizard extends QtProjectTemplateWizard {
|
||||
|
||||
@Override
|
||||
public void addPages() {
|
||||
mainPage = new WizardNewProjectCreationPage("basicNewProjectPage") { //$NON-NLS-1$
|
||||
@Override
|
||||
public void createControl(Composite parent) {
|
||||
super.createControl(parent);
|
||||
createWorkingSetGroup((Composite) getControl(), getSelection(),
|
||||
new String[] { "org.eclipse.ui.resourceWorkingSetPage" }); //$NON-NLS-1$
|
||||
Dialog.applyDialogFont(getControl());
|
||||
}
|
||||
};
|
||||
mainPage.setTitle("New Qt Project"); //$NON-NLS-1$
|
||||
mainPage.setDescription("Specify properties of new Qt project."); //$NON-NLS-1$
|
||||
this.addPage(mainPage);
|
||||
}
|
||||
|
||||
protected String getTemplateManifestPath() {
|
||||
return "templates/project2/appProject/manifest.xml"; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean performFinish() {
|
||||
QtProjectGenerator generator = new QtProjectGenerator();
|
||||
generator.setTemplateManifestPath(getTemplateManifestPath());
|
||||
generator.setProjectName(mainPage.getProjectName());
|
||||
if (!mainPage.useDefaults()) {
|
||||
generator.setLocationURI(mainPage.getLocationURI());
|
||||
}
|
||||
|
||||
Map<String, Object> model = new HashMap<>();
|
||||
|
||||
try {
|
||||
getContainer().run(true, true, new WorkspaceModifyOperation() {
|
||||
@Override
|
||||
protected void execute(IProgressMonitor monitor)
|
||||
throws CoreException, InvocationTargetException, InterruptedException {
|
||||
monitor.beginTask("Generating project", 1); //$NON-NLS-1$
|
||||
generator.generate(model, monitor);
|
||||
monitor.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ISchedulingRule getRule() {
|
||||
return ResourcesPlugin.getWorkspace().getRoot();
|
||||
}
|
||||
});
|
||||
} catch (InterruptedException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2016 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.internal.qt.ui.wizards;
|
||||
|
||||
import org.eclipse.cdt.internal.qt.core.project.QtProjectGenerator;
|
||||
import org.eclipse.jface.dialogs.Dialog;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.tools.templates.core.IGenerator;
|
||||
import org.eclipse.tools.templates.ui.TemplateWizard;
|
||||
import org.eclipse.ui.dialogs.WizardNewProjectCreationPage;
|
||||
|
||||
public abstract class QtProjectTemplateWizard extends TemplateWizard {
|
||||
|
||||
private WizardNewProjectCreationPage mainPage;
|
||||
|
||||
@Override
|
||||
public void addPages() {
|
||||
mainPage = new WizardNewProjectCreationPage("basicNewProjectPage") { //$NON-NLS-1$
|
||||
@Override
|
||||
public void createControl(Composite parent) {
|
||||
super.createControl(parent);
|
||||
createWorkingSetGroup((Composite) getControl(), getSelection(),
|
||||
new String[] { "org.eclipse.ui.resourceWorkingSetPage" }); //$NON-NLS-1$
|
||||
Dialog.applyDialogFont(getControl());
|
||||
}
|
||||
};
|
||||
mainPage.setTitle("New Qt Project"); //$NON-NLS-1$
|
||||
mainPage.setDescription("Specify properties of new Qt project."); //$NON-NLS-1$
|
||||
this.addPage(mainPage);
|
||||
}
|
||||
|
||||
protected abstract String getTemplateManifestPath();
|
||||
|
||||
@Override
|
||||
protected IGenerator getGenerator() {
|
||||
QtProjectGenerator generator = new QtProjectGenerator(getTemplateManifestPath());
|
||||
generator.setProjectName(mainPage.getProjectName());
|
||||
if (!mainPage.useDefaults()) {
|
||||
generator.setLocationURI(mainPage.getLocationURI());
|
||||
}
|
||||
return generator;
|
||||
}
|
||||
|
||||
}
|
|
@ -95,6 +95,7 @@
|
|||
<feature id="org.eclipse.cdt.arduino">
|
||||
</feature>
|
||||
<iu id="org.freemarker" version="0.0.0"/>
|
||||
<iu id="org.eclipse.tools.templates.core" version="0.0.0"/>
|
||||
<iu id="org.eclipse.tools.templates.freemarker" version="0.0.0"/>
|
||||
<iu id="org.eclipse.tools.templates.ui" version="0.0.0"/>
|
||||
</site>
|
||||
|
|
|
@ -15,14 +15,14 @@ Require-Bundle: org.eclipse.core.runtime,
|
|||
org.eclipse.remote.serial.core;bundle-version="1.0.0",
|
||||
com.google.gson;bundle-version="2.2.4",
|
||||
org.apache.commons.compress;bundle-version="1.6.0",
|
||||
org.freemarker;bundle-version="2.3.22",
|
||||
org.eclipse.launchbar.remote.core;bundle-version="1.0.0"
|
||||
org.eclipse.launchbar.remote.core;bundle-version="1.0.0",
|
||||
org.eclipse.tools.templates.freemarker;bundle-version="1.0.0";visibility:=reexport,
|
||||
org.eclipse.cdt.build.gcc.core;bundle-version="1.0.0"
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-ClassPath: .
|
||||
Export-Package: org.eclipse.cdt.arduino.core.internal;x-friends:="org.eclipse.cdt.arduino.ui",
|
||||
org.eclipse.cdt.arduino.core.internal.board;x-friends:="org.eclipse.cdt.arduino.ui",
|
||||
org.eclipse.cdt.arduino.core.internal.build;x-friends:="org.eclipse.cdt.arduino.ui",
|
||||
org.eclipse.cdt.arduino.core.internal.console;x-friends:="org.eclipse.cdt.arduino.ui",
|
||||
org.eclipse.cdt.arduino.core.internal.remote;x-friends:="org.eclipse.cdt.arduino.ui"
|
||||
Bundle-Localization: plugin
|
||||
|
|
|
@ -75,40 +75,9 @@
|
|||
</run>
|
||||
</runtime>
|
||||
<builder
|
||||
id="org.eclipse.cdt.arduino.core.arduinoBuilder">
|
||||
id="com.qnx.tools.ide.qde.core.cbuilder">
|
||||
</builder>
|
||||
</extension>
|
||||
<extension
|
||||
id="arduinoBuilder"
|
||||
name="%ArduinoBuilder.name"
|
||||
point="org.eclipse.core.resources.builders">
|
||||
<builder
|
||||
callOnEmptyDelta="true"
|
||||
hasNature="true"
|
||||
isConfigurable="true"
|
||||
supportsConfigurations="true">
|
||||
<run
|
||||
class="org.eclipse.cdt.arduino.core.internal.build.ArduinoBuilder">
|
||||
</run>
|
||||
</builder>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.cdt.core.ScannerInfoProvider2">
|
||||
<provider
|
||||
builder="org.eclipse.cdt.arduino.core.arduinoBuilder"
|
||||
class="org.eclipse.cdt.arduino.core.internal.ArduinoScannerInfoProvider">
|
||||
</provider>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.core.runtime.adapters">
|
||||
<factory
|
||||
adaptableType="org.eclipse.core.resources.IBuildConfiguration"
|
||||
class="org.eclipse.cdt.arduino.core.internal.build.ArduinoBuildConfiguration$Factory">
|
||||
<adapter
|
||||
type="org.eclipse.cdt.arduino.core.internal.build.ArduinoBuildConfiguration">
|
||||
</adapter>
|
||||
</factory>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.launchbar.core.launchTargetTypes">
|
||||
<launchTargetType
|
||||
|
@ -116,4 +85,19 @@
|
|||
provider="org.eclipse.cdt.arduino.core.internal.remote.ArduinoLaunchTargetProvider">
|
||||
</launchTargetType>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.cdt.core.buildConfigProvider">
|
||||
<provider
|
||||
class="org.eclipse.cdt.arduino.core.internal.build.ArduinoBuildConfigurationProvider"
|
||||
id="org.eclipse.cdt.arduino.core.provider"
|
||||
natureId="org.eclipse.cdt.arduino.core.arduinoNature">
|
||||
</provider>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.cdt.core.toolChainProvider">
|
||||
<provider
|
||||
class="org.eclipse.cdt.arduino.core.internal.build.ArduinoToolChainProvider"
|
||||
id="org.eclipse.cdt.arduino.core.toolChainProvider">
|
||||
</provider>
|
||||
</extension>
|
||||
</plugin>
|
||||
|
|
|
@ -11,12 +11,8 @@
|
|||
package org.eclipse.cdt.arduino.core.internal;
|
||||
|
||||
import org.eclipse.cdt.arduino.core.internal.board.ArduinoManager;
|
||||
import org.eclipse.cdt.arduino.core.internal.console.ArduinoConsoleService;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IExtension;
|
||||
import org.eclipse.core.runtime.IExtensionPoint;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.core.runtime.Plugin;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
@ -46,11 +42,13 @@ public class Activator extends Plugin {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(BundleContext bundleContext) throws Exception {
|
||||
plugin = this;
|
||||
bundleContext.registerService(ArduinoManager.class, new ArduinoManager(), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop(BundleContext bundleContext) throws Exception {
|
||||
plugin = null;
|
||||
}
|
||||
|
@ -61,10 +59,4 @@ public class Activator extends Plugin {
|
|||
return ref != null ? context.getService(ref) : null;
|
||||
}
|
||||
|
||||
public static ArduinoConsoleService getConsoleService() throws CoreException {
|
||||
IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(Activator.getId(), "consoleService"); //$NON-NLS-1$
|
||||
IExtension extension = point.getExtensions()[0]; // should only be one
|
||||
return (ArduinoConsoleService) extension.getConfigurationElements()[0].createExecutableExtension("class"); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,73 +1,54 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015 QNX Software Systems and others.
|
||||
* Copyright (c) 2015, 2016 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
|
||||
*
|
||||
* Contributors:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.arduino.core.internal;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.arduino.core.internal.build.ArduinoBuilder;
|
||||
import org.eclipse.cdt.core.CCProjectNature;
|
||||
import org.eclipse.cdt.core.CProjectNature;
|
||||
import org.eclipse.cdt.core.build.CBuilder;
|
||||
import org.eclipse.cdt.core.model.CoreModel;
|
||||
import org.eclipse.cdt.core.model.IPathEntry;
|
||||
import org.eclipse.core.resources.ICommand;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IProjectDescription;
|
||||
import org.eclipse.core.resources.IncrementalProjectBuilder;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.tools.templates.freemarker.FMProjectGenerator;
|
||||
import org.osgi.framework.Bundle;
|
||||
|
||||
public class ArduinoProjectGenerator {
|
||||
public class ArduinoProjectGenerator extends FMProjectGenerator {
|
||||
|
||||
private final IProject project;
|
||||
private IFile sourceFile;
|
||||
|
||||
public ArduinoProjectGenerator(IProject project) {
|
||||
this.project = project;
|
||||
public ArduinoProjectGenerator(String manifestFile) {
|
||||
super(manifestFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initProjectDescription(IProjectDescription description) {
|
||||
description
|
||||
.setNatureIds(new String[] { CProjectNature.C_NATURE_ID, CCProjectNature.CC_NATURE_ID, ArduinoProjectNature.ID });
|
||||
ICommand command = description.newCommand();
|
||||
CBuilder.setupBuilder(command);
|
||||
description.setBuildSpec(new ICommand[] { command });
|
||||
}
|
||||
|
||||
public void generate(IProgressMonitor monitor) throws CoreException {
|
||||
// Generate files
|
||||
ArduinoTemplateGenerator templateGen = new ArduinoTemplateGenerator();
|
||||
Map<String, Object> fmModel = new HashMap<>();
|
||||
fmModel.put("projectName", project.getName()); //$NON-NLS-1$
|
||||
|
||||
sourceFile = project.getFile(project.getName() + ".cpp"); //$NON-NLS-1$
|
||||
templateGen.generateFile(fmModel, "arduino.cpp", sourceFile, monitor); //$NON-NLS-1$
|
||||
|
||||
// Add natures to project: C, C++, Arduino
|
||||
IProjectDescription projDesc = project.getDescription();
|
||||
String[] oldIds = projDesc.getNatureIds();
|
||||
String[] newIds = new String[oldIds.length + 3];
|
||||
System.arraycopy(oldIds, 0, newIds, 0, oldIds.length);
|
||||
newIds[newIds.length - 3] = CProjectNature.C_NATURE_ID;
|
||||
newIds[newIds.length - 2] = CCProjectNature.CC_NATURE_ID;
|
||||
newIds[newIds.length - 1] = ArduinoProjectNature.ID;
|
||||
projDesc.setNatureIds(newIds);
|
||||
|
||||
// Add Arduino Builder
|
||||
ICommand command = projDesc.newCommand();
|
||||
command.setBuilderName(ArduinoBuilder.ID);
|
||||
command.setBuilding(IncrementalProjectBuilder.AUTO_BUILD, false);
|
||||
projDesc.setBuildSpec(new ICommand[] { command });
|
||||
|
||||
project.setDescription(projDesc, monitor);
|
||||
|
||||
IPathEntry[] entries = new IPathEntry[] { CoreModel.newSourceEntry(project.getFullPath()) };
|
||||
CoreModel.getDefault().create(project).setRawPathEntries(entries, monitor);
|
||||
@Override
|
||||
public Bundle getSourceBundle() {
|
||||
return Activator.getPlugin().getBundle();
|
||||
}
|
||||
|
||||
public IFile getSourceFile() {
|
||||
return sourceFile;
|
||||
|
||||
@Override
|
||||
public void generate(Map<String, Object> model, IProgressMonitor monitor) throws CoreException {
|
||||
super.generate(model, monitor);
|
||||
IProject project = getProject();
|
||||
CoreModel.getDefault().create(project).setRawPathEntries(new IPathEntry[] {
|
||||
CoreModel.newSourceEntry(project.getFullPath())
|
||||
}, monitor);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015 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.arduino.core.internal;
|
||||
|
||||
import org.eclipse.cdt.arduino.core.internal.build.ArduinoBuildConfiguration;
|
||||
import org.eclipse.cdt.core.parser.IScannerInfo;
|
||||
import org.eclipse.cdt.core.parser.IScannerInfoChangeListener;
|
||||
import org.eclipse.cdt.core.parser.IScannerInfoProvider;
|
||||
import org.eclipse.core.resources.IBuildConfiguration;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
/**
|
||||
* Responsible for collecting scanner info on Arduino Projects.
|
||||
*/
|
||||
public class ArduinoScannerInfoProvider implements IScannerInfoProvider {
|
||||
|
||||
@Override
|
||||
public IScannerInfo getScannerInformation(IResource resource) {
|
||||
try {
|
||||
IProject project = resource.getProject();
|
||||
IBuildConfiguration config = project.getActiveBuildConfig();
|
||||
ArduinoBuildConfiguration arduinoConfig = config.getAdapter(ArduinoBuildConfiguration.class);
|
||||
return arduinoConfig.getScannerInfo(resource);
|
||||
} catch (CoreException e) {
|
||||
Activator.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribe(IResource resource, IScannerInfoChangeListener listener) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsubscribe(IResource resource, IScannerInfoChangeListener listener) {
|
||||
}
|
||||
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015 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.arduino.core.internal;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.io.StringWriter;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.FileLocator;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
|
||||
import freemarker.cache.TemplateLoader;
|
||||
import freemarker.template.Configuration;
|
||||
import freemarker.template.Template;
|
||||
import freemarker.template.TemplateException;
|
||||
|
||||
public class ArduinoTemplateGenerator implements TemplateLoader {
|
||||
|
||||
private final Configuration config;
|
||||
private Path templateRoot = new Path("/templates"); //$NON-NLS-1$
|
||||
|
||||
public ArduinoTemplateGenerator() throws CoreException {
|
||||
config = new Configuration(Configuration.VERSION_2_3_22);
|
||||
config.setTemplateLoader(this);
|
||||
}
|
||||
|
||||
public void generateFile(final Object model, String templateFile, final IFile outputFile, IProgressMonitor monitor)
|
||||
throws CoreException {
|
||||
try {
|
||||
final Template template = config.getTemplate(templateFile);
|
||||
try (StringWriter writer = new StringWriter()) {
|
||||
template.process(model, writer);
|
||||
try (ByteArrayInputStream in = new ByteArrayInputStream(
|
||||
writer.getBuffer().toString().getBytes(StandardCharsets.UTF_8))) {
|
||||
if (outputFile.exists()) {
|
||||
outputFile.setContents(in, true, true, monitor);
|
||||
} else {
|
||||
outputFile.create(in, true, monitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException | TemplateException e) {
|
||||
throw new CoreException(
|
||||
new Status(IStatus.ERROR, Activator.getId(), "Processing template " + templateFile, e)); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object findTemplateSource(String name) throws IOException {
|
||||
return FileLocator.find(Activator.getContext().getBundle(), templateRoot.append(name), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastModified(Object source) {
|
||||
try {
|
||||
URL url = (URL) source;
|
||||
if (url.getProtocol().equals("file")) { //$NON-NLS-1$
|
||||
File file = new File(url.toURI());
|
||||
return file.lastModified();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} catch (URISyntaxException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Reader getReader(Object source, String encoding) throws IOException {
|
||||
URL url = (URL) source;
|
||||
return new InputStreamReader(url.openStream());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeTemplateSource(Object arg0) throws IOException {
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
}
|
|
@ -45,7 +45,7 @@ import org.eclipse.cdt.arduino.core.internal.Activator;
|
|||
import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences;
|
||||
import org.eclipse.cdt.arduino.core.internal.Messages;
|
||||
import org.eclipse.cdt.arduino.core.internal.build.ArduinoBuildConfiguration;
|
||||
import org.eclipse.core.resources.IBuildConfiguration;
|
||||
import org.eclipse.cdt.core.build.ICBuildConfiguration;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.ProjectScope;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
@ -76,6 +76,7 @@ public class ArduinoManager {
|
|||
|
||||
public void loadIndices() {
|
||||
new Job(Messages.ArduinoBoardManager_0) {
|
||||
@Override
|
||||
protected IStatus run(IProgressMonitor monitor) {
|
||||
synchronized (ArduinoManager.this) {
|
||||
String[] boardUrls = ArduinoPreferences.getBoardUrls().split("\n"); //$NON-NLS-1$
|
||||
|
@ -207,7 +208,7 @@ public class ArduinoManager {
|
|||
private static final String LIBRARIES = "libraries"; //$NON-NLS-1$
|
||||
|
||||
private IEclipsePreferences getSettings(IProject project) {
|
||||
return (IEclipsePreferences) new ProjectScope(project).getNode(Activator.getId());
|
||||
return new ProjectScope(project).getNode(Activator.getId());
|
||||
}
|
||||
|
||||
public Collection<ArduinoLibrary> getLibraries(IProject project) throws CoreException {
|
||||
|
@ -218,8 +219,8 @@ public class ArduinoManager {
|
|||
Set<String> libraryNames = new Gson().fromJson(librarySetting, stringSet);
|
||||
LibraryIndex index = Activator.getService(ArduinoManager.class).getLibraryIndex();
|
||||
|
||||
ArduinoPlatform platform = project.getActiveBuildConfig().getAdapter(ArduinoBuildConfiguration.class).getBoard()
|
||||
.getPlatform();
|
||||
ICBuildConfiguration cconfig = project.getActiveBuildConfig().getAdapter(ICBuildConfiguration.class);
|
||||
ArduinoPlatform platform = cconfig.getAdapter(ArduinoBuildConfiguration.class).getBoard().getPlatform();
|
||||
List<ArduinoLibrary> libraries = new ArrayList<>(libraryNames.size());
|
||||
for (String name : libraryNames) {
|
||||
ArduinoLibrary lib = index.getLibrary(name);
|
||||
|
@ -247,6 +248,7 @@ public class ArduinoManager {
|
|||
}
|
||||
|
||||
new Job(Messages.ArduinoManager_0) {
|
||||
@Override
|
||||
protected IStatus run(IProgressMonitor monitor) {
|
||||
MultiStatus mstatus = new MultiStatus(Activator.getId(), 0, Messages.ArduinoManager_1, null);
|
||||
for (ArduinoLibrary library : libraries) {
|
||||
|
@ -255,16 +257,6 @@ public class ArduinoManager {
|
|||
mstatus.add(status);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear the scanner info caches to pick up new includes
|
||||
try {
|
||||
for (IBuildConfiguration config : project.getBuildConfigs()) {
|
||||
ArduinoBuildConfiguration arduinoConfig = config.getAdapter(ArduinoBuildConfiguration.class);
|
||||
arduinoConfig.clearScannerInfoCache();
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
mstatus.add(e.getStatus());
|
||||
}
|
||||
return mstatus;
|
||||
}
|
||||
}.schedule();
|
||||
|
|
|
@ -8,25 +8,30 @@
|
|||
package org.eclipse.cdt.arduino.core.internal.build;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.file.Files;
|
||||
import java.io.Reader;
|
||||
import java.io.StringWriter;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.cdt.arduino.core.internal.Activator;
|
||||
import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences;
|
||||
import org.eclipse.cdt.arduino.core.internal.ArduinoTemplateGenerator;
|
||||
import org.eclipse.cdt.arduino.core.internal.HierarchicalProperties;
|
||||
import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoard;
|
||||
import org.eclipse.cdt.arduino.core.internal.board.ArduinoLibrary;
|
||||
|
@ -34,152 +39,107 @@ import org.eclipse.cdt.arduino.core.internal.board.ArduinoManager;
|
|||
import org.eclipse.cdt.arduino.core.internal.board.ArduinoPackage;
|
||||
import org.eclipse.cdt.arduino.core.internal.board.ArduinoPlatform;
|
||||
import org.eclipse.cdt.arduino.core.internal.board.ToolDependency;
|
||||
import org.eclipse.cdt.arduino.core.internal.console.ArduinoConsoleParser;
|
||||
import org.eclipse.cdt.arduino.core.internal.console.ArduinoErrorParser;
|
||||
import org.eclipse.cdt.arduino.core.internal.remote.ArduinoRemoteConnection;
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.model.CoreModel;
|
||||
import org.eclipse.cdt.core.model.ICProject;
|
||||
import org.eclipse.cdt.core.model.IOutputEntry;
|
||||
import org.eclipse.cdt.core.model.IPathEntry;
|
||||
import org.eclipse.cdt.core.ConsoleOutputStream;
|
||||
import org.eclipse.cdt.core.ErrorParserManager;
|
||||
import org.eclipse.cdt.core.IConsoleParser;
|
||||
import org.eclipse.cdt.core.build.CBuildConfiguration;
|
||||
import org.eclipse.cdt.core.build.IToolChain;
|
||||
import org.eclipse.cdt.core.build.IToolChainManager;
|
||||
import org.eclipse.cdt.core.build.IToolChainProvider;
|
||||
import org.eclipse.cdt.core.model.ICModelMarker;
|
||||
import org.eclipse.cdt.core.model.ISourceRoot;
|
||||
import org.eclipse.cdt.core.parser.ExtendedScannerInfo;
|
||||
import org.eclipse.cdt.core.parser.IScannerInfo;
|
||||
import org.eclipse.cdt.core.resources.IConsole;
|
||||
import org.eclipse.core.resources.IBuildConfiguration;
|
||||
import org.eclipse.core.resources.IContainer;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IFolder;
|
||||
import org.eclipse.core.resources.IMarker;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IProjectDescription;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.resources.IResourceProxy;
|
||||
import org.eclipse.core.resources.IResourceProxyVisitor;
|
||||
import org.eclipse.core.resources.ProjectScope;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IAdapterFactory;
|
||||
import org.eclipse.core.runtime.FileLocator;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.content.IContentType;
|
||||
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
|
||||
import org.osgi.service.prefs.BackingStoreException;
|
||||
import org.osgi.service.prefs.Preferences;
|
||||
|
||||
public class ArduinoBuildConfiguration {
|
||||
import freemarker.cache.TemplateLoader;
|
||||
import freemarker.template.Configuration;
|
||||
import freemarker.template.Template;
|
||||
import freemarker.template.TemplateException;
|
||||
|
||||
public class ArduinoBuildConfiguration extends CBuildConfiguration implements TemplateLoader {
|
||||
|
||||
private static final String PACKAGE_NAME = "packageName"; //$NON-NLS-1$
|
||||
private static final String PLATFORM_NAME = "platformName"; //$NON-NLS-1$
|
||||
private static final String BOARD_NAME = "boardName"; //$NON-NLS-1$
|
||||
|
||||
private final IBuildConfiguration config;
|
||||
|
||||
private static ArduinoManager manager = Activator.getService(ArduinoManager.class);
|
||||
|
||||
private ArduinoBoard board;
|
||||
private final ArduinoBoard board;
|
||||
private final String launchMode;
|
||||
private Properties properties;
|
||||
|
||||
// Cache for scanner info
|
||||
private IScannerInfo cScannerInfo;
|
||||
private IScannerInfo cppScannerInfo;
|
||||
// for Makefile generation
|
||||
private Configuration templateConfig;
|
||||
|
||||
private final static boolean isWindows = Platform.getOS().equals(Platform.OS_WIN32);
|
||||
|
||||
private ArduinoBuildConfiguration(IBuildConfiguration config) {
|
||||
this.config = config;
|
||||
}
|
||||
public ArduinoBuildConfiguration(IBuildConfiguration config, String name) throws CoreException {
|
||||
super(config, name);
|
||||
|
||||
private static Map<IBuildConfiguration, ArduinoBuildConfiguration> cache = new HashMap<>();
|
||||
Preferences settings = getSettings();
|
||||
String packageName = settings.get(PACKAGE_NAME, ""); //$NON-NLS-1$
|
||||
String platformName = settings.get(PLATFORM_NAME, ""); //$NON-NLS-1$
|
||||
String boardName = settings.get(BOARD_NAME, ""); //$NON-NLS-1$
|
||||
ArduinoBoard b = manager.getBoard(boardName, platformName, packageName);
|
||||
|
||||
public static class Factory implements IAdapterFactory {
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> T getAdapter(Object adaptableObject, Class<T> adapterType) {
|
||||
if (adapterType.equals(ArduinoBuildConfiguration.class) && adaptableObject instanceof IBuildConfiguration) {
|
||||
IBuildConfiguration config = (IBuildConfiguration) adaptableObject;
|
||||
ArduinoBuildConfiguration arduinoConfig = cache.get(config);
|
||||
if (arduinoConfig == null) {
|
||||
arduinoConfig = new ArduinoBuildConfiguration(config);
|
||||
cache.put(config, arduinoConfig);
|
||||
}
|
||||
return (T) arduinoConfig;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getAdapterList() {
|
||||
return new Class<?>[] { ArduinoBuildConfiguration.class };
|
||||
}
|
||||
}
|
||||
|
||||
public static ArduinoBuildConfiguration getConfig(IProject project, ArduinoRemoteConnection target,
|
||||
IProgressMonitor monitor) throws CoreException {
|
||||
ArduinoBoard board = target.getBoard();
|
||||
|
||||
// return it if it exists already
|
||||
for (IBuildConfiguration config : project.getBuildConfigs()) {
|
||||
if (!config.getName().equals(IBuildConfiguration.DEFAULT_CONFIG_NAME)) {
|
||||
ArduinoBuildConfiguration arduinoConfig = config.getAdapter(ArduinoBuildConfiguration.class);
|
||||
if (arduinoConfig.matches(target)) {
|
||||
return arduinoConfig;
|
||||
if (b == null) {
|
||||
// Default to Uno or first one we find
|
||||
b = manager.getBoard("Arduino/Genuino Uno", "Arduino AVR Boards", "arduino"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
if (b == null) {
|
||||
List<ArduinoBoard> boards = manager.getInstalledBoards();
|
||||
if (!boards.isEmpty()) {
|
||||
b = boards.get(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
board = b;
|
||||
|
||||
// Not found, need to create one
|
||||
Set<String> configNames = new HashSet<>();
|
||||
for (IBuildConfiguration config : project.getBuildConfigs()) {
|
||||
configNames.add(config.getName());
|
||||
}
|
||||
String newName = board.getId();
|
||||
int n = 0;
|
||||
while (configNames.contains(newName)) {
|
||||
newName = board.getId() + (++n);
|
||||
}
|
||||
configNames.add(newName);
|
||||
IProjectDescription projectDesc = project.getDescription();
|
||||
projectDesc.setBuildConfigs(configNames.toArray(new String[configNames.size()]));
|
||||
project.setDescription(projectDesc, monitor);
|
||||
|
||||
// set it up for the board
|
||||
IBuildConfiguration config = project.getBuildConfig(newName);
|
||||
ArduinoBuildConfiguration arduinoConfig = config.getAdapter(ArduinoBuildConfiguration.class);
|
||||
arduinoConfig.setBoard(target);
|
||||
|
||||
return arduinoConfig;
|
||||
int i = name.lastIndexOf('.');
|
||||
this.launchMode = name.substring(i + 1);
|
||||
}
|
||||
|
||||
public void setActive(IProgressMonitor monitor) throws CoreException {
|
||||
IProject project = config.getProject();
|
||||
if (config.equals(project.getActiveBuildConfig())) {
|
||||
// already set
|
||||
return;
|
||||
}
|
||||
|
||||
IProjectDescription projectDesc = project.getDescription();
|
||||
projectDesc.setActiveBuildConfig(config.getName());
|
||||
project.setDescription(projectDesc, monitor);
|
||||
|
||||
// Reindex - assuming for now each config has different compiler
|
||||
// settings
|
||||
CCorePlugin.getIndexManager().reindex(CoreModel.getDefault().create(project));
|
||||
}
|
||||
|
||||
public IEclipsePreferences getSettings() {
|
||||
return (IEclipsePreferences) new ProjectScope(config.getProject()).getNode(Activator.getId()).node("config") //$NON-NLS-1$
|
||||
.node(config.getName());
|
||||
}
|
||||
|
||||
public void setBoard(ArduinoBoard board) throws CoreException {
|
||||
ArduinoBuildConfiguration(IBuildConfiguration config, String name, ArduinoBoard board, String launchMode)
|
||||
throws CoreException {
|
||||
super(config, name);
|
||||
this.board = board;
|
||||
this.launchMode = launchMode;
|
||||
|
||||
// Create the toolChain
|
||||
IToolChainManager toolChainManager = Activator.getService(IToolChainManager.class);
|
||||
IToolChainProvider provider = toolChainManager.getProvider(ArduinoToolChainProvider.ID);
|
||||
IToolChain toolChain = new ArduinoToolChain(provider, this);
|
||||
toolChainManager.addToolChain(toolChain);
|
||||
setToolChain(toolChain);
|
||||
|
||||
// Store the board identifer
|
||||
ArduinoPlatform platform = board.getPlatform();
|
||||
ArduinoPackage pkg = platform.getPackage();
|
||||
|
||||
IEclipsePreferences settings = getSettings();
|
||||
Preferences settings = getSettings();
|
||||
settings.put(PACKAGE_NAME, pkg.getName());
|
||||
settings.put(PLATFORM_NAME, platform.getName());
|
||||
settings.put(BOARD_NAME, board.getName());
|
||||
|
||||
try {
|
||||
settings.flush();
|
||||
} catch (BackingStoreException e) {
|
||||
|
@ -187,19 +147,14 @@ public class ArduinoBuildConfiguration {
|
|||
}
|
||||
}
|
||||
|
||||
public void setBoard(ArduinoRemoteConnection target) throws CoreException {
|
||||
this.board = target.getBoard();
|
||||
|
||||
ArduinoPlatform platform = board.getPlatform();
|
||||
ArduinoPackage pkg = platform.getPackage();
|
||||
|
||||
IEclipsePreferences settings = getSettings();
|
||||
settings.put(PACKAGE_NAME, pkg.getName());
|
||||
settings.put(PLATFORM_NAME, platform.getName());
|
||||
settings.put(BOARD_NAME, board.getName());
|
||||
ArduinoBuildConfiguration(IBuildConfiguration config, String name, ArduinoRemoteConnection target,
|
||||
String launchMode) throws CoreException {
|
||||
this(config, name, target.getBoard(), launchMode);
|
||||
|
||||
// Store the menu settings
|
||||
HierarchicalProperties menus = board.getMenus();
|
||||
if (menus != null) {
|
||||
Preferences settings = getSettings();
|
||||
for (String id : menus.getChildren().keySet()) {
|
||||
String key = ArduinoBoard.MENU_QUALIFIER + id;
|
||||
String value = target.getRemoteConnection().getAttribute(key);
|
||||
|
@ -207,22 +162,39 @@ public class ArduinoBuildConfiguration {
|
|||
settings.put(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
settings.flush();
|
||||
} catch (BackingStoreException e) {
|
||||
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Saving preferences", e)); //$NON-NLS-1$
|
||||
try {
|
||||
settings.flush();
|
||||
} catch (BackingStoreException e) {
|
||||
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Saving preferences", e)); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static String generateName(ArduinoBoard board, String launchMode) {
|
||||
return "arduino." + board.getId() + '.' + launchMode; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> T getAdapter(Class<T> adapter) {
|
||||
if (adapter.equals(ArduinoBuildConfiguration.class)) {
|
||||
return (T) this;
|
||||
}
|
||||
return super.getAdapter(adapter);
|
||||
}
|
||||
|
||||
public String getLaunchMode() {
|
||||
return launchMode;
|
||||
}
|
||||
|
||||
public boolean matches(ArduinoRemoteConnection target) throws CoreException {
|
||||
ArduinoBoard otherBoard = target.getBoard();
|
||||
if (!getBoard().equals(otherBoard)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
IEclipsePreferences settings = getSettings();
|
||||
Preferences settings = getSettings();
|
||||
HierarchicalProperties menus = board.getMenus();
|
||||
if (menus != null) {
|
||||
for (String id : menus.getChildren().keySet()) {
|
||||
|
@ -237,24 +209,6 @@ public class ArduinoBuildConfiguration {
|
|||
}
|
||||
|
||||
public ArduinoBoard getBoard() throws CoreException {
|
||||
if (board == null) {
|
||||
IEclipsePreferences settings = getSettings();
|
||||
String packageName = settings.get(PACKAGE_NAME, ""); //$NON-NLS-1$
|
||||
String platformName = settings.get(PLATFORM_NAME, ""); //$NON-NLS-1$
|
||||
String boardName = settings.get(BOARD_NAME, ""); //$NON-NLS-1$
|
||||
board = manager.getBoard(boardName, platformName, packageName);
|
||||
|
||||
if (board == null) {
|
||||
// Default to Uno or first one we find
|
||||
board = manager.getBoard("Arduino/Genuino Uno", "Arduino AVR Boards", "arduino"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
if (board == null) {
|
||||
List<ArduinoBoard> boards = manager.getInstalledBoards();
|
||||
if (!boards.isEmpty()) {
|
||||
board = boards.get(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return board;
|
||||
}
|
||||
|
||||
|
@ -268,7 +222,7 @@ public class ArduinoBuildConfiguration {
|
|||
properties.put("runtime.ide.version", "10607"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
properties.put("software", "ARDUINO"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
properties.put("build.arch", platform.getArchitecture().toUpperCase()); //$NON-NLS-1$
|
||||
String configName = config.getName();
|
||||
String configName = getBuildConfiguration().getName();
|
||||
if (configName.equals(IBuildConfiguration.DEFAULT_CONFIG_NAME)) {
|
||||
configName = "default"; //$NON-NLS-1$
|
||||
}
|
||||
|
@ -289,7 +243,7 @@ public class ArduinoBuildConfiguration {
|
|||
properties.putAll(board.getBoardProperties());
|
||||
|
||||
// Menus
|
||||
IEclipsePreferences settings = getSettings();
|
||||
Preferences settings = getSettings();
|
||||
HierarchicalProperties menus = board.getMenus();
|
||||
if (menus != null) {
|
||||
for (String menuId : menus.getChildren().keySet()) {
|
||||
|
@ -302,48 +256,22 @@ public class ArduinoBuildConfiguration {
|
|||
}
|
||||
|
||||
// always do this in case the project changes names
|
||||
properties.put("build.project_name", config.getProject().getName()); //$NON-NLS-1$
|
||||
properties.put("build.project_name", getProject().getName()); //$NON-NLS-1$
|
||||
return properties;
|
||||
}
|
||||
|
||||
public IFolder getBuildFolder() throws CoreException {
|
||||
IProject project = config.getProject();
|
||||
return project.getFolder("build"); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
public File getBuildDirectory() throws CoreException {
|
||||
return new File(getBuildFolder().getLocationURI());
|
||||
}
|
||||
|
||||
public IFile getMakeFile() throws CoreException {
|
||||
IFolder buildFolder = getBuildFolder();
|
||||
IFolder buildFolder = (IFolder) getBuildContainer();
|
||||
ArduinoBoard board = getBoard();
|
||||
String makeFileName = board.getId() + ".mk"; //$NON-NLS-1$
|
||||
return buildFolder.getFile(makeFileName);
|
||||
}
|
||||
|
||||
public IFile generateMakeFile(IProgressMonitor monitor) throws CoreException {
|
||||
final IProject project = config.getProject();
|
||||
|
||||
IFolder buildFolder = getBuildFolder();
|
||||
if (!buildFolder.exists()) {
|
||||
buildFolder.create(true, true, monitor);
|
||||
buildFolder.setDerived(true, monitor);
|
||||
ICProject cproject = CoreModel.getDefault().create(project);
|
||||
IOutputEntry output = CoreModel.newOutputEntry(buildFolder.getFullPath());
|
||||
IPathEntry[] oldEntries = cproject.getRawPathEntries();
|
||||
IPathEntry[] newEntries = new IPathEntry[oldEntries.length + 1];
|
||||
System.arraycopy(oldEntries, 0, newEntries, 0, oldEntries.length);
|
||||
newEntries[oldEntries.length] = output;
|
||||
cproject.setRawPathEntries(newEntries, monitor);
|
||||
}
|
||||
|
||||
public Map<String, Object> getBuildModel() throws CoreException {
|
||||
IProject project = getProject();
|
||||
ArduinoBoard board = getBoard();
|
||||
ArduinoPlatform platform = board.getPlatform();
|
||||
|
||||
IFile makeFile = getMakeFile();
|
||||
|
||||
// The board id
|
||||
Map<String, Object> buildModel = new HashMap<>();
|
||||
buildModel.put("boardId", board.getId()); //$NON-NLS-1$
|
||||
|
||||
|
@ -417,9 +345,56 @@ public class ArduinoBuildConfiguration {
|
|||
buildModel.put("recipe_objcopy_bin_pattern", resolveProperty("recipe.objcopy.bin.pattern", properties)); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
buildModel.put("recipe_size_pattern", resolveProperty("recipe.size.pattern", properties)); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
|
||||
ArduinoTemplateGenerator templateGen = new ArduinoTemplateGenerator();
|
||||
templateGen.generateFile(buildModel, "board.mk", makeFile, monitor); //$NON-NLS-1$
|
||||
return makeFile;
|
||||
return buildModel;
|
||||
}
|
||||
|
||||
public IFile generateMakeFile(IProgressMonitor monitor) throws CoreException {
|
||||
IFolder buildFolder = (IFolder) getBuildContainer();
|
||||
if (!buildFolder.exists()) {
|
||||
buildFolder.create(true, true, monitor);
|
||||
}
|
||||
|
||||
IFile makefile = getMakeFile();
|
||||
|
||||
Map<String, Object> buildModel = getBuildModel();
|
||||
|
||||
// Generate the Makefile
|
||||
try (StringWriter writer = new StringWriter()) {
|
||||
if (templateConfig == null) {
|
||||
templateConfig = new Configuration(Configuration.VERSION_2_3_22);
|
||||
templateConfig.setTemplateLoader(this);
|
||||
}
|
||||
|
||||
Template template = templateConfig.getTemplate("templates/Makefile"); //$NON-NLS-1$
|
||||
template.process(buildModel, writer);
|
||||
try (ByteArrayInputStream in = new ByteArrayInputStream(
|
||||
writer.getBuffer().toString().getBytes(StandardCharsets.UTF_8))) {
|
||||
createParent(makefile, monitor);
|
||||
if (makefile.exists()) {
|
||||
makefile.setContents(in, true, true, monitor);
|
||||
} else {
|
||||
makefile.create(in, true, monitor);
|
||||
}
|
||||
}
|
||||
} catch (IOException | TemplateException e) {
|
||||
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Error generating makefile", e));
|
||||
}
|
||||
|
||||
return makefile;
|
||||
}
|
||||
|
||||
protected static void createParent(IResource child, IProgressMonitor monitor) throws CoreException {
|
||||
if (child == null)
|
||||
return;
|
||||
|
||||
IContainer container = child.getParent();
|
||||
if (container.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
IFolder parent = container.getAdapter(IFolder.class);
|
||||
createParent(parent, monitor);
|
||||
parent.create(true, true, monitor);
|
||||
}
|
||||
|
||||
public static boolean isSource(String filename) {
|
||||
|
@ -435,35 +410,30 @@ public class ArduinoBuildConfiguration {
|
|||
}
|
||||
}
|
||||
|
||||
private String resolveProperty(String property, Properties dict) {
|
||||
String res = dict.getProperty(property);
|
||||
if (res == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private String resolvePropertyValue(String value, Properties dict) {
|
||||
String last;
|
||||
do {
|
||||
last = res;
|
||||
for (int i = res.indexOf('{'); i >= 0; i = res.indexOf('{', i)) {
|
||||
last = value;
|
||||
for (int i = value.indexOf('{'); i >= 0; i = value.indexOf('{', i)) {
|
||||
i++;
|
||||
int n = res.indexOf('}', i);
|
||||
int n = value.indexOf('}', i);
|
||||
if (n >= 0) {
|
||||
String p2 = res.substring(i, n);
|
||||
String p2 = value.substring(i, n);
|
||||
String r2 = dict.getProperty(p2);
|
||||
if (r2 != null) {
|
||||
res = res.replace('{' + p2 + '}', r2);
|
||||
value = value.replace('{' + p2 + '}', r2);
|
||||
}
|
||||
}
|
||||
i = n;
|
||||
}
|
||||
} while (!res.equals(last));
|
||||
} while (!value.equals(last));
|
||||
|
||||
return res;
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setEnvironment(Map<String, String> env) throws CoreException {
|
||||
// Everything is specified with full path, do not need to add anything
|
||||
// to the environment.
|
||||
private String resolveProperty(String property, Properties dict) {
|
||||
String value = dict.getProperty(property);
|
||||
return value != null ? resolvePropertyValue(value, dict) : null;
|
||||
}
|
||||
|
||||
public String getMakeCommand() {
|
||||
|
@ -546,31 +516,75 @@ public class ArduinoBuildConfiguration {
|
|||
}
|
||||
}
|
||||
|
||||
public IScannerInfo getScannerInfo(IResource resource) throws CoreException {
|
||||
IContentType contentType = CCorePlugin.getContentType(resource.getProject(), resource.getName());
|
||||
if (contentType != null) {
|
||||
// what language is this resource and pick the right path;
|
||||
switch (contentType.getId()) {
|
||||
case CCorePlugin.CONTENT_TYPE_CXXSOURCE:
|
||||
case CCorePlugin.CONTENT_TYPE_CXXHEADER:
|
||||
if (cppScannerInfo == null) {
|
||||
cppScannerInfo = calculateScannerInfo("recipe.cpp.o.pattern", resource); //$NON-NLS-1$
|
||||
}
|
||||
return cppScannerInfo;
|
||||
default:
|
||||
if (cScannerInfo == null) {
|
||||
cScannerInfo = calculateScannerInfo("recipe.c.o.pattern", resource); //$NON-NLS-1$
|
||||
}
|
||||
return cScannerInfo;
|
||||
}
|
||||
}
|
||||
// use the cpp scanner info if all else fails
|
||||
return cppScannerInfo;
|
||||
}
|
||||
// Scanner Info Cache
|
||||
private String[] cachedIncludePath;
|
||||
private String cachedInfoCommand;
|
||||
private IScannerInfo cachedScannerInfo;
|
||||
|
||||
public void clearScannerInfoCache() {
|
||||
cppScannerInfo = null;
|
||||
cScannerInfo = null;
|
||||
@Override
|
||||
public IScannerInfo getScannerInformation(IResource resource) {
|
||||
try {
|
||||
IContentType contentType = CCorePlugin.getContentType(resource.getProject(), resource.getName());
|
||||
String recipe;
|
||||
if (contentType != null && (contentType.getId() == CCorePlugin.CONTENT_TYPE_CSOURCE
|
||||
|| contentType.getId() == CCorePlugin.CONTENT_TYPE_CSOURCE)) {
|
||||
recipe = "recipe.c.o.pattern"; //$NON-NLS-1$
|
||||
} else {
|
||||
recipe = "recipe.cpp.o.pattern"; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
ArduinoPlatform platform = getBoard().getPlatform();
|
||||
Properties properties = new Properties();
|
||||
properties.putAll(getProperties());
|
||||
|
||||
// Overrides for scanner discovery
|
||||
properties.put("source_file", ""); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
properties.put("object_file", "-"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
// the base scanner info does includes
|
||||
properties.put("includes", ""); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
String commandString = resolveProperty(recipe, properties);
|
||||
|
||||
List<Path> includePath = new ArrayList<>();
|
||||
includePath.addAll(platform.getIncludePath());
|
||||
Collection<ArduinoLibrary> libs = manager.getLibraries(getProject());
|
||||
for (ArduinoLibrary lib : libs) {
|
||||
includePath.addAll(lib.getIncludePath());
|
||||
}
|
||||
String[] includes = includePath.stream()
|
||||
.map(path -> resolvePropertyValue(path.toString(), properties)).collect(Collectors.toList())
|
||||
.toArray(new String[includePath.size()]);
|
||||
|
||||
// Use cache if we can
|
||||
if (cachedScannerInfo != null && cachedInfoCommand.equals(commandString)
|
||||
&& cachedIncludePath.length == includes.length) {
|
||||
boolean matches = true;
|
||||
for (int i = 0; i < includes.length; ++i) {
|
||||
if (!includes[i].equals(cachedIncludePath[i])) {
|
||||
matches = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (matches) {
|
||||
return cachedScannerInfo;
|
||||
}
|
||||
}
|
||||
|
||||
ExtendedScannerInfo baseInfo = new ExtendedScannerInfo(null, includes);
|
||||
String[] command = splitCommand(commandString);
|
||||
IScannerInfo info = getToolChain().getScannerInfo(getBuildConfiguration(), Paths.get(command[0]),
|
||||
Arrays.copyOfRange(command, 1, command.length), baseInfo, resource, getBuildDirectoryURI());
|
||||
|
||||
// cache the results
|
||||
cachedScannerInfo = info;
|
||||
cachedInfoCommand = commandString;
|
||||
cachedIncludePath = includes;
|
||||
|
||||
return info;
|
||||
} catch (CoreException e) {
|
||||
Activator.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static String pathString(Path path) {
|
||||
|
@ -581,109 +595,151 @@ public class ArduinoBuildConfiguration {
|
|||
return str;
|
||||
}
|
||||
|
||||
private IScannerInfo calculateScannerInfo(String recipe, IResource resource) throws CoreException {
|
||||
try {
|
||||
ArduinoPlatform platform = getBoard().getPlatform();
|
||||
Properties properties = new Properties();
|
||||
properties.putAll(getProperties());
|
||||
|
||||
Path tmpFile = Files.createTempFile("cdt", ".cpp"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
properties.put("source_file", pathString(tmpFile)); //$NON-NLS-1$
|
||||
properties.put("object_file", "-"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
|
||||
String includes = "-E -P -v -dD"; //$NON-NLS-1$
|
||||
for (Path include : platform.getIncludePath()) {
|
||||
includes += " -I\"" + pathString(include) + '"'; //$NON-NLS-1$
|
||||
}
|
||||
Collection<ArduinoLibrary> libs = manager.getLibraries(config.getProject());
|
||||
for (ArduinoLibrary lib : libs) {
|
||||
for (Path path : lib.getIncludePath()) {
|
||||
includes += " -I\"" + pathString(path) + '"'; //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
properties.put("includes", includes); //$NON-NLS-1$
|
||||
|
||||
String[] command;
|
||||
if (isWindows) {
|
||||
command = splitCommand(resolveProperty(recipe, properties));
|
||||
} else {
|
||||
command = new String[] { "sh", "-c", resolveProperty(recipe, properties) }; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
ProcessBuilder processBuilder = new ProcessBuilder(command).directory(tmpFile.getParent().toFile())
|
||||
.redirectErrorStream(true);
|
||||
setEnvironment(processBuilder.environment());
|
||||
Process process = processBuilder.start();
|
||||
|
||||
Map<String, String> symbols = new HashMap<>();
|
||||
List<String> includePath = new ArrayList<>();
|
||||
Pattern definePattern = Pattern.compile("#define (.*)\\s(.*)"); //$NON-NLS-1$
|
||||
boolean inIncludePaths = false;
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
|
||||
for (String line = reader.readLine(); line != null; line = reader.readLine()) {
|
||||
if (inIncludePaths) {
|
||||
if (line.equals("End of search list.")) { //$NON-NLS-1$
|
||||
inIncludePaths = false;
|
||||
} else {
|
||||
includePath.add(line.trim());
|
||||
}
|
||||
} else if (line.startsWith("#define ")) { //$NON-NLS-1$
|
||||
Matcher matcher = definePattern.matcher(line);
|
||||
if (matcher.matches()) {
|
||||
symbols.put(matcher.group(1), matcher.group(2));
|
||||
}
|
||||
} else if (line.equals("#include <...> search starts here:")) { //$NON-NLS-1$
|
||||
inIncludePaths = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Files.delete(tmpFile);
|
||||
ExtendedScannerInfo scannerInfo = new ExtendedScannerInfo(symbols,
|
||||
includePath.toArray(new String[includePath.size()]));
|
||||
return scannerInfo;
|
||||
} catch (IOException e) {
|
||||
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Compiler built-ins", e)); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
private String[] splitCommand(String command) {
|
||||
// TODO deal with quotes properly, for now just strip
|
||||
return command.replaceAll("\"", "").split("\\s+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
}
|
||||
|
||||
public ArduinoConsoleParser[] getBuildConsoleParsers() {
|
||||
// ../src/Test.cpp:4:1: error: 'x' was not declared in this scope
|
||||
@Override
|
||||
public IProject[] build(int kind, Map<String, String> args, IConsole console, IProgressMonitor monitor)
|
||||
throws CoreException {
|
||||
IProject project = getProject();
|
||||
try {
|
||||
project.deleteMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE);
|
||||
|
||||
return new ArduinoConsoleParser[] { new ArduinoErrorParser("(.*?):(\\d+):(\\d+:)? (fatal )?error: (.*)") { //$NON-NLS-1$
|
||||
@Override
|
||||
protected int getSeverity(Matcher matcher) {
|
||||
return IMarker.SEVERITY_ERROR;
|
||||
ConsoleOutputStream consoleOut = console.getOutputStream();
|
||||
consoleOut.write(String.format("\nBuilding %s\n", project.getName()));
|
||||
|
||||
generateMakeFile(monitor);
|
||||
|
||||
try (ErrorParserManager epm = new ErrorParserManager(project, getBuildDirectoryURI(), this,
|
||||
getToolChain().getErrorParserIds())) {
|
||||
ProcessBuilder processBuilder = new ProcessBuilder().command(getBuildCommand())
|
||||
.directory(getBuildDirectory().toFile());
|
||||
setBuildEnvironment(processBuilder.environment());
|
||||
Process process = processBuilder.start();
|
||||
if (watchProcess(process, new IConsoleParser[] { epm }, console) == 0) {
|
||||
showSizes(console);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getMessage(Matcher matcher) {
|
||||
return matcher.group(matcher.groupCount());
|
||||
getBuildContainer().refreshLocal(IResource.DEPTH_INFINITE, monitor);
|
||||
} catch (IOException e) {
|
||||
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Build error", e));
|
||||
}
|
||||
|
||||
// TODO if there are references we want to watch, return them here
|
||||
return new IProject[] { project };
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clean(IConsole console, IProgressMonitor monitor) throws CoreException {
|
||||
try {
|
||||
IProject project = getProject();
|
||||
project.deleteMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE);
|
||||
|
||||
ConsoleOutputStream consoleOut = console.getOutputStream();
|
||||
consoleOut.write(String.format("\nCleaning %s\n", project.getName()));
|
||||
|
||||
ProcessBuilder processBuilder = new ProcessBuilder().command(getCleanCommand())
|
||||
.directory(getBuildDirectory().toFile());
|
||||
setBuildEnvironment(processBuilder.environment());
|
||||
Process process = processBuilder.start();
|
||||
|
||||
watchProcess(process, new IConsoleParser[0], console);
|
||||
|
||||
getBuildContainer().refreshLocal(IResource.DEPTH_INFINITE, monitor);
|
||||
} catch (IOException e) {
|
||||
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Build error", e));
|
||||
}
|
||||
}
|
||||
|
||||
private void showSizes(IConsole console) throws CoreException {
|
||||
try {
|
||||
int codeSize = -1;
|
||||
int dataSize = -1;
|
||||
|
||||
String codeSizeRegex = getCodeSizeRegex();
|
||||
Pattern codeSizePattern = codeSizeRegex != null ? Pattern.compile(codeSizeRegex) : null;
|
||||
String dataSizeRegex = getDataSizeRegex();
|
||||
Pattern dataSizePattern = dataSizeRegex != null ? Pattern.compile(dataSizeRegex) : null;
|
||||
|
||||
if (codeSizePattern == null && dataSizePattern == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLineNumber(Matcher matcher) {
|
||||
return Integer.parseInt(matcher.group(2));
|
||||
int maxCodeSize = getMaxCodeSize();
|
||||
int maxDataSize = getMaxDataSize();
|
||||
|
||||
ProcessBuilder processBuilder = new ProcessBuilder().command(getSizeCommand())
|
||||
.directory(getBuildDirectory().toFile()).redirectErrorStream(true);
|
||||
setBuildEnvironment(processBuilder.environment());
|
||||
Process process = processBuilder.start();
|
||||
try (BufferedReader processOut = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
|
||||
for (String line = processOut.readLine(); line != null; line = processOut.readLine()) {
|
||||
if (codeSizePattern != null) {
|
||||
Matcher matcher = codeSizePattern.matcher(line);
|
||||
if (matcher.matches()) {
|
||||
codeSize += Integer.parseInt(matcher.group(1));
|
||||
}
|
||||
}
|
||||
if (dataSizePattern != null) {
|
||||
Matcher matcher = dataSizePattern.matcher(line);
|
||||
if (matcher.matches()) {
|
||||
dataSize += Integer.parseInt(matcher.group(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getFileName(Matcher matcher) {
|
||||
return matcher.group(1);
|
||||
ConsoleOutputStream consoleOut = console.getOutputStream();
|
||||
consoleOut.write("Program store usage: " + codeSize);
|
||||
if (maxCodeSize > 0) {
|
||||
consoleOut.write(" of maximum " + maxCodeSize);
|
||||
}
|
||||
consoleOut.write(" bytes\n");
|
||||
|
||||
@Override
|
||||
protected int getLinkOffset(Matcher matcher) {
|
||||
if (maxDataSize >= 0) {
|
||||
consoleOut.write("Initial RAM usage: " + dataSize);
|
||||
if (maxCodeSize > 0) {
|
||||
consoleOut.write(" of maximum " + maxDataSize);
|
||||
}
|
||||
consoleOut.write(" bytes\n");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Checking sizes", e));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object findTemplateSource(String name) throws IOException {
|
||||
return FileLocator.find(Activator.getPlugin().getBundle(), new org.eclipse.core.runtime.Path(name), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastModified(Object source) {
|
||||
try {
|
||||
URL url = (URL) source;
|
||||
if (url.getProtocol().equals("file")) { //$NON-NLS-1$
|
||||
File file = new File(url.toURI());
|
||||
return file.lastModified();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} catch (URISyntaxException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLinkLength(Matcher matcher) {
|
||||
return matcher.group(1).length() + 1 + matcher.group(2).length() + 1 + matcher.group(3).length();
|
||||
}
|
||||
} };
|
||||
@Override
|
||||
public Reader getReader(Object source, String encoding) throws IOException {
|
||||
URL url = (URL) source;
|
||||
return new InputStreamReader(url.openStream(), encoding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeTemplateSource(Object arg0) throws IOException {
|
||||
// Nothing
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2016 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.arduino.core.internal.build;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.arduino.core.internal.Activator;
|
||||
import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoard;
|
||||
import org.eclipse.cdt.arduino.core.internal.board.ArduinoManager;
|
||||
import org.eclipse.cdt.arduino.core.internal.remote.ArduinoRemoteConnection;
|
||||
import org.eclipse.cdt.core.build.ICBuildConfiguration;
|
||||
import org.eclipse.cdt.core.build.ICBuildConfigurationManager;
|
||||
import org.eclipse.cdt.core.build.ICBuildConfigurationProvider;
|
||||
import org.eclipse.core.resources.IBuildConfiguration;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
|
||||
public class ArduinoBuildConfigurationProvider implements ICBuildConfigurationProvider {
|
||||
|
||||
public static final String ID = "org.eclipse.cdt.arduino.core.provider"; //$NON-NLS-1$
|
||||
|
||||
private static final ICBuildConfigurationManager configManager = Activator
|
||||
.getService(ICBuildConfigurationManager.class);
|
||||
private static final ArduinoManager arduinoManager = Activator.getService(ArduinoManager.class);
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICBuildConfiguration getCBuildConfiguration(IBuildConfiguration config, String name) throws CoreException {
|
||||
return new ArduinoBuildConfiguration(config, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICBuildConfiguration getDefaultCBuildConfiguration(IProject project) throws CoreException {
|
||||
ArduinoBoard board = arduinoManager.getBoard("Arduino/Genuino Uno", "Arduino AVR Boards", "arduino"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
if (board == null) {
|
||||
List<ArduinoBoard> boards = arduinoManager.getInstalledBoards();
|
||||
if (!boards.isEmpty()) {
|
||||
board = boards.get(0);
|
||||
}
|
||||
}
|
||||
if (board != null) {
|
||||
String launchMode = "run"; //$NON-NLS-1$
|
||||
for (IBuildConfiguration config : project.getBuildConfigs()) {
|
||||
ICBuildConfiguration cconfig = config.getAdapter(ICBuildConfiguration.class);
|
||||
if (cconfig != null) {
|
||||
ArduinoBuildConfiguration arduinoConfig = cconfig.getAdapter(ArduinoBuildConfiguration.class);
|
||||
if (arduinoConfig != null && arduinoConfig.getLaunchMode().equals(launchMode)
|
||||
&& arduinoConfig.getBoard().equals(board)) {
|
||||
return arduinoConfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// not found, create one
|
||||
String configName = ArduinoBuildConfiguration.generateName(board, launchMode);
|
||||
IBuildConfiguration config = configManager.createBuildConfiguration(this, project, configName,
|
||||
null);
|
||||
ArduinoBuildConfiguration arduinoConfig = new ArduinoBuildConfiguration(config, configName, board,
|
||||
launchMode);
|
||||
arduinoConfig.setActive(null);
|
||||
configManager.addBuildConfiguration(config, arduinoConfig);
|
||||
return arduinoConfig;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ArduinoBuildConfiguration getConfiguration(IProject project, ArduinoRemoteConnection target,
|
||||
String launchMode,
|
||||
IProgressMonitor monitor) throws CoreException {
|
||||
ArduinoBoard board = target.getBoard();
|
||||
for (IBuildConfiguration config : project.getBuildConfigs()) {
|
||||
ICBuildConfiguration cconfig = config.getAdapter(ICBuildConfiguration.class);
|
||||
if (cconfig != null) {
|
||||
ArduinoBuildConfiguration arduinoConfig = cconfig.getAdapter(ArduinoBuildConfiguration.class);
|
||||
if (arduinoConfig != null && arduinoConfig.getLaunchMode().equals(launchMode)
|
||||
&& arduinoConfig.getBoard().equals(board) && arduinoConfig.matches(target)) {
|
||||
return arduinoConfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ArduinoBuildConfiguration createConfiguration(IProject project, ArduinoRemoteConnection target,
|
||||
String launchMode,
|
||||
IProgressMonitor monitor) throws CoreException {
|
||||
ArduinoBoard board = target.getBoard();
|
||||
String configName = ArduinoBuildConfiguration.generateName(board, launchMode);
|
||||
IBuildConfiguration config = configManager.createBuildConfiguration(this, project, configName,
|
||||
monitor);
|
||||
ArduinoBuildConfiguration arduinoConfig = new ArduinoBuildConfiguration(config, configName, target, launchMode);
|
||||
return arduinoConfig;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,147 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015 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.arduino.core.internal.build;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.cdt.arduino.core.internal.Activator;
|
||||
import org.eclipse.cdt.arduino.core.internal.console.ArduinoConsoleService;
|
||||
import org.eclipse.cdt.core.model.ICModelMarker;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.resources.IncrementalProjectBuilder;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
|
||||
/**
|
||||
* This class is responsible for generating the Makefile for the current build config.
|
||||
*/
|
||||
public class ArduinoBuilder extends IncrementalProjectBuilder {
|
||||
|
||||
public static final String ID = Activator.getId() + ".arduinoBuilder"; //$NON-NLS-1$
|
||||
|
||||
@Override
|
||||
protected IProject[] build(int kind, Map<String, String> args, IProgressMonitor monitor) throws CoreException {
|
||||
IProject project = getProject();
|
||||
try {
|
||||
project.deleteMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE);
|
||||
|
||||
ArduinoConsoleService consoleService = Activator.getConsoleService();
|
||||
consoleService.writeOutput(String.format("\nBuilding %s\n", project.getName()));
|
||||
|
||||
ArduinoBuildConfiguration config = getBuildConfig().getAdapter(ArduinoBuildConfiguration.class);
|
||||
config.generateMakeFile(monitor);
|
||||
|
||||
ProcessBuilder processBuilder = new ProcessBuilder().command(config.getBuildCommand())
|
||||
.directory(config.getBuildDirectory());
|
||||
config.setEnvironment(processBuilder.environment());
|
||||
Process process = processBuilder.start();
|
||||
|
||||
consoleService.monitor(process, config.getBuildConsoleParsers(), config.getBuildFolder());
|
||||
|
||||
if (process.exitValue() == 0) {
|
||||
showSizes(config, consoleService);
|
||||
}
|
||||
|
||||
config.getBuildFolder().refreshLocal(IResource.DEPTH_INFINITE, monitor);
|
||||
} catch (IOException e) {
|
||||
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Build error", e));
|
||||
}
|
||||
|
||||
// TODO if there are references we want to watch, return them here
|
||||
return new IProject[] { project };
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void clean(IProgressMonitor monitor) throws CoreException {
|
||||
try {
|
||||
IProject project = getProject();
|
||||
project.deleteMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE);
|
||||
|
||||
ArduinoConsoleService consoleService = Activator.getConsoleService();
|
||||
consoleService.writeOutput(String.format("\nCleaning %s\n", project.getName()));
|
||||
|
||||
ArduinoBuildConfiguration config = getBuildConfig().getAdapter(ArduinoBuildConfiguration.class);
|
||||
|
||||
ProcessBuilder processBuilder = new ProcessBuilder().command(config.getCleanCommand())
|
||||
.directory(config.getBuildDirectory());
|
||||
config.setEnvironment(processBuilder.environment());
|
||||
Process process = processBuilder.start();
|
||||
|
||||
consoleService.monitor(process, config.getBuildConsoleParsers(), config.getBuildFolder());
|
||||
|
||||
config.getBuildFolder().refreshLocal(IResource.DEPTH_INFINITE, monitor);
|
||||
} catch (IOException e) {
|
||||
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Build error", e));
|
||||
}
|
||||
}
|
||||
|
||||
private void showSizes(ArduinoBuildConfiguration config, ArduinoConsoleService console) throws CoreException {
|
||||
try {
|
||||
int codeSize = -1;
|
||||
int dataSize = -1;
|
||||
|
||||
String codeSizeRegex = config.getCodeSizeRegex();
|
||||
Pattern codeSizePattern = codeSizeRegex != null ? Pattern.compile(codeSizeRegex) : null;
|
||||
String dataSizeRegex = config.getDataSizeRegex();
|
||||
Pattern dataSizePattern = dataSizeRegex != null ? Pattern.compile(dataSizeRegex) : null;
|
||||
|
||||
if (codeSizePattern == null && dataSizePattern == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int maxCodeSize = config.getMaxCodeSize();
|
||||
int maxDataSize = config.getMaxDataSize();
|
||||
|
||||
ProcessBuilder processBuilder = new ProcessBuilder().command(config.getSizeCommand())
|
||||
.directory(config.getBuildDirectory()).redirectErrorStream(true);
|
||||
config.setEnvironment(processBuilder.environment());
|
||||
Process process = processBuilder.start();
|
||||
try (BufferedReader processOut = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
|
||||
for (String line = processOut.readLine(); line != null; line = processOut.readLine()) {
|
||||
if (codeSizePattern != null) {
|
||||
Matcher matcher = codeSizePattern.matcher(line);
|
||||
if (matcher.matches()) {
|
||||
codeSize += Integer.parseInt(matcher.group(1));
|
||||
}
|
||||
}
|
||||
if (dataSizePattern != null) {
|
||||
Matcher matcher = dataSizePattern.matcher(line);
|
||||
if (matcher.matches()) {
|
||||
dataSize += Integer.parseInt(matcher.group(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.writeOutput("Program store usage: " + codeSize);
|
||||
if (maxCodeSize > 0) {
|
||||
console.writeOutput(" of maximum " + maxCodeSize);
|
||||
}
|
||||
console.writeOutput(" bytes\n");
|
||||
|
||||
if (maxDataSize >= 0) {
|
||||
console.writeOutput("Initial RAM usage: " + dataSize);
|
||||
if (maxCodeSize > 0) {
|
||||
console.writeOutput(" of maximum " + maxDataSize);
|
||||
}
|
||||
console.writeOutput(" bytes\n");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Checking sizes", e));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package org.eclipse.cdt.arduino.core.internal.build;
|
||||
|
||||
import org.eclipse.cdt.arduino.core.internal.Activator;
|
||||
import org.eclipse.cdt.build.gcc.core.GCCToolChain;
|
||||
import org.eclipse.cdt.core.build.ICBuildConfiguration;
|
||||
import org.eclipse.cdt.core.build.ICBuildConfigurationManager;
|
||||
import org.eclipse.cdt.core.build.IToolChain;
|
||||
import org.eclipse.cdt.core.build.IToolChainProvider;
|
||||
import org.eclipse.core.resources.IBuildConfiguration;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
|
||||
public class ArduinoToolChain extends GCCToolChain {
|
||||
|
||||
private final ArduinoBuildConfiguration buildConfig;
|
||||
|
||||
public ArduinoToolChain(IToolChainProvider provider, ArduinoBuildConfiguration config) {
|
||||
super(provider, config.getProject().getName() + '#' + config.getName());
|
||||
this.buildConfig = config;
|
||||
}
|
||||
|
||||
ArduinoToolChain(IToolChainProvider provider, String name) throws CoreException {
|
||||
super(provider, name);
|
||||
String[] segments = name.split("#"); //$NON-NLS-1$
|
||||
if (segments.length == 2) {
|
||||
String projectName = segments[0];
|
||||
String configName = segments[1];
|
||||
|
||||
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
|
||||
if (project != null) {
|
||||
ICBuildConfigurationManager configManager = Activator.getService(ICBuildConfigurationManager.class);
|
||||
IBuildConfiguration config = configManager.getBuildConfiguration(
|
||||
configManager.getProvider(ArduinoBuildConfigurationProvider.ID), project, configName);
|
||||
ICBuildConfiguration cconfig = config.getAdapter(ICBuildConfiguration.class);
|
||||
buildConfig = cconfig.getAdapter(ArduinoBuildConfiguration.class);
|
||||
} else {
|
||||
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "No project"));
|
||||
}
|
||||
} else {
|
||||
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Bad Name"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProperty(String key) {
|
||||
// TODO architecture if I need it
|
||||
if (key.equals(IToolChain.ATTR_OS)) {
|
||||
return "arduino"; //$NON-NLS-1$
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO do I really need this?
|
||||
public ArduinoBuildConfiguration getBuildConfig() {
|
||||
return buildConfig;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package org.eclipse.cdt.arduino.core.internal.build;
|
||||
|
||||
import org.eclipse.cdt.core.build.IToolChain;
|
||||
import org.eclipse.cdt.core.build.IToolChainProvider;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
public class ArduinoToolChainProvider implements IToolChainProvider {
|
||||
|
||||
public static final String ID = "org.eclipse.cdt.arduino.core.toolChainProvider"; //$NON-NLS-1$
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IToolChain getToolChain(String name) throws CoreException {
|
||||
return new ArduinoToolChain(this, name);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015 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.arduino.core.internal.console;
|
||||
|
||||
public abstract class ArduinoConsoleParser {
|
||||
|
||||
private final String pattern;
|
||||
private final int flags;
|
||||
private final String lineQualifier;
|
||||
|
||||
protected ArduinoConsoleParser(String pattern, int flags, String lineQualifier) {
|
||||
this.pattern = pattern;
|
||||
this.flags = flags;
|
||||
this.lineQualifier = lineQualifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pattern to be used for matching. The pattern is a string
|
||||
* representing a regular expression.
|
||||
*
|
||||
* @return the regular expression to be used for matching
|
||||
*/
|
||||
public String getPattern() {
|
||||
return pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the flags to use when compiling this pattern match listener's
|
||||
* regular expression, as defined by by
|
||||
* <code>Pattern.compile(String regex, int flags)</code>
|
||||
*
|
||||
* @return the flags to use when compiling this pattern match listener's
|
||||
* regular expression
|
||||
* @see java.util.regex.Pattern#compile(java.lang.String, int)
|
||||
*/
|
||||
public int getCompilerFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a simple regular expression used to identify lines that may match
|
||||
* this pattern matcher's complete pattern, or <code>null</code>. Use of
|
||||
* this attribute can improve performance by disqualifying lines from the
|
||||
* search. When a line is found containing a match for this expression, the
|
||||
* line is searched from the beginning for this pattern matcher's complete
|
||||
* pattern. Lines not containing this pattern are discarded.
|
||||
*
|
||||
* @return a simple regular expression used to identify lines that may match
|
||||
* this pattern matcher's complete pattern, or <code>null</code>
|
||||
*/
|
||||
public String getLineQualifier() {
|
||||
return lineQualifier;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015 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
|
||||
*
|
||||
* Contributors:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.arduino.core.internal.console;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.core.resources.IFolder;
|
||||
|
||||
public interface ArduinoConsoleService {
|
||||
|
||||
void monitor(Process process, ArduinoConsoleParser[] consoleParsers, IFolder buildDirectory) throws IOException;
|
||||
|
||||
void writeOutput(String msg) throws IOException;
|
||||
|
||||
void writeError(String msg) throws IOException;
|
||||
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015 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.arduino.core.internal.console;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.cdt.arduino.core.internal.Activator;
|
||||
import org.eclipse.cdt.core.model.ICModelMarker;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IFolder;
|
||||
import org.eclipse.core.resources.IMarker;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
public abstract class ArduinoErrorParser extends ArduinoConsoleParser {
|
||||
|
||||
public static final String LINK_OFFSET = "arduino.link.offset"; //$NON-NLS-1$
|
||||
public static final String LINK_LENGTH = "arduino.link.length"; //$NON-NLS-1$
|
||||
|
||||
private final Pattern errorPattern;
|
||||
|
||||
public ArduinoErrorParser(String pattern, int flags, String lineQualifier) {
|
||||
super(pattern, flags, lineQualifier);
|
||||
this.errorPattern = Pattern.compile(pattern);
|
||||
}
|
||||
|
||||
public ArduinoErrorParser(String pattern) {
|
||||
this(pattern, 0, null);
|
||||
}
|
||||
|
||||
protected abstract String getFileName(Matcher matcher);
|
||||
|
||||
protected abstract int getLineNumber(Matcher matcher);
|
||||
|
||||
protected abstract String getMessage(Matcher matcher);
|
||||
|
||||
protected abstract int getSeverity(Matcher matcher);
|
||||
|
||||
protected abstract int getLinkOffset(Matcher matcher);
|
||||
|
||||
protected abstract int getLinkLength(Matcher matcher);
|
||||
|
||||
public IMarker generateMarker(IFolder buildDirectory, String text) throws CoreException {
|
||||
Matcher matcher = errorPattern.matcher(text);
|
||||
if (matcher.matches()) {
|
||||
String fileName = getFileName(matcher);
|
||||
|
||||
IFile file = buildDirectory.getFile(fileName);
|
||||
if (file.exists()) {
|
||||
for (IMarker marker : file.findMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, false,
|
||||
IResource.DEPTH_ZERO)) {
|
||||
if (marker.getAttribute(IMarker.SEVERITY, -1) == getSeverity(matcher)
|
||||
&& marker.getAttribute(IMarker.LINE_NUMBER, -1) == getLineNumber(matcher)
|
||||
&& marker.getAttribute(IMarker.MESSAGE, "").equals(getMessage(matcher))) { //$NON-NLS-1$
|
||||
return marker;
|
||||
}
|
||||
}
|
||||
try {
|
||||
IMarker marker = file.createMarker(ICModelMarker.C_MODEL_PROBLEM_MARKER);
|
||||
marker.setAttribute(IMarker.MESSAGE, getMessage(matcher));
|
||||
marker.setAttribute(IMarker.SEVERITY, getSeverity(matcher));
|
||||
marker.setAttribute(IMarker.LINE_NUMBER, getLineNumber(matcher));
|
||||
marker.setAttribute(IMarker.CHAR_START, -1);
|
||||
marker.setAttribute(IMarker.CHAR_END, -1);
|
||||
marker.setAttribute(LINK_OFFSET, getLinkOffset(matcher));
|
||||
marker.setAttribute(LINK_LENGTH, getLinkLength(matcher));
|
||||
return marker;
|
||||
} catch (CoreException e) {
|
||||
Activator.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -15,7 +15,9 @@ import java.io.IOException;
|
|||
import org.eclipse.cdt.arduino.core.internal.Activator;
|
||||
import org.eclipse.cdt.arduino.core.internal.Messages;
|
||||
import org.eclipse.cdt.arduino.core.internal.build.ArduinoBuildConfiguration;
|
||||
import org.eclipse.cdt.arduino.core.internal.build.ArduinoBuildConfigurationProvider;
|
||||
import org.eclipse.cdt.arduino.core.internal.remote.ArduinoRemoteConnection;
|
||||
import org.eclipse.cdt.core.build.ICBuildConfigurationManager;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
|
@ -34,6 +36,9 @@ public class ArduinoLaunchConfigurationDelegate extends LaunchConfigurationTarge
|
|||
public static final String TYPE_ID = "org.eclipse.cdt.arduino.core.launchConfigurationType"; //$NON-NLS-1$
|
||||
public static final String CONNECTION_NAME = Activator.getId() + ".connectionName"; //$NON-NLS-1$
|
||||
|
||||
private static final ICBuildConfigurationManager buildConfigManager = Activator
|
||||
.getService(ICBuildConfigurationManager.class);
|
||||
|
||||
@Override
|
||||
public ITargetedLaunch getLaunch(ILaunchConfiguration configuration, String mode, ILaunchTarget target)
|
||||
throws CoreException {
|
||||
|
@ -49,7 +54,7 @@ public class ArduinoLaunchConfigurationDelegate extends LaunchConfigurationTarge
|
|||
|
||||
// 1. make sure proper build config is set active
|
||||
IProject project = configuration.getMappedResources()[0].getProject();
|
||||
ArduinoBuildConfiguration arduinoConfig = ArduinoBuildConfiguration.getConfig(project, arduinoTarget,
|
||||
ArduinoBuildConfiguration arduinoConfig = getArduinoConfiguration(project, mode, arduinoTarget,
|
||||
monitor);
|
||||
arduinoConfig.setActive(monitor);
|
||||
}
|
||||
|
@ -81,7 +86,7 @@ public class ArduinoLaunchConfigurationDelegate extends LaunchConfigurationTarge
|
|||
IProject project = (IProject) configuration.getMappedResources()[0];
|
||||
|
||||
// The build config
|
||||
ArduinoBuildConfiguration arduinoConfig = ArduinoBuildConfiguration.getConfig(project, arduinoTarget,
|
||||
ArduinoBuildConfiguration arduinoConfig = getArduinoConfiguration(project, mode, arduinoTarget,
|
||||
monitor);
|
||||
String[] uploadCmd = arduinoConfig.getUploadCommand(arduinoTarget.getPortName());
|
||||
|
||||
|
@ -94,8 +99,9 @@ public class ArduinoLaunchConfigurationDelegate extends LaunchConfigurationTarge
|
|||
((ArduinoLaunch) launch).start();
|
||||
|
||||
// Run the process and capture the results in the console
|
||||
ProcessBuilder processBuilder = new ProcessBuilder(uploadCmd).directory(arduinoConfig.getBuildDirectory());
|
||||
arduinoConfig.setEnvironment(processBuilder.environment());
|
||||
ProcessBuilder processBuilder = new ProcessBuilder(uploadCmd)
|
||||
.directory(arduinoConfig.getBuildDirectory().toFile());
|
||||
arduinoConfig.setBuildEnvironment(processBuilder.environment());
|
||||
Process process = processBuilder.start();
|
||||
DebugPlugin.newProcess(launch, process, cmdStr.toString());
|
||||
} catch (IOException e) {
|
||||
|
@ -104,4 +110,15 @@ public class ArduinoLaunchConfigurationDelegate extends LaunchConfigurationTarge
|
|||
|
||||
}
|
||||
|
||||
public ArduinoBuildConfiguration getArduinoConfiguration(IProject project, String launchMode,
|
||||
ArduinoRemoteConnection arduinoTarget,
|
||||
IProgressMonitor monitor) throws CoreException {
|
||||
ArduinoBuildConfigurationProvider provider = (ArduinoBuildConfigurationProvider) buildConfigManager
|
||||
.getProvider(ArduinoBuildConfigurationProvider.ID);
|
||||
ArduinoBuildConfiguration config = provider.getConfiguration(project, arduinoTarget, launchMode, monitor);
|
||||
if (config == null) {
|
||||
config = provider.createConfiguration(project, arduinoTarget, launchMode, monitor);
|
||||
}
|
||||
return config;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -91,7 +91,7 @@ size:
|
|||
<#list project_srcs as file>
|
||||
<#assign cpp = file?matches("(.*)\\.cpp")>
|
||||
<#if cpp>
|
||||
${build_path}/project/${cpp?groups[1]}.cpp.o: ../${file} ${build_path}/project/${cpp?groups[1]}.cpp.d
|
||||
${build_path}/project/${cpp?groups[1]}.cpp.o: ../../${file} ${build_path}/project/${cpp?groups[1]}.cpp.d
|
||||
@$(call mymkdir,$(dir $@))
|
||||
${recipe_cpp_o_pattern}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<templateManifest>
|
||||
<file src="/templates/cppsketch/arduino.cpp"
|
||||
dest="/${projectName}/${projectName}.cpp"/>
|
||||
</templateManifest>
|
|
@ -19,7 +19,8 @@ Require-Bundle: org.eclipse.core.runtime,
|
|||
org.eclipse.remote.ui;bundle-version="2.0.0",
|
||||
org.eclipse.cdt.core,
|
||||
org.eclipse.cdt.native.serial;bundle-version="1.0.0",
|
||||
org.eclipse.launchbar.remote.ui;bundle-version="1.0.0"
|
||||
org.eclipse.launchbar.remote.ui;bundle-version="1.0.0",
|
||||
org.eclipse.tools.templates.ui;bundle-version="1.0.0"
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-Vendor: %providerName
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
|
@ -112,8 +112,7 @@
|
|||
<view
|
||||
id="org.eclipse.remote.ui.view.connections"
|
||||
minimized="false"
|
||||
ratio="0.75"
|
||||
relationship="bottom"
|
||||
relationship="stack"
|
||||
relative="org.eclipse.ui.navigator.ProjectExplorer">
|
||||
</view>
|
||||
</perspectiveExtension>
|
||||
|
@ -149,4 +148,23 @@
|
|||
name="Arduino">
|
||||
</wizard>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.tools.templates.ui.templates">
|
||||
<tag
|
||||
id="org.eclipse.cdt.arduino.ui.tag"
|
||||
label="Arduino">
|
||||
</tag>
|
||||
<template
|
||||
icon="icons/arduino48.png"
|
||||
id="org.eclipse.cdt.arduino.ui.template.sketch"
|
||||
label="Arduino C++ Sketch"
|
||||
wizard="org.eclipse.cdt.arduino.ui.internal.project.NewArduinoCPPSketchWizard">
|
||||
<tagReference
|
||||
id="org.eclipse.cdt.arduino.ui.tag">
|
||||
</tagReference>
|
||||
<description>
|
||||
A single C++ file with empty setup() and loop() functions.
|
||||
</description>
|
||||
</template>
|
||||
</extension>
|
||||
</plugin>
|
||||
|
|
|
@ -1,162 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015 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
|
||||
*
|
||||
* Contributors:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.arduino.ui.internal.launch;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
import org.eclipse.cdt.arduino.core.internal.console.ArduinoConsoleParser;
|
||||
import org.eclipse.cdt.arduino.core.internal.console.ArduinoConsoleService;
|
||||
import org.eclipse.cdt.arduino.core.internal.console.ArduinoErrorParser;
|
||||
import org.eclipse.cdt.arduino.ui.internal.Activator;
|
||||
import org.eclipse.cdt.arduino.ui.internal.Messages;
|
||||
import org.eclipse.core.resources.IFolder;
|
||||
import org.eclipse.core.resources.IResourceChangeEvent;
|
||||
import org.eclipse.core.resources.IResourceChangeListener;
|
||||
import org.eclipse.core.resources.IncrementalProjectBuilder;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
import org.eclipse.ui.console.ConsolePlugin;
|
||||
import org.eclipse.ui.console.IConsole;
|
||||
import org.eclipse.ui.console.MessageConsole;
|
||||
import org.eclipse.ui.console.MessageConsoleStream;
|
||||
|
||||
public class ArduinoConsole implements ArduinoConsoleService, IResourceChangeListener {
|
||||
|
||||
private static MessageConsole console;
|
||||
private static MessageConsoleStream out;
|
||||
private static MessageConsoleStream err;
|
||||
|
||||
private IFolder buildDirectory;
|
||||
List<ArduinoPatternMatchListener> listeners = new ArrayList<>();
|
||||
|
||||
public ArduinoConsole() {
|
||||
if (console == null) {
|
||||
console = new MessageConsole(Messages.ArduinoLaunchConsole_0, null);
|
||||
ConsolePlugin.getDefault().getConsoleManager().addConsoles(new IConsole[] { console });
|
||||
out = console.newMessageStream();
|
||||
err = console.newMessageStream();
|
||||
|
||||
// set the colors
|
||||
final Display display = Display.getDefault();
|
||||
display.syncExec(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
out.setColor(display.getSystemColor(SWT.COLOR_BLACK));
|
||||
err.setColor(display.getSystemColor(SWT.COLOR_RED));
|
||||
}
|
||||
});
|
||||
ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.PRE_BUILD);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resourceChanged(IResourceChangeEvent event) {
|
||||
switch (event.getType()) {
|
||||
case IResourceChangeEvent.PRE_BUILD:
|
||||
if (event.getBuildKind() != IncrementalProjectBuilder.AUTO_BUILD) {
|
||||
// TODO this really should be done from the core and only when
|
||||
// our projects are being built
|
||||
console.clearConsole();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public IFolder getBuildDirectory() {
|
||||
return buildDirectory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void monitor(final Process process, ArduinoConsoleParser[] consoleParsers, IFolder buildDirectory)
|
||||
throws IOException {
|
||||
this.buildDirectory = buildDirectory;
|
||||
|
||||
// Clear the old listeners
|
||||
for (ArduinoPatternMatchListener listener : listeners) {
|
||||
console.removePatternMatchListener(listener);
|
||||
}
|
||||
listeners.clear();
|
||||
|
||||
// Add in the new ones if any
|
||||
if (consoleParsers != null) {
|
||||
for (ArduinoConsoleParser parser : consoleParsers) {
|
||||
ArduinoPatternMatchListener listener;
|
||||
if (parser instanceof ArduinoErrorParser) {
|
||||
listener = new ArduinoErrorMatchListener(this, (ArduinoErrorParser) parser);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
listeners.add(listener);
|
||||
console.addPatternMatchListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
console.activate();
|
||||
|
||||
final Semaphore sema = new Semaphore(-1);
|
||||
|
||||
// Output stream reader
|
||||
new Thread(Messages.ArduinoLaunchConsole_2) {
|
||||
public void run() {
|
||||
try (BufferedReader processOut = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
|
||||
for (String line = processOut.readLine(); line != null; line = processOut.readLine()) {
|
||||
out.write(line);
|
||||
out.write('\n');
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
sema.release();
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
|
||||
// Error stream reader
|
||||
new Thread(Messages.ArduinoLaunchConsole_2) {
|
||||
public void run() {
|
||||
try (BufferedReader processErr = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
|
||||
for (String line = processErr.readLine(); line != null; line = processErr.readLine()) {
|
||||
err.write(line);
|
||||
out.write('\n');
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
sema.release();
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
|
||||
try {
|
||||
sema.acquire();
|
||||
process.waitFor();
|
||||
} catch (InterruptedException e) {
|
||||
Activator.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeOutput(String msg) throws IOException {
|
||||
out.write(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeError(String msg) throws IOException {
|
||||
err.write(msg);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015 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.arduino.ui.internal.launch;
|
||||
|
||||
import org.eclipse.cdt.arduino.core.internal.console.ArduinoErrorParser;
|
||||
import org.eclipse.cdt.arduino.ui.internal.Activator;
|
||||
import org.eclipse.core.resources.IMarker;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.jface.text.BadLocationException;
|
||||
import org.eclipse.ui.console.PatternMatchEvent;
|
||||
|
||||
public class ArduinoErrorMatchListener extends ArduinoPatternMatchListener {
|
||||
|
||||
public ArduinoErrorMatchListener(ArduinoConsole arduinoConsole, ArduinoErrorParser parser) {
|
||||
super(arduinoConsole, parser);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void matchFound(PatternMatchEvent event) {
|
||||
try {
|
||||
String text = textConsole.getDocument().get(event.getOffset(), event.getLength());
|
||||
IMarker marker = ((ArduinoErrorParser) parser).generateMarker(arduinoConsole.getBuildDirectory(), text);
|
||||
if (marker != null) {
|
||||
textConsole.addHyperlink(new ArduinoHyperlink(marker),
|
||||
event.getOffset() + marker.getAttribute(ArduinoErrorParser.LINK_OFFSET, 0),
|
||||
marker.getAttribute(ArduinoErrorParser.LINK_LENGTH, event.getLength()));
|
||||
}
|
||||
} catch (BadLocationException | CoreException e) {
|
||||
Activator.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015 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.arduino.ui.internal.launch;
|
||||
|
||||
import org.eclipse.cdt.arduino.ui.internal.Activator;
|
||||
import org.eclipse.core.resources.IMarker;
|
||||
import org.eclipse.ui.IWorkbenchPage;
|
||||
import org.eclipse.ui.PartInitException;
|
||||
import org.eclipse.ui.PlatformUI;
|
||||
import org.eclipse.ui.console.IHyperlink;
|
||||
import org.eclipse.ui.ide.IDE;
|
||||
|
||||
public class ArduinoHyperlink implements IHyperlink {
|
||||
|
||||
private final IMarker marker;
|
||||
|
||||
public ArduinoHyperlink(IMarker marker) {
|
||||
this.marker = marker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void linkEntered() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void linkExited() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void linkActivated() {
|
||||
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
|
||||
try {
|
||||
IDE.openEditor(page, marker);
|
||||
} catch (PartInitException e) {
|
||||
Activator.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015 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.arduino.ui.internal.launch;
|
||||
|
||||
import org.eclipse.cdt.arduino.core.internal.console.ArduinoConsoleParser;
|
||||
import org.eclipse.ui.console.IPatternMatchListener;
|
||||
import org.eclipse.ui.console.TextConsole;
|
||||
|
||||
public abstract class ArduinoPatternMatchListener implements IPatternMatchListener {
|
||||
|
||||
protected final ArduinoConsole arduinoConsole;
|
||||
protected final ArduinoConsoleParser parser;
|
||||
|
||||
protected TextConsole textConsole;
|
||||
|
||||
public ArduinoPatternMatchListener(ArduinoConsole arduinoConsole, ArduinoConsoleParser parser) {
|
||||
this.arduinoConsole = arduinoConsole;
|
||||
this.parser = parser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect(TextConsole console) {
|
||||
this.textConsole = console;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPattern() {
|
||||
return parser.getPattern();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCompilerFlags() {
|
||||
return parser.getCompilerFlags();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLineQualifier() {
|
||||
return parser.getLineQualifier();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015 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.arduino.ui.internal.project;
|
||||
|
||||
import org.eclipse.cdt.arduino.core.internal.ArduinoProjectGenerator;
|
||||
import org.eclipse.jface.dialogs.Dialog;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.tools.templates.core.IGenerator;
|
||||
import org.eclipse.tools.templates.ui.TemplateWizard;
|
||||
import org.eclipse.ui.dialogs.WizardNewProjectCreationPage;
|
||||
|
||||
public class NewArduinoCPPSketchWizard extends TemplateWizard {
|
||||
|
||||
private WizardNewProjectCreationPage mainPage;
|
||||
|
||||
@Override
|
||||
public void addPages() {
|
||||
mainPage = new WizardNewProjectCreationPage("basicNewProjectPage") { //$NON-NLS-1$
|
||||
@Override
|
||||
public void createControl(Composite parent) {
|
||||
super.createControl(parent);
|
||||
createWorkingSetGroup((Composite) getControl(), getSelection(),
|
||||
new String[] { "org.eclipse.ui.resourceWorkingSetPage" }); //$NON-NLS-1$
|
||||
Dialog.applyDialogFont(getControl());
|
||||
}
|
||||
};
|
||||
mainPage.setTitle("New Arduino Project"); //$NON-NLS-1$
|
||||
mainPage.setDescription("Specify properties of new Arduino project."); //$NON-NLS-1$
|
||||
this.addPage(mainPage);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IGenerator getGenerator() {
|
||||
ArduinoProjectGenerator generator = new ArduinoProjectGenerator("templates/cppsketch/manifest.xml"); //$NON-NLS-1$
|
||||
generator.setProjectName(mainPage.getProjectName());
|
||||
if (!mainPage.useDefaults()) {
|
||||
generator.setLocationURI(mainPage.getLocationURI());
|
||||
}
|
||||
return generator;
|
||||
}
|
||||
|
||||
}
|
|
@ -7,55 +7,28 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.arduino.ui.internal.project;
|
||||
|
||||
import org.eclipse.cdt.arduino.core.internal.ArduinoProjectGenerator;
|
||||
import org.eclipse.cdt.arduino.ui.internal.Activator;
|
||||
import org.eclipse.cdt.arduino.ui.internal.Messages;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.jobs.Job;
|
||||
import org.eclipse.ui.IWorkbenchPage;
|
||||
import org.eclipse.ui.PartInitException;
|
||||
import org.eclipse.ui.ide.IDE;
|
||||
import org.eclipse.tools.templates.ui.TemplateSelectionPage;
|
||||
import org.eclipse.ui.wizards.newresource.BasicNewProjectResourceWizard;
|
||||
|
||||
public class NewArduinoProjectWizard extends BasicNewProjectResourceWizard {
|
||||
|
||||
private static final String ARDUINO_TAG_ID = "org.eclipse.cdt.arduino.ui.tag"; //$NON-NLS-1$
|
||||
|
||||
private TemplateSelectionPage templateSelectionPage;
|
||||
|
||||
public NewArduinoProjectWizard() {
|
||||
setForcePreviousAndNextButtons(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPages() {
|
||||
super.addPages();
|
||||
templateSelectionPage = new TemplateSelectionPage("templateSelection", ARDUINO_TAG_ID); //$NON-NLS-1$
|
||||
templateSelectionPage.setTitle("Template for New Arduino Project");
|
||||
this.addPage(templateSelectionPage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean performFinish() {
|
||||
if (!super.performFinish())
|
||||
return false;
|
||||
|
||||
new Job(Messages.NewArduinoProjectWizard_0) {
|
||||
@Override
|
||||
protected IStatus run(IProgressMonitor monitor) {
|
||||
try {
|
||||
final ArduinoProjectGenerator generator = new ArduinoProjectGenerator(getNewProject());
|
||||
generator.generate(monitor);
|
||||
getWorkbench().getDisplay().asyncExec(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
IWorkbenchPage activePage = getWorkbench().getActiveWorkbenchWindow().getActivePage();
|
||||
IDE.openEditor(activePage, generator.getSourceFile());
|
||||
} catch (PartInitException e) {
|
||||
Activator.getDefault().getLog().log(e.getStatus());
|
||||
}
|
||||
}
|
||||
});
|
||||
return Status.OK_STATUS;
|
||||
} catch (CoreException e) {
|
||||
return e.getStatus();
|
||||
}
|
||||
}
|
||||
}.schedule();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue