From 70b4950e0956498f482fd2f351b72deb42a1f574 Mon Sep 17 00:00:00 2001 From: benfry Date: Sat, 22 Jan 2011 22:27:52 +0000 Subject: [PATCH] get android code to compile --- app/src/processing/app/Mode.java | 8 + app/src/processing/app/Sketch.java | 21 +- .../processing/mode/android/AndroidBuild.java | 94 ++++----- .../mode/android/AndroidEditor.java | 196 ++++++++++-------- .../processing/mode/android/AndroidMode.java | 26 +++ .../mode/android/AndroidPreprocessor.java | 2 +- .../processing/mode/android/AndroidSDK.java | 20 +- app/src/processing/mode/java/JavaBuild.java | 6 +- app/src/processing/mode/java/JavaToolbar.java | 2 +- build/shared/revisions.txt | 25 +++ todo.txt | 22 +- 11 files changed, 248 insertions(+), 174 deletions(-) diff --git a/app/src/processing/app/Mode.java b/app/src/processing/app/Mode.java index d356f91ec..7fd5117b0 100644 --- a/app/src/processing/app/Mode.java +++ b/app/src/processing/app/Mode.java @@ -51,6 +51,14 @@ public abstract class Mode { } + public File getContentFile(String path) { + return new File(folder, path); + } + + + + + /** * Return the pretty/printable/menu name for this mode. This is separate from * the single word name of the folder that contains this mode. It could even diff --git a/app/src/processing/app/Sketch.java b/app/src/processing/app/Sketch.java index 1f3a0ef40..4e7a9de47 100644 --- a/app/src/processing/app/Sketch.java +++ b/app/src/processing/app/Sketch.java @@ -1128,22 +1128,23 @@ public class Sketch { * When running from the editor, take care of preparations before running * a build or an export. Also erases and/or creates 'targetFolder' if it's * not null, and if preferences say to do so when exporting. + * @param targetFolder is something like applet, application, android... */ public void prepareBuild(File targetFolder) throws SketchException { // make sure the user didn't hide the sketch folder ensureExistence(); - // make sure any edits have been stored - current.setProgram(editor.getText()); + // don't do from the command line + if (editor != null) { + // make sure any edits have been stored + current.setProgram(editor.getText()); - // if an external editor is being used, need to grab the - // latest version of the code from the file. - if (Preferences.getBoolean("editor.external")) { - // set current to null so that the tab gets updated - // http://dev.processing.org/bugs/show_bug.cgi?id=515 - current = null; - // don't do from the command line - if (editor != null) { + // if an external editor is being used, need to grab the + // latest version of the code from the file. + if (Preferences.getBoolean("editor.external")) { + // set current to null so that the tab gets updated + // http://dev.processing.org/bugs/show_bug.cgi?id=515 + current = null; // nuke previous files and settings load(); } diff --git a/app/src/processing/mode/android/AndroidBuild.java b/app/src/processing/mode/android/AndroidBuild.java index 9954adf50..c59f03908 100644 --- a/app/src/processing/mode/android/AndroidBuild.java +++ b/app/src/processing/mode/android/AndroidBuild.java @@ -40,8 +40,10 @@ class AndroidBuild extends JavaBuild { private final AndroidSDK sdk; Manifest manifest; - String className; - File tempBuildFolder; +// String className; + /** temporary folder safely inside a 8.3-friendly folder */ + File tmpFolder; + /** build.xml file for this project */ File buildFile; @@ -50,54 +52,42 @@ class AndroidBuild extends JavaBuild { this.sdk = sdk; } - - public File createProject(String target) throws IOException, SketchException { -// try { - tempBuildFolder = createTempBuildFolder(sketch); -// } catch (final IOException e) { -// editor.statusError(e); -// return null; -// } + + public File createProject(String target, File coreZipFile) throws IOException, SketchException { + tmpFolder = createTempBuildFolder(sketch); // Create the 'src' folder with the preprocessed code. - final File srcFolder = new File(tempBuildFolder, "src"); + final File srcFolder = new File(tmpFolder, "src"); if (processing.app.Base.DEBUG) { - Base.openFolder(tempBuildFolder); + Base.openFolder(tmpFolder); } -// try { manifest = new Manifest(sketch); // grab code from current editing window (GUI only) - sketch.prepare(); + sketch.prepareBuild(null); // build the preproc and get to work AndroidPreprocessor preproc = new AndroidPreprocessor(sketch, getPackageName()); if (!preproc.parseSketchSize()) { - editor.statusError("Could not parse the size() command."); - return null; + throw new SketchException("Could not parse the size() command."); } - className = preprocess(srcFolder.getAbsolutePath(), - manifest.getPackageName(), - preproc); - if (className != null) { -// final File androidXML = new File(tempBuildFolder, "AndroidManifest.xml"); -// writeAndroidManifest(androidXML, sketch.getName(), className); -// manifest.setClassName(className); - File tempManifest = new File(tempBuildFolder, "AndroidManifest.xml"); - manifest.writeBuild(tempManifest, className, target.equals("debug")); + sketchClassName = preprocess(srcFolder, manifest.getPackageName(), preproc); + if (sketchClassName != null) { + File tempManifest = new File(tmpFolder, "AndroidManifest.xml"); + manifest.writeBuild(tempManifest, sketchClassName, target.equals("debug")); - writeBuildProps(new File(tempBuildFolder, "build.properties")); - buildFile = new File(tempBuildFolder, "build.xml"); + writeBuildProps(new File(tmpFolder, "build.properties")); + buildFile = new File(tmpFolder, "build.xml"); writeBuildXML(buildFile, sketch.getName()); - writeDefaultProps(new File(tempBuildFolder, "default.properties")); - writeLocalProps(new File(tempBuildFolder, "local.properties")); - writeRes(new File(tempBuildFolder, "res"), className); + writeDefaultProps(new File(tmpFolder, "default.properties")); + writeLocalProps(new File(tmpFolder, "local.properties")); + writeRes(new File(tmpFolder, "res"), sketchClassName); - final File libsFolder = mkdirs(tempBuildFolder, "libs"); - final File assetsFolder = mkdirs(tempBuildFolder, "assets"); + final File libsFolder = mkdirs(tmpFolder, "libs"); + final File assetsFolder = mkdirs(tmpFolder, "assets"); - final InputStream input = - PApplet.createInput(AndroidEditor.getCoreZipLocation()); - PApplet.saveStream(new File(libsFolder, "processing-core.jar"), input); +// InputStream input = PApplet.createInput(getCoreZipLocation()); +// PApplet.saveStream(new File(libsFolder, "processing-core.jar"), input); + Base.copyFile(coreZipFile, new File(libsFolder, "processing-core.jar")); try { // Copy any imported libraries or code folder contents to the project @@ -121,7 +111,7 @@ class AndroidBuild extends JavaBuild { // editor.statusError(e); // return null; // } - return tempBuildFolder; + return tmpFolder; } @@ -199,7 +189,7 @@ class AndroidBuild extends JavaBuild { /** * @param target "debug" or "release" */ - protected boolean antBuild(final String target) { + protected boolean antBuild(final String target) throws SketchException { final Project p = new Project(); String path = buildFile.getAbsolutePath().replace('\\', '/'); p.setUserProperty("ant.file", path); @@ -225,7 +215,7 @@ class AndroidBuild extends JavaBuild { p.addBuildListener(errorLogger); try { - editor.statusNotice("Building sketch for Android..."); +// editor.statusNotice("Building sketch for Android..."); p.fireBuildStarted(); p.init(); final ProjectHelper helper = ProjectHelper.getProjectHelper(); @@ -233,7 +223,7 @@ class AndroidBuild extends JavaBuild { helper.parse(p, buildFile); // p.executeTarget(p.getDefaultTarget()); p.executeTarget(target); - editor.statusNotice("Finished building sketch."); +// editor.statusNotice("Finished building sketch."); return true; } catch (final BuildException e) { @@ -270,31 +260,35 @@ class AndroidBuild extends JavaBuild { final int lineNumber = PApplet.parseInt(pieces[2]) - 1; // PApplet.println("looking for " + fileName + " line " + // lineNumber); - final SketchException rex = placeException(pieces[3], - fileName, lineNumber); + SketchException rex = placeException(pieces[3], fileName, lineNumber); if (rex != null) { - rex.hideStackTrace(); - editor.statusError(rex); - return false; // get outta here +// rex.hideStackTrace(); +// editor.statusError(rex); +// return false; // get outta here + throw rex; } } } } - editor.statusError(e); +// editor.statusError(e); + System.err.println("Problem during build:"); + e.printStackTrace(); + // Couldn't parse the exception, so wrap it up and chuck it +// throw new SketchException(e); } return false; } - protected String getClassName() { - return className; - } +// protected String getClassName() { +// return className; +// } String getPathForAPK(final String target) { String suffix = target.equals("release") ? "unsigned" : "debug"; String apkName = "bin/" + sketch.getName() + "-" + suffix + ".apk"; - final File apkFile = new File(tempBuildFolder, apkName); + final File apkFile = new File(tmpFolder, apkName); return apkFile.getAbsolutePath(); } @@ -538,6 +532,6 @@ class AndroidBuild extends JavaBuild { public void cleanup() { // don't want to be responsible for this //rm(tempBuildFolder); - tempBuildFolder.deleteOnExit(); + tmpFolder.deleteOnExit(); } } \ No newline at end of file diff --git a/app/src/processing/mode/android/AndroidEditor.java b/app/src/processing/mode/android/AndroidEditor.java index 266bb88e9..8fefaca65 100644 --- a/app/src/processing/mode/android/AndroidEditor.java +++ b/app/src/processing/mode/android/AndroidEditor.java @@ -21,27 +21,29 @@ package processing.mode.android; -import java.awt.Frame; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; -import java.io.*; -import java.net.URL; +import java.io.File; +import java.io.IOException; import java.text.SimpleDateFormat; -import java.util.*; -import java.util.concurrent.*; -import java.util.regex.*; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; -import javax.swing.JCheckBoxMenuItem; import javax.swing.JMenu; -import javax.swing.JMenuBar; import javax.swing.JMenuItem; -import processing.app.*; - +import processing.app.Base; +import processing.app.Mode; +import processing.app.SketchException; import processing.core.PApplet; -import processing.mode.java.*; +import processing.mode.java.JavaEditor; import processing.mode.java.runner.Runner; // http://dl.google.com/android/repository/repository.xml @@ -57,22 +59,40 @@ import processing.mode.java.runner.Runner; public class AndroidEditor extends JavaEditor implements DeviceListener { private AndroidSDK sdk; -// private Editor editor; private AndroidBuild build; - - private static final String ANDROID_CORE_FILENAME = - "processing-android-core-" + Base.VERSION_NAME + ".zip"; - private static final String ANDROID_CORE_URL = - "http://processing.googlecode.com/files/" + ANDROID_CORE_FILENAME; +// private static final String ANDROID_CORE_FILENAME = +// "processing-android-core-" + Base.VERSION_NAME + ".zip"; + +// private static final String ANDROID_CORE_URL = +// "http://processing.googlecode.com/files/" + ANDROID_CORE_FILENAME; -// JCheckBoxMenuItem toggleItem; AndroidMode amode; protected AndroidEditor(Base base, String path, int[] location, Mode mode) { super(base, path, location, mode); amode = (AndroidMode) mode; + + statusNotice("Loading Android tools."); + + if (sdk == null) { + try { + sdk = AndroidSDK.find(this); + statusNotice("Done loading Android tools."); + + } catch (Exception e) { + Base.showWarning("Android Tools Error", e.getMessage(), null); + statusError("Android Mode is disabled."); + } + } + + // Make sure that the processing.android.core.* classes are available + // if (!checkCore()) { + // statusNotice("Android mode canceled."); + // return false; + // } + } @@ -222,69 +242,50 @@ public class AndroidEditor extends JavaEditor implements DeviceListener { // } - protected boolean loadAndroid() { - statusNotice("Loading Android tools."); - - try { - sdk = AndroidSDK.find((editor instanceof Frame) ? (Frame) editor : null); - } catch (final Exception e) { - Base.showWarning("Android Tools Error", e.getMessage(), null); - editor.statusNotice("Android mode canceled."); - return false; - } - - // Make sure that the processing.android.core.* classes are available - if (!checkCore()) { - editor.statusNotice("Android mode canceled."); - return false; - } - - editor.statusNotice("Done loading Android tools."); - return true; - } +// protected boolean loadAndroid() { +// statusNotice("Loading Android tools."); +// +// try { +// sdk = AndroidSDK.find(this); +// } catch (final Exception e) { +// Base.showWarning("Android Tools Error", e.getMessage(), null); +// statusNotice("Android mode canceled."); +// return false; +// } +// +// // Make sure that the processing.android.core.* classes are available +// if (!checkCore()) { +// statusNotice("Android mode canceled."); +// return false; +// } +// +// statusNotice("Done loading Android tools."); +// return true; +// } - static private File coreZipLocation; - - static protected File getCoreZipLocation() { - if (coreZipLocation == null) { - coreZipLocation = checkCoreZipLocation(); - } - return coreZipLocation; - } +// static protected File getCoreZipLocation() { +// if (coreZipLocation == null) { +// coreZipLocation = checkCoreZipLocation(); +// } +// return coreZipLocation; +// } - static protected File checkCoreZipLocation() { - // for debugging only, check to see if this is an svn checkout - File debugFile = new File("../../../android/core.zip"); - if (!debugFile.exists() && Base.isMacOS()) { - // current path might be inside Processing.app, so need to go much higher - debugFile = new File("../../../../../../../android/core.zip"); - } - if (debugFile.exists()) { - System.out.println("Using version of core.zip from local SVN checkout."); - return debugFile; - } - - // otherwise do the usual - return new File(base.getSketchbookFolder(), ANDROID_CORE_FILENAME); - } - - - private boolean checkCore() { - final File target = getCoreZipLocation(); - if (!target.exists()) { - try { - final URL url = new URL(ANDROID_CORE_URL); - PApplet.saveStream(target, url.openStream()); - } catch (final Exception e) { - Base.showWarning("Download Error", - "Could not download Android core.zip", e); - return false; - } - } - return true; - } +// private boolean checkCore() { +// final File target = getCoreZipLocation(); +// if (!target.exists()) { +// try { +// final URL url = new URL(ANDROID_CORE_URL); +// PApplet.saveStream(target, url.openStream()); +// } catch (final Exception e) { +// Base.showWarning("Download Error", +// "Could not download Android core.zip", e); +// return false; +// } +// } +// return true; +// } static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyMMdd.HHmm"); @@ -303,7 +304,7 @@ public class AndroidEditor extends JavaEditor implements DeviceListener { private boolean startSketch(final Device device) { final String packageName = build.getPackageName(); - final String className = build.getClassName(); + final String className = build.getSketchClassName(); try { if (device.launchApp(packageName, className)) { return true; @@ -351,16 +352,26 @@ public class AndroidEditor extends JavaEditor implements DeviceListener { "Building and launching...", "Creating project..."); try { - if (build.createProject(target) == null) { - return; + try { + if (build.createProject(target, amode.getCoreZipLocation()) == null) { + return; + } + } catch (SketchException se) { + statusError(se); + } catch (IOException e) { + statusError(e); } try { if (monitor.isCanceled()) { throw new MonitorCanceled(); } monitor.setNote("Building..."); - if (!build.antBuild(target)) { - return; + try { + if (!build.antBuild(target)) { + return; + } + } catch (SketchException se) { + statusError(se); } if (monitor.isCanceled()) { @@ -411,9 +422,16 @@ public class AndroidEditor extends JavaEditor implements DeviceListener { "Building and exporting...", "Creating project..."); try { - File tempFolder = build.createProject(target); - if (tempFolder == null) { - return; + File tempFolder = null; + try { + tempFolder = build.createProject(target, amode.getCoreZipLocation()); + if (tempFolder == null) { + return; + } + } catch (IOException e) { + e.printStackTrace(); + } catch (SketchException se) { + se.printStackTrace(); } try { if (monitor.isCanceled()) { @@ -484,8 +502,8 @@ public class AndroidEditor extends JavaEditor implements DeviceListener { if (lm.find()) { final String filename = lm.group(1); final int lineNumber = Integer.parseInt(lm.group(2)) - 1; - final SketchException rex = - sketch.placeException(exceptionLine, filename, lineNumber); + final SketchException rex = + build.placeException(exceptionLine, filename, lineNumber); statusError(rex == null ? new SketchException(exceptionLine, false) : rex); return; } diff --git a/app/src/processing/mode/android/AndroidMode.java b/app/src/processing/mode/android/AndroidMode.java index fc3dabf1e..10934d783 100644 --- a/app/src/processing/mode/android/AndroidMode.java +++ b/app/src/processing/mode/android/AndroidMode.java @@ -28,18 +28,44 @@ import processing.mode.java.JavaMode; public class AndroidMode extends JavaMode { + static private File coreZipLocation; + public AndroidMode(Base base, File folder) { super(base, folder); } + @Override public Editor createEditor(Base base, String path, int[] location) { return new AndroidEditor(base, path, location, this); } + @Override public String getTitle() { return "Android"; } + + + protected File getCoreZipLocation() { + if (coreZipLocation == null) { + // for debugging only, check to see if this is an svn checkout + File debugFile = new File("../../../android/core.zip"); + if (!debugFile.exists() && Base.isMacOS()) { + // current path might be inside Processing.app, so need to go much higher + debugFile = new File("../../../../../../../android/core.zip"); + } + if (debugFile.exists()) { + System.out.println("Using version of core.zip from local SVN checkout."); +// return debugFile; + coreZipLocation = debugFile; + } + + // otherwise do the usual + // return new File(base.getSketchbookFolder(), ANDROID_CORE_FILENAME); + coreZipLocation = getContentFile("android-core.zip"); + } + return coreZipLocation; + } } \ No newline at end of file diff --git a/app/src/processing/mode/android/AndroidPreprocessor.java b/app/src/processing/mode/android/AndroidPreprocessor.java index 0ffa98625..1d0ad4c8e 100644 --- a/app/src/processing/mode/android/AndroidPreprocessor.java +++ b/app/src/processing/mode/android/AndroidPreprocessor.java @@ -48,7 +48,7 @@ public class AndroidPreprocessor extends PdePreprocessor { public AndroidPreprocessor(final Sketch sketch, - final String packageName) throws IOException { + final String packageName) throws IOException { super(sketch.getName()); this.sketch = sketch; this.packageName = packageName; diff --git a/app/src/processing/mode/android/AndroidSDK.java b/app/src/processing/mode/android/AndroidSDK.java index 124aafbc5..a1d04e8cf 100644 --- a/app/src/processing/mode/android/AndroidSDK.java +++ b/app/src/processing/mode/android/AndroidSDK.java @@ -13,7 +13,7 @@ import processing.app.exec.ProcessResult; import processing.core.PApplet; class AndroidSDK { - private final File sdk; + private final File folder; private final File tools; private final File platformTools; private final File androidTool; @@ -39,19 +39,19 @@ class AndroidSDK { public AndroidSDK(final String sdkPath) throws BadSDKException, IOException { - sdk = new File(sdkPath); - if (!sdk.exists()) { - throw new BadSDKException(sdk + " does not exist"); + folder = new File(sdkPath); + if (!folder.exists()) { + throw new BadSDKException(folder + " does not exist"); } - tools = new File(sdk, "tools"); + tools = new File(folder, "tools"); if (!tools.exists()) { - throw new BadSDKException("There is no tools folder in " + sdk); + throw new BadSDKException("There is no tools folder in " + folder); } - platformTools = new File(sdk, "platform-tools"); + platformTools = new File(folder, "platform-tools"); if (!platformTools.exists()) { - throw new BadSDKException("There is no platform-tools folder in " + sdk); + throw new BadSDKException("There is no platform-tools folder in " + folder); } androidTool = findAndroidTool(tools); @@ -60,7 +60,7 @@ class AndroidSDK { String path = p.getenv("PATH"); - p.setenv("ANDROID_SDK", sdk.getCanonicalPath()); + p.setenv("ANDROID_SDK", folder.getCanonicalPath()); path = platformTools.getCanonicalPath() + File.pathSeparator + tools.getCanonicalPath() + File.pathSeparator + path; @@ -89,7 +89,7 @@ class AndroidSDK { public File getSdkFolder() { - return sdk; + return folder; } diff --git a/app/src/processing/mode/java/JavaBuild.java b/app/src/processing/mode/java/JavaBuild.java index 2127f874e..b04f4dcd1 100644 --- a/app/src/processing/mode/java/JavaBuild.java +++ b/app/src/processing/mode/java/JavaBuild.java @@ -57,7 +57,7 @@ public class JavaBuild { private File binFolder; private boolean foundMain = false; private String classPath; - private String appletClassName; + protected String sketchClassName; /** * This will include the code folder, any library folders, etc. that might @@ -162,7 +162,7 @@ public class JavaBuild { // String bootClasses = System.getProperty("sun.boot.class.path"); // if (compiler.compile(this, srcFolder, binFolder, primaryClassName, getClassPath(), bootClasses)) { if (Compiler.compile(this)) { - appletClassName = classNameFound; + sketchClassName = classNameFound; return classNameFound; } return null; @@ -170,7 +170,7 @@ public class JavaBuild { public String getSketchClassName() { - return appletClassName; + return sketchClassName; } diff --git a/app/src/processing/mode/java/JavaToolbar.java b/app/src/processing/mode/java/JavaToolbar.java index d70743cda..68abb8d4e 100644 --- a/app/src/processing/mode/java/JavaToolbar.java +++ b/app/src/processing/mode/java/JavaToolbar.java @@ -115,7 +115,7 @@ public class JavaToolbar extends EditorToolbar { if (shift) { jeditor.handleExportApplication(); } else { - jeditor.handleExportProject(); + jeditor.handleExportApplet(); } break; } diff --git a/build/shared/revisions.txt b/build/shared/revisions.txt index 0159a9657..ff28a500e 100644 --- a/build/shared/revisions.txt +++ b/build/shared/revisions.txt @@ -1,3 +1,28 @@ +PROCESSING REV 0193 - XX February 2011 + +The PDE is receiving a major overhaul. + +[ internal changes ] + ++ Removed build.path from preferences.txt. + Not really used anywhere, just trying to clean things up. + ++ Removed 'console.output.file' and 'console.error.file'. + These weren't respected as paths, no reason for them. + ++ Change console to write to the 'console/' folder in settings. + This may eventually create a problem with logs that need to be cleaned, + but we'll keep an eye on it for now. + ++ Removed 'console' true/false from preferences. + ++ Cannot reproduce problem with wrong character encoding in the console. + http://code.google.com/p/processing/issues/detail?id=197 + + +. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + PROCESSING REV 0192 - 18 December 2010 This release contains a roll-up of lots of bug fixes. However, it's being diff --git a/todo.txt b/todo.txt index ed59c6e6d..1db4aeadc 100644 --- a/todo.txt +++ b/todo.txt @@ -10,16 +10,6 @@ X http://code.google.com/p/processing/issues/detail?id=466 o occasional exception in "copy for discourse" o http://dev.processing.org/bugs/show_bug.cgi?id=729 -DO NOT USE "JVMArchs". It is deprecated, and manually overrides the natural architecture launching and ordering that LaunchServices does, including accommodating the 32-bit checkbox in the Get Info window. - -[ from the major refactoring work, not in trunk ] - -_ export is broken in 0192 -_ http://code.google.com/p/processing/issues/detail?id=487 - -_ the build is broken! the build is broken! -_ http://code.google.com/p/processing/issues/detail?id=519 - fixed in 0192 J auto-format screws up if/else/else if blocks J http://code.google.com/p/processing/issues/detail?id=325 @@ -49,6 +39,18 @@ o message(new String(b, offset, length), err, false); o http://code.google.com/p/processing/issues/detail?id=197 X couldn't find a good way to reproduce this, closing +_ remove any reference to 'Editor' from Sketch.java +_ or is that excessive, since Document is in there, etc +_ Build does the heavy lifting anyway... + +_ export is broken in 0192 +_ http://code.google.com/p/processing/issues/detail?id=487 + +_ the build is broken! the build is broken! +_ http://code.google.com/p/processing/issues/detail?id=519 + +DO NOT USE "JVMArchs". It is deprecated, and manually overrides the natural architecture launching and ordering that LaunchServices does, including accommodating the 32-bit checkbox in the Get Info window. + + Removed build.path from preferences.txt. Not really used anywhere, just trying to clean things up.