1 /*
<lambda>null2 * Copyright 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package androidx.build.clang
18
19 import com.android.utils.appendCapitalized
20 import org.gradle.api.Project
21 import org.gradle.api.artifacts.Configuration
22 import org.gradle.api.file.RegularFile
23 import org.gradle.api.provider.Provider
24 import org.gradle.api.tasks.TaskProvider
25 import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeCompilation
26 import org.jetbrains.kotlin.konan.target.HostManager
27 import org.jetbrains.kotlin.konan.target.KonanTarget
28
29 /**
30 * Configures a CInterop for the given [kotlinNativeCompilation]. The cinterop will be based on the
31 * [cinteropName] in the project sources but will additionally include the references to the library
32 * archive from the [ClangArchiveTask] so that it can be embedded in the generated klib of the
33 * cinterop.
34 */
35 internal fun MultiTargetNativeCompilation.configureCinterop(
36 kotlinNativeCompilation: KotlinNativeCompilation,
37 cinteropName: String = archiveName,
38 ) {
39 val kotlinNativeTarget = kotlinNativeCompilation.target
40 if (!canCompileOnCurrentHost(kotlinNativeTarget.konanTarget)) {
41 return
42 }
43 val konanTarget = kotlinNativeTarget.konanTarget
44 val nativeTargetCompilation = targetProvider(konanTarget)
45 val taskNamePrefix = "androidXCinterop".appendCapitalized(kotlinNativeTarget.name, archiveName)
46 val createDefFileTask =
47 registerCreateDefFileTask(
48 project = project,
49 taskNamePrefix = taskNamePrefix,
50 konanTarget = konanTarget,
51 archiveProvider =
52 nativeTargetCompilation
53 .flatMap { it.archiveTask }
54 .flatMap { it.llvmArchiveParameters.outputFile },
55 cinteropName = cinteropName
56 )
57 registerCInterop(
58 kotlinNativeCompilation,
59 cinteropName,
60 createDefFileTask,
61 nativeTargetCompilation
62 )
63 }
64
65 /**
66 * Configures a CInterop for the given [kotlinNativeCompilation]. The cinterop will be based on the
67 * [archiveConfiguration] name in the project sources but will additionally include the references
68 * to the library archive from the [ClangArchiveTask] so that it can be embedded in the generated
69 * klib of the cinterop.
70 */
configureCinteropnull71 internal fun configureCinterop(
72 project: Project,
73 kotlinNativeCompilation: KotlinNativeCompilation,
74 archiveConfiguration: Configuration
75 ) {
76 val kotlinNativeTarget = kotlinNativeCompilation.target
77 if (!HostManager().isEnabled(kotlinNativeTarget.konanTarget)) {
78 return
79 }
80 val taskNamePrefix =
81 "androidXCinterop".appendCapitalized(kotlinNativeTarget.name, archiveConfiguration.name)
82 val createDefFileTask =
83 registerCreateDefFileTask(
84 project = project,
85 taskNamePrefix = taskNamePrefix,
86 konanTarget = kotlinNativeCompilation.konanTarget,
87 archiveProvider =
88 project.layout.file(archiveConfiguration.elements.map { it.single().asFile }),
89 cinteropName = archiveConfiguration.name
90 )
91 registerCInterop(kotlinNativeCompilation, archiveConfiguration.name, createDefFileTask)
92 }
93
registerCreateDefFileTasknull94 private fun registerCreateDefFileTask(
95 project: Project,
96 taskNamePrefix: String,
97 konanTarget: KonanTarget,
98 archiveProvider: Provider<RegularFile>,
99 cinteropName: String
100 ) =
101 project.tasks.register(
102 taskNamePrefix.appendCapitalized("createDefFileFor", konanTarget.name),
103 CreateDefFileWithLibraryPathTask::class.java
104 ) { task ->
105 task.objectFile.set(archiveProvider)
106 task.target.set(
107 project.layout.buildDirectory.file(
108 "cinteropDefFiles/$taskNamePrefix/${konanTarget.name}/$cinteropName.def"
109 )
110 )
111 task.original.set(
112 project.layout.projectDirectory.file("src/nativeInterop/cinterop/$cinteropName.def")
113 )
114 task.projectDir.set(project.layout.projectDirectory)
115 }
116
registerCInteropnull117 private fun registerCInterop(
118 kotlinNativeCompilation: KotlinNativeCompilation,
119 cinteropName: String,
120 createDefFileTask: TaskProvider<CreateDefFileWithLibraryPathTask>,
121 nativeTargetCompilation: Provider<NativeTargetCompilation>? = null
122 ) {
123 kotlinNativeCompilation.cinterops.register(cinteropName) { cInteropSettings ->
124 cInteropSettings.definitionFile.set(createDefFileTask.flatMap { it.target })
125 nativeTargetCompilation?.let { nativeTargetCompilation ->
126 cInteropSettings.includeDirs(
127 nativeTargetCompilation
128 .flatMap { it.compileTask }
129 .map { it.clangParameters.includes }
130 )
131 }
132 }
133 }
134