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 org.gradle.api.DefaultTask
20 import org.gradle.api.file.DirectoryProperty
21 import org.gradle.api.file.RegularFileProperty
22 import org.gradle.api.tasks.InputFile
23 import org.gradle.api.tasks.Internal
24 import org.gradle.api.tasks.OutputFile
25 import org.gradle.api.tasks.PathSensitive
26 import org.gradle.api.tasks.PathSensitivity
27 import org.gradle.api.tasks.TaskAction
28 import org.gradle.work.DisableCachingByDefault
29 
30 /**
31  * Creates a CInterop def file based on an [original] with added static library path to include the
32  * given [objectFile].
33  *
34  * Once KT-62800 is fixed, we can consider removing this task and do all of this programmatically.
35  *
36  * https://kotlinlang.org/docs/native-c-interop.html
37  */
38 @DisableCachingByDefault(because = "not worth caching, it is a copy with file modification")
39 abstract class CreateDefFileWithLibraryPathTask : DefaultTask() {
40     @get:InputFile
41     @get:PathSensitive(PathSensitivity.NONE)
42     abstract val original: RegularFileProperty
43 
44     @get:InputFile
45     @get:PathSensitive(PathSensitivity.NAME_ONLY)
46     abstract val objectFile: RegularFileProperty
47 
48     @get:OutputFile abstract val target: RegularFileProperty
49 
50     @get:Internal abstract val projectDir: DirectoryProperty
51 
52     @TaskAction
createPlatformSpecificDefFilenull53     fun createPlatformSpecificDefFile() {
54         val target = target.asFile.get()
55         target.parentFile?.mkdirs()
56         // use relative path to the owning project so it can be cached (as much as possible).
57         // Right now,the only way to add libraryPaths/staticLibraries is the def file, which
58         // resolves paths relative to the project. Once KT-62800 is fixed, we should remove this
59         // task but until than, this is the only option to pass a generated so file
60         val objectFileParentDir =
61             objectFile.asFile
62                 .get()
63                 .parentFile
64                 .canonicalFile
65                 .relativeTo(projectDir.get().asFile.canonicalFile)
66         val outputContents =
67             listOf(
68                     original.asFile.get().readText(Charsets.UTF_8),
69                     "libraryPaths=\"$objectFileParentDir\"",
70                     "staticLibraries=" + objectFile.asFile.get().name
71                 )
72                 .joinToString(System.lineSeparator())
73         target.writeText(outputContents, Charsets.UTF_8)
74     }
75 }
76