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,
)
}