I'm writing a Kotlin/Native library that wraps som...
# gradle
a
I'm writing a Kotlin/Native library that wraps some C++ libraries. I want to statically embed them into the final KN artifact. I have Gradle tasks to compile each C++ library from sources into static libraries. Each library has a variant per Kotlin/Native target, and debug or release. The libs are synced to a directory, per target and build type, e.g.
tasks.named<Sync>("syncLinkedLibs${konanTargetName}${buildType}")
syncs the libs into directory
build/macosx64/debug/
I then need to tell all
KotlinNativeTarget
compilation tasks about the relevant libs. I can do that manually...
Copy code
kotlin.targets.withType<KotlinNativeTarget>().configureEach {
  val konanTargetName = konanTarget.presetName.uppercaseFirstChar()

  binaries.configureEach {

    @OptIn(ExperimentalPathApi::class)
    fun TaskProvider<KotlinNativeCompile>.dependOnSyncedLibs(buildType: NativeBuildType): Unit = letConfigure { task ->

      val type = when (buildType) {
        NativeBuildType.RELEASE -> "Release"
        NativeBuildType.DEBUG   -> "Debug"
      }

      val syncLibsTask = tasks.named<Sync>("syncLinkedLibs${konanTargetName}${type}")
      val syncLinkedLibs = objects.fileCollection().from(syncLibsTask)
      task.inputs.files(syncLinkedLibs).withPathSensitivity(RELATIVE)

      val includeBinaryArgs = syncLinkedLibs.elements.map { elements ->
        elements
          .asSequence()
          .flatMap {
            val p = it.asFile.toPath()
            if (p.isRegularFile()) sequenceOf(p)
            else p.walk()
          }
          .filter { it.isRegularFile() }
          .flatMap { listOf("-include-binary", it.absolute().invariantSeparatorsPathString) }
          .sorted()
          .toList()
      }

      task.compilerOptions {
        this.freeCompilerArgs.addAll(includeBinaryArgs)
      }
    }

    compilation.compileTaskProvider.dependOnSyncedLibs(buildType)
  }
}
but I don't like the string-based task selection. I also want to release this as a Gradle plugin, so I want a more ergonomic API. Is there a pretty way of 'transferring' the files, maybe with Gradle Configurations?
h
What exactly do you don’t like? The named usage? The files usage? I guess, the latter could be simplified, eg, why do you need a sorted list? Does the output really contains folders or just flat files?
a
Yeah, I don't like getting the tasks based on constructing the names with string templates. I'd like the files to be fetched dynamically, using something similar to the whole Gradle Configuration attributes idea.
I sorted the files just in case the order would affect up-to-date checks