Android Studio vs Gradle中的差异构建项目

时间:2018-07-17 14:22:18

标签: android-studio gradle android-gradle

我有一个复杂的Android项目,该项目由多个Java和C ++模块组成,并使用多个构建工具(例如CMake,swig)。使用./gradlew clean assembleDebug从命令行构建时,项目的构建就很好,但从Android Studio构建时,则无法构建。我清理,使缓存无效,已同步等无济于事。

要注意的是:该项目在Android Studio(在Ubuntu(17. *和18. *)等其他系统上也可以很好地构建,但在MacOS(10.13,如果我没记错的话还可以更早)上失败)。

这是Android Studio报告的错误:

org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':IndoorsLocator:runSwig'.
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:84)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:55)
    at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:62)
    at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
    at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:88)
    at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:46)
    at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:51)
    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.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker$1.execute(DefaultTaskGraphExecuter.java:236)
    at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker$1.execute(DefaultTaskGraphExecuter.java:228)
    at org.gradle.internal.Transformers$4.transform(Transformers.java:169)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:106)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:61)
    at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:228)
    at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:215)
    at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:77)
    at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:58)
    at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:32)
    at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:113)
    at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:37)
    at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
    at org.gradle.execution.DefaultBuildExecuter.access$000(DefaultBuildExecuter.java:23)
    at org.gradle.execution.DefaultBuildExecuter$1.proceed(DefaultBuildExecuter.java:43)
    at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)
    at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
    at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:30)
    at org.gradle.initialization.DefaultGradleLauncher$3.execute(DefaultGradleLauncher.java:196)
    at org.gradle.initialization.DefaultGradleLauncher$3.execute(DefaultGradleLauncher.java:193)
    at org.gradle.internal.Transformers$4.transform(Transformers.java:169)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:106)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:56)
    at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:193)
    at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:119)
    at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:102)
    at org.gradle.launcher.exec.GradleBuildController.run(GradleBuildController.java:71)
    at org.gradle.tooling.internal.provider.runner.BuildModelActionRunner.run(BuildModelActionRunner.java:50)
    at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
    at org.gradle.tooling.internal.provider.runner.RunAsBuildOperationBuildActionRunner$1.execute(RunAsBuildOperationBuildActionRunner.java:43)
    at org.gradle.tooling.internal.provider.runner.RunAsBuildOperationBuildActionRunner$1.execute(RunAsBuildOperationBuildActionRunner.java:40)
    at org.gradle.internal.Transformers$4.transform(Transformers.java:169)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:106)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:56)
    at org.gradle.tooling.internal.provider.runner.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:40)
    at org.gradle.tooling.internal.provider.runner.SubscribableBuildActionRunner.run(SubscribableBuildActionRunner.java:75)
    at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:41)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:26)
    at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:75)
    at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:49)
    at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:44)
    at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:29)
    at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:67)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:47)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
    at org.gradle.util.Swapper.swap(Swapper.java:38)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:60)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:72)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
    at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:297)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
    at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.gradle.process.internal.ExecException: A problem occurred starting process 'command 'swig''
    at org.gradle.process.internal.DefaultExecHandle.setEndStateInfo(DefaultExecHandle.java:198)
    at org.gradle.process.internal.DefaultExecHandle.failed(DefaultExecHandle.java:329)
    at org.gradle.process.internal.ExecHandleRunner.run(ExecHandleRunner.java:86)
    ... 5 more
Caused by: net.rubygrapefruit.platform.NativeException: Could not start 'swig'
    at net.rubygrapefruit.platform.internal.DefaultProcessLauncher.start(DefaultProcessLauncher.java:27)
    at net.rubygrapefruit.platform.internal.WrapperProcessLauncher.start(WrapperProcessLauncher.java:36)
    at org.gradle.process.internal.ExecHandleRunner.run(ExecHandleRunner.java:68)
    ... 5 more
Caused by: java.io.IOException: Cannot run program "swig" (in directory "/Users/tom/workspace/indoors-scripts/setup-scripts/workspace-android/IndoorsAndroid/IndoorsLocator"): error=2, No such file or directory
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
    at net.rubygrapefruit.platform.internal.DefaultProcessLauncher.start(DefaultProcessLauncher.java:25)
    ... 7 more
