11

we use Kotlin to share a library between Android and iOS.

We set up everything, but on iOS i need Bitcode enabled. After a research I found solution:

kotlin {
targets {
    fromPreset(presets.jvm, 'jvm') {
        mavenPublication {
            artifactId = 'my-lib-name'
        }
    }
    // Switch here to presets.iosArm64 to build library for iPhone device || iosX64 for emulator
    fromPreset(presets.iosArm64, 'iOS') {
        compilations.main.outputKinds('FRAMEWORK')
        compilations.main.extraOpts '-Xembed-bitcode' // for release binaries
        compilations.main.extraOpts '-Xembed-bitcode-marker'//  for debug binaries
    }
  }
}

But the question is now, do I have and if yes, how do I separate between release and debug binaries and the specific flags? Can i simply add both flags without any drawbacks?

Maybe somebody can enlighten me thanks

hotkey
  • 140,743
  • 39
  • 371
  • 326
Vario
  • 490
  • 4
  • 13

3 Answers3

10

Since Kotlin 1.3.20 bitcode embedding for iOS frameworks works out of the box. You also can configure embedding manually if you need:

kotlin {
    iosArm64("ios") {
        binaries {
            framework {
                // The following embedding modes are available:
                //   - "marker"  - Embed placeholder LLVM IR data as a marker.
                //                 Has the same effect as '-Xembed-bitcode-marker.'
                //   - "bitcode" - Embed LLVM IR bitcode as data.
                //                 Has the same effect as the '-Xembed-bitcode'.
                //   - "disable" - Don't embed LLVM IR bitcode.
                embedBitcode("marker")
            }
        }
    }
}
Ilya Matveev
  • 191
  • 4
5

Currently, all of the binary link tasks for the same iOS target share the compiler and linker options, so there's no way to setup the options for them separately. Please follow KT-26887 for updates.

If you can afford running several builds with different options, you can set the options conditionally and run the build with a flag:

compilations.main.outputKinds('FRAMEWORK')

if (project.findProperty("releaseFramework") == "true")
    compilations.main.extraOpts '-Xembed-bitcode' // for release binaries
else
    compilations.main.extraOpts '-Xembed-bitcode-marker'//  for debug binaries

Then run the build with or without the flag, respectively:

./gradlew linkDebugFrameworkIOS

and

./gradlew linkReleaseFrameworkIOS -PreleaseFramework=true
hotkey
  • 140,743
  • 39
  • 371
  • 326
0

I only want to use Bitcode when it's actually needed. Xcode passes down an environment variable ENABLE_BITCODE which we can use to conditionally embed bitcode.

kotlin {
  iosArm64("ios") {
    binaries {
      framework {
        embedBitcode("YES".equals(System.getenv("ENABLE_BITCODE")) ? "bitcode" : "marker")
      }
    }
  }
}
Niklas
  • 23,674
  • 33
  • 131
  • 170
  • This is not completely correct, Xcode will set `ENABLE_BITCODE` for both debug and release builds, you should use `bitcode` only for release builds as it will slow down your compilation process, and `mark` for debug builds. If `ENABLE_BITCODE` is false (or not there) you should use `disable`, instead. – JP Illanes Jan 25 '21 at 13:02
  • You can use the env var `CONFIGURATION` to know if is a debug or release build. – JP Illanes Jan 25 '21 at 13:04
  • (By default there are 2 possible values for `CONFIGURATION`, "Debug" or "Release" but you can add more through Xcode, so check your project config...) – JP Illanes Jan 25 '21 at 13:07