diff --git a/launchers/macosx/README.md b/launchers/macosx/README.md index ca89b27a10..800320bd17 100644 --- a/launchers/macosx/README.md +++ b/launchers/macosx/README.md @@ -6,3 +6,4 @@ However, this is a thin wrapper launching both Mac OS X trayicon and the I2P rou More code will be merged in, it's just a f* mess which Meeh needs to clean up and move into repo. +`./fullBuild.sh` triggers Ant jobs and prepare the base.zip, as well as starting the ninja build. diff --git a/launchers/macosx/build.sbt b/launchers/macosx/build.sbt index 1b1cb5968f..300102eab2 100644 --- a/launchers/macosx/build.sbt +++ b/launchers/macosx/build.sbt @@ -8,41 +8,12 @@ lazy val buildAppBundleTask = taskKey[Unit](s"Build an Mac OS X bundle for I2P $ lazy val buildDeployZipTask = taskKey[String](s"Build an zipfile with base directory for I2P ${i2pVersion}.") lazy val bundleBuildPath = new File("./output") -lazy val staticFiles = List( - "blocklist.txt", - "clients.config", - "continents.txt", - "countries.txt", - "hosts.txt", - "geoip.txt", - "router.config", - "webapps.config" -) lazy val resDir = new File("./../installer/resources") lazy val i2pBuildDir = new File("./../pkg-temp") lazy val warsForCopy = new File(i2pBuildDir, "webapps").list.filter { f => f.endsWith(".war") } lazy val jarsForCopy = new File(i2pBuildDir, "lib").list.filter { f => f.endsWith(".jar") } -// TODO: Meeh: To be removed - logic is moved to obj-cpp -def defaultOSXLauncherShellScript(javaOpts: Seq[String] = Seq.empty): Seq[String] = { - val javaOptsString = javaOpts.map(_ + " ").mkString - Seq( - "#!/usr/bin/env sh", - s""" - |echo "I2P - Mac OS X Launcher starting up" - |export I2P=$$HOME/Library/I2P - |for jar in `ls $${I2P}/lib/*.jar`; do - | if [ ! -z $$CP ]; then - | CP=$${CP}:$${jar}; - | else - | CP=$${jar} - | fi - |done - |export CLASSPATH=$$CP - |exec java -jar $javaOptsString$$JAVA_OPTS "$$0" "$$@"""".stripMargin, - "") -} // Pointing the resources directory to the "installer" directory resourceDirectory in Compile := baseDirectory.value / ".." / ".." / "installer" / "resources" @@ -55,22 +26,10 @@ unmanagedClasspath in Compile ++= Seq( baseDirectory.value / ".." / ".." / "pkg-temp" / "lib" / "*.jar" ) -assemblyOption in assembly := (assemblyOption in assembly).value.copy( - prependShellScript = Some(defaultOSXLauncherShellScript( - Seq( - "-Xmx512M", - "-Xms128m", - "-Dwrapper.logfile=/tmp/router.log", - "-Dwrapper.logfile.loglevel=DEBUG", - "-Dwrapper.java.pidfile=/tmp/routerjvm.pid", - "-Dwrapper.console.loglevel=DEBUG", - "-Di2p.dir.base=$I2P", - "-Djava.library.path=$I2P" - ))) -) +assemblyOption in assembly := (assemblyOption in assembly).value.copy(includeScala = false, includeDependency = false) -assemblyJarName in assembly := s"OSXLauncher" +assemblyJarName in assembly := s"launcher.jar" assemblyExcludedJars in assembly := { val cp = (fullClasspath in assembly).value diff --git a/launchers/macosx/obj-cpp/JavaRunner.cpp b/launchers/macosx/obj-cpp/JavaRunner.cpp index 531a948401..6b1ec673ac 100644 --- a/launchers/macosx/obj-cpp/JavaRunner.cpp +++ b/launchers/macosx/obj-cpp/JavaRunner.cpp @@ -2,8 +2,10 @@ #include #include +#include using namespace subprocess; +using namespace std::experimental; JavaRunner::JavaRunner(std::string javaBin, const fp_proc_t& execFn, const fp_t& cb) : javaBinaryPath(javaBin), executingFn(execFn), exitCallbackFn(cb) @@ -11,7 +13,7 @@ JavaRunner::JavaRunner(std::string javaBin, const fp_proc_t& execFn, const fp_t& javaProcess = std::shared_ptr(new Popen({javaBin.c_str(), "-version"}, defer_spawn{true})); } -void JavaRunner::execute() +optional > JavaRunner::execute() { try { auto executingFn = dispatch_block_create(DISPATCH_BLOCK_INHERIT_QOS_CLASS, ^{ @@ -24,7 +26,9 @@ void JavaRunner::execute() printf("Finished executingFn - Runs callbackFn\n"); this->exitCallbackFn(); + return std::async(std::launch::async, []{ return 0; }); } catch (std::exception* ex) { printf("ERROR: %s\n", ex->what()); + return nullopt; } } diff --git a/launchers/macosx/obj-cpp/JavaRunner.h b/launchers/macosx/obj-cpp/JavaRunner.h index 5035be730a..78f1ba17a2 100644 --- a/launchers/macosx/obj-cpp/JavaRunner.h +++ b/launchers/macosx/obj-cpp/JavaRunner.h @@ -3,10 +3,14 @@ #include #include #include +#include +#include #include +#include using namespace subprocess; +using namespace std::experimental; class JavaRunner; @@ -23,9 +27,9 @@ typedef std::function fp_t; typedef std::function fp_proc_t; /** - * + * * class JavaRunner - * + * **/ class JavaRunner { @@ -34,7 +38,31 @@ public: JavaRunner(std::string javaBin, const fp_proc_t& executingFn, const fp_t& cb); ~JavaRunner() = default; - void execute(); + const std::list defaultStartupFlags { + "-Xmx512M", + "-Xms128m", + "-Djava.awt.headless=true", + "-Dwrapper.logfile=/tmp/router.log", + "-Dwrapper.logfile.loglevel=DEBUG", + "-Dwrapper.java.pidfile=/tmp/routerjvm.pid", + "-Dwrapper.console.loglevel=DEBUG", + "-Di2p.dir.base=$BASEPATH", + "-Djava.library.path=$BASEPATH", + "$JAVA_OPTS", + "net.i2p.launchers.SimpleOSXLauncher" + }; + + const std::list defaultFlagsForExtractorJob { + "-Xmx512M", + "-Xms128m", + "-Djava.awt.headless=true", + "-Di2p.dir.base=$BASEPATH", + "-Di2p.dir.zip=$ZIPPATH", + "net.i2p.launchers.BaseExtractor", + "extract" + }; + + optional > execute(); std::shared_ptr javaProcess; std::string javaBinaryPath; private: diff --git a/launchers/macosx/obj-cpp/build.ninja b/launchers/macosx/obj-cpp/build.ninja index eb9506c581..2fe451b73b 100644 --- a/launchers/macosx/obj-cpp/build.ninja +++ b/launchers/macosx/obj-cpp/build.ninja @@ -22,8 +22,11 @@ rule ar rule cleanup command = rm -fr *.o clauncher I2PLauncher.app +# TODO: There must exists a cleaner way to solve this. rule bundledir - command = mkdir -p I2PLauncher.app/Contents/{MacOS,Resources,Frameworks} && cp Info.plist I2PLauncher.app/Contents/Info.plist + command = mkdir -p I2PLauncher.app/Contents/{MacOS,Resources,Frameworks} $ + && cp Info.plist I2PLauncher.app/Contents/Info.plist $ + && cp base.zip I2PLauncher.app/Contents/Resources/base.zip rule copytobundledir command = cp clauncher I2PLauncher.app/Contents/MacOS/I2PLauncher @@ -31,6 +34,9 @@ rule copytobundledir rule copyimgtobundle command = cp ItoopieTransparent.png I2PLauncher.app/Contents/Resources/ItoopieTransparent.png +rule builddir + command = mkdir -p build + build main.o: cxx main.mm build StatusItemButton.o: cxx StatusItemButton.mm build JavaRunner.o: cxx JavaRunner.cpp @@ -43,4 +49,5 @@ build copytobundle: copytobundledir | bundle clauncher build clauncher: link main.o StatusItemButton.o JavaRunner.o build appbundle: copyimgtobundle | clauncher bundle copytobundle -#build all: clauncher + +default appbundle diff --git a/launchers/macosx/src/main/java/net/i2p/launchers/BaseExtractor.java b/launchers/macosx/src/main/java/net/i2p/launchers/BaseExtractor.java new file mode 100644 index 0000000000..b1251cc782 --- /dev/null +++ b/launchers/macosx/src/main/java/net/i2p/launchers/BaseExtractor.java @@ -0,0 +1,65 @@ +package net.i2p.launchers; + + +import java.io.BufferedInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Enumeration; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +/** + * As the name suggest, it extracts the base path. + * + * @author Meeh + * @since 0.9.35 + */ +public class BaseExtractor extends EnvCheck { + + private void runExtract(String zipFilename, String destinationPath) { + try(ZipFile file = new ZipFile(zipFilename)) { + FileSystem fileSystem = FileSystems.getDefault(); + Enumeration entries = file.entries(); + Files.createDirectory(fileSystem.getPath(destinationPath)); + while (entries.hasMoreElements()) { + ZipEntry entry = entries.nextElement(); + if (entry.isDirectory()) { + System.out.println("Creating Directory:" + destinationPath + entry.getName()); + Files.createDirectories(fileSystem.getPath(destinationPath + entry.getName())); + } else { + InputStream is = file.getInputStream(entry); + BufferedInputStream bis = new BufferedInputStream(is); + String uncompressedFileName = destinationPath + entry.getName(); + Path uncompressedFilePath = fileSystem.getPath(uncompressedFileName); + Files.createFile(uncompressedFilePath); + FileOutputStream fileOutput = new FileOutputStream(uncompressedFileName); + while (bis.available() > 0) fileOutput.write(bis.read()); + fileOutput.close(); + System.out.println("Written :" + entry.getName()); + } + } + } catch (IOException e) { + // + } + } + + public BaseExtractor(String[] args) { + super(args); + + if (args.length == 2) { + if ("extract".equals(args[0])) { + // Start extract + + }this.runExtract(System.getProperty("i2p.base.zip"),this.baseDirPath); + } + } + + public static void main(String[] args) { + new BaseExtractor(args); + } +} diff --git a/launchers/macosx/src/main/java/net/i2p/launchers/EnvCheck.java b/launchers/macosx/src/main/java/net/i2p/launchers/EnvCheck.java new file mode 100644 index 0000000000..3fa214b6f7 --- /dev/null +++ b/launchers/macosx/src/main/java/net/i2p/launchers/EnvCheck.java @@ -0,0 +1,27 @@ +package net.i2p.launchers; + +/** + * Both the extractor class and the launcher class needs to be able to verify + * the environment (variables) to work. This is a base class implementing it. + * + * @author Meeh + * @since 0.9.35 + */ +public class EnvCheck { + + protected String baseDirPath = null; + + protected boolean isBaseDirectorySet() { + baseDirPath = System.getProperty("i2p.base.dir"); + if (baseDirPath == null) { + baseDirPath = System.getenv("I2PBASE"); + } + return (baseDirPath != null); + } + + public EnvCheck(String[] args) { + if (!isBaseDirectorySet()) { + throw new RuntimeException("Can't detect I2P's base directory!"); + } + } +} diff --git a/launchers/macosx/src/main/java/net/i2p/launchers/SimpleOSXLauncher.java b/launchers/macosx/src/main/java/net/i2p/launchers/SimpleOSXLauncher.java new file mode 100644 index 0000000000..3897a32f0e --- /dev/null +++ b/launchers/macosx/src/main/java/net/i2p/launchers/SimpleOSXLauncher.java @@ -0,0 +1,25 @@ +package net.i2p.launchers; + +import net.i2p.router.Router; + +public class SimpleOSXLauncher extends EnvCheck { + + protected Router i2pRouter; + + /** + * + * This is bairly a abstraction layer for the Router. + * Why? I suspect we will add some spesific osx launcher code at startup + * in the jvm somewhere, and this seem like a nice place to not make a mess everywhere. + * + * @author Meeh + * @since 0.9.35 + */ + public SimpleOSXLauncher(String[] args) { + super(args); + i2pRouter = new Router(); + } + public static void main(String[] args) { + new SimpleOSXLauncher(args); + } +}