Caused by: java.io.IOException: error=2, No such file or directory
    at java.lang.UNIXProcess.forkAndExec(Native Method)
    at java.lang.UNIXProcess.<init>(UNIXProcess.java:247)
    at java.lang.ProcessImpl.start(ProcessImpl.java:134)
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
    ... 8 more

build failing in Android Studio

在命令行上: build going through via command line (note we are passed "IndoorsLocator:runSwig" already)

“ runSwig”任务的定义如下所示:

task runSwig(type: Exec) {
    commandLine 'swig'

    doFirst {
        coreWrapperDir.mkdirs()
    }

    def swigFileCore = "${projectDir}/src/" + "swig.i"
    def headerFiles = "${projectDir}/include"
    def swigWrapFile = 'src/swig_wrap.cxx'

    inputs.file swigFileCore
    inputs.dir headerFiles
    outputs.dir coreWrapperDir.absolutePath
    outputs.file swigWrapFile

    // this write the generated swig C++ file to "${projectDir}/src"
    args '-c++', '-java', '-package', javaPackage, '-noexcept', '-outdir', coreWrapperDir.absolutePath, "-I${headerFiles}", '-o', swigWrapFile, swigFileCore
}

该日志表明Android Studio在当前工作目录中查找swig,而不是在$ PATH中查找它,但是对于如何告诉Android Studio在哪里查找,我一无所知。有什么想法吗?

Cannot run program "swig" (in directory "/Users/tom/workspace/indoors-scripts/setup-scripts/workspace-android/IndoorsAndroid/IndoorsLocator")

3 个答案:

答案 0 :(得分:1)

您是否已在build.gradle中添加此行?

tasks.withType(JavaCompile) {
    compileTask -> compileTask.dependsOn runSwig
}

无论如何,您可以参考使用swig的github项目:https://github.com/sureshjoshi/android-ndk-swig-example

答案 1 :(得分:1)

需要进行一些调试才能获取有关该问题的更多信息。将以下代码添加到build.gradle模块的IndoorsLocator文件中,然后再次运行。这应该打印路径环境变量,并运行一个Java命令,我假设它也在路径内。然后执行gradle同步并编译或运行代码。打开第一个镜像中的构建窗口,并在构建停止时,在testPath列表中找到Run tasks并共享其输出。或更优选地,如下图所示,将Build切换为文本视图并共享完整的日志。通过命令对其进行测试也将有助于确保其按预期运行。

tasks.whenTaskAdded { addedTask ->
    if (addedTask.name.startsWith("preDebugBuild")) {
        addedTask.dependsOn 'testPath'
    }
}

task testPath {
    mustRunBefore 'checkDebugManifest'
    doLast {
        exec {
            commandLine 'echo', '$PATH'
        }
        exec {
            commandLine 'java', '-version'
        }
    }
}

enter image description here

更新1

根据您的第一条评论,这是一个奇怪的结果!应该使用Java,因此必须以某种方式设置$ PATH,但是echo $PATH无效。更新了代码,以进一步解决问题。

tasks.whenTaskAdded { addedTask ->
    if (addedTask.name.startsWith("preDebugBuild")) {
        addedTask.dependsOn 'testPath'
    }
}

task testPath {
    doLast {
        exec {
            commandLine 'printenv'
        }
        exec {
            commandLine 'which', 'java'
        }
        exec {
            commandLine 'which', 'swig'
        }
    }
}

PS:我在mustRunBefore上的错误,这个错误不存在,我加了意外!

答案 2 :(得分:1)

事实证明,这是由于OSX中的“错误”引起的:https://github.com/gradle/gradle/issues/5631#issuecomment-401775152

我没有找到一种方法可以轻松地针对最新版本的OSX(https://apple.stackexchange.com/questions/106355/setting-the-system-wide-path-environment-variable-in-mavericks)对其进行修复,但是通过在build.gradle中对路径进行硬编码来解决该问题:

task runSwig(type: Exec) {
    // workaround for OSX, see https://stackoverflow.com/q/51383822/198996
    File testFile = new File('/usr/local/bin/swig');
    if (testFile.isFile()) {
        commandLine '/usr/local/bin/swig'
    } else {
        commandLine 'swig'
    }
}

如果您问我,这是一个糟糕的解决方法,所以我很乐意将悬赏奖励给提出更清洁解决方案的人。