mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-22 06:02:11 +02:00
Completed new Arduino makefile generator and build.
Change-Id: I0ab166174131b81361b7ee249cd0f178c9d6e5e2
This commit is contained in:
parent
19629b7ab5
commit
fbee145ff0
10 changed files with 376 additions and 105 deletions
|
@ -96,7 +96,7 @@
|
||||||
point="org.eclipse.cdt.core.ScannerInfoProvider2">
|
point="org.eclipse.cdt.core.ScannerInfoProvider2">
|
||||||
<provider
|
<provider
|
||||||
builder="org.eclipse.cdt.arduino.core.arduinoBuilder"
|
builder="org.eclipse.cdt.arduino.core.arduinoBuilder"
|
||||||
class="org.eclipse.cdt.arduino.core.ArduinoScannerInfoProvider">
|
class="org.eclipse.cdt.arduino.core.internal.ArduinoScannerInfoProvider">
|
||||||
</provider>
|
</provider>
|
||||||
</extension>
|
</extension>
|
||||||
<extension
|
<extension
|
||||||
|
|
|
@ -74,9 +74,6 @@ public class ArduinoProjectGenerator {
|
||||||
Map<String, Object> fmModel = new HashMap<>();
|
Map<String, Object> fmModel = new HashMap<>();
|
||||||
fmModel.put("projectName", project.getName()); //$NON-NLS-1$
|
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$
|
IFolder sourceFolder = project.getFolder("src"); //$NON-NLS-1$
|
||||||
if (!sourceFolder.exists()) {
|
if (!sourceFolder.exists()) {
|
||||||
sourceFolder.create(true, true, monitor);
|
sourceFolder.create(true, true, monitor);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package org.eclipse.cdt.arduino.core;
|
package org.eclipse.cdt.arduino.core.internal;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
|
@ -20,13 +20,17 @@ import java.net.URL;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.StandardCopyOption;
|
import java.nio.file.StandardCopyOption;
|
||||||
|
import java.nio.file.attribute.PosixFilePermission;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.commons.compress.archivers.ArchiveEntry;
|
import org.apache.commons.compress.archivers.ArchiveEntry;
|
||||||
import org.apache.commons.compress.archivers.ArchiveException;
|
import org.apache.commons.compress.archivers.ArchiveException;
|
||||||
import org.apache.commons.compress.archivers.ArchiveInputStream;
|
import org.apache.commons.compress.archivers.ArchiveInputStream;
|
||||||
import org.apache.commons.compress.archivers.ArchiveStreamFactory;
|
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.CompressorException;
|
||||||
import org.apache.commons.compress.compressors.CompressorStreamFactory;
|
import org.apache.commons.compress.compressors.CompressorStreamFactory;
|
||||||
import org.eclipse.cdt.arduino.core.internal.Activator;
|
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.CoreException;
|
||||||
import org.eclipse.core.runtime.IProgressMonitor;
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
import org.eclipse.core.runtime.IStatus;
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.Platform;
|
||||||
import org.eclipse.core.runtime.Status;
|
import org.eclipse.core.runtime.Status;
|
||||||
import org.eclipse.core.runtime.jobs.Job;
|
import org.eclipse.core.runtime.jobs.Job;
|
||||||
|
|
||||||
|
@ -110,6 +115,8 @@ public class ArduinoBoardManager {
|
||||||
Path archivePath = dlDir.resolve(archiveFileName);
|
Path archivePath = dlDir.resolve(archiveFileName);
|
||||||
Files.copy(dl.openStream(), archivePath, StandardCopyOption.REPLACE_EXISTING);
|
Files.copy(dl.openStream(), archivePath, StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
|
||||||
|
boolean isWin = Platform.getOS().equals(Platform.OS_WIN32);
|
||||||
|
|
||||||
// extract
|
// extract
|
||||||
ArchiveInputStream archiveIn = null;
|
ArchiveInputStream archiveIn = null;
|
||||||
try {
|
try {
|
||||||
|
@ -139,10 +146,24 @@ public class ArduinoBoardManager {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO check for soft links in tar files.
|
|
||||||
Path entryPath = installPath.resolve(entry.getName());
|
Path entryPath = installPath.resolve(entry.getName());
|
||||||
Files.createDirectories(entryPath.getParent());
|
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 {
|
} finally {
|
||||||
if (archiveIn != null) {
|
if (archiveIn != null) {
|
||||||
|
@ -165,4 +186,37 @@ public class ArduinoBoardManager {
|
||||||
return new Status(IStatus.ERROR, Activator.getId(), "Installing Platform", e);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.io.IOException;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
@ -125,7 +126,7 @@ public class ArduinoPlatform {
|
||||||
|
|
||||||
public Properties getPlatformProperties() throws CoreException {
|
public Properties getPlatformProperties() throws CoreException {
|
||||||
Properties properties = new Properties();
|
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);
|
properties.load(reader);
|
||||||
return properties;
|
return properties;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -137,11 +138,17 @@ public class ArduinoPlatform {
|
||||||
return getInstallPath().resolve("boards.txt").toFile().exists(); //$NON-NLS-1$
|
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$
|
return ArduinoPreferences.getArduinoHome().resolve("hardware").resolve(pkg.getName()).resolve(architecture) //$NON-NLS-1$
|
||||||
.resolve(version);
|
.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) {
|
public IStatus install(IProgressMonitor monitor) {
|
||||||
// Check if we're installed already
|
// Check if we're installed already
|
||||||
if (isInstalled()) {
|
if (isInstalled()) {
|
||||||
|
|
|
@ -9,6 +9,7 @@ package org.eclipse.cdt.arduino.core.internal.board;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.eclipse.cdt.arduino.core.internal.Activator;
|
import org.eclipse.cdt.arduino.core.internal.Activator;
|
||||||
import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences;
|
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);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,40 @@
|
||||||
package org.eclipse.cdt.arduino.core.internal.build;
|
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.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.ArduinoBoard;
|
||||||
import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoardManager;
|
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.ArduinoPackage;
|
||||||
import org.eclipse.cdt.arduino.core.internal.board.ArduinoPlatform;
|
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.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.resources.ProjectScope;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.core.runtime.IAdapterFactory;
|
import org.eclipse.core.runtime.IAdapterFactory;
|
||||||
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
import org.eclipse.core.runtime.IStatus;
|
import org.eclipse.core.runtime.IStatus;
|
||||||
import org.eclipse.core.runtime.Status;
|
import org.eclipse.core.runtime.Status;
|
||||||
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
|
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
|
||||||
|
@ -16,9 +42,9 @@ import org.osgi.service.prefs.BackingStoreException;
|
||||||
|
|
||||||
public class ArduinoBuildConfiguration {
|
public class ArduinoBuildConfiguration {
|
||||||
|
|
||||||
private static final String PACKAGE_NAME = "packageId";
|
private static final String PACKAGE_NAME = "packageId"; //$NON-NLS-1$
|
||||||
private static final String PLATFORM_NAME = "platformName";
|
private static final String PLATFORM_NAME = "platformName"; //$NON-NLS-1$
|
||||||
private static final String BOARD_NAME = "boardName";
|
private static final String BOARD_NAME = "boardName"; //$NON-NLS-1$
|
||||||
|
|
||||||
private final IBuildConfiguration config;
|
private final IBuildConfiguration config;
|
||||||
|
|
||||||
|
@ -70,4 +96,201 @@ public class ArduinoBuildConfiguration {
|
||||||
return ArduinoBoardManager.instance.getBoard(boardName, platformName, packageName);
|
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()]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,27 +9,13 @@ package org.eclipse.cdt.arduino.core.internal.build;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.eclipse.cdt.arduino.core.internal.Activator;
|
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.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.IFolder;
|
||||||
import org.eclipse.core.resources.IProject;
|
import org.eclipse.core.resources.IProject;
|
||||||
import org.eclipse.core.resources.IResource;
|
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.resources.IncrementalProjectBuilder;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.core.runtime.IProgressMonitor;
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
|
@ -47,29 +33,17 @@ public class ArduinoBuilder extends IncrementalProjectBuilder {
|
||||||
@Override
|
@Override
|
||||||
protected IProject[] build(int kind, Map<String, String> args, IProgressMonitor monitor) throws CoreException {
|
protected IProject[] build(int kind, Map<String, String> args, IProgressMonitor monitor) throws CoreException {
|
||||||
IProject project = getProject();
|
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 {
|
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$
|
ArduinoBuildConfiguration config = getBuildConfig().getAdapter(ArduinoBuildConfiguration.class);
|
||||||
if (!buildFolder.exists()) {
|
config.generateMakeFile(monitor);
|
||||||
buildFolder.create(true, true, monitor);
|
|
||||||
CoreModel.newOutputEntry(buildFolder.getFullPath());
|
|
||||||
}
|
|
||||||
|
|
||||||
String makeFileName = board.getId() + ".mk"; //$NON-NLS-1$
|
IFolder buildFolder = config.getBuildFolder();
|
||||||
IFile makeFile = buildFolder.getFile(makeFileName);
|
Process process = Runtime.getRuntime().exec(config.getBuildCommand(), config.getEnvironment(),
|
||||||
generateMakefile(makeFile, board, monitor);
|
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);
|
consoleService.monitor(process, null);
|
||||||
|
|
||||||
buildFolder.refreshLocal(IResource.DEPTH_INFINITE, monitor);
|
buildFolder.refreshLocal(IResource.DEPTH_INFINITE, monitor);
|
||||||
|
@ -83,32 +57,16 @@ public class ArduinoBuilder extends IncrementalProjectBuilder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void clean(IProgressMonitor monitor) throws CoreException {
|
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 {
|
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$
|
ArduinoBuildConfiguration config = getBuildConfig().getAdapter(ArduinoBuildConfiguration.class);
|
||||||
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$
|
IFolder buildFolder = config.getBuildFolder();
|
||||||
IFile makeFile = buildFolder.getFile(makeFileName);
|
Process process = Runtime.getRuntime().exec(config.getCleanCommand(), config.getEnvironment(),
|
||||||
generateMakefile(makeFile, board, monitor);
|
new File(buildFolder.getLocationURI()));
|
||||||
|
|
||||||
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);
|
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$
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,14 +8,67 @@ RMDIR = rm -fr
|
||||||
mymkdir = mkdir -p $1
|
mymkdir = mkdir -p $1
|
||||||
endif
|
endif
|
||||||
|
|
||||||
SOURCES = \
|
PROJECT_OBJS = \
|
||||||
<#list sources as file>
|
<#list project_srcs as file>
|
||||||
../src/${file} \
|
<#assign cpp = file?matches("(.*)\\.cpp")>
|
||||||
|
<#if cpp>
|
||||||
|
$(OUTPUT_DIR)/project/${cpp?groups[1]}.o \
|
||||||
|
</#if>
|
||||||
</#list>
|
</#list>
|
||||||
|
|
||||||
all:
|
PLATFORM_OBJS = \
|
||||||
@$(call mymkdir,$(OUTPUT_DIR))
|
<#list platform_srcs as file>
|
||||||
echo hello from template
|
<#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:
|
clean:
|
||||||
$(RMDIR) $(OUTPUT_DIR)
|
$(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>
|
||||||
|
|
|
@ -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.ArduinoConsoleService;
|
||||||
import org.eclipse.cdt.arduino.core.internal.console.ConsoleParser;
|
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.cdt.arduino.ui.internal.Messages;
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.widgets.Display;
|
import org.eclipse.swt.widgets.Display;
|
||||||
|
@ -91,13 +92,9 @@ public class ArduinoConsole implements ArduinoConsoleService {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
sema.acquire();
|
sema.acquire();
|
||||||
int rc = process.waitFor();
|
process.waitFor();
|
||||||
if (rc != 0) {
|
|
||||||
writeError("failed.");
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
// TODO
|
Activator.log(e);
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue