Completed new Arduino makefile generator and build.
authorDoug Schaefer <dschaefer@qnx.com>
Wed, 12 Aug 2015 02:01:10 +0000 (22:01 -0400)
committerDoug Schaefer <dschaefer@qnx.com>
Wed, 12 Aug 2015 02:01:10 +0000 (22:01 -0400)
Change-Id: I0ab166174131b81361b7ee249cd0f178c9d6e5e2

toolchains/arduino/org.eclipse.cdt.arduino.core/plugin.xml
toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/ArduinoProjectGenerator.java
toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/ArduinoScannerInfoProvider.java [moved from toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/ArduinoScannerInfoProvider.java with 95% similarity]
toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoBoardManager.java
toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoPlatform.java
toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoTool.java
toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfiguration.java
toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuilder.java
toolchains/arduino/org.eclipse.cdt.arduino.core/templates/board.mk
toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/launch/ArduinoConsole.java

index d603ce8..9f194eb 100644 (file)
@@ -96,7 +96,7 @@
          point="org.eclipse.cdt.core.ScannerInfoProvider2">
       <provider
             builder="org.eclipse.cdt.arduino.core.arduinoBuilder"
-            class="org.eclipse.cdt.arduino.core.ArduinoScannerInfoProvider">
+            class="org.eclipse.cdt.arduino.core.internal.ArduinoScannerInfoProvider">
       </provider>
    </extension>
    <extension
