Skip to content

05nelsonm/kmp-tor-binary

Repository files navigation

kmp-tor-binary

badge-license badge-latest-release

badge-kotlin

badge-platform-android badge-platform-jvm

Tor binary resource distribution for the kmp-tor project

NOTE: This branch is for kmp-tor 1.x.x support and is feature frozen. See master branch for the latest and greatest.

Getting Started (Configuration)

Android

Tor binaries for Android are automatically imported with the kmp-tor dependency, so you do not need to add the kmp-tor-binary-android dependency if you are using kmp-tor. CONFIGURATION BELOW IS STILL NEEDED THOUGH.

Android requires some configuration so binaries will be appropriately extracted to your app's nativeLibraryDir upon application installation.

  • Ensure JavaVersion is greater than or equal to 11:

    // build.gradle.kts
    
    android {
        // ...
    
        compileOptions {
            sourceCompatibility = JavaVersion.VERSION_11
            targetCompatibility = JavaVersion.VERSION_11
        }
    
        kotlinOptions {
            jvmTarget = JavaVersion.VERSION_11.toString()
        }
    }
  • Enable legacy packaging for jniLibs directory:

    // build.gradle.kts
    
    android {
        // ...
    
        packagingOptions {
            jniLibs.useLegacyPackaging = true
        }
    }
  • Add to your AndroidManifest.xml, within the application tag:

    <application
        android:extractNativeLibs="true">
    
    </application>
  • Configure splits for each architecture by adding the following to your application module's android block:

    // build.gradle.kts
    
    android {
        // ...
    
        splits {
    
            // Configures multiple APKs based on ABI. This helps keep the size
            // down, since PT binaries can be large.
            abi {
    
                // Enables building multiple APKs per ABI.
                isEnable = true
    
                // By default, all ABIs are included, so use reset() and include to specify
                // that we only want APKs for x86 and x86_64, armeabi-v7a, and arm64-v8a.
    
                // Resets the list of ABIs that Gradle should create APKs for to none.
                reset()
    
                // Specifies a list of ABIs that Gradle should create APKs for.
                include("x86", "armeabi-v7a", "arm64-v8a", "x86_64")
    
                // Specify whether you wish to also generate a universal APK that
                // includes _all_ ABIs.
                isUniversalApk = true
            }
        }
    }
  • If you are publishing your application to Google Play using app bundling, add the following to your project's gradle.properties file:

    android.bundle.enableUncompressedNativeLibs=false
    • You can also verify (prior to pushing your release to Google Play) if the bundled apk extracts binaries on install correctly by using the bundletool.

That's it, you should be good to go for your Android project!

Java

Tor binaries for Java are not automatically imported with the kmp-tor dependency. You need to add the dependencies for the platform(s) you wish to support.

  • Add dependencies:
    // build.gradle.kts
    
    dependencies {
        val vTor = "4.8.10-0"
        val vKmpTor = "1.4.4" // <-- see kmp-tor repo for latest version
        implementation("io.matthewnelson.kotlin-components:kmp-tor:$vTor-$vKmpTor")
    
        // Linux x86_64
        implementation("io.matthewnelson.kotlin-components:kmp-tor-binary-linuxx64:$vTor")
        // Linux i686
        implementation("io.matthewnelson.kotlin-components:kmp-tor-binary-linuxx86:$vTor")
        // macOS aarch64
        implementation("io.matthewnelson.kotlin-components:kmp-tor-binary-macosarm64:$vTor")
        // macOS x86_64
        implementation("io.matthewnelson.kotlin-components:kmp-tor-binary-macosx64:$vTor")
        // Windows x86_64
        implementation("io.matthewnelson.kotlin-components:kmp-tor-binary-mingwx64:$vTor")
        // Windows i686
        implementation("io.matthewnelson.kotlin-components:kmp-tor-binary-mingwx86:$vTor")
    }
  • If a specific platform or architecture is not currently supported by kmp-tor-binary, you can package your own and provide them to kmp-tor at runtime for extraction and execution.
    // Add the additional 'extract' dependency
    dependencies {
        implementation("io.matthewnelson.kotlin-components:kmp-tor-binary-extract:$vTor")
    }
    • See TorBinaryResource documentation for packaging requirements and details.
    • Load them via kmp-tor's PlatformInstaller (available since v4.7.13-1-1.4.0)
      val installer = PlatformInstaller.custom(
          option = InstallOption.CleanInstallIfMissing,
          resource = TorBinaryResource.from(
              os = TorBinaryResource.OS.Linux,
              arch = "arm64",
              loadPathPrefix = "com.example",
              sha256sum = "abcdefg123...",
              resourceManifest = listOf(
                  "directory/file1.gz",
                  "directory/file2.gz",
                  "file3.gz",
                  "tor.gz",
              )
          )
      )
    • Then in the module that contains your custom binary resources
      // pacakge ${loadPathPrefix}.<lowercase os name>.<arch>
      package com.example.linux.arm64
      
      // Must be named "Loader"
      private class Loader
      • In the event finding your custom resources fails using the standard method, extraction will fall back to attempting to retrieve the com.example.linux.arm64.Loader via reflection and use its ClassLoader to retrieve the resources located in that module/jar. This is often the case for projects that are utilizing the Java 9 Module system (such as JavaFX).

That's it, you should be good to go for your Java project!

Where do the binaries come from?

Binaries are reproducibly built via Tor Project's tor-browser-build

You can verify the reproducability of published binaries by following the BUILD.md guide.