Slackbot
02/21/2023, 12:14 AMVampire
02/21/2023, 12:35 AMdependsOn
.
But I'm not sure how layout.buildDirectory
or its absence or presence should be anyhow related to broken builds where tasks uses outputs of other tasks without having a proper dependency and thus are flaky and broken by nature.
Just have all dependencies you should have, preferably implicitly, then there should be no problem for upgrading in that regard.Vampire
02/21/2023, 12:36 AMCopy
task with layout.buildDirectory
as into
.
But that is majorly evil and should be fixed anyway.Zak Taccardi
02/21/2023, 12:37 AMZak Taccardi
02/21/2023, 12:37 AMbuild/task1Output/
build/task2Output/
both task1
and task2
are coupled to the creation of the build/
folderVampire
02/21/2023, 12:38 AMVampire
02/21/2023, 12:38 AMVampire
02/21/2023, 12:38 AMbuild
is created or not is meaninglessVampire
02/21/2023, 12:39 AMtask1Output
directory as output and task2Output
as output, there is no problem at allVampire
02/21/2023, 12:39 AMbuild
is not an output, it is just an automatically created parent directory.Vampire
02/21/2023, 12:39 AMbuild
directly would be the output directory of a taskZak Taccardi
02/21/2023, 12:39 AMbuild/someAgpTask/
build/myTask/
someAgpTask
created the original build
folder, and myTask
uses it. so I’m getting the implicit dependency errorVampire
02/21/2023, 12:40 AMZak Taccardi
02/21/2023, 12:40 AMVampire
02/21/2023, 12:40 AMVampire
02/21/2023, 12:41 AMsomeAgpTask
defines build
as output directory and then in there creates someAgpTask
, that would be evil and bad.
But if someAgpTask
is the output directory, there is no problem.Vampire
02/21/2023, 12:42 AMmyTask
uses the contents of someAgpTask
directory and has no implicit or explicit dependency, that is when you get an errorVampire
02/21/2023, 12:42 AMZak Taccardi
02/21/2023, 12:44 AM- Gradle detected a problem with the following location: '/Users/zak/Development/git/my-app/my-android-lib/build'.
Reason: Task ':my-android-lib:createMyDirectory' uses this output of task ':my-android-lib:compileReleaseRenderscript' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed.
Possible solutions:
1. Declare task ':my-android-lib:compileReleaseRenderscript' as an input of ':my-android-lib:createMyDirectory'.
2. Declare an explicit dependency on ':my-android-lib:compileReleaseRenderscript' from ':my-android-lib:createMyDirectory' using Task#dependsOn.
3. Declare an explicit dependency on ':my-android-lib:compileReleaseRenderscript' from ':my-android-lib:createMyDirectory' using Task#mustRunAfter.
Zak Taccardi
02/21/2023, 12:45 AMcompileReleaseRenderscript
(AGP task) creates the build
folder on the first run bc it doesn’t exist, but my :my-android-lib:createMyDirectory
task fails because it needs that build
folder as input to create build/myDirectory
Vampire
02/21/2023, 12:47 AMcompileReleaseRenderscript
has build
defined as output directory.
Again, it has nothing to do with who creates the directory.
The task evilly defines the whole build
directory as output directory, that is the problem.Vampire
02/21/2023, 12:47 AMZak Taccardi
02/21/2023, 12:49 AMVampire
02/21/2023, 12:49 AMephemient
02/21/2023, 12:50 AMVampire
02/21/2023, 12:51 AMephemient
02/21/2023, 12:52 AMFollowing the deprecation of RenderScript in the Android platform, we are also removing support for RenderScript in the Android Gradle plugin. Starting with Android Gradle plugin 7.2, the RenderScript APIs are deprecated. They will continue to function, but will invoke warnings, and will be completely removed in future versions of AGP.
ephemient
02/21/2023, 12:52 AMephemient
02/21/2023, 12:54 AMVampire
02/21/2023, 12:55 AMVampire
02/21/2023, 12:55 AMZak Taccardi
02/21/2023, 12:55 AMprocessReleaseManifest
generateReleaseResValues
compileReleaseRenderscript
com.android.build.gradle.tasks.RenderscriptCompile
com.android.build.gradle.tasks.ProcessLibraryManifest
com.android.build.gradle.tasks.AidlCompile
com.android.build.gradle.tasks.GenerateResValues
Zak Taccardi
02/21/2023, 12:58 AM7.4.1
- which I guess is then incompatible with Gradle 8.0 because of that.
But of course, I can’t upgrade to AGP 8.0 due to an unrelated issue.
Presuming this is an AGP bug, Gradle could have given AGP/plugin authors a flag to turn this implicit dependency warning into an errorVampire
02/21/2023, 12:59 AMZak Taccardi
02/21/2023, 1:01 AM7.x
could turn these warnings into errors instead of having to wait for 8.x
for that behaviorZak Taccardi
02/21/2023, 1:19 AM// @OutputDirectory
// val output = objects.directoryProperty()
output.set(
layout
.buildDirectory
.dir("generatedBuildConfigConstant/$name/$sourceSet")
)
or do I need to create a dedicated task to create build/generatedBuildConfigConstant/name/sourceSet/
Vampire
02/21/2023, 1:23 AMVampire
02/21/2023, 1:24 AMZak Taccardi
02/21/2023, 1:28 AMlayout.buildDir
is an @InputDirectory
Vampire
02/21/2023, 1:30 AMVampire
02/21/2023, 1:31 AMZak Taccardi
02/21/2023, 1:31 AMBut why the heck should the whole build directory be your input?I started that workaround for possible solution #2 below:
org.gradle.internal.execution.WorkValidationException: A problem was found with the configuration of task ':my-android-lib:createEmptyObfuscationFile' (type 'CreateEmptyObfuscationFile').
- Type 'my.app.publishing.internal.tasks.CreateEmptyObfuscationFile' property 'outputDir' specifies directory '/Users/zak/Development/git/my-app/my-android-lib/build/artifactory-publishing/artifacts' which doesn't exist.
Reason: An input file was expected to be present but it doesn't exist.
Possible solutions:
1. Make sure the directory exists before the task is called.
2. Make sure that the task which produces the directory is declared as an input.
Please refer to <https://docs.gradle.org/8.0/userguide/validation_problems.html#input_file_does_not_exist> for more details about this problem.
Vampire
02/21/2023, 1:31 AMZak Taccardi
02/21/2023, 1:34 AM:my-android-lib:createEmptyObfuscationFile
receives the output of :my-android-lib:createMyDirectory
as its @InputDirectory
.
:my-android-lib:createMyDirectory
uses layout.buildDirectory
as its @InputDirectory
to create build/myDirectory
.
However, gradle then detects that a bunch of other AGP tasks end up created build/
- which puts me in this problemVampire
02/21/2023, 1:34 AMoutputDir
annotated with @InputDirectory
?Vampire
02/21/2023, 1:35 AMThis is the non-sense partuses:my-android-lib:createMyDirectory
as itslayout.buildDirectory
to create@InputDirectory
.build/myDirectory
Zak Taccardi
02/21/2023, 1:36 AMinternal open class CreateDirectoryTask @Inject constructor(
objects: ObjectFactory,
) : DefaultTask() {
// this ends up being `layout.buildDirectory`
@InputDirectory
val parentDir: DirectoryProperty = objects.directoryProperty()
@Input
val directoryName: Property<String> = objects.property(String::class.java)
@OutputDirectory
val outputDir: Provider<Directory> = parentDir
.map { it.dir(directoryName.get()) }
@TaskAction
fun doWork() {
outputDir.get().asFile.mkdirs()
}
}
Vampire
02/21/2023, 1:36 AMlayout.buildDirectory
is not an input directory, you do not use the files in there as input for your task.
It simply is the parent directory of your @OutputDirectory
, that's allZak Taccardi
02/21/2023, 1:36 AMZak Taccardi
02/21/2023, 1:36 AMZak Taccardi
02/21/2023, 1:36 AMZak Taccardi
02/21/2023, 1:36 AM@OutputDirectory
is kind of input, reallyVampire
02/21/2023, 1:37 AM@OutputDirectory
is the output directoryVampire
02/21/2023, 1:38 AMparentDir
as @Internal
and actually you could do so for directoryName
tooZak Taccardi
02/21/2023, 1:38 AMCreateDirectoryTask
btwVampire
02/21/2023, 1:39 AM@OutputDirectory
already.
If you change either of those properties, the @OutputDirectory
changes too and thus the task already is out-of-dateephemient
02/21/2023, 1:39 AMephemient
02/21/2023, 1:40 AMVampire
02/21/2023, 1:40 AM@OutputDirectory
of a task, Gradle already creates it before the task beginsVampire
02/21/2023, 1:40 AMZak Taccardi
02/21/2023, 1:41 AMwhy do you even need tasks to mkdirI previously used
mkDirs()
in the configuration phase to workaround dirs not existing. Which does not work well with the config cacheephemient
02/21/2023, 1:41 AMephemient
02/21/2023, 1:42 AMephemient
02/21/2023, 1:43 AMVampire
02/21/2023, 1:43 AMinternal abstract class CreateDirectoryTask : DefaultTask() {
@Internal
abstract val parentDir: DirectoryProperty
@Internal
abstract val directoryName: Property<String>
@OutputDirectory
val outputDir: Provider<Directory> = parentDir
.map { it.dir(directoryName.get()) }
}
Vampire
02/21/2023, 1:43 AMVampire
02/21/2023, 1:44 AMZak Taccardi
02/21/2023, 1:44 AMhaving one task mkdir and another task write into the same directory is overlapping outputs, don’t do thatI’ll generally have
build/myPlugin
and then:
build/myPlugin/task1Output/
build/myPlugin/task2Output/
build/myPlugin/task3Output/
ephemient
02/21/2023, 1:44 AMval outputDir
@OutputDirectory get() = parentDir.dir(directoryName.get())
Vampire
02/21/2023, 1:44 AMdirectoryName.get()
ephemient
02/21/2023, 1:45 AMget()
Vampire
02/21/2023, 1:45 AMVampire
02/21/2023, 1:45 AMI’ll generally haveand then:build/myPlugin
```build/myPlugin/task1Output/
build/myPlugin/task2Output/
build/myPlugin/task3Output/```Baaaaad, as @ephemient said
Vampire
02/21/2023, 1:46 AMtask1Output
writes in the output directory of the task that created myPlugin
, so you are doomed!ephemient
02/21/2023, 1:46 AMbuild/myPlugin
itself isn't the output of any taskephemient
02/21/2023, 1:46 AMVampire
02/21/2023, 1:46 AMVampire
02/21/2023, 1:46 AMZak Taccardi
02/21/2023, 1:49 AMinternal val ProjectLayout.artifactsDir
get(): Provider<Directory> = buildDirectory.dir("my-publishing-plugin")
.map { it.dir("artifacts") }
internal val ProjectLayout.mavenPublishPluginDir
get(): Provider<Directory> = artifactsDir
.map { it.dir("maven-publish-plugin-output") }
internal val ProjectLayout.libraryArtifactDir
get(): Provider<Directory> = artifactsDir
.map { it.dir("library") }
so I have nice little accessors:
layout.artifactsDir
layout.mavenPublishPluginDir
layout.libraryArtifactDir
But I think I hit bugs in my code around the directories not existing because these are used as `@InputDirectory`s. It may be bc I am not using @OutputDirectory
correctly to have gradle automatically create these dirsephemient
02/21/2023, 1:50 AM@OutputDirectory
, even if they are a DirectoryProperty
that is configurable as an "input"ephemient
02/21/2023, 1:50 AMVampire
02/21/2023, 1:52 AMephemient
02/21/2023, 1:53 AMephemient
02/21/2023, 1:55 AMval task1 = tasks.register<Task1> {
outputDirectory.set(layout.buildDirectory.dir("my/foo"))
}
val task2 = tasks.register<Task2> {
inputDirectory.set(task1.flatMap { it.outputDirectory })
}
Zak Taccardi
02/21/2023, 1:58 AM@InputDirectory
val outputDir = layout.artifactsDir
Vampire
02/21/2023, 2:02 AMZak Taccardi
02/21/2023, 2:03 AMVampire
02/21/2023, 2:04 AMVampire
02/21/2023, 2:04 AMephemient
02/21/2023, 2:05 AMProjectLayout
and TaskContainer
injected into a task looks a bit odd. you shouldn't be using them at execution time and you don't need them at configuration time. I don't think an immediate problem thoughZak Taccardi
02/21/2023, 2:05 AMephemient
02/21/2023, 2:08 AMVampire
02/21/2023, 2:08 AMexec
, you do not use tasks
.
layout
is probably fine, but of course again having it as @InputDirectory
is non-senseZak Taccardi
02/21/2023, 2:10 AMI would just check one in.it’s on a per-project basis and whether it is needed or not is dynamic, based on whether proguard/R8 are leveraged
ephemient
02/21/2023, 2:10 AMproject.layout
fine during the configuration phase? as long as it's not getting serializedephemient
02/21/2023, 2:11 AM