index d217639..d60295c 100644 (file)
@@ -74,9 +74,6 @@ public class ArduinoProjectGenerator {
                Map<String, Object> fmModel = new HashMap<>();
                fmModel.put("projectName", project.getName()); //$NON-NLS-1$
 
-               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$
-
                IFolder sourceFolder = project.getFolder("src"); //$NON-NLS-1$
                if (!sourceFolder.exists()) {
                        sourceFolder.create(true, true, monitor);
index bc7d96c..2b32902 100644 (file)
@@ -20,13 +20,17 @@ import java.net.URL;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.StandardCopyOption;
+import java.nio.file.attribute.PosixFilePermission;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 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.archivers.tar.TarArchiveEntry;
 import org.apache.commons.compress.compressors.CompressorException;
 import org.apache.commons.compress.compressors.CompressorStreamFactory;
 import org.eclipse.cdt.arduino.core.internal.Activator;
@@ -35,6 +39,7 @@ 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.Platform;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
 
@@ -110,6 +115,8 @@ public class ArduinoBoardManager {
                        Path archivePath = dlDir.resolve(archiveFileName);
                        Files.copy(dl.openStream(), archivePath, StandardCopyOption.REPLACE_EXISTING);
 
+                       boolean isWin = Platform.getOS().equals(Platform.OS_WIN32);
+
                        // extract
                        ArchiveInputStream archiveIn = null;
                        try {
@@ -139,10 +146,24 @@ public class ArduinoBoardManager {
                                                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);
+
+                                       if (entry instanceof TarArchiveEntry) {
+                                               TarArchiveEntry tarEntry = (TarArchiveEntry) entry;
+                                               if (tarEntry.isLink()) {
+                                                       Path linkPath = installPath.resolve(tarEntry.getLinkName());
+                                                       Files.createSymbolicLink(entryPath, entryPath.getParent().relativize(linkPath));
+                                               } else {
+                                                       Files.copy(archiveIn, entryPath, StandardCopyOption.REPLACE_EXISTING);
+                                               }
+                                               if (!isWin) {
+                                                       int mode = tarEntry.getMode();
+                                                       Files.setPosixFilePermissions(entryPath, toPerms(mode));
+                                               }
+                                       } else {
+                                               Files.copy(archiveIn, entryPath, StandardCopyOption.REPLACE_EXISTING);
+                                       }
                                }
                        } finally {
                                if (archiveIn != null) {
@@ -165,4 +186,37 @@ public class ArduinoBoardManager {
                        return new Status(IStatus.ERROR, Activator.getId(), "Installing Platform", e);
                }
        }
+
+       private static Set<PosixFilePermission> toPerms(int mode) {
+               Set<PosixFilePermission> perms = new HashSet<>();
+               if ((mode & 0400) != 0) {
+                       perms.add(PosixFilePermission.OWNER_READ);
+               }
+               if ((mode & 0200) != 0) {
+                       perms.add(PosixFilePermission.OWNER_WRITE);
+               }
+               if ((mode & 0100) != 0) {
+                       perms.add(PosixFilePermission.OWNER_EXECUTE);
+               }
+               if ((mode & 0040) != 0) {
+                       perms.add(PosixFilePermission.GROUP_READ);
+               }
+               if ((mode & 0020) != 0) {
+                       perms.add(PosixFilePermission.GROUP_WRITE);
+               }
+               if ((mode & 0010) != 0) {
+                       perms.add(PosixFilePermission.GROUP_EXECUTE);
+               }
+               if ((mode & 0004) != 0) {
+                       perms.add(PosixFilePermission.OTHERS_READ);
+               }
+               if ((mode & 0002) != 0) {
+                       perms.add(PosixFilePermission.OTHERS_WRITE);
+               }
+               if ((mode & 0001) != 0) {
+                       perms.add(PosixFilePermission.OTHERS_EXECUTE);
+               }
+               return perms;
+       }
+
 }
index 2a1f376..ad38778 100644 (file)
@@ -12,6 +12,7 @@ import java.io.IOException;
 import java.io.Reader;
 import java.nio.file.Path;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
@@ -125,7 +126,7 @@ public class ArduinoPlatform {
 
        public Properties getPlatformProperties() throws CoreException {
                Properties properties = new Properties();
-               try (Reader reader = new FileReader(getInstallPath().resolve("boards.txt").toFile())) { //$NON-NLS-1$
+               try (Reader reader = new FileReader(getInstallPath().resolve("platform.txt").toFile())) { //$NON-NLS-1$
                        properties.load(reader);
                        return properties;
                } catch (IOException e) {
@@ -137,11 +138,17 @@ public class ArduinoPlatform {
                return getInstallPath().resolve("boards.txt").toFile().exists(); //$NON-NLS-1$
        }
 
-       private Path getInstallPath() {
+       public Path getInstallPath() {
                return ArduinoPreferences.getArduinoHome().resolve("hardware").resolve(pkg.getName()).resolve(architecture) //$NON-NLS-1$
                                .resolve(version);
        }
 
+       public List<Path> getIncludePath() {
+               Path installPath = getInstallPath();
+               return Arrays.asList(installPath.resolve("cores/{build.core}"), //$NON-NLS-1$
+                               installPath.resolve("variants/{build.variant}")); //$NON-NLS-1$
+       }
+
        public IStatus install(IProgressMonitor monitor) {
                // Check if we're installed already
                if (isInstalled()) {
index e2dda8e..38c9371 100644 (file)
@@ -9,6 +9,7 @@ package org.eclipse.cdt.arduino.core.internal.board;
 
 import java.nio.file.Path;
 import java.util.List;
+import java.util.Properties;
 
 import org.eclipse.cdt.arduino.core.internal.Activator;
 import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences;
@@ -71,4 +72,10 @@ public class ArduinoTool {
                return new Status(IStatus.ERROR, Activator.getId(), "No valid system found for " + name);
        }
 
+       public Properties getToolProperties() {
+               Properties properties = new Properties();
+               properties.put("runtime.tools." + name + ".path", getInstallPath().toString()); //$NON-NLS-1$ //$NON-NLS-2$
+               return properties;
+       }
+
 }
index f1adddb..a576ee7 100644 (file)
@@ -1,14 +1,40 @@
 package org.eclipse.cdt.arduino.core.internal.build;
 
+import java.io.File;
+import java.io.FilenameFilter;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.HashMap;
+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.ArduinoTemplateGenerator;
 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.cdt.arduino.core.internal.board.ArduinoTool;
+import org.eclipse.cdt.arduino.core.internal.board.ToolDependency;
+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.IBuildConfiguration;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceProxy;
+import org.eclipse.core.resources.IResourceProxyVisitor;
 import org.eclipse.core.resources.ProjectScope;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IAdapterFactory;
+import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.preferences.IEclipsePreferences;
@@ -16,9 +42,9 @@ 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 static final String PACKAGE_NAME = "packageId"; //$NON-NLS-1$
+       private static final String PLATFORM_NAME = "platformName"; //$NON-NLS-1$
+       private static final String BOARD_NAME = "boardName"; //$NON-NLS-1$
 
        private final IBuildConfiguration config;
 
@@ -70,4 +96,201 @@ public class ArduinoBuildConfiguration {
                return ArduinoBoardManager.instance.getBoard(boardName, platformName, packageName);
        }
 
+       public IFolder getBuildFolder() throws CoreException {
+               IProject project = config.getProject();
+               return project.getFolder("build"); //$NON-NLS-1$
+       }
+
+       public IFile getMakeFile() throws CoreException {
+               IFolder buildFolder = getBuildFolder();
+               ArduinoBoard board = getBoard();
+               String makeFileName = board.getId() + ".mk"; //$NON-NLS-1$
+               return buildFolder.getFile(makeFileName);
+       }
+
+       public IFile generateMakeFile(IProgressMonitor monitor) throws CoreException {
+               final IProject project = config.getProject();
+
+               // Make sure build folder exists
+               IFolder buildFolder = getBuildFolder();
+               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 + 1];
+                       System.arraycopy(oldEntries, 0, newEntries, 0, oldEntries.length);
+                       newEntries[oldEntries.length] = output;
+                       cproject.setRawPathEntries(newEntries, monitor);
+               }
+
+               ArduinoBoard board = getBoard();
+               ArduinoPlatform platform = board.getPlatform();
+
+               IFile makeFile = getMakeFile();
+
+               // The board id
+               Map<String, Object> buildModel = new HashMap<>();
+               buildModel.put("boardId", board.getId()); //$NON-NLS-1$
+
+               // The list of source files in the project
+               final Path projectPath = new File(project.getLocationURI()).toPath();
+               final List<String> sourceFiles = new ArrayList<>();
+               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())) {
+                                                       Path sourcePath = new File(proxy.requestResource().getLocationURI()).toPath();
+                                                       sourceFiles.add(projectPath.relativize(sourcePath).toString());
+                                               }
+                                       }
+                                       return true;
+                               }
+                       }, 0);
+               }
+               buildModel.put("project_srcs", sourceFiles); //$NON-NLS-1$
+
+               // the recipes
+               Properties properties = board.getBoardProperties();
+               properties.putAll(board.getPlatform().getPlatformProperties());
+               for (ToolDependency toolDep : platform.getToolsDependencies()) {
+                       properties.putAll(toolDep.getTool().getToolProperties());
+               }
+               properties.put("runtime.ide.version", "1.6.7"); //$NON-NLS-1$ //$NON-NLS-2$
+               properties.put("build.arch", platform.getArchitecture().toUpperCase()); //$NON-NLS-1$
+               properties.put("build.path", "$(OUTPUT_DIR)"); //$NON-NLS-1$ //$NON-NLS-2$
+               properties.put("build.project_name", project.getName()); //$NON-NLS-1$
+               buildModel.put("project_name", project.getName()); //$NON-NLS-1$
+
+               String includes = null;
+               for (Path include : platform.getIncludePath()) {
+                       if (includes == null) {
+                               includes = "-I"; //$NON-NLS-1$
+                       } else {
+                               includes += " -I"; //$NON-NLS-1$
+                       }
+                       includes += '"' + include.toString() + '"';
+               }
+               properties.put("includes", includes); //$NON-NLS-1$
+
+               Path platformPath = platform.getInstallPath();
+               buildModel.put("platform_path", platformPath.toString()); //$NON-NLS-1$
+
+               Path corePath = platformPath.resolve("cores").resolve((String) properties.get("build.core")); //$NON-NLS-1$ //$NON-NLS-2$
+               File[] platformFiles = corePath.toFile().listFiles(new FilenameFilter() {
+                       @Override
+                       public boolean accept(File dir, String name) {
+                               return name.endsWith(".cpp") || name.endsWith(".c");
+                       }
+               });
+               String[] platformSource = new String[platformFiles.length];
+               for (int i = 0; i < platformSource.length; ++i) {
+                       platformSource[i] = platformFiles[i].getAbsolutePath();
+               }
+               buildModel.put("platform_srcs", platformSource); //$NON-NLS-1$
+
+               properties.put("object_file", "$@"); //$NON-NLS-1$ //$NON-NLS-2$
+               properties.put("source_file", "$<"); //$NON-NLS-1$ //$NON-NLS-2$
+               properties.put("archive_file", "libc.a"); //$NON-NLS-1$ //$NON-NLS-2$
+               properties.put("object_files", "$(PROJECT_OBJS)"); //$NON-NLS-1$ //$NON-NLS-2$
+
+               buildModel.put("recipe_cpp_o_pattern", resolveProperty("recipe.cpp.o.pattern", properties)); //$NON-NLS-1$ //$NON-NLS-2$
+               buildModel.put("recipe_c_o_pattern", resolveProperty("recipe.c.o.pattern", properties)); //$NON-NLS-1$ //$NON-NLS-2$
+               buildModel.put("recipe_ar_pattern", resolveProperty("recipe.ar.pattern", properties)); //$NON-NLS-1$ //$NON-NLS-2$
+               buildModel.put("recipe_c_combine_pattern", resolveProperty("recipe.c.combine.pattern", properties)); //$NON-NLS-1$ //$NON-NLS-2$
+               buildModel.put("recipe_objcopy_eep_pattern", resolveProperty("recipe.objcopy.eep.pattern", properties)); //$NON-NLS-1$ //$NON-NLS-2$
+               buildModel.put("recipe_objcopy_hex_pattern", resolveProperty("recipe.objcopy.hex.pattern", properties)); //$NON-NLS-1$ //$NON-NLS-2$
+
+               ArduinoTemplateGenerator templateGen = new ArduinoTemplateGenerator();
+               templateGen.generateFile(buildModel, "board.mk", makeFile, monitor); //$NON-NLS-1$
+               return makeFile;
+       }
+
+       private String resolveProperty(String property, Properties dict) {
+               String res = dict.getProperty(property);
+               if (res == null) {
+                       return null;
+               }
+
+               String last;
+               do {
+                       last = res;
+                       for (int i = res.indexOf('{'); i >= 0; i = res.indexOf('{', i)) {
+                               i++;
+                               int n = res.indexOf('}', i);
+                               if (n >= 0) {
+                                       String p2 = res.substring(i, n);
+                                       String r2 = dict.getProperty(p2);
+                                       if (r2 != null) {
+                                               res = res.replace('{' + p2 + '}', r2);
+                                       }
+                               }
+                               i = n;
+                       }
+               } while (!res.equals(last));
+
+               return res;
+       }
+
+       public String[] getBuildCommand() throws CoreException {
+               return new String[] { "make", "-f", getMakeFile().getName() }; //$NON-NLS-1$ //$NON-NLS-2$
+       }
+
+       public String[] getCleanCommand() throws CoreException {
+               return new String[] { "make", "-f", getMakeFile().getName(), "clean" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+       }
+
+       public String[] getEnvironment() throws CoreException {
+               Map<String, String> env = new HashMap<>(System.getenv());
+
+               // Arduino home to find platforms and libraries
+               env.put("ARDUINO_HOME", ArduinoPreferences.getArduinoHome().toString()); //$NON-NLS-1$
+
+               // Add tools to the path
+               String pathKey = null;
+               String path = null;
+               for (Map.Entry<String, String> entry : env.entrySet()) {
+                       if (entry.getKey().equalsIgnoreCase("PATH")) { //$NON-NLS-1$
+                               pathKey = entry.getKey();
+                               path = entry.getValue();
+                               break;
+                       }
+               }
+
+               List<String> toolPaths = new ArrayList<>();
+               ArduinoBoard board = getBoard();
+               ArduinoPlatform platform = board.getPlatform();
+               for (ToolDependency dep : platform.getToolsDependencies()) {
+                       ArduinoTool tool = dep.getTool();
+                       Path installPath = tool.getInstallPath();
+                       Path binPath = installPath.resolve("bin"); //$NON-NLS-1$
+                       if (binPath.toFile().exists()) {
+                               toolPaths.add(binPath.toString());
+                       } else {
+                               // use the install dir by default
+                               toolPaths.add(installPath.toString());
+                       }
+               }
+               for (String toolPath : toolPaths) {
+                       if (path != null) {
+                               path = toolPath + File.pathSeparatorChar + path;
+                       } else {
+                               path = toolPath;
+                       }
+               }
+               if (pathKey == null) {
+                       pathKey = "PATH"; //$NON-NLS-1$
+               }
+               env.put(pathKey, path);
+
+               // Reformat as a proper env.
+               List<String> strEnv = new ArrayList<>(env.size());
+               for (Map.Entry<String, String> entry : env.entrySet()) {
+                       strEnv.add(entry.getKey() + "=" + entry.getValue()); //$NON-NLS-1$
+               }
+               return strEnv.toArray(new String[strEnv.size()]);
+       }
+
 }
