1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-07 01:36:01 +02:00

Much progress on the Arduino build system.

Change-Id: I437621ed8af02abddc05852bf6c1b62b50f17a25
This commit is contained in:
Doug Schaefer 2015-08-10 23:33:15 -04:00 committed by Gerrit Code Review @ Eclipse.org
parent 64b26a87d5
commit 19629b7ab5
38 changed files with 1424 additions and 1288 deletions

View file

@ -89,13 +89,16 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
static String CONTAINER_INITIALIZER_EXTPOINT_ID = "PathEntryContainerInitializer"; //$NON-NLS-1$
/**
* An empty array of strings indicating that a project doesn't have any prerequesite projects.
* An empty array of strings indicating that a project doesn't have any
* prerequesite projects.
*/
static final String[] NO_PREREQUISITES = {};
/**
* pathentry containers pool accessing the Container is done synch with the class
* pathentry containers pool accessing the Container is done synch with the
* class
*/
private static HashMap<ICProject, Map<IPath, IPathEntryContainer>> Containers = new HashMap<ICProject, Map<IPath, IPathEntryContainer>>(5);
private static HashMap<ICProject, Map<IPath, IPathEntryContainer>> Containers = new HashMap<ICProject, Map<IPath, IPathEntryContainer>>(
5);
static final IPathEntry[] NO_PATHENTRIES = {};
@ -411,6 +414,7 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
/**
* Return the cached entries, if no cache null.
*
* @param cproject
*/
protected IPathEntry[] getCachedResolvedPathEntries(ICProject cproject) {
@ -461,7 +465,8 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
return null;
}
private IPathEntry[] getCachedResolvedPathEntries(ArrayList<IPathEntry> resolvedListEntries, ICProject cproject) throws CModelException {
private IPathEntry[] getCachedResolvedPathEntries(ArrayList<IPathEntry> resolvedListEntries,
ICProject cproject) throws CModelException {
IPathEntry[] entries = resolvedListEntries.toArray(NO_PATHENTRIES);
boolean hasContainerExtension = false;
for (IPathEntry entry : entries) {
@ -485,7 +490,8 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
IPathEntry[] containerEntries = container.getPathEntries();
if (containerEntries != null) {
for (IPathEntry containerEntry : containerEntries) {
IPathEntry newEntry = PathEntryUtil.cloneEntryAndExpand(projectPath, containerEntry);
IPathEntry newEntry = PathEntryUtil.cloneEntryAndExpand(projectPath,
containerEntry);
listEntries.add(newEntry);
}
}
@ -506,7 +512,8 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
}
/**
* This method will not expand container extending IPathEntryContainerExtension
* This method will not expand container extending
* IPathEntryContainerExtension
*
* @param cproject
* @param generateMarkers
@ -514,14 +521,16 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
* @throws CModelException
*/
@SuppressWarnings("unchecked")
private ArrayList<IPathEntry> getResolvedPathEntries(ICProject cproject, boolean generateMarkers) throws CModelException {
private ArrayList<IPathEntry> getResolvedPathEntries(ICProject cproject, boolean generateMarkers)
throws CModelException {
Object[] result = getResolvedPathEntries(cproject, generateMarkers, true);
if (result != null)
return (ArrayList<IPathEntry>) result[0];
return null;
}
private Object[] getResolvedPathEntries(ICProject cproject, boolean generateMarkers, boolean useCache) throws CModelException {
private Object[] getResolvedPathEntries(ICProject cproject, boolean generateMarkers, boolean useCache)
throws CModelException {
ArrayList<IPathEntry> resolvedEntries = null;
PathEntryResolveInfo rInfo = null;
if (useCache) {
@ -539,14 +548,16 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
IContainerEntry centry = (IContainerEntry) entry;
IPathEntryContainer container = getPathEntryContainer(centry, cproject);
if (container != null) {
// For backward compatibility we need to expand and cache container that
// For backward compatibility we need to expand and
// cache container that
// are not IPathEntryContainerExtension.
if (!(container instanceof IPathEntryContainerExtension)) {
IPathEntry[] containerEntries = container.getPathEntries();
List<IPathEntry> resolvedList = new ArrayList<IPathEntry>();
if (containerEntries != null) {
for (IPathEntry containerEntry : containerEntries) {
IPathEntry newEntry = PathEntryUtil.cloneEntryAndExpand(projectPath, containerEntry);
IPathEntry newEntry = PathEntryUtil.cloneEntryAndExpand(projectPath,
containerEntry);
resolvedEntries.add(newEntry);
resolvedList.add(newEntry);
}
@ -611,10 +622,12 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
return new Object[] { resolvedEntries, rInfo };
}
public void setRawPathEntries(ICProject cproject, IPathEntry[] newEntries, IProgressMonitor monitor) throws CModelException {
public void setRawPathEntries(ICProject cproject, IPathEntry[] newEntries, IProgressMonitor monitor)
throws CModelException {
try {
IPathEntry[] oldResolvedEntries = getCachedResolvedPathEntries(cproject);
SetPathEntriesOperation op = new SetPathEntriesOperation(cproject, oldResolvedEntries, newEntries);
SetPathEntriesOperation op = new SetPathEntriesOperation(cproject, oldResolvedEntries,
newEntries);
op.runOperation(monitor);
} catch (CoreException e) {
throw new CModelException(e);
@ -625,7 +638,8 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
IProject project = cproject.getProject();
// Check if the Project is accessible.
if (!CoreModel.hasCNature(project) && !CoreModel.hasCCNature(project)) {
throw new CModelException(new CModelStatus(ICModelStatusConstants.ELEMENT_DOES_NOT_EXIST));
throw new CModelException(
new CModelStatus(ICModelStatusConstants.ELEMENT_DOES_NOT_EXIST, cproject));
}
IPathEntry[] pathEntries;
try {
@ -666,17 +680,19 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
return pathEntries;
}
public void setPathEntryContainer(ICProject[] affectedProjects, IPathEntryContainer newContainer, IProgressMonitor monitor)
throws CModelException {
public void setPathEntryContainer(ICProject[] affectedProjects, IPathEntryContainer newContainer,
IProgressMonitor monitor) throws CModelException {
SetPathEntryContainerOperation op = new SetPathEntryContainerOperation(affectedProjects, newContainer);
SetPathEntryContainerOperation op = new SetPathEntryContainerOperation(affectedProjects,
newContainer);
op.runOperation(monitor);
}
public void clearPathEntryContainer(ICProject[] affectedProjects, IPath containerPath , IProgressMonitor monitor)
throws CModelException {
public void clearPathEntryContainer(ICProject[] affectedProjects, IPath containerPath,
IProgressMonitor monitor) throws CModelException {
SetPathEntryContainerOperation op = new SetPathEntryContainerOperation(affectedProjects, containerPath);
SetPathEntryContainerOperation op = new SetPathEntryContainerOperation(affectedProjects,
containerPath);
op.runOperation(monitor);
}
@ -690,11 +706,13 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
return pcs;
}
public IPathEntryContainer getPathEntryContainer(IContainerEntry entry, ICProject cproject) throws CModelException {
public IPathEntryContainer getPathEntryContainer(IContainerEntry entry, ICProject cproject)
throws CModelException {
return getPathEntryContainer(entry.getPath(), cproject);
}
public IPathEntryContainer getPathEntryContainer(final IPath containerPath, final ICProject project) throws CModelException {
public IPathEntryContainer getPathEntryContainer(final IPath containerPath, final ICProject project)
throws CModelException {
// Try the cache.
IPathEntryContainer container = containerGet(project, containerPath, true);
if (container instanceof PathEntryContainerLock) {
@ -706,8 +724,10 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
lock.setContainerInitialize(runInitializer);
} else if (!Thread.holdsLock(lock)) {
// FIXME: Use Thread.holdsLock(lock) to break the cycle.
// This seem to happend when the container(say the auto discovery)
// trigger a resource change, the CoreModel will try to get the pathentries .. deadlock.
// This seem to happend when the container(say the auto
// discovery)
// trigger a resource change, the CoreModel will try to get
// the pathentries .. deadlock.
// Wait for the inialization to finish.
while (containerGet(project, containerPath, true) instanceof PathEntryContainerLock) {
@ -721,7 +741,8 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
}
if (runInitializer) {
// Remove the lock.
final PathEntryContainerInitializer initializer = getPathEntryContainerInitializer(containerPath.segment(0));
final PathEntryContainerInitializer initializer = getPathEntryContainerInitializer(
containerPath.segment(0));
final boolean[] ok = { false };
if (initializer != null) {
// wrap initializer call with Safe runnable in case
@ -743,7 +764,8 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
});
}
if (!ok[0]) {
containerPut(project, containerPath, null); // flush and notify
containerPut(project, containerPath, null); // flush and
// notify
}
}
// Retrieve new value
@ -754,16 +776,16 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
/**
* Helper method finding the container initializer registered for a given
* container ID or <code>null</code> if none was found while iterating
* over the contributions to extension point to the extension point
* container ID or <code>null</code> if none was found while iterating over
* the contributions to extension point to the extension point
* "org.eclipse.cdt.core.PathEntryContainerInitializer".
* <p>
* A containerID is the first segment of any container path, used to
* identify the registered container initializer.
* <p>
*
* @param containerID -
* a containerID identifying a registered initializer
* @param containerID
* - a containerID identifying a registered initializer
* @return PathEntryContainerInitializer - the registered container
* initializer or <code>null</code> if none was found.
*/
@ -797,7 +819,8 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
return null;
}
synchronized IPathEntryContainer containerGet(ICProject cproject, IPath containerPath, boolean bCreateLock) {
synchronized IPathEntryContainer containerGet(ICProject cproject, IPath containerPath,
boolean bCreateLock) {
Map<IPath, IPathEntryContainer> projectContainers = Containers.get(cproject);
if (projectContainers == null) {
projectContainers = new HashMap<IPath, IPathEntryContainer>();
@ -835,7 +858,8 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
Containers.remove(cproject);
}
public void pathEntryContainerUpdates(IPathEntryContainerExtension container, PathEntryContainerChanged[] events, IProgressMonitor monitor) {
public void pathEntryContainerUpdates(IPathEntryContainerExtension container,
PathEntryContainerChanged[] events, IProgressMonitor monitor) {
PathEntryContainerUpdatesOperation op = new PathEntryContainerUpdatesOperation(container, events);
try {
op.runOperation(monitor);
@ -882,7 +906,8 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
// Do not do this for container, the path is the ID.
if (kind != IPathEntry.CDT_CONTAINER) {
// Translate to project relative from absolute (unless a device path)
// Translate to project relative from absolute (unless a device
// path)
if (resourcePath.isAbsolute()) {
if (projectPath != null && projectPath.isPrefixOf(resourcePath)) {
if (resourcePath.segment(0).equals(projectPath.segment(0))) {
@ -902,8 +927,9 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
IIncludeEntry include = (IIncludeEntry) pathEntry;
IPath baseRef = include.getBaseReference();
if (baseRef == null || baseRef.isEmpty()) {
entry = CoreModel.newIncludeEntry(resourcePath, include.getBasePath(), include.getIncludePath(),
include.isSystemInclude(), include.getExclusionPatterns(), include.isExported());
entry = CoreModel.newIncludeEntry(resourcePath, include.getBasePath(),
include.getIncludePath(), include.isSystemInclude(),
include.getExclusionPatterns(), include.isExported());
} else {
entry = CoreModel.newIncludeRefEntry(resourcePath, baseRef, include.getIncludePath());
}
@ -930,9 +956,9 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
}
IPath baseRef = library.getBaseReference();
if (baseRef == null || baseRef.isEmpty()) {
entry = CoreModel.newLibraryEntry(resourcePath, library.getBasePath(), library.getLibraryPath(),
sourcePath, library.getSourceAttachmentRootPath(), library.getSourceAttachmentPrefixMapping(),
library.isExported());
entry = CoreModel.newLibraryEntry(resourcePath, library.getBasePath(),
library.getLibraryPath(), sourcePath, library.getSourceAttachmentRootPath(),
library.getSourceAttachmentPrefixMapping(), library.isExported());
} else {
entry = CoreModel.newLibraryRefEntry(resourcePath, baseRef, library.getLibraryPath());
}
@ -952,8 +978,8 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
case IPathEntry.CDT_MACRO_FILE: {
IMacroFileEntry macro = (IMacroFileEntry) pathEntry;
entry = CoreModel.newMacroFileEntry(resourcePath, macro.getBasePath(),
macro.getBaseReference(), macro.getMacroFilePath(),
macro.getExclusionPatterns(), macro.isExported());
macro.getBaseReference(), macro.getMacroFilePath(), macro.getExclusionPatterns(),
macro.isExported());
break;
}
case IPathEntry.CDT_OUTPUT: {
@ -993,9 +1019,13 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
}
/**
* Collects path entry errors for each project and generates error markers for these errors
* @param project - Project with path entry errors
* @param problems - The path entry errors associated with the project
* Collects path entry errors for each project and generates error markers
* for these errors
*
* @param project
* - Project with path entry errors
* @param problems
* - The path entry errors associated with the project
*/
public void addProblemMarkers(final IProject project, final ICModelStatus[] problems) {
PathEntryProblem problem = new PathEntryProblem(project, problems);
@ -1034,7 +1064,8 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
return false;
}
public ICElementDelta[] generatePathEntryDeltas(ICProject cproject, IPathEntry[] oldEntries, IPathEntry[] newEntries) {
public ICElementDelta[] generatePathEntryDeltas(ICProject cproject, IPathEntry[] oldEntries,
IPathEntry[] newEntries) {
if (!needDelta(cproject))
return new ICElementDelta[0];
@ -1096,7 +1127,8 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
}
}
}
// They may have remove some duplications, catch here .. consider it as reordering.
// They may have remove some duplications, catch here .. consider it as
// reordering.
if (list.size() == 0 && oldEntries.length != newEntries.length) {
ICElementDelta delta = makePathEntryDelta(cproject, null, true);
if (delta != null) {
@ -1124,12 +1156,14 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
ISourceEntry source = (ISourceEntry) entry;
IPath path = source.getPath();
celement = CoreModel.getDefault().create(path);
flag = (removed) ? ICElementDelta.F_REMOVED_PATHENTRY_SOURCE : ICElementDelta.F_ADDED_PATHENTRY_SOURCE;
flag = (removed) ? ICElementDelta.F_REMOVED_PATHENTRY_SOURCE
: ICElementDelta.F_ADDED_PATHENTRY_SOURCE;
break;
}
case IPathEntry.CDT_LIBRARY: {
celement = cproject;
flag = (removed) ? ICElementDelta.F_REMOVED_PATHENTRY_LIBRARY : ICElementDelta.F_ADDED_PATHENTRY_LIBRARY;
flag = (removed) ? ICElementDelta.F_REMOVED_PATHENTRY_LIBRARY
: ICElementDelta.F_ADDED_PATHENTRY_LIBRARY;
break;
}
case IPathEntry.CDT_PROJECT: {
@ -1242,9 +1276,11 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
// IPathEntryStore store = null;
// if (project != null) {
// try {
// ICDescriptor cdesc = CCorePlugin.getDefault().getCProjectDescription(project, false);
// ICDescriptor cdesc =
// CCorePlugin.getDefault().getCProjectDescription(project, false);
// if (cdesc != null) {
// ICExtensionReference[] cextensions = cdesc.get(PATHENTRY_STORE_UNIQ_ID, true);
// ICExtensionReference[] cextensions =
// cdesc.get(PATHENTRY_STORE_UNIQ_ID, true);
// if (cextensions.length > 0) {
// for (int i = 0; i < cextensions.length; i++) {
// try {
@ -1268,7 +1304,8 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
}
// private IPathEntryStore createDefaultStore(IProject project){
// if (CProjectDescriptionManager.getInstance().isNewStyleIndexCfg(project)){
// if
// (CProjectDescriptionManager.getInstance().isNewStyleIndexCfg(project)){
// return new ConfigBasedPathEntryStore(project);
// }
// return new DefaultPathEntryStore(project);
@ -1277,7 +1314,9 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
/*
* (non-Javadoc)
*
* @see org.eclipse.cdt.core.resources.IPathEntryStoreListener#pathEntryStoreChanged(org.eclipse.cdt.core.resources.PathEntryChangedEvent)
* @see org.eclipse.cdt.core.resources.IPathEntryStoreListener#
* pathEntryStoreChanged(org.eclipse.cdt.core.resources.
* PathEntryChangedEvent)
*/
@Override
public void pathEntryStoreChanged(PathEntryStoreChangedEvent event) {
@ -1318,11 +1357,13 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
if (entries != null) {
IProject project = project2.getProject();
try {
IMarker[] markers = project.findMarkers(ICModelMarker.PATHENTRY_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
IMarker[] markers = project.findMarkers(ICModelMarker.PATHENTRY_PROBLEM_MARKER,
false, IResource.DEPTH_ZERO);
if (markers != null && markers.length > 0) {
ArrayList<ICModelStatus> problemList = new ArrayList<>();
for (IPathEntry entry : entries) {
ICModelStatus status = PathEntryUtil.validatePathEntry(project2, entry, true, false);
ICModelStatus status = PathEntryUtil.validatePathEntry(project2, entry,
true, false);
if (!status.isOK()) {
problemList.add(status);
}
@ -1378,8 +1419,10 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
return false;
}
if (kind == ICElementDelta.ADDED || kind == ICElementDelta.REMOVED) {
// If the element path maps to the some IPathEntry we need to remove that entry
// but I'm not sure of the side effects so lets just do this for the ISourceEntry type
// If the element path maps to the some IPathEntry we need to remove
// that entry
// but I'm not sure of the side effects so lets just do this for the
// ISourceEntry type
if (element instanceof ISourceRoot) {
ISourceRoot sourceRoot = (ISourceRoot) element;
if (kind == ICElementDelta.REMOVED) {
@ -1403,6 +1446,7 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
/**
* The source root been deleted update the path entries
*
* @param sourceRoot
* @throws CModelException
*/
@ -1429,7 +1473,8 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
Job updatePathEntry = new WorkspaceJob("PathEntry Update source roots") { //$NON-NLS-1$
@Override
public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
// If the path which triggered this change exists when we run this job then
// If the path which triggered this change exists when we
// run this job then
// nothing to do.
if (sourceRoot.getResource() == null || !sourceRoot.getResource().exists())
setRawPathEntries(cproject, finalEntries, monitor);
@ -1447,8 +1492,8 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
return PathEntryUtil.validatePathEntry(cProject, entries);
}
public ICModelStatus validatePathEntry(ICProject cProject, IPathEntry entry, boolean checkSourceAttachment,
boolean recurseInContainers) {
public ICModelStatus validatePathEntry(ICProject cProject, IPathEntry entry,
boolean checkSourceAttachment, boolean recurseInContainers) {
return PathEntryUtil.validatePathEntry(cProject, entry, checkSourceAttachment, recurseInContainers);
}
}

View file

@ -9,8 +9,6 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.core.resources,
org.eclipse.debug.core,
org.eclipse.cdt.core,
org.eclipse.cdt.managedbuilder.core,
org.eclipse.cdt.managedbuilder.gnu.ui,
org.eclipse.launchbar.core,
org.eclipse.remote.core;bundle-version="2.0.0",
org.eclipse.cdt.native.serial;bundle-version="1.0.0",
@ -25,5 +23,6 @@ Bundle-ClassPath: libs/freemarker-2.3.22.jar,
.
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.build;x-friends:="org.eclipse.cdt.arduino.ui",
org.eclipse.cdt.arduino.core.internal.console;x-friends:="org.eclipse.cdt.arduino.ui"
Bundle-Localization: plugin

View file

@ -10,3 +10,4 @@
###############################################################################
pluginName=Arduino C++ Core
providerName=Eclipse CDT
ArduinoBuilder.name=Arduino Builder

View file

@ -2,95 +2,6 @@
<?eclipse version="3.4"?>
<plugin>
<extension-point id="consoleService" name="Arduino Launch Console Service" schema="schema/consoleService.exsd"/>
<extension
point="org.eclipse.cdt.managedbuilder.core.buildDefinitions">
<managedBuildRevision
fileVersion="4.0.0">
</managedBuildRevision>
<toolChain
archList="all"
configurationEnvironmentSupplier="org.eclipse.cdt.arduino.core.internal.EnvVarSupplier"
id="org.eclipse.cdt.arduino.toolChain.avr"
isAbstract="false"
languageSettingsProviders="org.eclipse.cdt.arduino.avr.builtins;org.eclipse.cdt.arduino.avr.outputParser"
name="Arduino AVR C++"
osList="all"
supportsManagedBuild="false">
<targetPlatform
id="org.eclipse.cdt.arduino.targetPlatform"
isAbstract="false"
name="Arduino">
</targetPlatform>
<builder
autoBuildTarget="all"
buildRunner="org.eclipse.cdt.managedbuilder.core.ExternalBuildRunner"
cleanBuildTarget="clean"
command="make"
commandLauncher="org.eclipse.cdt.core.CommandLauncher"
id="org.eclipse.cdt.arduino.builder.make"
incrementalBuildTarget="all"
isAbstract="false"
isVariableCaseSensitive="false"
name="Arduino Make">
</builder>
<tool
command="avr-g++"
id="org.eclipse.cdt.arduino.tool.avr.compiler"
isAbstract="false"
name="Arduino AVR C++ Compiler"
natureFilter="ccnature"
superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base">
</tool>
<option
category="org.eclipse.cdt.arduino.optionCategory.board"
id="org.eclipse.cdt.arduino.option.board"
isAbstract="false"
name="Board Type"
resourceFilter="all"
valueType="string">
</option>
<option
category="org.eclipse.cdt.arduino.optionCategory.board"
id="org.eclipse.cdt.arduino.option.platform"
isAbstract="false"
name="Board Platform"
resourceFilter="all"
valueType="string">
</option>
<option
category="org.eclipse.cdt.arduino.optionCategory.board"
id="org.eclipse.cdt.arduino.option.package"
isAbstract="false"
name="Board Package"
resourceFilter="all"
valueType="string">
</option>
<optionCategory
id="org.eclipse.cdt.arduino.optionCategory.board"
name="Board Type">
</optionCategory>
</toolChain>
</extension>
<extension
point="org.eclipse.cdt.core.LanguageSettingsProvider">
<provider
class="org.eclipse.cdt.arduino.core.internal.AvrLanguageSettingsProvider"
id="org.eclipse.cdt.arduino.avr.builtins"
name="Arduino AVR Compiler Built-ins"
parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;"
prefer-non-shared="true">
<language-scope
id="org.eclipse.cdt.core.g++">
</language-scope>
</provider>
<provider
class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuildCommandParser"
id="org.eclipse.cdt.arduino.avr.outputParser"
name="Arduino AVR Built Output Parser"
parameter="(avr-gcc)|(avr-g\+\+)"
prefer-non-shared="true">
</provider>
</extension>
<extension
point="org.eclipse.debug.core.launchConfigurationTypes">
<launchConfigurationType
@ -163,15 +74,39 @@
class="org.eclipse.cdt.arduino.core.internal.ArduinoProjectNature">
</run>
</runtime>
<builder
id="org.eclipse.cdt.arduino.core.arduinoBuilder">
</builder>
</extension>
<extension
id="arduinoBuilder"
name="%ArduinoBuilder.name"
point="org.eclipse.core.resources.builders">
<builder
hasNature="true">
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.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>
</plugin>

View file

@ -0,0 +1,37 @@
package org.eclipse.cdt.arduino.core;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.cdt.core.parser.ExtendedScannerInfo;
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.IResource;
/**
* Responsible for collecting scanner info on Arduino Projects.
*/
public class ArduinoScannerInfoProvider implements IScannerInfoProvider {
@Override
public IScannerInfo getScannerInformation(IResource resource) {
Map<String, String> symbols = new HashMap<>();
String[] includePath = { "/Users/dschaefer/.arduinocdt/hardware/arduino/avr/1.6.7/cores/arduino" };
ExtendedScannerInfo scannerInfo = new ExtendedScannerInfo(symbols, includePath);
return scannerInfo;
}
@Override
public void subscribe(IResource resource, IScannerInfoChangeListener listener) {
// TODO Auto-generated method stub
}
@Override
public void unsubscribe(IResource resource, IScannerInfoChangeListener listener) {
// TODO Auto-generated method stub
}
}

View file

@ -10,12 +10,12 @@
*******************************************************************************/
package org.eclipse.cdt.arduino.core.internal;
import org.eclipse.cdt.arduino.core.internal.build.ArduinoBuilder;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.settings.model.CProjectDescriptionEvent;
import org.eclipse.cdt.core.settings.model.ICProjectDescriptionListener;
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;
@ -47,14 +47,6 @@ public class Activator extends Plugin {
public void start(BundleContext bundleContext) throws Exception {
plugin = this;
// register listener for build config changes
CoreModel.getDefault().addCProjectDescriptionListener(new ICProjectDescriptionListener() {
@Override
public void handleEvent(CProjectDescriptionEvent event) {
ArduinoBuilder.handleProjectDescEvent(event);
}
}, CProjectDescriptionEvent.APPLIED);
}
public void stop(BundleContext bundleContext) throws Exception {
@ -67,4 +59,10 @@ 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$
}
}

View file

@ -10,47 +10,27 @@
*******************************************************************************/
package org.eclipse.cdt.arduino.core.internal;
import java.io.File;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.Writer;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoard;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoardManager;
import org.eclipse.cdt.arduino.core.internal.build.ArduinoBuildConfiguration;
import org.eclipse.cdt.arduino.core.internal.build.ArduinoBuilder;
import org.eclipse.cdt.arduino.core.internal.remote.ArduinoRemoteConnection;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
import org.eclipse.cdt.managedbuilder.internal.core.ManagedBuildInfo;
import org.eclipse.cdt.managedbuilder.internal.core.ManagedProject;
import org.eclipse.cdt.core.CCProjectNature;
import org.eclipse.cdt.core.CProjectNature;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.IPathEntry;
import org.eclipse.core.resources.IBuildConfiguration;
import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
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.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 org.eclipse.core.runtime.jobs.Job;
import org.eclipse.remote.core.IRemoteConnection;
import org.eclipse.remote.core.IRemoteConnectionType;
import org.eclipse.remote.core.IRemoteServicesManager;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
@SuppressWarnings("restriction")
public class ArduinoProjectGenerator {
private final IProject project;
@ -61,100 +41,51 @@ public class ArduinoProjectGenerator {
}
public void setupArduinoProject(IProgressMonitor monitor) throws CoreException {
// Add Arduino nature
// Add natures to project: C, C++, Arduino
IProjectDescription projDesc = project.getDescription();
String[] oldIds = projDesc.getNatureIds();
String[] newIds = new String[oldIds.length + 1];
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 });
// Create the default config
projDesc.setBuildConfigs(new String[] { "arduinoDefault" }); //$NON-NLS-1$
project.setDescription(projDesc, monitor);
// create the CDT natures and build setup
CCorePlugin.getDefault().createCDTProject(projDesc, project, monitor);
ICProjectDescription cprojDesc = CCorePlugin.getDefault().createProjectDescription(project, false);
ManagedBuildInfo info = ManagedBuildManager.createBuildInfo(project);
ManagedProject mProj = new ManagedProject(cprojDesc);
info.setManagedProject(mProj);
// TODO make this a preference, the default board
String boardName = "Arduino Uno"; //$NON-NLS-1$
String platformName = "Arduino AVR Boards"; //$NON-NLS-1$
String packageName = "arduino"; //$NON-NLS-1$
IRemoteServicesManager remoteManager = Activator.getService(IRemoteServicesManager.class);
IRemoteConnectionType connectionType = remoteManager.getConnectionType(ArduinoRemoteConnection.TYPE_ID);
Collection<IRemoteConnection> connections = connectionType.getConnections();
if (!connections.isEmpty()) {
IRemoteConnection firstConnection = connections.iterator().next();
IArduinoRemoteConnection firstArduino = firstConnection.getService(IArduinoRemoteConnection.class);
boardName = firstArduino.getBoardName();
platformName = firstArduino.getPlatformName();
packageName = firstArduino.getPackageName();
}
ArduinoBoardManager.instance.createBuildConfiguration(cprojDesc, boardName, platformName, packageName);
CCorePlugin.getDefault().setProjectDescription(project, cprojDesc, true, monitor);
// Test config
IBuildConfiguration config = project.getBuildConfig("arduinoDefault"); //$NON-NLS-1$
ArduinoBuildConfiguration arduinoConfig = config.getAdapter(ArduinoBuildConfiguration.class);
// TODO for now assume Uno
ArduinoBoard board = ArduinoBoardManager.instance.getBoard("Arduino Uno", "Arduino AVR Boards", "arduino"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
arduinoConfig.setBoard(board);
// Generate files
try {
Configuration fmConfig = new Configuration(Configuration.VERSION_2_3_22);
URL templateDirURL = FileLocator.find(Activator.getContext().getBundle(), new Path("/templates"), null); //$NON-NLS-1$
fmConfig.setDirectoryForTemplateLoading(new File(FileLocator.toFileURL(templateDirURL).toURI()));
final Map<String, Object> fmModel = new HashMap<>();
ArduinoTemplateGenerator templateGen = new ArduinoTemplateGenerator();
Map<String, Object> fmModel = new HashMap<>();
fmModel.put("projectName", project.getName()); //$NON-NLS-1$
generateFile(fmModel, fmConfig.getTemplate("Makefile"), project.getFile("Makefile")); //$NON-NLS-1$ //$NON-NLS-2$
generateFile(fmModel, fmConfig.getTemplate("arduino.mk"), project.getFile("arduino.mk")); //$NON-NLS-1$ //$NON-NLS-2$
templateGen.generateFile(fmModel, "Makefile", project.getFile("Makefile"), monitor); //$NON-NLS-1$ //$NON-NLS-2$
templateGen.generateFile(fmModel, "arduino.mk", project.getFile("arduino.mk"), monitor); //$NON-NLS-1$ //$NON-NLS-2$
sourceFile = project.getFile(project.getName() + ".cpp"); //$NON-NLS-1$
generateFile(fmModel, fmConfig.getTemplate("arduino.cpp"), sourceFile); //$NON-NLS-1$
} catch (IOException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), e.getLocalizedMessage(), e));
} catch (URISyntaxException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), e.getLocalizedMessage(), e));
} catch (TemplateException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), e.getLocalizedMessage(), e));
IFolder sourceFolder = project.getFolder("src"); //$NON-NLS-1$
if (!sourceFolder.exists()) {
sourceFolder.create(true, true, monitor);
}
IPathEntry[] entries = new IPathEntry[] { CoreModel.newOutputEntry(sourceFolder.getFullPath()) };
CoreModel.getDefault().create(project).setRawPathEntries(entries, monitor);
// Do the initial build
project.build(IncrementalProjectBuilder.FULL_BUILD, monitor);
}
private static void generateFile(Object model, Template template, final IFile outputFile)
throws TemplateException, IOException, CoreException {
final PipedInputStream in = new PipedInputStream();
PipedOutputStream out = new PipedOutputStream(in);
final Writer writer = new OutputStreamWriter(out);
Job job = new Job(Messages.ArduinoProjectGenerator_0) {
protected IStatus run(IProgressMonitor monitor) {
try {
outputFile.create(in, true, monitor);
} catch (CoreException e) {
return e.getStatus();
}
return Status.OK_STATUS;
}
};
job.setRule(outputFile.getProject());
job.schedule();
template.process(model, writer);
writer.close();
try {
job.join();
} catch (InterruptedException e) {
// TODO anything?
}
IStatus status = job.getResult();
if (!status.isOK())
throw new CoreException(status);
sourceFile = sourceFolder.getFile(project.getName() + ".cpp"); //$NON-NLS-1$
templateGen.generateFile(fmModel, "arduino.cpp", sourceFile, monitor); //$NON-NLS-1$
}
public IFile getSourceFile() {

View file

@ -0,0 +1,58 @@
package org.eclipse.cdt.arduino.core.internal;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
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.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
public class ArduinoTemplateGenerator {
private final Configuration config;
public ArduinoTemplateGenerator() throws CoreException {
config = new Configuration(Configuration.VERSION_2_3_22);
URL templateDirURL = FileLocator.find(Activator.getContext().getBundle(), new Path("/templates"), null); //$NON-NLS-1$
try {
config.setDirectoryForTemplateLoading(new File(FileLocator.toFileURL(templateDirURL).toURI()));
} catch (IOException | URISyntaxException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Template configuration", e));
}
}
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));
}
}
}

View file

@ -1,72 +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;
import java.io.File;
import java.util.List;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoardManager;
import org.eclipse.cdt.arduino.core.internal.board.Board;
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
import org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Platform;
public class AvrLanguageSettingsProvider extends GCCBuiltinSpecsDetector {
@Override
public String getToolchainId() {
return "org.eclipse.cdt.arduino.toolChain.avr"; //$NON-NLS-1$
}
@Override
protected String getToolOptions(String languageId) {
String opts = super.getToolOptions(languageId);
try {
IConfiguration config = ManagedBuildManager.getConfigurationForDescription(currentCfgDescription);
Board board = ArduinoBoardManager.instance.getBoard(config);
String mcu = board.getProperty("build.mcu"); //$NON-NLS-1$
if (mcu != null) {
opts += " -mmcu=" + mcu; //$NON-NLS-1$
}
} catch (CoreException e) {
Activator.getPlugin().getLog().log(e.getStatus());
}
return opts;
}
@Override
protected List<String> parseOptions(String line) {
if (Platform.getOS().equals(Platform.OS_WIN32)) {
if (line.startsWith(" /arduino/")) { //$NON-NLS-1$
// TODO
File full = new File(ArduinoPreferences.getArduinoHome().toFile(), line.trim());
return parseOptions(" " + full.getAbsolutePath()); //$NON-NLS-1$
}
}
return super.parseOptions(line);
}
@Override
public AvrLanguageSettingsProvider cloneShallow() throws CloneNotSupportedException {
return (AvrLanguageSettingsProvider) super.cloneShallow();
}
@Override
public AvrLanguageSettingsProvider clone() throws CloneNotSupportedException {
return (AvrLanguageSettingsProvider) super.clone();
}
}

View file

@ -1,118 +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;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
import org.eclipse.cdt.managedbuilder.envvar.IBuildEnvironmentVariable;
import org.eclipse.cdt.managedbuilder.envvar.IConfigurationEnvironmentVariableSupplier;
import org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider;
import org.eclipse.core.runtime.Platform;
public class EnvVarSupplier implements IConfigurationEnvironmentVariableSupplier {
private EnvVar arduinoHome;
private EnvVar arduinoLibs;
private EnvVar path;
private static final String OUTPUT_DIR = "OUTPUT_DIR"; //$NON-NLS-1$
private static final class EnvVar implements IBuildEnvironmentVariable {
String name;
String value;
int operation = IBuildEnvironmentVariable.ENVVAR_REPLACE;
String delimiter = null;
@Override
public String getName() {
return name;
}
@Override
public String getValue() {
return value;
}
@Override
public int getOperation() {
return operation;
}
@Override
public String getDelimiter() {
return delimiter;
}
}
private String clean(String str) {
return str.replaceAll("\\\\", "/"); //$NON-NLS-1$ //$NON-NLS-2$
}
public EnvVarSupplier() {
arduinoHome = new EnvVar();
arduinoHome.name = "ARDUINO_HOME"; //$NON-NLS-1$
arduinoHome.value = clean(ArduinoPreferences.getArduinoHome().toString());
arduinoLibs = new EnvVar();
arduinoLibs.name = "ARDUINO_USER_LIBS"; //$NON-NLS-1$
arduinoLibs.value = clean(System.getProperty("user.home") + "/Documents/Arduino/libraries"); //$NON-NLS-1$ //$NON-NLS-2$
String avrDir = ArduinoPreferences.getArduinoHome().toString() + "/hardware/tools/avr/bin"; //$NON-NLS-1$
String installDir = Platform.getInstallLocation().getURL().getPath();
path = new EnvVar();
path.name = "PATH"; //$NON-NLS-1$
path.value = avrDir + File.pathSeparator + installDir;
path.operation = IBuildEnvironmentVariable.ENVVAR_PREPEND;
path.delimiter = File.pathSeparator;
}
private IBuildEnvironmentVariable getOutputDir(IConfiguration configuration) {
EnvVar outputDir = new EnvVar();
outputDir.name = OUTPUT_DIR;
outputDir.value = "build/" + configuration.getName(); //$NON-NLS-1$
return outputDir;
}
@Override
public IBuildEnvironmentVariable getVariable(String variableName, IConfiguration configuration,
IEnvironmentVariableProvider provider) {
if (variableName.equals(path.name)) {
return path;
} else if (variableName.equals(arduinoHome.name)) {
return arduinoHome;
} else if (variableName.equals(arduinoLibs.name)) {
return arduinoLibs;
} else if (variableName.equals(OUTPUT_DIR)) {
return getOutputDir(configuration);
}
return null;
}
@Override
public IBuildEnvironmentVariable[] getVariables(IConfiguration configuration,
IEnvironmentVariableProvider provider) {
List<IBuildEnvironmentVariable> vars = new ArrayList<>();
vars.add(path);
vars.add(arduinoHome);
vars.add(arduinoLibs);
if (configuration != null) {
vars.add(getOutputDir(configuration));
}
return vars.toArray(new IBuildEnvironmentVariable[vars.size()]);
}
}

View file

@ -68,7 +68,7 @@ public class HierarchicalProperties {
HierarchicalProperties child = children.get(key);
if (child == null) {
child = new HierarchicalProperties();
children.put(qualifiedKey, child);
children.put(key, child);
}
String childKey = qualifiedKey.substring(i + 1);
child.putProperty(childKey, value);
@ -133,4 +133,26 @@ public class HierarchicalProperties {
}
}
public Properties flatten() {
Properties properties = new Properties();
flatten(null, this, properties);
return properties;
}
private static void flatten(String prefix, HierarchicalProperties tree, Properties props) {
if (tree.getValue() != null && prefix != null) {
props.put(prefix, tree.getValue());
}
if (tree.getChildren() != null) {
for (Map.Entry<String, HierarchicalProperties> entry : tree.getChildren().entrySet()) {
String childPrefix = entry.getKey();
if (prefix != null) {
childPrefix = prefix + "." + childPrefix; //$NON-NLS-1$
}
flatten(childPrefix, entry.getValue(), props);
}
}
}
}

View file

@ -7,23 +7,25 @@
*******************************************************************************/
package org.eclipse.cdt.arduino.core.internal.board;
import java.util.Properties;
import org.eclipse.cdt.arduino.core.internal.HierarchicalProperties;
public class Board {
public class ArduinoBoard {
private String name;
private String id;
private Platform platform;
private ArduinoPlatform platform;
private HierarchicalProperties properties;
public Board() {
public ArduinoBoard() {
}
public Board(HierarchicalProperties properties) {
public ArduinoBoard(String id, HierarchicalProperties properties) {
this.properties = properties;
this.id = this.properties.getValue();
this.id = id;
this.name = this.properties.getChild("name").getValue(); //$NON-NLS-1$
}
@ -35,11 +37,11 @@ public class Board {
return id;
}
public Platform getPlatform() {
public ArduinoPlatform getPlatform() {
return platform;
}
Board setOwners(Platform platform) {
ArduinoBoard setOwners(ArduinoPlatform platform) {
this.platform = platform;
return this;
}
@ -48,12 +50,8 @@ public class Board {
return properties.getProperty(key);
}
public String getPlatformId() {
return platform.getArchitecture();
}
public String getPackageId() {
return platform.getPackage().getName();
public Properties getBoardProperties() {
return properties.flatten();
}
}

View file

@ -10,32 +10,28 @@
*******************************************************************************/
package org.eclipse.cdt.arduino.core.internal.board;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.ArchiveException;
import org.apache.commons.compress.archivers.ArchiveInputStream;
import org.apache.commons.compress.archivers.ArchiveStreamFactory;
import org.apache.commons.compress.compressors.CompressorException;
import org.apache.commons.compress.compressors.CompressorStreamFactory;
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.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.core.settings.model.extension.CConfigurationData;
import org.eclipse.cdt.managedbuilder.core.BuildException;
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
import org.eclipse.cdt.managedbuilder.core.IOption;
import org.eclipse.cdt.managedbuilder.core.IToolChain;
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
import org.eclipse.cdt.managedbuilder.internal.core.ManagedProject;
import org.eclipse.cdt.managedbuilder.internal.core.ToolChain;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
@ -62,21 +58,10 @@ public class ArduinoBoardManager {
public ArduinoBoardManager() {
new Job(Messages.ArduinoBoardManager_0) {
protected IStatus run(IProgressMonitor monitor) {
try (CloseableHttpClient client = HttpClients.createDefault()) {
HttpGet get = new HttpGet("http://downloads.arduino.cc/packages/package_index.json"); //$NON-NLS-1$
try (CloseableHttpResponse response = client.execute(get)) {
if (response.getStatusLine().getStatusCode() >= 400) {
return new Status(IStatus.ERROR, Activator.getId(),
response.getStatusLine().getReasonPhrase());
} else {
HttpEntity entity = response.getEntity();
if (entity == null) {
return new Status(IStatus.ERROR, Activator.getId(), Messages.ArduinoBoardManager_1);
}
try {
URL url = new URL("http://downloads.arduino.cc/packages/package_index.json"); //$NON-NLS-1$
Files.createDirectories(packageIndexPath.getParent());
Files.copy(entity.getContent(), packageIndexPath, StandardCopyOption.REPLACE_EXISTING);
}
}
Files.copy(url.openStream(), packageIndexPath, StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
return new Status(IStatus.ERROR, Activator.getId(), e.getLocalizedMessage(), e);
}
@ -85,72 +70,99 @@ public class ArduinoBoardManager {
}.schedule();
}
public PackageIndex getPackageIndex() throws IOException {
public PackageIndex getPackageIndex() throws CoreException {
if (packageIndex == null) {
try (FileReader reader = new FileReader(packageIndexPath.toFile())) {
packageIndex = new Gson().fromJson(reader, PackageIndex.class);
packageIndex.setOwners(this);
} catch (IOException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Reading package index", e));
}
}
return packageIndex;
}
public ICConfigurationDescription createBuildConfiguration(ICProjectDescription projDesc, String boardId,
String platformId, String packageId) throws CoreException {
Board board = packageIndex.getPackage(packageId).getPlatform(platformId).getBoard(boardId);
ManagedProject managedProject = new ManagedProject(projDesc);
// TODO find toolchain based on package (os), platform (arch).
String configId = ManagedBuildManager.calculateChildId(ArduinoBoardManager.AVR_TOOLCHAIN_ID, null);
IToolChain avrToolChain = ManagedBuildManager.getExtensionToolChain(ArduinoBoardManager.AVR_TOOLCHAIN_ID);
org.eclipse.cdt.managedbuilder.internal.core.Configuration newConfig = new org.eclipse.cdt.managedbuilder.internal.core.Configuration(
managedProject, (ToolChain) avrToolChain, configId, board.getName());
IToolChain newToolChain = newConfig.getToolChain();
IOption boardOption = newToolChain.getOptionBySuperClassId(BOARD_OPTION_ID);
ManagedBuildManager.setOption(newConfig, newToolChain, boardOption, boardId);
IOption platformOption = newToolChain.getOptionBySuperClassId(PLATFORM_OPTION_ID);
ManagedBuildManager.setOption(newConfig, newToolChain, platformOption, platformId);
IOption packageOption = newToolChain.getOptionBySuperClassId(PACKAGE_OPTION_ID);
ManagedBuildManager.setOption(newConfig, newToolChain, packageOption, packageId);
CConfigurationData data = newConfig.getConfigurationData();
return projDesc.createConfiguration(ManagedBuildManager.CFG_DATA_PROVIDER_ID, data);
public ArduinoBoard getBoard(String boardName, String platformName, String packageName) throws CoreException {
return getPackageIndex().getPackage(packageName).getPlatform(platformName).getBoard(boardName);
}
public Board getBoard(String boardName, String platformName, String packageName) throws CoreException {
return packageIndex.getPackage(packageName).getPlatform(platformName).getBoard(boardName);
}
public Board getBoard(IConfiguration configuration) throws CoreException {
try {
IToolChain toolChain = configuration.getToolChain();
IOption boardOption = toolChain.getOptionBySuperClassId(BOARD_OPTION_ID);
String boardName = boardOption.getStringValue();
IOption platformOption = toolChain.getOptionBySuperClassId(PLATFORM_OPTION_ID);
String platformName = platformOption.getStringValue();
IOption packageOption = toolChain.getOptionBySuperClassId(PACKAGE_OPTION_ID);
String packageName = packageOption.getStringValue();
return getBoard(boardName, platformName, packageName);
} catch (BuildException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), e.getLocalizedMessage(), e));
}
}
public List<Board> getBoards() throws CoreException {
List<Board> boards = new ArrayList<>();
for (BoardPackage pkg : packageIndex.getPackages()) {
for (Platform platform : pkg.getPlatforms()) {
public List<ArduinoBoard> getBoards() throws CoreException {
List<ArduinoBoard> boards = new ArrayList<>();
for (ArduinoPackage pkg : packageIndex.getPackages()) {
for (ArduinoPlatform platform : pkg.getPlatforms()) {
boards.addAll(platform.getBoards());
}
}
return boards;
}
public Tool getTool(String packageName, String toolName, String version) {
BoardPackage pkg = packageIndex.getPackage(packageName);
public ArduinoTool getTool(String packageName, String toolName, String version) {
ArduinoPackage pkg = packageIndex.getPackage(packageName);
return pkg != null ? pkg.getTool(toolName, version) : null;
}
public static IStatus downloadAndInstall(String url, String archiveFileName, Path installPath,
IProgressMonitor monitor) {
try {
URL dl = new URL(url);
Path dlDir = ArduinoPreferences.getArduinoHome().resolve("downloads");
Files.createDirectories(dlDir);
Path archivePath = dlDir.resolve(archiveFileName);
Files.copy(dl.openStream(), archivePath, StandardCopyOption.REPLACE_EXISTING);
// extract
ArchiveInputStream archiveIn = null;
try {
String compressor = null;
String archiver = null;
if (archiveFileName.endsWith("tar.bz2")) { //$NON-NLS-1$
compressor = CompressorStreamFactory.BZIP2;
archiver = ArchiveStreamFactory.TAR;
} else if (archiveFileName.endsWith(".tar.gz") || archiveFileName.endsWith(".tgz")) { //$NON-NLS-1$ //$NON-NLS-2$
compressor = CompressorStreamFactory.GZIP;
archiver = ArchiveStreamFactory.TAR;
} else if (archiveFileName.endsWith(".tar.xz")) { //$NON-NLS-1$
compressor = CompressorStreamFactory.XZ;
archiver = ArchiveStreamFactory.TAR;
} else if (archiveFileName.endsWith(".zip")) { //$NON-NLS-1$
archiver = ArchiveStreamFactory.ZIP;
}
InputStream in = new BufferedInputStream(new FileInputStream(archivePath.toFile()));
if (compressor != null) {
in = new CompressorStreamFactory().createCompressorInputStream(compressor, in);
}
archiveIn = new ArchiveStreamFactory().createArchiveInputStream(archiver, in);
for (ArchiveEntry entry = archiveIn.getNextEntry(); entry != null; entry = archiveIn.getNextEntry()) {
if (entry.isDirectory()) {
continue;
}
// TODO check for soft links in tar files.
Path entryPath = installPath.resolve(entry.getName());
Files.createDirectories(entryPath.getParent());
Files.copy(archiveIn, entryPath, StandardCopyOption.REPLACE_EXISTING);
}
} finally {
if (archiveIn != null) {
archiveIn.close();
}
}
// Fix up directory
File[] children = installPath.toFile().listFiles();
if (children.length == 1 && children[0].isDirectory()) {
// make that directory the install path
Path childPath = children[0].toPath();
Path tmpPath = installPath.getParent().resolve("_t"); //$NON-NLS-1$
Files.move(childPath, tmpPath);
Files.delete(installPath);
Files.move(tmpPath, installPath);
}
return Status.OK_STATUS;
} catch (IOException | CompressorException | ArchiveException e) {
return new Status(IStatus.ERROR, Activator.getId(), "Installing Platform", e);
}
}
}

View file

@ -7,7 +7,7 @@
*******************************************************************************/
package org.eclipse.cdt.arduino.core.internal.board;
public class Help {
public class ArduinoHelp {
private String online;

View file

@ -15,22 +15,25 @@ import java.util.Map;
import org.eclipse.core.runtime.IProgressMonitor;
public class BoardPackage {
public class ArduinoPackage {
private String name;
private String maintainer;
private String websiteURL;
private String email;
private Help help;
private List<Platform> platforms;
private List<Tool> tools;
private ArduinoHelp help;
private List<ArduinoPlatform> platforms;
private List<ArduinoTool> tools;
private transient ArduinoBoardManager manager;
void setOwners(ArduinoBoardManager manager) {
void setOwner(ArduinoBoardManager manager) {
this.manager = manager;
for (Platform platform : platforms) {
platform.setOwners(this);
for (ArduinoPlatform platform : platforms) {
platform.setOwner(this);
}
for (ArduinoTool tool : tools) {
tool.setOwner(this);
}
}
@ -54,11 +57,11 @@ public class BoardPackage {
return email;
}
public Help getHelp() {
public ArduinoHelp getHelp() {
return help;
}
public Collection<Platform> getPlatforms() {
public Collection<ArduinoPlatform> getPlatforms() {
return Collections.unmodifiableCollection(platforms);
}
@ -67,10 +70,10 @@ public class BoardPackage {
*
* @return latest platforms
*/
public Collection<Platform> getLatestPlatforms() {
Map<String, Platform> platformMap = new HashMap<>();
for (Platform platform : platforms) {
Platform p = platformMap.get(platform.getName());
public Collection<ArduinoPlatform> getLatestPlatforms() {
Map<String, ArduinoPlatform> platformMap = new HashMap<>();
for (ArduinoPlatform platform : platforms) {
ArduinoPlatform p = platformMap.get(platform.getName());
if (p == null || compareVersions(platform.getVersion(), p.getVersion()) > 0) {
platformMap.put(platform.getName(), platform);
}
@ -124,22 +127,30 @@ public class BoardPackage {
return 0;
}
public Platform getPlatform(String architecture) {
for (Platform platform : platforms) {
if (platform.getArchitecture().equals(architecture)) {
return platform;
public ArduinoPlatform getPlatform(String name) {
ArduinoPlatform foundPlatform = null;
for (ArduinoPlatform platform : platforms) {
if (platform.getName().equals(name)) {
if (foundPlatform == null) {
foundPlatform = platform;
} else {
if (platform.isInstalled()
&& compareVersions(platform.getVersion(), foundPlatform.getVersion()) > 0) {
foundPlatform = platform;
}
}
return null;
}
}
return foundPlatform;
}
public List<Tool> getTools() {
public List<ArduinoTool> getTools() {
return tools;
}
public Tool getTool(String toolName, String version) {
for (Tool tool : tools) {
if (tool.getName().equals(toolName) && tool.getName().equals(version)) {
public ArduinoTool getTool(String toolName, String version) {
for (ArduinoTool tool : tools) {
if (tool.getName().equals(toolName) && tool.getVersion().equals(version)) {
return tool;
}
}
@ -150,4 +161,17 @@ public class BoardPackage {
}
@Override
public boolean equals(Object obj) {
if (obj instanceof ArduinoPackage) {
return ((ArduinoPackage) obj).getName().equals(name);
}
return super.equals(obj);
}
@Override
public int hashCode() {
return name.hashCode();
}
}

View file

@ -0,0 +1,176 @@
/*******************************************************************************
* 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.board;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.eclipse.cdt.arduino.core.internal.Activator;
import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences;
import org.eclipse.cdt.arduino.core.internal.HierarchicalProperties;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Status;
public class ArduinoPlatform {
private String name;
private String architecture;
private String version;
private String category;
private String url;
private String archiveFileName;
private String checksum;
private String size;
private List<ArduinoBoard> boards;
private List<ToolDependency> toolsDependencies;
private transient ArduinoPackage pkg;
private transient HierarchicalProperties boardsFile;
void setOwner(ArduinoPackage pkg) {
this.pkg = pkg;
for (ArduinoBoard board : boards) {
board.setOwners(this);
}
for (ToolDependency toolDep : toolsDependencies) {
toolDep.setOwner(this);
}
}
public ArduinoPackage getPackage() {
return pkg;
}
public String getName() {
return name;
}
public String getArchitecture() {
return architecture;
}
public String getVersion() {
return version;
}
public String getCategory() {
return category;
}
public String getUrl() {
return url;
}
public String getArchiveFileName() {
return archiveFileName;
}
public String getChecksum() {
return checksum;
}
public String getSize() {
return size;
}
public List<ArduinoBoard> getBoards() throws CoreException {
if (isInstalled() && boardsFile == null) {
Properties boardProps = new Properties();
try (Reader reader = new FileReader(getInstallPath().resolve("boards.txt").toFile())) { //$NON-NLS-1$
boardProps.load(reader);
} catch (IOException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Loading boards.txt", e));
}
boardsFile = new HierarchicalProperties(boardProps);
// Replace the boards with a real ones
boards = new ArrayList<>();
for (Map.Entry<String, HierarchicalProperties> entry : boardsFile.getChildren().entrySet()) {
if (entry.getValue().getChild("name") != null) { //$NON-NLS-1$
// assume things with names are boards
boards.add(new ArduinoBoard(entry.getKey(), entry.getValue()).setOwners(this));
}
}
}
return boards;
}
public ArduinoBoard getBoard(String name) throws CoreException {
for (ArduinoBoard board : getBoards()) {
if (name.equals(board.getName())) {
return board;
}
}
return null;
}
public List<ToolDependency> getToolsDependencies() {
return toolsDependencies;
}
public Properties getPlatformProperties() throws CoreException {
Properties properties = new Properties();
try (Reader reader = new FileReader(getInstallPath().resolve("boards.txt").toFile())) { //$NON-NLS-1$
properties.load(reader);
return properties;
} catch (IOException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Loading platform.txt", e));
}
}
public boolean isInstalled() {
return getInstallPath().resolve("boards.txt").toFile().exists(); //$NON-NLS-1$
}
private Path getInstallPath() {
return ArduinoPreferences.getArduinoHome().resolve("hardware").resolve(pkg.getName()).resolve(architecture) //$NON-NLS-1$
.resolve(version);
}
public IStatus install(IProgressMonitor monitor) {
// Check if we're installed already
if (isInstalled()) {
return Status.OK_STATUS;
}
// Download platform archive
IStatus status = ArduinoBoardManager.downloadAndInstall(url, archiveFileName, getInstallPath(), monitor);
if (!status.isOK()) {
return status;
}
// Install the tools
MultiStatus mstatus = null;
for (ToolDependency toolDep : toolsDependencies) {
status = toolDep.install(monitor);
if (!status.isOK()) {
if (mstatus == null) {
mstatus = new MultiStatus(status.getPlugin(), status.getCode(), status.getMessage(),
status.getException());
} else {
mstatus.add(status);
}
}
}
// TODO on Windows install make from equations.org
return mstatus != null ? mstatus : Status.OK_STATUS;
}
}

View file

@ -0,0 +1,74 @@
/*******************************************************************************
* 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.board;
import java.nio.file.Path;
import java.util.List;
import org.eclipse.cdt.arduino.core.internal.Activator;
import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
public class ArduinoTool {
private String name;
private String version;
private List<ArduinoToolSystem> systems;
private transient ArduinoPackage pkg;
public void setOwner(ArduinoPackage pkg) {
this.pkg = pkg;
for (ArduinoToolSystem system : systems) {
system.setOwner(this);
}
}
public ArduinoPackage getPackage() {
return pkg;
}
public String getName() {
return name;
}
public String getVersion() {
return version;
}
public List<ArduinoToolSystem> getSystems() {
return systems;
}
public Path getInstallPath() {
return ArduinoPreferences.getArduinoHome().resolve("tools").resolve(pkg.getName()).resolve(name) //$NON-NLS-1$
.resolve(version);
}
public boolean isInstalled() {
return getInstallPath().toFile().exists();
}
public IStatus install(IProgressMonitor monitor) {
if (isInstalled()) {
return Status.OK_STATUS;
}
for (ArduinoToolSystem system : systems) {
if (system.isApplicable()) {
return system.install(monitor);
}
}
// No valid system
return new Status(IStatus.ERROR, Activator.getId(), "No valid system found for " + name);
}
}

View file

@ -0,0 +1,78 @@
/*******************************************************************************
* 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.board;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
public class ArduinoToolSystem {
private String host;
private String archiveFileName;
private String url;
private String checksum;
private String size;
private transient ArduinoTool tool;
public void setOwner(ArduinoTool tool) {
this.tool = tool;
}
public String getHost() {
return host;
}
public String getArchiveFileName() {
return archiveFileName;
}
public String getUrl() {
return url;
}
public String getChecksum() {
return checksum;
}
public String getSize() {
return size;
}
public boolean isApplicable() {
switch (Platform.getOS()) {
case Platform.OS_WIN32:
return "i686-mingw32".equals(host); //$NON-NLS-1$
case Platform.OS_MACOSX:
switch (host) {
case "i386-apple-darwin11": //$NON-NLS-1$
case "x86_64-apple-darwin:": //$NON-NLS-1$
return true;
default:
return false;
}
case Platform.OS_LINUX:
switch (Platform.getOSArch()) {
case Platform.ARCH_X86_64:
return "x86_64-pc-linux-gnu".equals(host); //$NON-NLS-1$
case Platform.ARCH_X86:
return "i686-pc-linux-gnu".equals(host); //$NON-NLS-1$
default:
return false;
}
default:
return false;
}
}
public IStatus install(IProgressMonitor monitor) {
return ArduinoBoardManager.downloadAndInstall(url, archiveFileName, tool.getInstallPath(), monitor);
}
}

View file

@ -11,14 +11,14 @@ import java.util.List;
public class PackageIndex {
private List<BoardPackage> packages;
private List<ArduinoPackage> packages;
public List<BoardPackage> getPackages() {
public List<ArduinoPackage> getPackages() {
return packages;
}
public BoardPackage getPackage(String packageName) {
for (BoardPackage pkg : packages) {
public ArduinoPackage getPackage(String packageName) {
for (ArduinoPackage pkg : packages) {
if (pkg.getName().equals(packageName)) {
return pkg;
}
@ -27,8 +27,8 @@ public class PackageIndex {
}
void setOwners(ArduinoBoardManager manager) {
for (BoardPackage pkg : packages) {
pkg.setOwners(manager);
for (ArduinoPackage pkg : packages) {
pkg.setOwner(manager);
}
}

View file

@ -1,216 +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.board;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.ArchiveException;
import org.apache.commons.compress.archivers.ArchiveInputStream;
import org.apache.commons.compress.archivers.ArchiveStreamFactory;
import org.apache.commons.compress.compressors.CompressorException;
import org.apache.commons.compress.compressors.CompressorStreamFactory;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.eclipse.cdt.arduino.core.internal.Activator;
import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences;
import org.eclipse.cdt.arduino.core.internal.HierarchicalProperties;
import org.eclipse.cdt.arduino.core.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;
@SuppressWarnings("restriction")
public class Platform {
private String name;
private String architecture;
private String version;
private String category;
private String url;
private String archiveFileName;
private String checksum;
private String size;
private List<Board> boards;
private List<ToolDependency> toolsDependencies;
private transient BoardPackage pkg;
private transient HierarchicalProperties boardsFile;
void setOwners(BoardPackage pkg) {
this.pkg = pkg;
for (Board board : boards) {
board.setOwners(this);
}
}
public BoardPackage getPackage() {
return pkg;
}
public String getName() {
return name;
}
public String getArchitecture() {
return architecture;
}
public String getVersion() {
return version;
}
public String getCategory() {
return category;
}
public String getUrl() {
return url;
}
public String getArchiveFileName() {
return archiveFileName;
}
public String getChecksum() {
return checksum;
}
public String getSize() {
return size;
}
public List<Board> getBoards() throws CoreException {
if (isInstalled() && boardsFile == null) {
Properties boardProps = new Properties();
try (Reader reader = new FileReader(getInstallPath().resolve("boards.txt").toFile())) { //$NON-NLS-1$
boardProps.load(reader);
} catch (IOException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Loading boards", e));
}
boardsFile = new HierarchicalProperties(boardProps);
// Replace the boards with a real ones
boards = new ArrayList<>();
for (HierarchicalProperties child : boardsFile.getChildren().values()) {
if (child.getChild("name") != null) { //$NON-NLS-1$
// assume things with names are boards
boards.add(new Board(child).setOwners(this));
}
}
}
return boards;
}
public Board getBoard(String boardId) throws CoreException {
for (Board board : getBoards()) {
if (boardId.equals(board.getId())) {
return board;
}
}
return null;
}
public List<ToolDependency> getToolsDependencies() {
return toolsDependencies;
}
public boolean isInstalled() {
return getInstallPath().resolve("boards.txt").toFile().exists(); //$NON-NLS-1$
}
private Path getInstallPath() {
return ArduinoPreferences.getArduinoHome().resolve("hardware").resolve(pkg.getName()).resolve(architecture) //$NON-NLS-1$
.resolve(version);
}
public IStatus install(IProgressMonitor monitor) throws CoreException {
try {
try (CloseableHttpClient client = HttpClients.createDefault()) {
HttpGet get = new HttpGet(url);
try (CloseableHttpResponse response = client.execute(get)) {
if (response.getStatusLine().getStatusCode() >= 400) {
return new Status(IStatus.ERROR, Activator.getId(), response.getStatusLine().getReasonPhrase());
} else {
HttpEntity entity = response.getEntity();
if (entity == null) {
return new Status(IStatus.ERROR, Activator.getId(), Messages.ArduinoBoardManager_1);
}
// the archive has the version number as the root
// directory
Path installPath = getInstallPath().getParent();
Files.createDirectories(installPath);
Path archivePath = installPath.resolve(archiveFileName);
Files.copy(entity.getContent(), archivePath, StandardCopyOption.REPLACE_EXISTING);
// extract
ArchiveInputStream archiveIn = null;
try {
String compressor = null;
String archiver = null;
if (archiveFileName.endsWith("tar.bz2")) { //$NON-NLS-1$
compressor = CompressorStreamFactory.BZIP2;
archiver = ArchiveStreamFactory.TAR;
} else if (archiveFileName.endsWith(".tar.gz") || archiveFileName.endsWith(".tgz")) { //$NON-NLS-1$ //$NON-NLS-2$
compressor = CompressorStreamFactory.GZIP;
archiver = ArchiveStreamFactory.TAR;
} else if (archiveFileName.endsWith(".tar.xz")) { //$NON-NLS-1$
compressor = CompressorStreamFactory.XZ;
archiver = ArchiveStreamFactory.TAR;
} else if (archiveFileName.endsWith(".zip")) { //$NON-NLS-1$
archiver = ArchiveStreamFactory.ZIP;
}
InputStream in = new BufferedInputStream(new FileInputStream(archivePath.toFile()));
if (compressor != null) {
in = new CompressorStreamFactory().createCompressorInputStream(compressor, in);
}
archiveIn = new ArchiveStreamFactory().createArchiveInputStream(archiver, in);
for (ArchiveEntry entry = archiveIn.getNextEntry(); entry != null; entry = archiveIn
.getNextEntry()) {
if (entry.isDirectory()) {
continue;
}
// TODO check for soft links in tar files.
Path entryPath = installPath.resolve(entry.getName());
Files.createDirectories(entryPath.getParent());
Files.copy(archiveIn, entryPath, StandardCopyOption.REPLACE_EXISTING);
}
} finally {
if (archiveIn != null) {
archiveIn.close();
}
}
}
}
}
return Status.OK_STATUS;
} catch (IOException | CompressorException | ArchiveException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Installing Platform", e));
}
}
}

View file

@ -1,30 +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.board;
import java.util.List;
public class Tool {
private String name;
private String version;
private List<ToolSystem> systems;
public String getName() {
return name;
}
public String getVersion() {
return version;
}
public List<ToolSystem> getSystems() {
return systems;
}
}

View file

@ -7,12 +7,24 @@
*******************************************************************************/
package org.eclipse.cdt.arduino.core.internal.board;
import org.eclipse.cdt.arduino.core.internal.Activator;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
public class ToolDependency {
private String packager;
private String name;
private String version;
private transient ArduinoPlatform platform;
public void setOwner(ArduinoPlatform platform) {
this.platform = platform;
}
public String getPackager() {
return packager;
}
@ -25,4 +37,26 @@ public class ToolDependency {
return version;
}
public ArduinoTool getTool() throws CoreException {
ArduinoPackage pkg = platform.getPackage();
if (!pkg.getName().equals(packager)) {
pkg = pkg.getManager().getPackageIndex().getPackage(packager);
}
return pkg.getTool(name, version);
}
public IStatus install(IProgressMonitor monitor) {
try {
ArduinoTool tool = getTool();
if (tool == null) {
return new Status(IStatus.ERROR, Activator.getId(),
String.format("Tool not found %s %s", name, version));
}
return getTool().install(monitor);
} catch (CoreException e) {
return e.getStatus();
}
}
}

View file

@ -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.core.internal.board;
public class ToolSystem {
private String host;
private String archiveFileName;
private String url;
private String checksum;
private String size;
public String getHost() {
return host;
}
public String getArchiveFileName() {
return archiveFileName;
}
public String getUrl() {
return url;
}
public String getChecksum() {
return checksum;
}
public String getSize() {
return size;
}
}

View file

@ -0,0 +1,73 @@
package org.eclipse.cdt.arduino.core.internal.build;
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.ArduinoBoardManager;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoPackage;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoPlatform;
import org.eclipse.core.resources.IBuildConfiguration;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.osgi.service.prefs.BackingStoreException;
public class ArduinoBuildConfiguration {
private static final String PACKAGE_NAME = "packageId";
private static final String PLATFORM_NAME = "platformName";
private static final String BOARD_NAME = "boardName";
private final IBuildConfiguration config;
private ArduinoBuildConfiguration(IBuildConfiguration config) {
this.config = config;
}
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) {
return (T) new ArduinoBuildConfiguration((IBuildConfiguration) adaptableObject);
}
return null;
}
@Override
public Class<?>[] getAdapterList() {
return new Class<?>[] { ArduinoBuildConfiguration.class };
}
}
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 {
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());
try {
settings.flush();
} catch (BackingStoreException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Saving preferences", e));
}
}
public ArduinoBoard getBoard() throws CoreException {
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$
return ArduinoBoardManager.instance.getBoard(boardName, platformName, packageName);
}
}

View file

@ -7,21 +7,34 @@
*******************************************************************************/
package org.eclipse.cdt.arduino.core.internal.build;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.arduino.core.internal.Activator;
import org.eclipse.cdt.arduino.core.internal.ArduinoProjectNature;
import org.eclipse.cdt.core.settings.model.CProjectDescriptionEvent;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo;
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
import org.eclipse.cdt.arduino.core.internal.ArduinoTemplateGenerator;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoard;
import org.eclipse.cdt.arduino.core.internal.console.ArduinoConsoleService;
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.model.ISourceRoot;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
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.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
/**
* This class is responsible for generating the Makefile for the current build
@ -33,36 +46,101 @@ public class ArduinoBuilder extends IncrementalProjectBuilder {
@Override
protected IProject[] build(int kind, Map<String, String> args, IProgressMonitor monitor) throws CoreException {
IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(getProject());
IConfiguration config = info.getDefaultConfiguration();
IProject project = getProject();
// What board are we building for?
ArduinoBuildConfiguration config = getBuildConfig().getAdapter(ArduinoBuildConfiguration.class);
ArduinoBoard board = config.getBoard();
// Get the build console
ArduinoConsoleService consoleService = Activator.getConsoleService();
try {
consoleService.writeOutput(String.format("\nBuilding project: %s\n", project.getName()));
IFolder buildFolder = project.getFolder("build"); //$NON-NLS-1$
if (!buildFolder.exists()) {
buildFolder.create(true, true, monitor);
CoreModel.newOutputEntry(buildFolder.getFullPath());
}
String makeFileName = board.getId() + ".mk"; //$NON-NLS-1$
IFile makeFile = buildFolder.getFile(makeFileName);
generateMakefile(makeFile, board, monitor);
String[] cmd = new String[] { "make", "-f", makeFileName }; //$NON-NLS-1$ //$NON-NLS-2$
Process process = Runtime.getRuntime().exec(cmd, null, new File(buildFolder.getLocationURI()));
consoleService.monitor(process, null);
buildFolder.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 null;
return new IProject[] { project };
}
public static void handleProjectDescEvent(CProjectDescriptionEvent event) {
@Override
protected void clean(IProgressMonitor monitor) throws CoreException {
IProject project = getProject();
ArduinoBuildConfiguration config = getBuildConfig().getAdapter(ArduinoBuildConfiguration.class);
ArduinoBoard board = config.getBoard();
ArduinoConsoleService consoleService = Activator.getConsoleService();
try {
IProject project = event.getProject();
// Is this an arduino project?
if (!ArduinoProjectNature.hasNature(project)) {
return;
consoleService.writeOutput(String.format("\nCleaning project: %s\n", project.getName()));
IFolder buildFolder = project.getFolder("build"); //$NON-NLS-1$
if (!buildFolder.exists()) {
buildFolder.create(true, true, monitor);
ICProject cproject = CoreModel.getDefault().create(project);
IOutputEntry output = CoreModel.newOutputEntry(buildFolder.getFullPath());
IPathEntry[] oldEntries = cproject.getRawPathEntries();
IPathEntry[] newEntries = new IPathEntry[oldEntries.length];
System.arraycopy(oldEntries, 0, newEntries, 0, oldEntries.length);
newEntries[oldEntries.length] = output;
cproject.setRawPathEntries(newEntries, monitor);
}
// See if CDT config changed and sync the Resource config
ICConfigurationDescription newConfigDesc = event.getNewCProjectDescription().getActiveConfiguration();
ICConfigurationDescription oldConfigDesc = event.getOldCProjectDescription().getActiveConfiguration();
if (!newConfigDesc.equals(oldConfigDesc)) {
System.out.println("Active config changed: " + newConfigDesc.getName()); //$NON-NLS-1$
String configName = newConfigDesc.getName();
if (project.hasBuildConfig(configName)) {
IProjectDescription projDesc = project.getDescription();
projDesc.setActiveBuildConfig(configName);
project.setDescription(projDesc, new NullProgressMonitor());
}
}
} catch (CoreException e) {
Activator.log(e);
String makeFileName = board.getId() + ".mk"; //$NON-NLS-1$
IFile makeFile = buildFolder.getFile(makeFileName);
generateMakefile(makeFile, board, monitor);
String[] cmd = new String[] { "make", "-f", makeFileName, "clean" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
Process process = Runtime.getRuntime().exec(cmd, null, new File(buildFolder.getLocationURI()));
consoleService.monitor(process, null);
buildFolder.refreshLocal(IResource.DEPTH_INFINITE, monitor);
} catch (IOException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Build error", e));
}
}
private void generateMakefile(IFile makeFile, ArduinoBoard board, IProgressMonitor monitor) throws CoreException {
Map<String, Object> buildModel = new HashMap<>();
buildModel.put("boardId", board.getId()); //$NON-NLS-1$
final List<String> sourceFiles = new ArrayList<>();
final IProject project = getProject();
for (ISourceRoot sourceRoot : CCorePlugin.getDefault().getCoreModel().create(project).getSourceRoots()) {
sourceRoot.getResource().accept(new IResourceProxyVisitor() {
@Override
public boolean visit(IResourceProxy proxy) throws CoreException {
if (proxy.getType() == IResource.FILE) {
if (CoreModel.isValidSourceUnitName(project, proxy.getName())) {
sourceFiles.add(proxy.getName());
}
}
return true;
}
}, 0);
}
buildModel.put("sources", sourceFiles); //$NON-NLS-1$
ArduinoTemplateGenerator templateGen = new ArduinoTemplateGenerator();
templateGen.generateFile(buildModel, "board.mk", makeFile, monitor); //$NON-NLS-1$
}
}

View file

@ -8,16 +8,21 @@
* Contributors:
* QNX Software Systems - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.arduino.core.internal;
package org.eclipse.cdt.arduino.core.internal.console;
import java.io.IOException;
public interface ArduinoLaunchConsoleService {
public interface ArduinoConsoleService {
/**
* Capture the output for the process and display on the console.
*
* @param process
*/
void monitor(Process process);
void monitor(Process process, ConsoleParser[] consoleParsers) throws IOException;
void writeOutput(String msg) throws IOException;
void writeError(String msg) throws IOException;
}

View file

@ -0,0 +1,48 @@
package org.eclipse.cdt.arduino.core.internal.console;
import java.nio.file.Path;
public interface ConsoleParser {
/**
* 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();
/**
* 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();
/**
* 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();
/**
* The pattern has been matched. Perform any necessary actions. Generally
* this would include creating markers for the errors.
*
* @param text text that matched the pattern
* @param directory calculated current directory
*/
public void patternMatched(String text, Path directory);
}

View file

@ -16,25 +16,14 @@ import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.arduino.core.internal.Activator;
import org.eclipse.cdt.arduino.core.internal.ArduinoLaunchConsoleService;
import org.eclipse.cdt.arduino.core.internal.IArduinoRemoteConnection;
import org.eclipse.cdt.arduino.core.internal.Messages;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoardManager;
import org.eclipse.cdt.arduino.core.internal.board.Board;
import org.eclipse.cdt.arduino.core.internal.console.ArduinoConsoleService;
import org.eclipse.cdt.arduino.core.internal.remote.ArduinoRemoteConnection;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
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.jobs.Job;
import org.eclipse.debug.core.DebugPlugin;
@ -64,19 +53,7 @@ public class ArduinoLaunchConfigurationDelegate extends LaunchConfigurationDeleg
// 1. make sure proper build config is set active
IProject project = configuration.getMappedResources()[0].getProject();
ICProjectDescription projDesc = CCorePlugin.getDefault().getProjectDescription(project);
ICConfigurationDescription configDesc = getBuildConfiguration(projDesc, target);
boolean newConfig = false;
if (configDesc == null) {
IArduinoRemoteConnection arduinoRemote = target.getService(IArduinoRemoteConnection.class);
configDesc = ArduinoBoardManager.instance.createBuildConfiguration(projDesc, arduinoRemote.getBoardName(),
arduinoRemote.getPlatformName(), arduinoRemote.getPackageName());
newConfig = true;
}
if (newConfig || !projDesc.getActiveConfiguration().equals(configDesc)) {
projDesc.setActiveConfiguration(configDesc);
CCorePlugin.getDefault().setProjectDescription(project, projDesc);
}
// TODO set active build config for the selected target
// 2. Run the build
return super.buildForLaunch(configuration, mode, monitor);
@ -95,7 +72,7 @@ public class ArduinoLaunchConfigurationDelegate extends LaunchConfigurationDeleg
new Job(Messages.ArduinoLaunchConfigurationDelegate_0) {
protected IStatus run(IProgressMonitor monitor) {
try {
ArduinoLaunchConsoleService consoleService = getConsoleService();
ArduinoConsoleService consoleService = Activator.getConsoleService();
IRemoteConnection target = getTarget(configuration);
if (target == null) {
return new Status(IStatus.ERROR, Activator.getId(),
@ -106,14 +83,8 @@ public class ArduinoLaunchConfigurationDelegate extends LaunchConfigurationDeleg
IProject project = (IProject) configuration.getMappedResources()[0];
// The build environment
ICProjectDescription projDesc = CCorePlugin.getDefault().getProjectDescription(project);
ICConfigurationDescription configDesc = getBuildConfiguration(projDesc, target);
IEnvironmentVariable[] envVars = CCorePlugin.getDefault().getBuildEnvironmentManager()
.getVariables(configDesc, true);
List<String> envVarList = new ArrayList<String>(envVars.length + 1);
for (IEnvironmentVariable var : envVars) {
envVarList.add(var.getName() + '=' + var.getValue());
}
List<String> envVarList = new ArrayList<>();
// Add in the serial port based on launch config
IArduinoRemoteConnection arduinoRemote = target.getService(IArduinoRemoteConnection.class);
envVarList.add("SERIAL_PORT=" + arduinoRemote.getPortName()); //$NON-NLS-1$
@ -123,8 +94,7 @@ public class ArduinoLaunchConfigurationDelegate extends LaunchConfigurationDeleg
File projectDir = new File(project.getLocationURI());
// The build command
IConfiguration buildConfig = ManagedBuildManager.getConfigurationForDescription(configDesc);
String command = buildConfig.getBuilder().getCommand();
String command = "make";
// If opened, temporarily close the connection so we can use
// it to download the firmware.
@ -135,7 +105,7 @@ public class ArduinoLaunchConfigurationDelegate extends LaunchConfigurationDeleg
// Run the process and capture the results in the console
Process process = Runtime.getRuntime().exec(command + " load", envp, projectDir); //$NON-NLS-1$
consoleService.monitor(process);
consoleService.monitor(process, null);
try {
process.waitFor();
} catch (InterruptedException e) {
@ -158,46 +128,4 @@ public class ArduinoLaunchConfigurationDelegate extends LaunchConfigurationDeleg
}.schedule();
}
private ArduinoLaunchConsoleService getConsoleService() throws CoreException {
IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(Activator.getId(), "consoleService"); //$NON-NLS-1$
IExtension extension = point.getExtensions()[0]; // should only be one
return (ArduinoLaunchConsoleService) extension.getConfigurationElements()[0].createExecutableExtension("class"); //$NON-NLS-1$
}
/**
* Returns the build configuration for the active target and the launch
* configuration.
*
* @param launchConfig
* @return
*/
private ICConfigurationDescription getBuildConfiguration(ICProjectDescription projDesc, IRemoteConnection target)
throws CoreException {
String boardName;
String platformName;
String packageName;
if (target != null) {
IArduinoRemoteConnection arduinoRemote = target.getService(IArduinoRemoteConnection.class);
boardName = arduinoRemote.getBoardName();
platformName = arduinoRemote.getPlatformName();
packageName = arduinoRemote.getPackageName();
} else {
// TODO
boardName = "Arduino Uno"; //$NON-NLS-1$
platformName = "Arduino AVR Boards"; //$NON-NLS-1$
packageName = "arduino"; //$NON-NLS-1$
}
for (ICConfigurationDescription configDesc : projDesc.getConfigurations()) {
IConfiguration config = ManagedBuildManager.getConfigurationForDescription(configDesc);
Board board = ArduinoBoardManager.instance.getBoard(config);
if (boardName.equals(board.getId()) && platformName.equals(board.getPlatform().getArchitecture())
&& packageName.equals(board.getPlatform().getPackage().getName())) {
return configDesc;
}
}
return null;
}
}

View file

@ -0,0 +1,21 @@
OUTPUT_DIR = ${boardId}
ifeq ($(OS),Windows_NT)
RMDIR = rmdir /s /q
mymkdir = if not exist "$(call fixpath,$1)" mkdir $(call fixpath,$1)
else
RMDIR = rm -fr
mymkdir = mkdir -p $1
endif
SOURCES = \
<#list sources as file>
../src/${file} \
</#list>
all:
@$(call mymkdir,$(OUTPUT_DIR))
echo hello from template
clean:
$(RMDIR) $(OUTPUT_DIR)

View file

@ -33,7 +33,7 @@
<extension
point="org.eclipse.cdt.arduino.core.consoleService">
<provider
class="org.eclipse.cdt.arduino.ui.internal.launch.ArduinoLaunchConsole">
class="org.eclipse.cdt.arduino.ui.internal.launch.ArduinoConsole">
</provider>
</extension>
<extension

View file

@ -11,6 +11,7 @@
package org.eclipse.cdt.arduino.ui.internal;
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.preferences.InstanceScope;
@ -18,6 +19,7 @@ import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.ui.preferences.ScopedPreferenceStore;
import org.eclipse.ui.progress.UIJob;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
@ -41,9 +43,14 @@ public class Activator extends AbstractUIPlugin {
super.start(context);
plugin = this;
new UIJob("Arduino UI Startup") {
public IStatus runInUIThread(IProgressMonitor monitor) {
ImageRegistry imageRegistry = getImageRegistry();
imageRegistry.put(IMG_ARDUINO, imageDescriptorFromPlugin(PLUGIN_ID, "icons/cprojects.gif")); //$NON-NLS-1$
imageRegistry.put(IMG_CONNECTION_TYPE, imageDescriptorFromPlugin(PLUGIN_ID, "icons/arduino.png")); //$NON-NLS-1$
return Status.OK_STATUS;
}
}.schedule();
}
public void stop(BundleContext context) throws Exception {

View file

@ -7,7 +7,6 @@ public class Messages extends NLS {
public static String ArduinoLaunchConsole_0;
public static String ArduinoLaunchConsole_1;
public static String ArduinoLaunchConsole_2;
public static String ArduinoLaunchConsole_3;
public static String ArduinoPreferencePage_0;
public static String ArduinoPreferencePage_1;
public static String ArduinoTargetPropertyPage_0;

View file

@ -0,0 +1,114 @@
/*******************************************************************************
* 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.concurrent.Semaphore;
import org.eclipse.cdt.arduino.core.internal.console.ArduinoConsoleService;
import org.eclipse.cdt.arduino.core.internal.console.ConsoleParser;
import org.eclipse.cdt.arduino.ui.internal.Messages;
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 {
private static MessageConsole console;
private static MessageConsoleStream out;
private static MessageConsoleStream err;
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));
}
});
}
}
@Override
public void monitor(final Process process, ConsoleParser[] consoleParsers) throws IOException {
// console.clearConsole();
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();
int rc = process.waitFor();
if (rc != 0) {
writeError("failed.");
}
} catch (InterruptedException e) {
// TODO
e.printStackTrace();
}
}
@Override
public void writeOutput(String msg) throws IOException {
out.write(msg);
}
@Override
public void writeError(String msg) throws IOException {
err.write(msg);
}
}

View file

@ -1,81 +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.IOException;
import java.io.InputStream;
import org.eclipse.cdt.arduino.core.internal.ArduinoLaunchConsoleService;
import org.eclipse.cdt.arduino.ui.internal.Messages;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
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.IOConsoleOutputStream;
import org.eclipse.ui.console.MessageConsole;
import org.eclipse.ui.progress.UIJob;
public class ArduinoLaunchConsole implements ArduinoLaunchConsoleService {
private static MessageConsole console;
public ArduinoLaunchConsole() {
if (console == null) {
console = new MessageConsole(Messages.ArduinoLaunchConsole_0, null);
ConsolePlugin.getDefault().getConsoleManager().addConsoles(new IConsole[] { console });
}
}
@Override
public void monitor(final Process process) {
console.clearConsole();
console.activate();
new UIJob(Messages.ArduinoLaunchConsole_1) {
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
final IOConsoleOutputStream out = console.newOutputStream();
out.setColor(Display.getDefault().getSystemColor(SWT.COLOR_BLACK));
new Thread(Messages.ArduinoLaunchConsole_2) {
public void run() {
try (InputStream processOut = process.getInputStream()) {
for (int c = processOut.read(); c >= 0; c = processOut.read()) {
out.write(c);
}
} catch (IOException e) {
// Nothing. Just exit
}
}
}.start();
final IOConsoleOutputStream err = console.newOutputStream();
err.setColor(Display.getDefault().getSystemColor(SWT.COLOR_RED));
new Thread(Messages.ArduinoLaunchConsole_3) {
public void run() {
try (InputStream processErr = process.getErrorStream()) {
for (int c = processErr.read(); c >= 0; c = processErr.read()) {
err.write(c);
}
} catch (IOException e) {
// Nothing. Just exit
}
}
}.start();
return Status.OK_STATUS;
}
}.schedule();
}
}

View file

@ -1,7 +1,6 @@
ArduinoLaunchConsole_0=Arduino Launch
ArduinoLaunchConsole_0=Arduino
ArduinoLaunchConsole_1=Start Arduino Console
ArduinoLaunchConsole_2=Arduino Launch Console Output
ArduinoLaunchConsole_3=Arduino Launch Console Output
ArduinoLaunchConsole_2=Arduino Console Output
ArduinoPreferencePage_0=Arduino IDE Install Location
ArduinoPreferencePage_1=Arduino C++ Preferences
ArduinoTargetPropertyPage_0=Serial Port:

View file

@ -7,7 +7,6 @@
*******************************************************************************/
package org.eclipse.cdt.arduino.ui.internal.preferences;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@ -15,16 +14,16 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoard;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoardManager;
import org.eclipse.cdt.arduino.core.internal.board.Board;
import org.eclipse.cdt.arduino.core.internal.board.BoardPackage;
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.PackageIndex;
import org.eclipse.cdt.arduino.core.internal.board.Platform;
import org.eclipse.cdt.arduino.ui.internal.Activator;
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.MultiStatus;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.preference.PreferencePage;
@ -47,7 +46,7 @@ public class ArduinoBoardsPreferencePage extends PreferencePage implements IWork
private Table table;
private Button installButton;
private Set<Board> toInstall = new HashSet<>();
private Set<ArduinoBoard> toInstall = new HashSet<>();
@Override
public void init(IWorkbench workbench) {
@ -100,7 +99,7 @@ public class ArduinoBoardsPreferencePage extends PreferencePage implements IWork
@Override
public void handleEvent(Event event) {
for (TableItem item : table.getSelection()) {
Board board = (Board) item.getData();
ArduinoBoard board = (ArduinoBoard) item.getData();
toInstall.add(board);
item.setText(2, "selected");
updateButtons();
@ -123,11 +122,11 @@ public class ArduinoBoardsPreferencePage extends PreferencePage implements IWork
try {
PackageIndex packageIndex = ArduinoBoardManager.instance.getPackageIndex();
List<Board> boards = new ArrayList<>();
for (BoardPackage pkg : packageIndex.getPackages()) {
for (Platform platform : pkg.getLatestPlatforms()) {
List<ArduinoBoard> boards = new ArrayList<>();
for (ArduinoPackage pkg : packageIndex.getPackages()) {
for (ArduinoPlatform platform : pkg.getLatestPlatforms()) {
try {
for (Board board : platform.getBoards()) {
for (ArduinoBoard board : platform.getBoards()) {
boards.add(board);
}
} catch (CoreException e) {
@ -136,13 +135,13 @@ public class ArduinoBoardsPreferencePage extends PreferencePage implements IWork
}
}
Collections.sort(boards, new Comparator<Board>() {
public int compare(Board o1, Board o2) {
Collections.sort(boards, new Comparator<ArduinoBoard>() {
public int compare(ArduinoBoard o1, ArduinoBoard o2) {
return o1.getName().compareTo(o2.getName());
}
});
for (Board board : boards) {
for (ArduinoBoard board : boards) {
TableItem item = new TableItem(table, SWT.NONE);
item.setData(board);
item.setText(0, board.getName());
@ -155,7 +154,7 @@ public class ArduinoBoardsPreferencePage extends PreferencePage implements IWork
}
item.setText(2, msg);
}
} catch (IOException e) {
} catch (CoreException e) {
Activator.log(e);
}
}
@ -167,11 +166,11 @@ public class ArduinoBoardsPreferencePage extends PreferencePage implements IWork
boolean enable = false;
for (TableItem item : table.getSelection()) {
Board board = (Board) item.getData();
ArduinoBoard board = (ArduinoBoard) item.getData();
if (toInstall.contains(board)) {
continue;
}
Platform platform = board.getPlatform();
ArduinoPlatform platform = board.getPlatform();
if (!platform.isInstalled()) {
enable = true;
}
@ -184,17 +183,15 @@ public class ArduinoBoardsPreferencePage extends PreferencePage implements IWork
new Job("Installing Arduino Board Platforms") {
@Override
protected IStatus run(IProgressMonitor monitor) {
Set<Platform> platforms = new HashSet<>();
for (Board board : toInstall) {
Set<ArduinoPlatform> platforms = new HashSet<>();
for (ArduinoBoard board : toInstall) {
platforms.add(board.getPlatform());
}
for (Platform platform : platforms) {
try {
platform.install(monitor);
} catch (CoreException e) {
return e.getStatus();
}
MultiStatus status = new MultiStatus(Activator.PLUGIN_ID, 0, "Installing Arduino Board Platforms",
null);
for (ArduinoPlatform platform : platforms) {
status.add(platform.install(monitor));
}
toInstall.clear();
@ -208,7 +205,7 @@ public class ArduinoBoardsPreferencePage extends PreferencePage implements IWork
});
}
return Status.OK_STATUS;
return status;
}
}.schedule();
return true;

View file

@ -5,7 +5,7 @@ import java.util.Collection;
import org.eclipse.cdt.arduino.core.internal.IArduinoRemoteConnection;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoardManager;
import org.eclipse.cdt.arduino.core.internal.board.Board;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoard;
import org.eclipse.cdt.arduino.ui.internal.Activator;
import org.eclipse.cdt.arduino.ui.internal.Messages;
import org.eclipse.cdt.serial.SerialPort;
@ -28,7 +28,7 @@ public class ArduinoTargetPropertyPage extends PropertyPage implements IWorkbenc
private Combo portSelector;
private Combo boardSelector;
private Board[] boards;
private ArduinoBoard[] boards;
@Override
protected Control createContents(Composite parent) {
@ -73,13 +73,13 @@ public class ArduinoTargetPropertyPage extends PropertyPage implements IWorkbenc
boardSelector.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
try {
Board currentBoard = ArduinoBoardManager.instance.getBoard(arduinoRemote.getBoardName(),
ArduinoBoard currentBoard = ArduinoBoardManager.instance.getBoard(arduinoRemote.getBoardName(),
arduinoRemote.getPlatformName(), arduinoRemote.getPackageName());
Collection<Board> boardList = ArduinoBoardManager.instance.getBoards();
boards = new Board[boardList.size()];
Collection<ArduinoBoard> boardList = ArduinoBoardManager.instance.getBoards();
boards = new ArduinoBoard[boardList.size()];
i = 0;
int boardSel = 0;
for (Board board : boardList) {
for (ArduinoBoard board : boardList) {
boards[i] = board;
boardSelector.add(board.getName());
if (board.equals(currentBoard)) {
@ -103,7 +103,7 @@ public class ArduinoTargetPropertyPage extends PropertyPage implements IWorkbenc
String portName = portSelector.getItem(portSelector.getSelectionIndex());
workingCopy.setAttribute(IArduinoRemoteConnection.PORT_NAME, portName);
Board board = boards[boardSelector.getSelectionIndex()];
ArduinoBoard board = boards[boardSelector.getSelectionIndex()];
workingCopy.setAttribute(IArduinoRemoteConnection.BOARD_ID, board.getId());
try {

View file

@ -3,7 +3,7 @@ package org.eclipse.cdt.arduino.ui.internal.remote;
import java.io.IOException;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoardManager;
import org.eclipse.cdt.arduino.core.internal.board.Board;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoard;
import org.eclipse.cdt.arduino.ui.internal.Activator;
import org.eclipse.cdt.arduino.ui.internal.Messages;
import org.eclipse.cdt.serial.SerialPort;
@ -30,8 +30,8 @@ public class NewArduinoTargetWizardPage extends WizardPage {
private String[] portNames;
private Combo portCombo;
Board board;
private Board[] boards;
ArduinoBoard board;
private ArduinoBoard[] boards;
private Combo boardCombo;
public NewArduinoTargetWizardPage() {
@ -90,8 +90,8 @@ public class NewArduinoTargetWizardPage extends WizardPage {
boardCombo = new Combo(comp, SWT.READ_ONLY);
boardCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
try {
boards = ArduinoBoardManager.instance.getBoards().toArray(new Board[0]);
for (Board board : boards) {
boards = ArduinoBoardManager.instance.getBoards().toArray(new ArduinoBoard[0]);
for (ArduinoBoard board : boards) {
boardCombo.add(board.getName());
}
boardCombo.select(0);