1 /*
2  * 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 javax.inject.Inject
20 import org.gradle.api.DefaultTask
21 import org.gradle.api.file.ConfigurableFileCollection
22 import org.gradle.api.file.RegularFileProperty
23 import org.gradle.api.provider.ListProperty
24 import org.gradle.api.provider.Property
25 import org.gradle.api.services.ServiceReference
26 import org.gradle.api.tasks.CacheableTask
27 import org.gradle.api.tasks.Input
28 import org.gradle.api.tasks.InputFiles
29 import org.gradle.api.tasks.Nested
30 import org.gradle.api.tasks.OutputFile
31 import org.gradle.api.tasks.PathSensitive
32 import org.gradle.api.tasks.PathSensitivity
33 import org.gradle.api.tasks.TaskAction
34 import org.gradle.workers.WorkAction
35 import org.gradle.workers.WorkParameters
36 import org.gradle.workers.WorkerExecutor
37 
38 @CacheableTask
39 abstract class ClangSharedLibraryTask
40 @Inject
41 constructor(private val workerExecutor: WorkerExecutor) : DefaultTask() {
42     init {
43         description =
44             "Combines multiple object files (.o) into a shared library file" + "(.so / .dylib)."
45         group = "Build"
46     }
47 
48     @get:ServiceReference(KonanBuildService.KEY)
49     abstract val konanBuildService: Property<KonanBuildService>
50 
51     @get:Nested abstract val clangParameters: ClangSharedLibraryParameters
52 
53     @TaskAction
archivenull54     fun archive() {
55         workerExecutor.noIsolation().submit(ClangSharedLibraryWorker::class.java) {
56             it.clangParameters.set(clangParameters)
57             it.buildService.set(konanBuildService)
58         }
59     }
60 }
61 
62 abstract class ClangSharedLibraryParameters {
63     /** The target platform for the shared file. */
64     @get:Input abstract val konanTarget: Property<SerializableKonanTarget>
65 
66     /** List of object files that will be added to the shared file output. */
67     @get:InputFiles
68     @get:PathSensitive(PathSensitivity.NAME_ONLY)
69     abstract val objectFiles: ConfigurableFileCollection
70 
71     /**
72      * The final output file that will include the shared library containing the given
73      * [objectFiles].
74      */
75     @get:OutputFile abstract val outputFile: RegularFileProperty
76 
77     /**
78      * List of additional objects that will be dynamically linked with the output file. At runtime,
79      * these need to be available for the shared object output to work.
80      */
81     @get:InputFiles
82     @get:PathSensitive(PathSensitivity.NAME_ONLY)
83     abstract val linkedObjects: ConfigurableFileCollection
84 
85     /** List of arguments that will be passed into linker when creating a shared library. */
86     @get:Input abstract val linkerArgs: ListProperty<String>
87 }
88 
89 private abstract class ClangSharedLibraryWorker : WorkAction<ClangSharedLibraryWorker.Params> {
90     interface Params : WorkParameters {
91         val clangParameters: Property<ClangSharedLibraryParameters>
92         val buildService: Property<KonanBuildService>
93     }
94 
executenull95     override fun execute() {
96         val buildService = parameters.buildService.get()
97         buildService.createSharedLibrary(parameters.clangParameters.get())
98     }
99 }
100