index f7cee03..30ca80e 100644 (file)
@@ -9,27 +9,13 @@ 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.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.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;
@@ -47,29 +33,17 @@ public class ArduinoBuilder extends IncrementalProjectBuilder {
        @Override
        protected IProject[] build(int kind, Map<String, String> args, IProgressMonitor monitor) throws CoreException {
                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()));
+                       ArduinoConsoleService consoleService = Activator.getConsoleService();
+                       consoleService.writeOutput(String.format("\nBuilding %s\n", project.getName()));
 
-                       IFolder buildFolder = project.getFolder("build"); //$NON-NLS-1$
-                       if (!buildFolder.exists()) {
-                               buildFolder.create(true, true, monitor);
-                               CoreModel.newOutputEntry(buildFolder.getFullPath());
-                       }
+                       ArduinoBuildConfiguration config = getBuildConfig().getAdapter(ArduinoBuildConfiguration.class);
+                       config.generateMakeFile(monitor);
 
-                       String makeFileName = board.getId() + ".mk"; //$NON-NLS-1$
-                       IFile makeFile = buildFolder.getFile(makeFileName);
-                       generateMakefile(makeFile, board, monitor);
+                       IFolder buildFolder = config.getBuildFolder();
+                       Process process = Runtime.getRuntime().exec(config.getBuildCommand(), config.getEnvironment(),
+                                       new File(buildFolder.getLocationURI()));
 
