Hi there!, I’m using a code that uses Metal or Ope...
# multiplatform
r
Hi there!, I’m using a code that uses Metal or OpenGL depending on if this runs on iphone or iphonesimulator. What’s the KMM approach to do this kind of
ifdef
?
k
You can use expect/actual as usual and use the iosX64 (simulator) and iosArm64 (device) targets with corresponding source sets to provide different implementations for each platform.
r
👍 understood, it is a bit painful since it is just one line of code which is different
but probably I can leverage this for other changes
k
Yes, the way we do it is have expect/actual for a method called ifSimulator and ifDevice that take a callback. Basically we re-implement the ifdef functionality using expect/actual. You could also just have a platform dependent constant and use if (isSimulator) for example.
r
mmm, I asume that ifSimulator is not exported so I cannot use directly?
I’m trying this approach, but actually I don’t know how to have different source sets for iosX64 and iosArm64 in the gradle file. Is it documented somewhere?
k
This is what I have in my project:
Copy code
kotlin {
  iosArm64() {
      binaries {
          framework() {
              embedBitcode("bitcode")
          }
      }
  }

  iosX64() {
      binaries {
          framework() {
              embedBitcode("bitcode")
          }
      }
  }

  sourceSets {
      iosMain {
            dependsOn(commonMain)
            iosX64Main.dependsOn(it)
            iosArm64Main.dependsOn(it)
      }

      // These two should be implicit, just in case
      iosX64Main {}
      iosArm64Main {}
   }
}
r
thanks!, it looks like it is working now. However if I remove this from gradle
Copy code
val iosTarget: (String, KotlinNativeTarget.() -> Unit) -> KotlinNativeTarget =
        if (System.getenv("SDK_NAME")?.startsWith("iphoneos") == true)
            ::iosArm64
        else
            ::iosX64

    iosTarget("ios") {}
I get a lot of errors in the Android studio ide
I cannot keep it or it will complain about duplicate targets
k
Yes, sometimes AS gets confused by multiple iOS targets. We use this workaround:
Copy code
boolean isIdeaSyncing = System.getProperty('idea.sync.active') != null

kotlin {
    if (isIdeaSyncing) {
        iosX64("ios") {
        }
    } else {

        iosArm64() {
        }

        iosX64() {
        }
    }
...
}
r
super!, thanks!
just a side note, if somebody else reads this thread. I’m placing the
expect
function in
iosMain
and
actual
implementations in
iosX64Main
and
iosArm64Main
folders. (don’t forget to put everything in the same package!) I tried putting the
expect
in
commonMain
but that does not work
k
yes, then you would also need to implement it for example on Android, iosMain is definitely the right place to put it