diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/plugin.xml b/toolchains/arduino/org.eclipse.cdt.arduino.core/plugin.xml index d603ce83d68..9f194ebf6cd 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/plugin.xml +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/plugin.xml @@ -96,7 +96,7 @@ point="org.eclipse.cdt.core.ScannerInfoProvider2"> + class="org.eclipse.cdt.arduino.core.internal.ArduinoScannerInfoProvider"> 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); diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/ArduinoScannerInfoProvider.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/ArduinoScannerInfoProvider.java similarity index 95% rename from toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/ArduinoScannerInfoProvider.java rename to toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/ArduinoScannerInfoProvider.java index c8a07d218ee..5cdc1a2ae09 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/ArduinoScannerInfoProvider.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/ArduinoScannerInfoProvider.java @@ -1,4 +1,4 @@ -package org.eclipse.cdt.arduino.core; +package org.eclipse.cdt.arduino.core.internal; import java.util.HashMap; import java.util.Map; diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoBoardManager.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoBoardManager.java index bc7d96c8565..2b329022e2e 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoBoardManager.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoBoardManager.java @@ -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 toPerms(int mode) { + Set 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; + } + } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoPlatform.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoPlatform.java index 2a1f3769b1e..ad387787140 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoPlatform.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoPlatform.java @@ -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 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()) { diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoTool.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoTool.java index e2dda8ef288..38c93711aa6 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoTool.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoTool.java @@ -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; + } + } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfiguration.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfiguration.java index f1adddbdf03..a576ee739ba 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfiguration.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfiguration.java @@ -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 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 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 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 entry : env.entrySet()) { + if (entry.getKey().equalsIgnoreCase("PATH")) { //$NON-NLS-1$ + pathKey = entry.getKey(); + path = entry.getValue(); + break; + } + } + + List 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 strEnv = new ArrayList<>(env.size()); + for (Map.Entry entry : env.entrySet()) { + strEnv.add(entry.getKey() + "=" + entry.getValue()); //$NON-NLS-1$ + } + return strEnv.toArray(new String[strEnv.size()]); + } + } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuilder.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuilder.java index f7cee036f95..30ca80e6915 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuilder.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuilder.java @@ -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 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())); + IProject project = getProject(); + ArduinoConsoleService consoleService = Activator.getConsoleService(); + consoleService.writeOutput(String.format("\nCleaning %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); - } + ArduinoBuildConfiguration config = getBuildConfig().getAdapter(ArduinoBuildConfiguration.class); - 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())); + 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 buildModel = new HashMap<>(); - buildModel.put("boardId", board.getId()); //$NON-NLS-1$ - - final List 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$ - } - } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/templates/board.mk b/toolchains/arduino/org.eclipse.cdt.arduino.core/templates/board.mk index 99db916c4b0..1add9209ad1 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/templates/board.mk +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/templates/board.mk @@ -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 \ + -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 \ + +<#assign c = file?matches("${platform_path}/(.*)\\.c")> +<#if c> + $(OUTPUT_DIR)/platform/${c?groups[1]}.o \ + + + +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} + + + + +<#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} + + +<#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} + + + diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/launch/ArduinoConsole.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/launch/ArduinoConsole.java index d60685243c6..97eebbb2a40 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/launch/ArduinoConsole.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/launch/ArduinoConsole.java @@ -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); } }