-                       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);
@@ -83,32 +57,16 @@ public class ArduinoBuilder extends IncrementalProjectBuilder {
 
        @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 {
-                       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);
-                       }
-
-                       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()));
+                       IProject project = getProject();
+                       ArduinoConsoleService consoleService = Activator.getConsoleService();
+                       consoleService.writeOutput(String.format("\nCleaning %s\n", project.getName()));
+
+                       ArduinoBuildConfiguration config = getBuildConfig().getAdapter(ArduinoBuildConfiguration.class);
+
+                       IFolder buildFolder = config.getBuildFolder();
+                       Process process = Runtime.getRuntime().exec(config.getCleanCommand(), config.getEnvironment(),
+                                       new File(buildFolder.getLocationURI()));
 
                        consoleService.monitor(process, null);
 
@@ -118,29 +76,4 @@ public class ArduinoBuilder extends IncrementalProjectBuilder {
                }
        }
 
-       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$
-       }
-
 }
index 99db916..1add920 100644 (file)
@@ -8,14 +8,67 @@ RMDIR = rm -fr
 mymkdir = mkdir -p $1
 endif
 
-SOURCES = \
-<#list sources as file>
-       ../src/${file} \
+PROJECT_OBJS = \
+<#list project_srcs as file>
+<#assign cpp = file?matches("(.*)\\.cpp")>
+<#if cpp>
+       $(OUTPUT_DIR)/project/${cpp?groups[1]}.o \
+</#if>
 </#list>
 
