override suspend fun run()

in sources/amper-cli/src/org/jetbrains/amper/tasks/native/NativeCompileKlibTask.kt [72:169]


    override suspend fun run(dependenciesResult: List<TaskResult>, executionContext: TaskGraphExecutionContext): TaskResult {
        val fragments = module.fragments.filter {
            it.platforms.contains(platform) && it.isTest == isTest
        }
        if (fragments.isEmpty()) {
            error("Zero fragments in module ${module.userReadableName} for platform $platform isTest=$isTest")
        }

        // TODO The native compiler needs recursive dependencies
        val externalDependencies = dependenciesResult
            .filterIsInstance<ResolveExternalDependenciesTask.Result>()
            .flatMap { it.compileClasspath } // compiler dependencies including transitive
            .distinct()
            .filterKLibs()
            .toList()

        logger.debug("" +
                "native compile ${module.userReadableName} -- collected external dependencies" +
                if (externalDependencies.isNotEmpty()) "\n" else "" +
                externalDependencies.sorted().joinToString("\n").prependIndent("  ")
        )

        val compiledModuleDependencies = dependenciesResult
            .filterIsInstance<Result>()
            .mapNotNull { it.compiledKlib }
            .toList()

        // todo native resources are what exactly?

        val kotlinUserSettings = fragments.singleLeafFragment().serializableKotlinSettings()

        logger.debug("native compile klib '${module.userReadableName}' -- ${fragments.joinToString(" ") { it.name }}")

        val libraryPaths = compiledModuleDependencies + externalDependencies

        val additionalSources = additionalKotlinJavaSourceDirs.map { artifact ->
            SourceRoot(
                fragmentName = artifact.fragmentName,
                path = artifact.path,
            )
        }

        val sources = fragments.flatMap { it.sourceRoots } + additionalSources.map { it.path }

        val artifact = incrementalCache.execute(
            key = taskName.name,
            inputValues = mapOf(
                "kotlin.settings" to Json.encodeToString(kotlinUserSettings),
                "task.output.root" to taskOutputRoot.path.pathString,
            ),
            inputFiles = sources + libraryPaths,
        ) {
            cleanDirectory(taskOutputRoot.path)

            // in Kotlin >= 2.2, we need to list all source files (not just dirs)
            val sourceFiles = sources.flatMap { dir ->
                // konanc only accepts *.kt files, and we need to align with fragment arguments
                dir.walk().filter { it.extension in validSourceFileExtensions }
            }
            if (sourceFiles.isEmpty()) {
                logger.debug("No sources were found for ${fragments.identificationPhrase()}, skipping compilation")
                return@execute IncrementalCache.ExecutionResult(emptyList())
            }

            val artifact = taskOutputRoot.path.resolve(KotlinCompilationType.LIBRARY.outputFilename(module, platform, isTest))

            val nativeCompiler = downloadNativeCompiler(kotlinUserSettings.compilerVersion, userCacheRoot, jdkProvider)
            val compilerPlugins = kotlinArtifactsDownloader.downloadCompilerPlugins(
                plugins = kotlinUserSettings.compilerPlugins,
            )
            val args = kotlinNativeCompilerArgs(
                buildType = buildType,
                kotlinUserSettings = kotlinUserSettings,
                compilerPlugins = compilerPlugins,
                entryPoint = null,
                libraryPaths = libraryPaths,
                exportedLibraryPaths = emptyList(),
                fragments = fragments,
                sourceFiles = sourceFiles,
                additionalSourceRoots = additionalSources,
                outputPath = artifact,
                compilationType = KotlinCompilationType.LIBRARY,
                binaryOptions = emptyMap(),
                include = null,
            )

            logger.info("Compiling module '${module.userReadableName}' for platform '${platform.pretty}'...")
            nativeCompiler.compile(processRunner, args, tempRoot, module)

            return@execute IncrementalCache.ExecutionResult(listOf(artifact))
        }.outputFiles.singleOrNull()

        return Result(
            compiledKlib = artifact,
            dependencyKlibs = libraryPaths,
            taskName = taskName,
        )
    }