public String getDefaultCompileCommands(File source) { /* TODO Split into String[] */ return GUI.getExternalToolsSetting("PATH_MAKE") + " " + getExpectedFirmwareFile(source).getName() + " TARGET=" + target; }
/** * Builds executable JAR from current simulation * * @param gui GUI. Must contain simulation * @param outputFile Output file */ public static boolean buildExecutableJAR(GUI gui, File outputFile) { String executeDir = null; executeDir = outputFile.getName(); if (!executeDir.endsWith(".jar")) { throw new RuntimeException("Not a proper JAR archive: " + executeDir); } executeDir = executeDir.substring(0, executeDir.length() - ".jar".length()); Simulation simulation = gui.getSimulation(); if (simulation == null) { throw new RuntimeException("No simulation active"); } /* Check dependencies: mote type */ for (MoteType t : simulation.getMoteTypes()) { if (!t.getClass().getName().contains("SkyMoteType")) { throw new RuntimeException( "You simulation contains the mote type: " + GUI.getDescriptionOf(t.getClass()) + "\n" + "Only the Sky Mote Type is currently supported.\n"); } logger.info("Checking mote types: '" + GUI.getDescriptionOf(t.getClass()) + "'"); } /* Check dependencies: Contiki Test Editor */ boolean hasTestEditor = false; for (Plugin startedPlugin : gui.getStartedPlugins()) { if (startedPlugin instanceof ScriptRunner) { hasTestEditor = true; break; } } logger.info("Checking that Contiki Test Editor exists: " + hasTestEditor); if (!hasTestEditor) { throw new RuntimeException( "The simulation needs at least one active Contiki Test Editor plugin.\n" + "The plugin is needed to control the non-visualized simulation."); } /* Create temporary directory */ File workingDir; try { workingDir = File.createTempFile("cooja", ".tmp"); workingDir.delete(); workingDir.mkdir(); logger.info("Creating temporary directory: " + workingDir.getAbsolutePath()); } catch (IOException e1) { throw (RuntimeException) new RuntimeException("Error when creating temporary directory: " + e1.getMessage()) .initCause(e1); } /* Unpacking project JARs */ ProjectConfig config = gui.getProjectConfig(); String[] projectJARs = config.getStringArrayValue(GUI.class.getName() + ".JARFILES"); for (String jar : projectJARs) { /* Locate project */ File project = config.getUserProjectDefining(GUI.class, "JARFILES", jar); File jarFile = new File(project, jar); if (!jarFile.exists()) { jarFile = new File(project, "lib/" + jar); } if (!jarFile.exists()) { throw new RuntimeException("Project JAR could not be found: " + jarFile.getAbsolutePath()); } logger.info("Unpacking project JAR " + jar + " (" + project + ")"); try { Process unjarProcess = Runtime.getRuntime() .exec(new String[] {"jar", "xf", jarFile.getAbsolutePath()}, null, workingDir); unjarProcess.waitFor(); } catch (Exception e1) { throw (RuntimeException) new RuntimeException("Error unpacking JAR file: " + e1.getMessage()).initCause(e1); } } /* Unpacking COOJA core JARs */ String[] coreJARs = new String[] { "tools/cooja/lib/jdom.jar", "tools/cooja/lib/log4j.jar", "tools/cooja/dist/cooja.jar" }; for (String jar : coreJARs) { File jarFile = new File(GUI.getExternalToolsSetting("PATH_CONTIKI"), jar); if (!jarFile.exists()) { throw new RuntimeException("Project JAR could not be found: " + jarFile.getAbsolutePath()); } logger.info("Unpacking core JAR " + jar); try { Process unjarProcess = Runtime.getRuntime() .exec(new String[] {"jar", "xf", jarFile.getAbsolutePath()}, null, workingDir); unjarProcess.waitFor(); } catch (Exception e1) { throw (RuntimeException) new RuntimeException("Error unpacking JAR file: " + e1.getMessage()).initCause(e1); } } /* Prepare simulation config */ Element rootElement = gui.extractSimulationConfig(); logger.info("Extracting simulation configuration"); handleExportAttributesToJAR(rootElement, gui, workingDir); /* Save simulation config */ File configFile = new File(workingDir, SIMCONFIG_FILENAME); try { Document doc = new Document(rootElement); FileOutputStream out = new FileOutputStream(configFile); XMLOutputter outputter = new XMLOutputter(); outputter.setFormat(Format.getPrettyFormat()); outputter.output(doc, out); out.close(); } catch (Exception e1) { throw (RuntimeException) new RuntimeException("Error when writing simulation configuration: " + configFile) .initCause(e1); } logger.info("Wrote simulation configuration: " + configFile.getName()); /* Export external tools config (without projects) */ try { File externalToolsConfig = new File(workingDir, EXTERNALTOOLS_FILENAME); FileOutputStream out = new FileOutputStream(externalToolsConfig); Properties differingSettings = new Properties(); Enumeration<Object> keyEnum = GUI.currentExternalToolsSettings.keys(); while (keyEnum.hasMoreElements()) { String key = (String) keyEnum.nextElement(); String defaultSetting = GUI.getExternalToolsDefaultSetting(key, ""); String currentSetting = GUI.currentExternalToolsSettings.getProperty(key, ""); if (key.equals("DEFAULT_PROJECTDIRS")) { differingSettings.setProperty(key, ""); } else if (!defaultSetting.equals(currentSetting)) { differingSettings.setProperty(key, currentSetting); } } differingSettings.store(out, "Cooja External Tools (User specific)"); out.close(); logger.info("Wrote external tools config: " + externalToolsConfig.getName()); } catch (Exception e2) { throw (RuntimeException) new RuntimeException( "Error when writing external tools configuration: " + e2.getMessage()) .initCause(e2); } /* Export current project configuration */ try { ProjectConfig pConfig = gui.getProjectConfig().clone(); Enumeration<String> pValues = pConfig.getPropertyNames(); File newConfigFile = new File(workingDir, PROJECT_DEFAULT_CONFIG_FILENAME); Properties newConfig = new Properties(); while (pValues.hasMoreElements()) { String name = pValues.nextElement(); newConfig.setProperty(name, pConfig.getStringValue(name)); } FileOutputStream out = new FileOutputStream(newConfigFile); newConfig.store(out, "Cooja Project Config"); logger.info("Wrote project config: " + newConfigFile.getName()); } catch (Exception e1) { e1.printStackTrace(); throw (RuntimeException) new RuntimeException("Error when writing project config: " + e1.getMessage()) .initCause(e1); } /* Delete existing META-INF dir */ File metaInfDir = new File(workingDir, "META-INF"); if (metaInfDir.exists() && metaInfDir.isDirectory()) { if (!deleteDirectory(metaInfDir)) { if (!deleteDirectory(metaInfDir)) { deleteDirectory(metaInfDir); } } } /* Prepare JAR manifest */ File manifestFile = new File(workingDir, "manifest.tmp"); if (manifestFile.exists()) { manifestFile.delete(); } StringBuilder sb = new StringBuilder(); sb.append("Manifest-Version: 1.0\r\n"); sb.append("Main-Class: " + ExecuteJAR.class.getName() + "\r\n"); sb.append("Class-path: .\r\n"); StringUtils.saveToFile(manifestFile, sb.toString()); logger.info("Wrote manifest file: " + manifestFile.getName()); /* Build executable JAR */ if (outputFile.exists()) { outputFile.delete(); } logger.info("Building executable JAR: " + outputFile); MessageList errors = new MessageList(); try { CompileContiki.compile( "jar cfm " + outputFile.getAbsolutePath() + " manifest.tmp .", null, outputFile, workingDir, null, null, errors, true); } catch (Exception e) { logger.warn("Building executable JAR error: " + e.getMessage()); MessageContainer[] err = errors.getMessages(); for (int i = 0; i < err.length; i++) { logger.fatal(">> " + err[i]); } /* Forward exception */ throw (RuntimeException) new RuntimeException("Error when building executable JAR: " + e.getMessage()) .initCause(e); } /* Delete temporary working directory */ logger.info("Deleting temporary files in: " + workingDir.getAbsolutePath()); if (!deleteDirectory(workingDir)) { if (!deleteDirectory(workingDir)) { deleteDirectory(workingDir); } } /* We are done! */ logger.info("Done! To run simulation: > java -jar " + outputFile.getName()); return true; }