-all:
-       @$(call mymkdir,$(OUTPUT_DIR))
-       echo hello from template
+PLATFORM_OBJS = \
+<#list platform_srcs as file>
+<#assign cpp = file?matches("${platform_path}/(.*)\\.cpp")>
+<#if cpp>
+       $(OUTPUT_DIR)/platform/${cpp?groups[1]}.o \
+</#if>
+<#assign c = file?matches("${platform_path}/(.*)\\.c")>
+<#if c>
+       $(OUTPUT_DIR)/platform/${c?groups[1]}.o \
+</#if>
+</#list>
+
+all: $(OUTPUT_DIR)/${project_name}.hex $(OUTPUT_DIR)/${project_name}.eep
+
+$(OUTPUT_DIR)/${project_name}.hex: $(OUTPUT_DIR)/${project_name}.elf
+       ${recipe_objcopy_hex_pattern}
+
+$(OUTPUT_DIR)/${project_name}.eep: $(OUTPUT_DIR)/${project_name}.elf
+       ${recipe_objcopy_eep_pattern}
+
+$(OUTPUT_DIR)/${project_name}.elf: $(PROJECT_OBJS) $(OUTPUT_DIR)/libc.a
+       ${recipe_c_combine_pattern}
+
+$(OUTPUT_DIR)/libc.a:  $(PLATFORM_OBJS)
 
 clean:
        $(RMDIR) $(OUTPUT_DIR)
+
+<#list project_srcs as file>
+<#assign cpp = file?matches("(.*)\\.cpp")>
+<#if cpp>
+$(OUTPUT_DIR)/project/${cpp?groups[1]}.o: ../${file}
+       @$(call mymkdir,$(dir $@))
+       ${recipe_cpp_o_pattern}
+
+</#if>
+</#list>
+
+<#list platform_srcs as file>
+<#assign cpp = file?matches("${platform_path}/(.*)\\.cpp")>
+<#if cpp>
+$(OUTPUT_DIR)/platform/${cpp?groups[1]}.o: ${file}
+       @$(call mymkdir,$(dir $@))
+       ${recipe_cpp_o_pattern}
+       ${recipe_ar_pattern}
+
+</#if>
+<#assign c = file?matches("${platform_path}/(.*)\\.c")>
+<#if c>
+$(OUTPUT_DIR)/platform/${c?groups[1]}.o: ${file}
+       @$(call mymkdir,$(dir $@))
+       ${recipe_c_o_pattern}
+       ${recipe_ar_pattern}
+
+</#if>
+</#list>
index d606852..97eebbb 100644 (file)
@@ -17,6 +17,7 @@ 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.Activator;
 import org.eclipse.cdt.arduino.ui.internal.Messages;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.Display;
@@ -91,13 +92,9 @@ public class ArduinoConsole implements ArduinoConsoleService {
 
                try {
                        sema.acquire();
-                       int rc = process.waitFor();
-                       if (rc != 0) {
-                               writeError("failed.");
-                       }
+                       process.waitFor();
                } catch (InterruptedException e) {
-                       // TODO
-                       e.printStackTrace();
+                       Activator.log(e);
                }
        }