mozilla / rust-android-gradle

Apache License 2.0
1.03k stars 67 forks source link

Building the Rust library sometimes fails #7

Open Dexterp37 opened 5 years ago

Dexterp37 commented 5 years ago

In my project, the first time I build it in the morning, building fails when invoking the Gradle task :project:cargoBuildArm (I'm on Windows). That's the thrown exception:

org.gradle.process.internal.ExecException: Process 'command 'cargo'' finished with non-zero exit value 101 at org.gradle.process.internal.DefaultExecHandle$ExecResultImpl.assertNormalExitValue(DefaultExecHandle.java:395) at org.gradle.process.internal.DefaultExecAction.execute(DefaultExecAction.java:37) at org.gradle.api.internal.file.DefaultFileOperations.exec(DefaultFileOperations.java:232) at org.gradle.api.internal.project.DefaultProject.exec(DefaultProject.java:1112) at com.nishtahir.CargoBuildTask$build$$inlined$with$lambda$1.execute(CargoBuildTask.kt:175) at com.nishtahir.CargoBuildTask$build$$inlined$with$lambda$1.execute(CargoBuildTask.kt:11) at org.gradle.api.internal.DefaultDomainObjectCollection.all(DefaultDomainObjectCollection.java:158) at com.nishtahir.CargoBuildTask.build(CargoBuildTask.kt:24) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:73) at org.gradle.api.internal.project.taskfactory.StandardTaskAction.doExecute(StandardTaskAction.java:46) at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:39) at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:26) at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:801) at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:768) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$1.run(ExecuteActionsTaskExecuter.java:131) at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:300) at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:292) at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:174) at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90) at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:120) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:99) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:77) at org.gradle.api.internal.tasks.execution.OutputDirectoryCreatingTaskExecuter.execute(OutputDirectoryCreatingTaskExecuter.java:51) at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:59) at org.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute(ResolveTaskOutputCachingStateExecuter.java:54) at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:59) at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:101) at org.gradle.api.internal.tasks.execution.FinalizeInputFilePropertiesTaskExecuter.execute(FinalizeInputFilePropertiesTaskExecuter.java:44) at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:91) at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:62) at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:59) at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:54) at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43) at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:34) at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.run(EventFiringTaskExecuter.java:51) at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:300) at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:292) at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:174) at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90) at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31) at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:46) at org.gradle.execution.taskgraph.LocalTaskInfoExecutor.execute(LocalTaskInfoExecutor.java:42) at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareWorkItemExecutor.execute(DefaultTaskExecutionGraph.java:277) at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareWorkItemExecutor.execute(DefaultTaskExecutionGraph.java:262) at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$ExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:135) at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$ExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:130) at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$ExecutorWorker.execute(DefaultTaskPlanExecutor.java:200) at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$ExecutorWorker.executeWithWork(DefaultTaskPlanExecutor.java:191) at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$ExecutorWorker.run(DefaultTaskPlanExecutor.java:130) at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63) at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55) at java.lang.Thread.run(Thread.java:745)

Looking a bit closer at Android Studio's errors, I can also see:

linking with E:\Mozilla\glean.rs\build\linker-wrapper\linker-wrapper.bat failed: exit code: 1

In order to make the build work again, I need to manually go to %Temp% and delete the rust-android-ndk-toolchains directory. After that, it rebuilds the directory and everything builds just fine.

mdboom commented 5 years ago

I think the OS is free to remove stuff in %Temp% at any time, so that might be the issue here. I have what I think is the same issue on Linux, in /tmp.

Perhaps we should use something in $GRADLE_HOME instead, which I've seen other plugins use as a place to put gradle-managed-downloaded content.

ncalexan commented 5 years ago

I think the OS is free to remove stuff in %Temp% at any time, so that might be the issue here. I have what I think is the same issue on Linux, in /tmp.

Perhaps we should use something in $GRADLE_HOME instead, which I've seen other plugins use as a place to put gradle-managed-downloaded content.

I'm not really against this, although I don't love putting stuff in dot-directories either. @Dexterp37, can you see if @mdboom's theory is correct by using the different ways to set the toolchain directory listed around: https://github.com/mozilla/rust-android-gradle/blob/fcea23838ca8d95bc5e6caff504dfcf605b2e323/plugin/src/main/kotlin/com/nishtahir/CargoExtension.kt#L58

Dexterp37 commented 5 years ago

@ncalexan yes, the theory seems correct, the failures haven't shown up since I set rust.androidNdkToolchainDir in local.properties to different directory.

mdboom commented 5 years ago

Yeah, I confirm the same.

I think there are two obvious choices for a better default, based on what other plugins I've seen do. If sharing these between projects is useful, it could use something under ~/.gradle. In that case, you have to be explicit about putting version numbers in the paths so different projects don't clobber each other. Alternatively, you could use $PROJECT_ROOT/.gradle. Even then, versioning is helpful to make jumping between git branches faster.

We went down a similar path making the Python environment "plugin" (it's not strictly a plugin) for Glean, and ultimately landed on using ~/.gradle/glean as the installation location and haven't had any issues since.

ncalexan commented 5 years ago

Yeah, I confirm the same.

I think there are two obvious choices for a better default, based on what other plugins I've seen do. If sharing these between projects is useful, it could use something under ~/.gradle. In that case, you have to be explicit about putting version numbers in the paths so different projects don't clobber each other. Alternatively, you could use $PROJECT_ROOT/.gradle. Even then, versioning is helpful to make jumping between git branches faster.

We went down a similar path making the Python environment "plugin" (it's not strictly a plugin) for Glean, and ultimately landed on using ~/.gradle/glean as the installation location and haven't had any issues since.

Thanks for the experience from the trenches. I can't make this happen myself, but I'm totally happy to take a patch that does it. Thanks, Glean team!