diff --git a/app/Sketch.java b/app/Sketch.java index 95e4f05f5..b29654e31 100644 --- a/app/Sketch.java +++ b/app/Sketch.java @@ -1942,7 +1942,7 @@ public class Sketch { // make sure the user didn't hide the sketch folder ensureExistence(); - int exportPlatform = PConstants.MACOSX; + int exportPlatform = PApplet.platform; //PConstants.MACOSX; // nuke the old folder because it can cause trouble File destFolder = new File(folder, "application"); @@ -2005,6 +2005,19 @@ public class Sketch { } + /// make the jar folder (windows and linux) + + if (!jarFolder.exists()) jarFolder.mkdirs(); + + + /// on windows, copy the exe file + + if (exportPlatform == PConstants.WINDOWS) { + Base.copyFile(new File("lib/export/application.exe"), + new File(destFolder, this.name + ".exe")); + } + + /// start copying all jar files Vector jarListVector = new Vector(); @@ -2150,6 +2163,16 @@ public class Sketch { if (i != 0) exportClassPath.append(":"); exportClassPath.append("$JAVAROOT/" + jarList[i]); } + } else if (exportPlatform == PConstants.WINDOWS) { + for (int i = 0; i < jarList.length; i++) { + if (i != 0) exportClassPath.append(","); + exportClassPath.append(jarList[i]); + } + } else { + for (int i = 0; i < jarList.length; i++) { + if (i != 0) exportClassPath.append(":"); + exportClassPath.append("lib/" + jarList[i]); + } } @@ -2183,6 +2206,17 @@ public class Sketch { } ps.flush(); ps.close(); + + } else if (exportPlatform == PConstants.WINDOWS) { + File argsFile = new File(destFolder + "/lib/args.txt"); + PrintStream ps = new PrintStream(new FileOutputStream(argsFile)); + + ps.println(Preferences.get("run.options")); + ps.println(this.name); + ps.println(exportClassPath); + + ps.flush(); + ps.close(); } diff --git a/build/windows/launcher/Makefile b/build/windows/launcher/Makefile deleted file mode 100644 index 38540deca..000000000 --- a/build/windows/launcher/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -CXXFLAGS = -mwindows -mno-cygwin -O2 -Wall -OBJS = launcher.o launcher-rc.o - -processing.exe: $(OBJS) - $(LINK.cc) $(CXXFLAGS) -o $@ $(OBJS) - cp processing.exe ../work/ - -$(OBJS): Makefile - -launcher-rc.o: launcher.rc - windres -i $< -o $@ - -clean: - $(RM) $(OBJS) processing.exe diff --git a/build/windows/launcher/export.exe b/build/windows/launcher/export.exe new file mode 100755 index 000000000..cc7ddb1c8 Binary files /dev/null and b/build/windows/launcher/export.exe differ diff --git a/build/windows/launcher/launcher.cpp b/build/windows/launcher/launcher.cpp index fa79155fe..1fb8213ef 100644 --- a/build/windows/launcher/launcher.cpp +++ b/build/windows/launcher/launcher.cpp @@ -1,20 +1,25 @@ // -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- -// launcher.cpp : Defines the class behaviors for the application. -// +// if this code looks shitty, that's because it is. people are likely to have +// the durndest things in their CLASSPATH and QTJAVA environment variables. +// mostly because installers often mangle them without the user knowing. +// so who knows where and when the quotes will show up. the code below is +// based on a couple years of trial and error with processing releases. // The size of all of the strings was made sort of ambiguously large, since // 1) nothing is hurt by allocating an extra few bytes temporarily and // 2) if the user has a long path, and it gets copied five times over for the // classpath, the program runs the risk of crashing. Bad bad. -#define JAVA_ARGS "-Xms128m -Xmx128m " -#define JAVA_MAIN_CLASS "processing.app.Base" +#define ARGS_FILE_PATH "\\lib\\args.txt" #include #include #include + +void removeLineEndings(char *what); + int STDCALL WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow) { @@ -24,12 +29,6 @@ WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow) char *incoming_cmdline = (char *)malloc(strlen(lpCmd) * sizeof(char)); strcpy (incoming_cmdline, lpCmd); - // what gets put together to pass to jre - char *outgoing_cmdline = (char *)malloc(16384 * sizeof(char)); - - // prepend the args for -mx and -ms - strcpy(outgoing_cmdline, JAVA_ARGS); - // append the classpath and launcher.Application char *loaddir = (char *)malloc(MAX_PATH * sizeof(char)); *loaddir = 0; @@ -38,18 +37,65 @@ WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow) // remove the application name *(strrchr(loaddir, '\\')) = '\0'; - char *cp = (char *)malloc(8 * strlen(loaddir) + 4096); + // + // open the file that contains the main class name and java args - // if this code looks shitty, that's because it is. people are - // likely to have the durndest things in their CLASSPATH and QTJAVA - // environment variables. mostly because installers often mangle - // them without the user knowing. so who knows where and when the - // quotes will show up. this is a guess at dealing with the things, - // without spending a whole day to make it overly robust. [fry] + char *argsfilepath = (char*) + malloc(strlen(loaddir) * sizeof(char) + + strlen(ARGS_FILE_PATH) * sizeof(char) + 1); + strcpy(argsfilepath, loaddir); + strcat(argsfilepath, ARGS_FILE_PATH); - - + char javaArgs[512]; + char javaMainClass[512]; + char jarList[512]; + char *app_classpath = (char *)malloc(10 * strlen(loaddir) + 4096); + + FILE *argsfile = fopen(argsfilepath, "r"); + if (argsfile == NULL) { // won't exist for processing.exe + strcpy(javaArgs, "-Xms128m -Xmx128m"); + strcpy(javaMainClass, "processing.app.Base"); + sprintf(app_classpath, + "%s\\lib;" + "%s\\lib\\build;" + "%s\\lib\\pde.jar;" + "%s\\lib\\core.jar;" + "%s\\lib\\mrj.jar;" + "%s\\lib\\oro.jar;" + "%s\\lib\\registry.jar;" + "%s\\lib\\antlr.jar;", + loaddir, loaddir, loaddir, loaddir, + loaddir, loaddir, loaddir, loaddir); + } else { + fgets(javaArgs, 511, argsfile); + removeLineEndings(javaArgs); + fgets(javaMainClass, 511, argsfile); + removeLineEndings(javaMainClass); + fgets(jarList, 511, argsfile); + removeLineEndings(jarList); + + //MessageBox(NULL, javaArgs, "args", MB_OK); + //MessageBox(NULL, javaMainClass, "class", MB_OK); + //MessageBox(NULL, jarList, "jarlist", MB_OK); + + app_classpath[0] = 0; + char *jar = (char*) strtok(jarList, ","); + while (jar != NULL) { + //MessageBox(NULL, jar, "entry 1", MB_OK); + char entry[1024]; + sprintf(entry, "%s\\lib\\%s;", loaddir, jar); + //MessageBox(NULL, entry, "entry 2", MB_OK); + strcat(app_classpath, entry); + jar = (char*) strtok(NULL, ","); + } + //MessageBox(NULL, app_classpath, "app cp", MB_OK); + fclose(argsfile); + } + + // + + char *cp = (char *)malloc(10 * strlen(loaddir) + 4096); // test to see if running with a java runtime nearby or not char *testpath = (char *)malloc(MAX_PATH * sizeof(char)); @@ -60,11 +106,6 @@ WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow) int local_jre_installed = (fp != NULL); //char *rt_jar = (fp == NULL) ? "" : "java\\lib\\rt.jar;"; if (fp != NULL) fclose(fp); // argh! this was probably causing trouble - - - //MessageBox(NULL, local_jre_installed ? - // "local jre installed" : "couldn't find jre", "p5", MB_OK); - //const char *envClasspath = getenv("CLASSPATH"); char *env_classpath = (char *)malloc(16384 * sizeof(char)); @@ -154,51 +195,20 @@ WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow) } } - //if (qtjava_path[0] == 0) { - //MessageBox(NULL, "not found", "msg", MB_OK); - //} + // don't put quotes around contents of cp, even though %s might have + // spaces in it. don't put quotes in it, because it's setting the + // environment variable for CLASSPATH, not being included on the + // command line. so setting the env var it's ok to have spaces, + // and the quotes prevent javax.comm.properties from being found. - // NO! put quotes around contents of cp, because %s might have spaces in it. - // don't put quotes in it, because it's setting the environment variable - // for CLASSPATH, not being included on the command line. so setting the - // env var it's ok to have spaces, and the quotes prevent - // javax.comm.properties from being found. - sprintf(cp, - //"\"" // begin quote - //"'" - - "%s" // local jre or blank - "%s" // qtjava path - - "%s\\lib;" - "%s\\lib\\build;" - "%s\\lib\\pde.jar;" - "%s\\lib\\core.jar;" - "%s\\lib\\mrj.jar;" - "%s\\lib\\oro.jar;" - "%s\\lib\\registry.jar;" - "%s\\lib\\antlr.jar;" - - "%s", // original CLASSPATH - - - //"C:\\WINNT\\system32\\QTJava.zip;" // worthless - //"C:\\WINDOWS\\system32\\QTJava.zip;" - - //"\"", // end quote - //"'", - //, - - // the first three %s args - //local_jre_installed ? "java\\lib\\rt.jar;java\\lib\\jaws.jar;" : "", - local_jre_installed ? "java\\lib\\rt.jar;" : "", - qtjava_path, - loaddir, loaddir, loaddir, loaddir, - loaddir, loaddir, loaddir, loaddir, - env_classpath); - - //MessageBox(NULL, qtjava_path, "qtjava", MB_OK); - //MessageBox(NULL, cp, "cp outgoing", MB_OK); + strcpy(cp, app_classpath); + if (local_jre_installed) { + char localjre[512]; + printf(localjre, "%s\\java\\lib\\rt.jar;", loaddir); + strcat(cp, localjre); + } + strcat(cp, qtjava_path); + strcat(cp, env_classpath); if (!SetEnvironmentVariable("CLASSPATH", cp)) { MessageBox(NULL, "Could not set CLASSPATH environment variable", @@ -206,8 +216,6 @@ WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow) return 0; } - - // need to add the local jre to the path for 'java mode' in the env if (local_jre_installed) { char *env_path = (char *)malloc(strlen(getenv("PATH")) * sizeof(char)); @@ -220,18 +228,24 @@ WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow) "Processing Error", MB_OK); return 0; } - - } - //MessageBox(NULL, cp, "whaadddup", MB_OK); + // what gets put together to pass to jre + char *outgoing_cmdline = (char *)malloc(16384 * sizeof(char)); + + // prepend the args for -mx and -ms + strcpy(outgoing_cmdline, javaArgs); + strcat(outgoing_cmdline, " "); // add the name of the class to execute and a space before the next arg - strcat(outgoing_cmdline, JAVA_MAIN_CLASS " "); + strcat(outgoing_cmdline, javaMainClass); + strcat(outgoing_cmdline, " "); // append additional incoming stuff (document names), if any strcat(outgoing_cmdline, incoming_cmdline); + //MessageBox(NULL, outgoing_cmdline, "cmdline", MB_OK); + char *executable = (char *)malloc((strlen(loaddir) + 256) * sizeof(char)); // loaddir is the name path to the current application @@ -290,3 +304,16 @@ WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow) return 0; } + + +void removeLineEndings(char *what) { + int index = strlen(what) - 1; + while (index >= 0) { + if ((what[index] == 10) || (what[index] == 13)) { + what[index] = 0; + --index; + } else { + return; + } + } +} diff --git a/build/windows/launcher/make.sh b/build/windows/launcher/make.sh new file mode 100755 index 000000000..49a8d3f2a --- /dev/null +++ b/build/windows/launcher/make.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +g++ -mwindows -mno-cygwin -O2 -Wall -c -o launcher.o launcher.cpp +windres -i launcher.rc -o launcher-rc.o +g++ -mwindows -mno-cygwin -O2 -Wall -mwindows -mno-cygwin -O2 -Wall -o processing.exe launcher.o launcher-rc.o +cp processing.exe ../work/ + +g++ -mwindows -mno-cygwin -O2 -Wall -DEXPORT -c -o launcher.o launcher.cpp +g++ -mwindows -mno-cygwin -O2 -Wall -mwindows -mno-cygwin -O2 -Wall -o export.exe launcher.o +cp export.exe ../work/lib/export/application.exe +cp export.exe ../../shared/lib/export/ diff --git a/build/windows/launcher/processing.exe b/build/windows/launcher/processing.exe index ac2c3847b..52e3952c8 100755 Binary files a/build/windows/launcher/processing.exe and b/build/windows/launcher/processing.exe differ diff --git a/build/windows/make.sh b/build/windows/make.sh index 65528f53a..f7b6be1ed 100755 --- a/build/windows/make.sh +++ b/build/windows/make.sh @@ -58,7 +58,7 @@ else echo Compiling processing.exe cd launcher - make && cp processing.exe ../work/ + ./make.sh # && cp processing.exe ../work/ cd .. # get jikes and depedencies