diff --git a/build-environment/src/main/kotlin/kmp/tor/env.kt b/build-environment/src/main/kotlin/kmp/tor/env.kt index 62d013c24..d56eec4ee 100644 --- a/build-environment/src/main/kotlin/kmp/tor/env.kt +++ b/build-environment/src/main/kotlin/kmp/tor/env.kt @@ -20,7 +20,7 @@ object env { // Must be either "-SNAPSHOT" || "" private const val SNAPSHOT = "-SNAPSHOT" - private const val MANAGER_VERSION_NAME = "1.3.5" + private const val MANAGER_VERSION_NAME = "1.4.0" // 1.0.0-alpha1 == 01_00_00_11 // 1.0.0-alpha2 == 01_00_00_12 // 1.0.0-beta1 == 01_00_00_21 @@ -29,13 +29,13 @@ object env { // 1.0.1 == 01_00_01_99 // 1.1.1 == 01_01_01_99 // 1.15.1 == 01_15_01_99 - private const val MANAGER_VERSION_CODE = /*0*/1_03_05_99 + private const val MANAGER_VERSION_CODE = /*0*/1_04_00_99 - private const val BINARY_VERSION_NAME = "4.7.13-0" + private const val BINARY_VERSION_NAME = "4.7.13-1" // 4.6.9-0 == 00_04_06_09_00 // 4.6.9-1 == 00_04_06_09_01 // 4.6.9-2 == 00_04_06_09_02 - private const val BINARY_VERSION_CODE = /*00_0*/4_07_13_00 + private const val BINARY_VERSION_CODE = /*00_0*/4_07_13_01 /** * Binaries exist in a different repo. Building against the staged diff --git a/library/kmp-tor/api/jvm/kmp-tor.api b/library/kmp-tor/api/jvm/kmp-tor.api index eb297fe4e..96e18be6d 100644 --- a/library/kmp-tor/api/jvm/kmp-tor.api +++ b/library/kmp-tor/api/jvm/kmp-tor.api @@ -10,6 +10,7 @@ public final class io/matthewnelson/kmp/tor/PlatformInstaller { public final field os Ljava/lang/String; public final field sha256Sum Ljava/lang/String; public synthetic fun (Lio/matthewnelson/kmp/tor/PlatformInstaller$InstallOption;Lio/matthewnelson/kmp/tor/binary/extract/TorResource$Binaries;Lkotlin/jvm/internal/DefaultConstructorMarker;)V + public static final fun custom (Lio/matthewnelson/kmp/tor/PlatformInstaller$InstallOption;Lio/matthewnelson/kmp/tor/binary/extract/TorBinaryResource;)Lio/matthewnelson/kmp/tor/PlatformInstaller; public final fun isLinux ()Z public final fun isMacos ()Z public final fun isMingw ()Z @@ -22,6 +23,7 @@ public final class io/matthewnelson/kmp/tor/PlatformInstaller { } public final class io/matthewnelson/kmp/tor/PlatformInstaller$Companion { + public final fun custom (Lio/matthewnelson/kmp/tor/PlatformInstaller$InstallOption;Lio/matthewnelson/kmp/tor/binary/extract/TorBinaryResource;)Lio/matthewnelson/kmp/tor/PlatformInstaller; public final fun linuxX64 (Lio/matthewnelson/kmp/tor/PlatformInstaller$InstallOption;)Lio/matthewnelson/kmp/tor/PlatformInstaller; public final fun linuxX86 (Lio/matthewnelson/kmp/tor/PlatformInstaller$InstallOption;)Lio/matthewnelson/kmp/tor/PlatformInstaller; public final fun macosArm64 (Lio/matthewnelson/kmp/tor/PlatformInstaller$InstallOption;)Lio/matthewnelson/kmp/tor/PlatformInstaller; diff --git a/library/kmp-tor/src/jvmMain/kotlin/io/matthewnelson/kmp/tor/PlatformInstaller.kt b/library/kmp-tor/src/jvmMain/kotlin/io/matthewnelson/kmp/tor/PlatformInstaller.kt index 217dcabf1..7d12b09e1 100644 --- a/library/kmp-tor/src/jvmMain/kotlin/io/matthewnelson/kmp/tor/PlatformInstaller.kt +++ b/library/kmp-tor/src/jvmMain/kotlin/io/matthewnelson/kmp/tor/PlatformInstaller.kt @@ -129,6 +129,31 @@ class PlatformInstaller private constructor( resource = TorResourceMingwX86, ) } + + /** + * In the event a platform and given architecture is not supported by kmp-tor, you + * can package your own, model the resources via [TorBinaryResource], and then have + * the files extracted and loaded at runtime. + * + * DISCLAIMER: Using this option does **not** guarantee kmp-tor compatibility with + * the version of Tor being loaded, as kmp-tor is only tested against binaries + * provided by the kmp-tor-binary project. + * + * Must: + * - Add dependency: + * - io.matthewnelson.kotlin-components:kmp-tor-binary-extract:(version) + * - package and model your binary resources in accordance with [TorBinaryResource] + * */ + @JvmStatic + fun custom( + option: InstallOption, + resource: TorBinaryResource + ): PlatformInstaller { + return PlatformInstaller( + installOption = option, + resource = resource, + ) + } } @JvmField @@ -139,6 +164,7 @@ class PlatformInstaller private constructor( is TorResourceMacosArm64 -> MACOS is TorResourceMingwX64, is TorResourceMingwX86 -> MINGW + is TorBinaryResource -> resource.osName } @JvmField @@ -149,6 +175,7 @@ class PlatformInstaller private constructor( is TorResourceMacosArm64 -> ARM64 is TorResourceMingwX64 -> X64 is TorResourceMingwX86 -> X86 + is TorBinaryResource -> resource.arch } @JvmField diff --git a/library/kmp-tor/src/jvmTest/kotlin/io/matthewnelson/kmp/tor/PlatformInstallerUnitTest.kt b/library/kmp-tor/src/jvmTest/kotlin/io/matthewnelson/kmp/tor/PlatformInstallerUnitTest.kt new file mode 100644 index 000000000..f0211fe1f --- /dev/null +++ b/library/kmp-tor/src/jvmTest/kotlin/io/matthewnelson/kmp/tor/PlatformInstallerUnitTest.kt @@ -0,0 +1,100 @@ +package io.matthewnelson.kmp.tor + +import io.matthewnelson.kmp.tor.binary.extract.TorBinaryResource +import kotlinx.coroutines.runBlocking +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.rules.TemporaryFolder +import java.io.File + +class PlatformInstallerUnitTest { + + @get:Rule + val testDir: TemporaryFolder = TemporaryFolder() + private lateinit var workDir: File + + private val osName = System.getProperty("os.name") + private var resource: TorBinaryResource? = null + + @Before + fun before() { + // Load static test resources for tor 0.4.7.12 + resource = when { + osName.startsWith("Windows", true) -> { + TorBinaryResource.from( + os = TorBinaryResource.OS.Mingw, + arch = "testx64", + sha256sum = "f228252a094f3fed8d9d08d6b98f1925644cfbbf59fbd08c566bf184027068e4", + resourceManifest = listOf( + "tor.exe.gz", + "tor-gencert.exe.gz" + ), + ) + } + + osName == "Mac OS X" -> { + TorBinaryResource.from( + os = TorBinaryResource.OS.Macos, + arch = "testx64", + sha256sum = "7c5687a3916483ee6c402ed77a99c6025c19b1bfdf54cb6e2e00601642451c82", + resourceManifest = listOf( + "libevent-2.1.7.dylib.gz", + "tor.gz" + ), + ) + } + + osName.contains("Mac", true) -> { + TorBinaryResource.from( + os = TorBinaryResource.OS.Macos, + arch = "testarm64", + sha256sum = "0d9217a47af322d72e9213c1afdd53f4f571ff0483d8053726e56efeec850ff1", + resourceManifest = listOf( + "libevent-2.1.7.dylib.gz", + "tor.gz" + ), + ) + } + + osName == "Linux" -> { + TorBinaryResource.from( + os = TorBinaryResource.OS.Linux, + arch = "testx64", + sha256sum = "7ea1e0a19f63d2542b34e1cfe8f8135b278a0eea5a7fd8d25e78e12972834ae2", + resourceManifest = listOf( + "libcrypto.so.1.1.gz", + "libevent-2.1.so.7.gz", + "libssl.so.1.1.gz", + "libstdc++.so.6.gz", + "tor.gz" + ) + ) + } + else -> null + } + + workDir = resource?.let { r -> + testDir.newFolder(r.osName + r.arch) + } ?: testDir.newFolder() + } + + @Test + fun givenPlatformInstaller_whenCustomBinaryResources_thenAreLoaded() = runBlocking { + val resource = resource + if (resource == null) { + println("osName($osName) not recognized. Skipping test") + } else { + + val installer = PlatformInstaller.custom( + option = PlatformInstaller.InstallOption.CleanInstallOnEachStart, + resource = resource + ) + + val tor = installer.retrieveTor(workDir) + println("Tor Executable for osName($osName): $tor") + } + + Unit + } +} diff --git a/library/kmp-tor/src/jvmTest/resources/kmptor/linux/testx64/libcrypto.so.1.1.gz b/library/kmp-tor/src/jvmTest/resources/kmptor/linux/testx64/libcrypto.so.1.1.gz new file mode 100755 index 000000000..cb7ff2225 Binary files /dev/null and b/library/kmp-tor/src/jvmTest/resources/kmptor/linux/testx64/libcrypto.so.1.1.gz differ diff --git a/library/kmp-tor/src/jvmTest/resources/kmptor/linux/testx64/libevent-2.1.so.7.gz b/library/kmp-tor/src/jvmTest/resources/kmptor/linux/testx64/libevent-2.1.so.7.gz new file mode 100755 index 000000000..7ac3bb705 Binary files /dev/null and b/library/kmp-tor/src/jvmTest/resources/kmptor/linux/testx64/libevent-2.1.so.7.gz differ diff --git a/library/kmp-tor/src/jvmTest/resources/kmptor/linux/testx64/libssl.so.1.1.gz b/library/kmp-tor/src/jvmTest/resources/kmptor/linux/testx64/libssl.so.1.1.gz new file mode 100755 index 000000000..a7abf3e95 Binary files /dev/null and b/library/kmp-tor/src/jvmTest/resources/kmptor/linux/testx64/libssl.so.1.1.gz differ diff --git a/library/kmp-tor/src/jvmTest/resources/kmptor/linux/testx64/libstdc++.so.6.gz b/library/kmp-tor/src/jvmTest/resources/kmptor/linux/testx64/libstdc++.so.6.gz new file mode 100755 index 000000000..c336b4f9e Binary files /dev/null and b/library/kmp-tor/src/jvmTest/resources/kmptor/linux/testx64/libstdc++.so.6.gz differ diff --git a/library/kmp-tor/src/jvmTest/resources/kmptor/linux/testx64/tor.gz b/library/kmp-tor/src/jvmTest/resources/kmptor/linux/testx64/tor.gz new file mode 100755 index 000000000..ecc8d6e08 Binary files /dev/null and b/library/kmp-tor/src/jvmTest/resources/kmptor/linux/testx64/tor.gz differ diff --git a/library/kmp-tor/src/jvmTest/resources/kmptor/macos/testarm64/libevent-2.1.7.dylib.gz b/library/kmp-tor/src/jvmTest/resources/kmptor/macos/testarm64/libevent-2.1.7.dylib.gz new file mode 100755 index 000000000..8243d3dab Binary files /dev/null and b/library/kmp-tor/src/jvmTest/resources/kmptor/macos/testarm64/libevent-2.1.7.dylib.gz differ diff --git a/library/kmp-tor/src/jvmTest/resources/kmptor/macos/testarm64/tor.gz b/library/kmp-tor/src/jvmTest/resources/kmptor/macos/testarm64/tor.gz new file mode 100755 index 000000000..b0884361e Binary files /dev/null and b/library/kmp-tor/src/jvmTest/resources/kmptor/macos/testarm64/tor.gz differ diff --git a/library/kmp-tor/src/jvmTest/resources/kmptor/macos/testx64/libevent-2.1.7.dylib.gz b/library/kmp-tor/src/jvmTest/resources/kmptor/macos/testx64/libevent-2.1.7.dylib.gz new file mode 100755 index 000000000..fb5d1c781 Binary files /dev/null and b/library/kmp-tor/src/jvmTest/resources/kmptor/macos/testx64/libevent-2.1.7.dylib.gz differ diff --git a/library/kmp-tor/src/jvmTest/resources/kmptor/macos/testx64/tor.gz b/library/kmp-tor/src/jvmTest/resources/kmptor/macos/testx64/tor.gz new file mode 100755 index 000000000..adadaead4 Binary files /dev/null and b/library/kmp-tor/src/jvmTest/resources/kmptor/macos/testx64/tor.gz differ diff --git a/library/kmp-tor/src/jvmTest/resources/kmptor/mingw/testx64/tor-gencert.exe.gz b/library/kmp-tor/src/jvmTest/resources/kmptor/mingw/testx64/tor-gencert.exe.gz new file mode 100755 index 000000000..dbbbda144 Binary files /dev/null and b/library/kmp-tor/src/jvmTest/resources/kmptor/mingw/testx64/tor-gencert.exe.gz differ diff --git a/library/kmp-tor/src/jvmTest/resources/kmptor/mingw/testx64/tor.exe.gz b/library/kmp-tor/src/jvmTest/resources/kmptor/mingw/testx64/tor.exe.gz new file mode 100755 index 000000000..18de1db48 Binary files /dev/null and b/library/kmp-tor/src/jvmTest/resources/kmptor/mingw/testx64/tor.exe.gz differ diff --git a/samples/kotlin/javafx/build.gradle.kts b/samples/kotlin/javafx/build.gradle.kts index f3aa27572..5676ea497 100644 --- a/samples/kotlin/javafx/build.gradle.kts +++ b/samples/kotlin/javafx/build.gradle.kts @@ -79,9 +79,14 @@ kotlin { osName.contains("Windows", true) -> { implementation("io.matthewnelson.kotlin-components:kmp-tor-binary-mingwx64:${env.kmpTorBinaries.version.name}") } - osName.contains("Mac", true) || osName.contains("Darwin", true) -> { + osName == "Mac OS X" -> { implementation("io.matthewnelson.kotlin-components:kmp-tor-binary-macosx64:${env.kmpTorBinaries.version.name}") } + osName.contains("Mac", true) -> { + // Will be providing our own binary resources for arm64 Tor 0.4.7.12 as an example + // which are located in resources/kmptor/macos/arm64 of this sample. +// implementation("io.matthewnelson.kotlin-components:kmp-tor-binary-macosx64:${env.kmpTorBinaries.version.name}") + } osName.contains("linux", true) -> { implementation("io.matthewnelson.kotlin-components:kmp-tor-binary-linuxx64:${env.kmpTorBinaries.version.name}") } @@ -90,6 +95,11 @@ kotlin { } } + // In order to model our binary resources for macOS arm64, will need the extract + // dependency (which is not provided with the kmp-tor import) to be able to use + // the TorBinaryResource class + implementation("io.matthewnelson.kotlin-components:kmp-tor-binary-extract:${env.kmpTorBinaries.version.name}") + // Add support for Unix Domain Sockets (Only necessary for JDK 15 and below) implementation(project(":library:extensions:kmp-tor-ext-unix-socket")) diff --git a/samples/kotlin/javafx/src/jvmMain/kotlin/io/matthewnelson/kmp/tor/sample/kotlin/javafx/SampleApp.kt b/samples/kotlin/javafx/src/jvmMain/kotlin/io/matthewnelson/kmp/tor/sample/kotlin/javafx/SampleApp.kt index 4c10b608b..2d4f3d21d 100644 --- a/samples/kotlin/javafx/src/jvmMain/kotlin/io/matthewnelson/kmp/tor/sample/kotlin/javafx/SampleApp.kt +++ b/samples/kotlin/javafx/src/jvmMain/kotlin/io/matthewnelson/kmp/tor/sample/kotlin/javafx/SampleApp.kt @@ -19,15 +19,14 @@ import io.matthewnelson.kmp.tor.KmpTorLoaderJvm import io.matthewnelson.kmp.tor.PlatformInstaller import io.matthewnelson.kmp.tor.PlatformInstaller.InstallOption import io.matthewnelson.kmp.tor.TorConfigProviderJvm +import io.matthewnelson.kmp.tor.binary.extract.TorBinaryResource import io.matthewnelson.kmp.tor.common.address.* -import io.matthewnelson.kmp.tor.common.annotation.InternalTorApi import io.matthewnelson.kmp.tor.controller.common.config.TorConfig import io.matthewnelson.kmp.tor.controller.common.config.TorConfig.Setting.* import io.matthewnelson.kmp.tor.controller.common.config.TorConfig.Option.* import io.matthewnelson.kmp.tor.controller.common.control.usecase.TorControlInfoGet import io.matthewnelson.kmp.tor.controller.common.events.TorEvent import io.matthewnelson.kmp.tor.controller.common.file.Path -import io.matthewnelson.kmp.tor.controller.common.internal.PlatformUtil import io.matthewnelson.kmp.tor.manager.TorManager import io.matthewnelson.kmp.tor.manager.common.TorControlManager import io.matthewnelson.kmp.tor.manager.common.TorOperationManager @@ -49,15 +48,35 @@ class SampleApp: App(SampleView::class) { private val platformInstaller: PlatformInstaller by lazy { - @OptIn(InternalTorApi::class) + val osName = System.getProperty("os.name") + val installer = when { - PlatformUtil.isMingw -> { + osName.contains("Windows", true) -> { PlatformInstaller.mingwX64(InstallOption.CleanInstallIfMissing) } - PlatformUtil.isDarwin -> { + osName == "Mac OS X" -> { PlatformInstaller.macosX64(InstallOption.CleanInstallIfMissing) } - PlatformUtil.isLinux -> { + osName.contains("Mac", true) -> { + + // Example of providing your own packaged binary resources in the event a + // platform or architecture is not currently supported by kmp-tor-binary. + // + // Note that there IS a macOS arm64 binary dependency provided by + // kmp-tor-binary and that should be used instead; this is just an example. + // + // Files are located in this sample's resources/kmptor/macos/arm64 directory + PlatformInstaller.custom( + InstallOption.CleanInstallIfMissing, + TorBinaryResource.from( + os = TorBinaryResource.OS.Macos, + arch = "arm64", + sha256sum = "0d9217a47af322d72e9213c1afdd53f4f571ff0483d8053726e56efeec850ff1", + resourceManifest = listOf("libevent-2.1.7.dylib.gz", "tor.gz") + ) + ) + } + osName.contains("linux", true) -> { PlatformInstaller.linuxX64(InstallOption.CleanInstallIfMissing) } else -> { diff --git a/samples/kotlin/javafx/src/jvmMain/resources/kmptor/macos/arm64/libevent-2.1.7.dylib.gz b/samples/kotlin/javafx/src/jvmMain/resources/kmptor/macos/arm64/libevent-2.1.7.dylib.gz new file mode 100755 index 000000000..8243d3dab Binary files /dev/null and b/samples/kotlin/javafx/src/jvmMain/resources/kmptor/macos/arm64/libevent-2.1.7.dylib.gz differ diff --git a/samples/kotlin/javafx/src/jvmMain/resources/kmptor/macos/arm64/tor.gz b/samples/kotlin/javafx/src/jvmMain/resources/kmptor/macos/arm64/tor.gz new file mode 100755 index 000000000..b0884361e Binary files /dev/null and b/samples/kotlin/javafx/src/jvmMain/resources/kmptor/macos/arm64/tor.gz differ