文章目录
一、需求描述
随着项目越来越大,需要越来越多的NDK开发,最近一个迭代需要Android NDK开发,在本地Window开发完毕之后,在jenkins服务器进行编译的时候出错了,如下所示,提示 NDK not configured. :
FAILURE: Build failed with an exception.
* What went wrong:
A problem occurred configuring project ':snmonitor'.
> NDK not configured.
Download it with SDK manager.
* Try:
Run with --info or --debug option to get more log output.
* Exception is:
org.gradle.api.ProjectConfigurationException: A problem occurred configuring project ':snmonitor'.
at org.gradle.configuration.project.LifecycleProjectEvaluator.addConfigurationFailure(LifecycleProjectEvaluator.java:87)
at org.gradle.configuration.project.LifecycleProjectEvaluator.notifyAfterEvaluate(LifecycleProjectEvaluator.java:82)
at org.gradle.configuration.project.LifecycleProjectEvaluator.doConfigure(LifecycleProjectEvaluator.java:69)
at org.gradle.configuration.project.LifecycleProjectEvaluator.access$100(LifecycleProjectEvaluator.java:33)
at org.gradle.configuration.project.LifecycleProjectEvaluator$ConfigureProject.run(LifecycleProjectEvaluator.java:103)
at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:197)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:107)
at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:49)
at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:651)
at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:133)
at org.gradle.execution.TaskPathProjectEvaluator.configure(TaskPathProjectEvaluator.java:35)
at org.gradle.execution.TaskPathProjectEvaluator.configureHierarchy(TaskPathProjectEvaluator.java:62)
at org.gradle.configuration.DefaultBuildConfigurer.configure(DefaultBuildConfigurer.java:38)
at org.gradle.initialization.DefaultGradleLauncher$ConfigureBuild.run(DefaultGradleLauncher.java:246)
at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:197)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:107)
at org.gradle.initialization.DefaultGradleLauncher.configureBuild(DefaultGradleLauncher.java:165)
at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:124)
at org.gradle.initialization.DefaultGradleLauncher.executeTasks(DefaultGradleLauncher.java:107)
at org.gradle.internal.invocation.GradleBuildController$1.call(GradleBuildController.java:78)
at org.gradle.internal.invocation.GradleBuildController$1.call(GradleBuildController.java:75)
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:152)
at org.gradle.internal.invocation.GradleBuildController.doBuild(GradleBuildController.java:100)
at org.gradle.internal.invocation.GradleBuildController.run(GradleBuildController.java:75)
at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:28)
at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
at org.gradle.tooling.internal.provider.ValidatingBuildActionRunner.run(ValidatingBuildActionRunner.java:32)
at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$1.run(RunAsBuildOperationBuildActionRunner.java:43)
at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:197)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:107)
at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:40)
at org.gradle.tooling.internal.provider.SubscribableBuildActionRunner.run(SubscribableBuildActionRunner.java:51)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:45)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:29)
at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:39)
at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:25)
at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:71)
at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:45)
at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:51)
at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:32)
at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:36)
at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:25)
at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:43)
at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:29)
at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:64)
at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:29)
at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:55)
at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:42)
at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:58)
at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:33)
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:37)
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:62)
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:82)
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:63)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
Caused by: org.gradle.api.InvalidUserDataException: NDK not configured.
Download it with SDK manager.
at com.android.build.gradle.tasks.ExternalNativeJsonGenerator.create(ExternalNativeJsonGenerator.java:580)
at com.android.build.gradle.internal.TaskManager.createExternalNativeBuildJsonGenerators(TaskManager.java:1630)
at com.android.build.gradle.internal.LibraryTaskManager.lambda$createTasksForVariantScope$12(LibraryTaskManager.java:269)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:81)
at com.android.build.gradle.internal.LibraryTaskManager.createTasksForVariantScope(LibraryTaskManager.java:264)
at com.android.build.gradle.internal.VariantManager.createTasksForVariantData(VariantManager.java:545)
at com.android.build.gradle.internal.VariantManager.lambda$createAndroidTasks$1(VariantManager.java:355)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:81)
at com.android.build.gradle.internal.VariantManager.createAndroidTasks(VariantManager.java:351)
at com.android.build.gradle.BasePlugin.lambda$createAndroidTasks$5(BasePlugin.java:641)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:81)
at com.android.build.gradle.BasePlugin.createAndroidTasks(BasePlugin.java:636)
at com.android.build.gradle.BasePlugin.lambda$null$3(BasePlugin.java:555)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:81)
at com.android.build.gradle.BasePlugin.lambda$createTasks$4(BasePlugin.java:551)
at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:91)
at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:80)
at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:42)
at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:230)
at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:149)
at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:58)
at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:324)
at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:234)
at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:140)
at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:37)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at com.sun.proxy.$Proxy24.afterEvaluate(Unknown Source)
at org.gradle.configuration.project.LifecycleProjectEvaluator.notifyAfterEvaluate(LifecycleProjectEvaluator.java:75)
... 81 more
* Get more help at https://help.gradle.org
BUILD FAILED in 23s
二、解决问题
2.1原因分析
从报错日志可以看到,原因是NDK没有配置好。
2.2 查找NDK下载地址
在本地电脑上打开android官网,关于ndk下载的页面,如下所示
https://developer.android.google.cn/ndk/downloads/index.html
找到适合自己的版本
当然,如果你不想下载最新的,也可以下载历史归档的旧版本,如下所示:
点击【NDK 归档页面】链接,进入如下所示的页面
点击【我同意这些条款】
就会刷新出来 历史归档的旧版本,如下所示:
2.3 判断Linux系统是32位还是64位
- 如何查看linux是32位还是64位
我们先判断下jenkins的节点编译服务器是32位还是64位?
使用命令
“getconf LONG_BIT”
如果返回的是32,那么就是32位
如果返回的是64,那么就是64位
[root@localhost ~]# getconf LONG_BIT
64
[root@localhost ~]#
2.4 下载合适的NDK版本
然后我们准备下载 最新稳定版 (r19c) 版本
勾选 【我已阅读并同意上述条款及条件】
勾选之后
点击【下载 ANDROID NDK FOR LINUX】,弹出下面的下载对话框
将下载链接复制出来
https://dl.google.com/android/repository/android-ndk-r19c-linux-x86_64.zip
进入 jenkins编译服务器节点,
[root@localhost android]# pwd
/data/opt/android
[root@localhost android]# ll
总用量 888520
-rw-r--r--. 1 root root 772863352 11月 7 2018 android-studio-ide-171.4408382-windows.zip
drwxr-xr-x. 2 root root 4096 11月 7 2018 ndk
drwxr-xr-x. 13 root root 4096 11月 7 2018 sdk
-rw-r--r--. 1 root root 136964098 11月 7 2018 sdk-tools-linux-3859397.zip
[root@localhost android]#
在 /data/opt/android 目录 下载 ndk的压缩包,
2.5 解压NDK压缩包
- 使用命令
unzip android-ndk-r19c-linux-x86_64.zip
解压文件
解压过程中。。。。。
解压完毕
解压完毕,生成android-ndk-r19c目录
[root@localhost android]# pwd
/data/opt/android
[root@localhost android]# ll
总用量 1692608
drwxr-xr-x. 13 root root 4096 3月 1 00:45 android-ndk-r19c
-rw-r--r--. 1 root root 823376982 3月 14 13:40 android-ndk-r19c-linux-x86_64.zip
-rw-r--r--. 1 root root 772863352 11月 7 2018 android-studio-ide-171.4408382-windows.zip
drwxr-xr-x. 2 root root 4096 11月 7 2018 ndk
drwxr-xr-x. 13 root root 4096 11月 7 2018 sdk
-rw-r--r--. 1 root root 136964098 11月 7 2018 sdk-tools-linux-3859397.zip
[root@localhost android]#
[root@localhost android]# cd android-ndk-r19c
[root@localhost android-ndk-r19c]# ll
总用量 6972
drwxr-xr-x. 7 root root 4096 3月 1 00:41 build
-rw-r--r--. 1 root root 8680 3月 1 00:40 CHANGELOG.md
drwxr-xr-x. 2 root root 4096 3月 1 00:40 meta
-rwxr-xr-x. 1 root root 72 3月 1 00:41 ndk-build
-rwxr-xr-x. 1 root root 90 3月 1 00:41 ndk-gdb
-rwxr-xr-x. 1 root root 92 3月 1 00:41 ndk-stack
-rwxr-xr-x. 1 root root 92 3月 1 00:41 ndk-which
-rw-r--r--. 1 root root 3458821 3月 1 00:45 NOTICE
-rw-r--r--. 1 root root 3594297 3月 1 00:45 NOTICE.toolchain
drwxr-xr-x. 13 root root 4096 3月 1 00:41 platforms
drwxr-xr-x. 7 root root 4096 3月 1 00:43 prebuilt
drwxr-xr-x. 5 root root 4096 3月 1 00:40 python-packages
-rw-r--r--. 1 root root 730 3月 1 00:40 README.md
drwxr-xr-x. 3 root root 4096 3月 1 00:42 shader-tools
drwxr-xr-x. 5 root root 4096 3月 1 00:41 simpleperf
-rw-r--r--. 1 root root 51 3月 1 00:41 source.properties
drwxr-xr-x. 5 root root 4096 3月 1 00:41 sources
drwxr-xr-x. 3 root root 4096 3月 1 00:41 sysroot
drwxr-xr-x. 8 root root 4096 3月 1 00:41 toolchains
drwxr-xr-x. 2 root root 4096 3月 1 00:40 wrap.sh
[root@localhost android-ndk-r19c]#
2.5 配置NDK环境变量
vim /etc/profile
添加 NDK的配置
export NDKROOT=/data/opt/android/android-ndk-r19c
export PATH=$NDKROOT:$PATH
配置好后, 然后命令行下输入source /etc/profile来更新下系统环境变量,就成功安装了NDK啦。
[root@localhost android-ndk-r19c]# source /etc/profile
[root@localhost android-ndk-r19c]#
- 验证ndk是否配置好了
[root@localhost /]# pwd
/
[root@localhost /]# ndk-
ndk-build ndk-gdb ndk-stack ndk-which
[root@localhost /]# ndk-build
Android NDK: Could not find application project directory !
Android NDK: Please define the NDK_PROJECT_PATH variable to point to it.
/data/opt/android/android-ndk-r19c/build/core/build-local.mk:151: *** Android NDK: Aborting . Stop.
[root@localhost /]#
如上所示,输入ndk,按tab键会提示 ndk的相关命令,然后输入 ndk-build 命令,可以运行。 说明 NDK环境变量配置好了!
那提示的四个命令就是/data/opt/android/android-ndk-r19c目录下对应的命令。
2.6 jenkins节点服务器配置NDK环境变量
进入
http://xxx.xxx.xxx.xxx:8080/jenkins/computer/Android_Phone_Server/configure
配置 Android_Phone_Server 这台节点服务器的环境变量,添加
键:【ANDROID_NDK】
值:【/data/opt/android/android-ndk-r19c】
如下所示:
发现如果jenkins配置成上面那样的话,还是会报一样的错误
Caused by: org.gradle.api.InvalidUserDataException: NDK not configured.
Download it with SDK manager.
at com.android.build.gradle.tasks.ExternalNativeJsonGenerator.create(ExternalNativeJsonGenerator.java:580)
at com.android.build.gradle.internal.TaskManager.createExternalNativeBuildJsonGenerators(TaskManager.java:1630)
at com.android.build.gradle.internal.LibraryTaskManager.lambda$createTasksForVariantScope$12(LibraryTaskManager.java:269)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:81)
at com.android.build.gradle.internal.LibraryTaskManager.createTasksForVariantScope(LibraryTaskManager.java:264)
at com.android.build.gradle.internal.VariantManager.createTasksForVariantData(VariantManager.java:545)
at com.android.build.gradle.internal.VariantManager.lambda$createAndroidTasks$1(VariantManager.java:355)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:81)
at com.android.build.gradle.internal.VariantManager.createAndroidTasks(VariantManager.java:351)
at com.android.build.gradle.BasePlugin.lambda$createAndroidTasks$5(BasePlugin.java:641)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:81)
at com.android.build.gradle.BasePlugin.createAndroidTasks(BasePlugin.java:636)
at com.android.build.gradle.BasePlugin.lambda$null$3(BasePlugin.java:555)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:81)
at com.android.build.gradle.BasePlugin.lambda$createTasks$4(BasePlugin.java:551)
at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:91)
at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:80)
at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:42)
at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:230)
at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:149)
at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:58)
at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:324)
at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:234)
at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:140)
at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:37)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at com.sun.proxy.$Proxy24.afterEvaluate(Unknown Source)
at org.gradle.configuration.project.LifecycleProjectEvaluator.notifyAfterEvaluate(LifecycleProjectEvaluator.java:75)
... 81 more
需要配置成 【ANDROID_NDK_HOME】,为什么 jenkins 只识别ANDROID_NDK_HOME???
键:【ANDROID_NDK_HOME】
值:【/data/opt/android/android-ndk-r19c】
如下所示:
三、错误 No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-android
3.1 错误描述
这一次编译,出现的错误是:
FAILURE: Build failed with an exception.
* What went wrong:
A problem occurred configuring project ':app'.
> No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-android
* Try:
Run with --info or --debug option to get more log output.
* Exception is:
org.gradle.api.ProjectConfigurationException: A problem occurred configuring project ':app'.
at org.gradle.configuration.project.LifecycleProjectEvaluator.addConfigurationFailure(LifecycleProjectEvaluator.java:87)
at org.gradle.configuration.project.LifecycleProjectEvaluator.notifyAfterEvaluate(LifecycleProjectEvaluator.java:82)
at org.gradle.configuration.project.LifecycleProjectEvaluator.doConfigure(LifecycleProjectEvaluator.java:69)
at org.gradle.configuration.project.LifecycleProjectEvaluator.access$100(LifecycleProjectEvaluator.java:33)
at org.gradle.configuration.project.LifecycleProjectEvaluator$ConfigureProject.run(LifecycleProjectEvaluator.java:103)
at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:197)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:107)
at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:49)
at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:651)
at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:133)
at org.gradle.execution.TaskPathProjectEvaluator.configure(TaskPathProjectEvaluator.java:35)
at org.gradle.execution.TaskPathProjectEvaluator.configureHierarchy(TaskPathProjectEvaluator.java:62)
at org.gradle.configuration.DefaultBuildConfigurer.configure(DefaultBuildConfigurer.java:38)
at org.gradle.initialization.DefaultGradleLauncher$ConfigureBuild.run(DefaultGradleLauncher.java:246)
at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:197)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:107)
at org.gradle.initialization.DefaultGradleLauncher.configureBuild(DefaultGradleLauncher.java:165)
at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:124)
at org.gradle.initialization.DefaultGradleLauncher.executeTasks(DefaultGradleLauncher.java:107)
at org.gradle.internal.invocation.GradleBuildController$1.call(GradleBuildController.java:78)
at org.gradle.internal.invocation.GradleBuildController$1.call(GradleBuildController.java:75)
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:152)
at org.gradle.internal.invocation.GradleBuildController.doBuild(GradleBuildController.java:100)
at org.gradle.internal.invocation.GradleBuildController.run(GradleBuildController.java:75)
at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:28)
at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
at org.gradle.tooling.internal.provider.ValidatingBuildActionRunner.run(ValidatingBuildActionRunner.java:32)
at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$1.run(RunAsBuildOperationBuildActionRunner.java:43)
at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:197)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:107)
at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:40)
at org.gradle.tooling.internal.provider.SubscribableBuildActionRunner.run(SubscribableBuildActionRunner.java:51)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:45)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:29)
at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:39)
at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:25)
at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:71)
at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:45)
at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:51)
at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:32)
at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:36)
at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:25)
at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:43)
at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:29)
at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:64)
at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:29)
at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:55)
at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:42)
at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:58)
at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:33)
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:37)
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:62)
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:82)
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:63)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
Caused by: java.lang.RuntimeException: No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-android
at com.android.build.gradle.internal.ndk.DefaultNdkInfo.getDefaultToolchainVersion(DefaultNdkInfo.java:441)
at com.android.build.gradle.internal.ndk.DefaultNdkInfo.getToolchainPath(DefaultNdkInfo.java:284)
at com.android.build.gradle.internal.ndk.DefaultNdkInfo.getStripExecutable(DefaultNdkInfo.java:410)
at com.android.build.gradle.internal.ndk.NdkHandler.getStripExecutable(NdkHandler.java:459)
at com.android.build.gradle.internal.transforms.StripDebugSymbolTransform.<init>(StripDebugSymbolTransform.java:89)
at com.android.build.gradle.internal.TaskManager.createStripNativeLibraryTask(TaskManager.java:1718)
at com.android.build.gradle.internal.ApplicationTaskManager.createTasksForVariantScope(ApplicationTaskManager.java:226)
at com.android.build.gradle.internal.VariantManager.createTasksForVariantData(VariantManager.java:545)
at com.android.build.gradle.internal.VariantManager.lambda$createAndroidTasks$1(VariantManager.java:355)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:81)
at com.android.build.gradle.internal.VariantManager.createAndroidTasks(VariantManager.java:351)
at com.android.build.gradle.BasePlugin.lambda$createAndroidTasks$5(BasePlugin.java:641)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:81)
at com.android.build.gradle.BasePlugin.createAndroidTasks(BasePlugin.java:636)
at com.android.build.gradle.BasePlugin.lambda$null$3(BasePlugin.java:555)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:81)
at com.android.build.gradle.BasePlugin.lambda$createTasks$4(BasePlugin.java:551)
at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:91)
at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:80)
at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:42)
at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:230)
at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:149)
at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:58)
at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:324)
at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:234)
at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:140)
at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:37)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at com.sun.proxy.$Proxy24.afterEvaluate(Unknown Source)
at org.gradle.configuration.project.LifecycleProjectEvaluator.notifyAfterEvaluate(LifecycleProjectEvaluator.java:75)
... 81 more
* Get more help at https://help.gradle.org
BUILD FAILED in 5s
3.2 错误原因
- https://developer.android.google.cn/ndk/guides/abis
- https://blog.csdn.net/qq_24118527/article/details/82867864
- https://www.jianshu.com/p/fd3d49c7f1f8
3.2.1 ABI 管理
不同的 Android 手机使用不同的 CPU,而不同的 CPU 支持不同的指令集。CPU 与指令集的每种组合都有专属的应用二进制接口,即 ABI。ABI 可以非常精确地定义应用的机器代码在运行时如何与系统交互。您必须为应用要使用的每个 CPU 架构指定 ABI。
典型的 ABI 包含以下信息:
- 机器代码应使用的 CPU 指令集。
- 运行时内存存储和加载的字节顺序。
- 可执行二进制文件(例如程序和共享库)的格式,以及它们支持的内容类型。
- 在代码与系统之间传递数据的各种规范。这些规范包括对齐限制,以及系统调用函数时如何使用堆栈和寄存器。
- 运行时可用于机器代码的函数符号列表 - 通常来自非常具体的库集。
支持的 ABI
每个 ABI 支持一个或多个指令集。表 1 概述了每个 ABI 支持的指令集。
表 1. ABI 和支持的指令集。
ABI | 支持的指令集 | 备注 |
---|---|---|
armeabi | ARMV5TE 和更高版本 、Thumb-1 | 在 r16 中已弃用。在 r17 中已移除。无硬浮点数。 |
armeabi-v7a | armeabi、Thumb-2、VFPv3-D16、其他(可选) | 与 ARMv5、ARMv6 设备不兼容。 |
arm64-v8a | armeabi、Thumb-2、VFPv3-D16、其他(可选) | 与 ARMv5、ARMv6 设备不兼容。 |
x86 | x86 (IA-32)、MMX、SSE/2/3、SSSE3 | 不支持 MOVBE 或 SSE4。 |
x86_64 | MMX、SSE/2/3、SSSE3、SSE4.1、4.2、POPCNT |
注意:NDK 以前支持 32 位和 64 位 MIPS,但这项支持已在 NDK r17 中移除。
3.2.2 分析toolchains目录
[root@localhost android-ndk-r19c]# pwd
/data/opt/android/android-ndk-r19c
[root@localhost android-ndk-r19c]# ll
总用量 6972
drwxr-xr-x. 7 root root 4096 3月 1 00:41 build
-rw-r--r--. 1 root root 8680 3月 1 00:40 CHANGELOG.md
drwxr-xr-x. 2 root root 4096 3月 1 00:40 meta
-rwxr-xr-x. 1 root root 72 3月 1 00:41 ndk-build
-rwxr-xr-x. 1 root root 90 3月 1 00:41 ndk-gdb
-rwxr-xr-x. 1 root root 92 3月 1 00:41 ndk-stack
-rwxr-xr-x. 1 root root 92 3月 1 00:41 ndk-which
-rw-r--r--. 1 root root 3458821 3月 1 00:45 NOTICE
-rw-r--r--. 1 root root 3594297 3月 1 00:45 NOTICE.toolchain
drwxr-xr-x. 13 root root 4096 3月 1 00:41 platforms
drwxr-xr-x. 7 root root 4096 3月 1 00:43 prebuilt
drwxr-xr-x. 5 root root 4096 3月 1 00:40 python-packages
-rw-r--r--. 1 root root 730 3月 1 00:40 README.md
drwxr-xr-x. 3 root root 4096 3月 1 00:42 shader-tools
drwxr-xr-x. 5 root root 4096 3月 1 00:41 simpleperf
-rw-r--r--. 1 root root 51 3月 1 00:41 source.properties
drwxr-xr-x. 5 root root 4096 3月 1 00:41 sources
drwxr-xr-x. 3 root root 4096 3月 1 00:41 sysroot
drwxr-xr-x. 9 root root 4096 6月 11 14:35 toolchains
drwxr-xr-x. 2 root root 4096 3月 1 00:40 wrap.sh
进入toolchains目录,如下所示:
[root@localhost android-ndk-r19c]# cd toolchains/
[root@localhost toolchains]# ll
总用量 24
drwxr-xr-x. 3 root root 4096 3月 1 00:41 aarch64-linux-android-4.9
drwxr-xr-x. 3 root root 4096 3月 1 00:41 arm-linux-androideabi-4.9
drwxr-xr-x. 3 root root 4096 3月 1 00:41 llvm
drwxr-xr-x. 3 root root 4096 3月 1 00:41 renderscript
drwxr-xr-x. 3 root root 4096 3月 1 00:41 x86-4.9
drwxr-xr-x. 3 root root 4096 3月 1 00:41 x86_64-4.9
[root@localhost toolchains]#
我们注意到里边确实没有mips64el相关的文件.
https://github.com/android-ndk/ndk/wiki/Changelog-r18
This version of the NDK is incompatible with the Android Gradle plugin version 3.0 or older. If you see an error like No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-android, update your project file to use plugin version 3.1 or newer. You will also need to upgrade to Android Studio 3.1 or newer.
大概的意思就是说,这个版本与Gradle 3.0之前的版本不兼容,会报我们遇到的这个问题,所以,有一个更简单的解决办法:
如果项目允许的话,将Gradle版本升级到高于3.0的版本,同时也需要将Android Studio升级到3.1或更高的版本.
然后我查看了下 这个项目的gradle版本
3.3 解决错误
3.3.1 官方解决办法
既然google官方已经移除了MIP,那么我们就按照官方指示 升级下 gradle 版本即可。
将
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
}
升级到 下面的版本3.1.0以上的版本即可即可。
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
}
3.3.2 歪门邪道
http://www.mingjianhua.com/post/82.html
有时候你不想去升级gradle版本,能不能有什么版本解决这个问题呢?
[root@localhost toolchains]# pwd
/data/opt/android/android-ndk-r19c/toolchains
[root@localhost toolchains]# ll
总用量 24
drwxr-xr-x. 3 root root 4096 3月 1 00:41 aarch64-linux-android-4.9
drwxr-xr-x. 3 root root 4096 3月 1 00:41 arm-linux-androideabi-4.9
drwxr-xr-x. 3 root root 4096 3月 1 00:41 llvm
drwxr-xr-x. 3 root root 4096 3月 1 00:41 renderscript
drwxr-xr-x. 3 root root 4096 3月 1 00:41 x86-4.9
drwxr-xr-x. 3 root root 4096 3月 1 00:41 x86_64-4.9
[root@localhost toolchains]# mkdir -p mips64el-linux-android/prebuilt/linux-x86_64
[root@localhost toolchains]# ll
总用量 28
drwxr-xr-x. 3 root root 4096 3月 1 00:41 aarch64-linux-android-4.9
drwxr-xr-x. 3 root root 4096 3月 1 00:41 arm-linux-androideabi-4.9
drwxr-xr-x. 3 root root 4096 3月 1 00:41 llvm
drwxr-xr-x. 3 root root 4096 6月 11 15:40 mips64el-linux-android
drwxr-xr-x. 3 root root 4096 3月 1 00:41 renderscript
drwxr-xr-x. 3 root root 4096 3月 1 00:41 x86-4.9
drwxr-xr-x. 3 root root 4096 3月 1 00:41 x86_64-4.9
[root@localhost toolchains]# cd mips64el-linux-android/
[root@localhost mips64el-linux-android]# ll
总用量 4
drwxr-xr-x. 3 root root 4096 6月 11 15:40 prebuilt
[root@localhost mips64el-linux-android]# cd prebuilt/
[root@localhost prebuilt]# ll
总用量 4
drwxr-xr-x. 2 root root 4096 6月 11 15:40 linux-x86_64
[root@localhost prebuilt]# cd linux-x86_64/
[root@localhost linux-x86_64]# ll
总用量 0
[root@localhost linux-x86_64]# pwd
/data/opt/android/android-ndk-r19c/toolchains/mips64el-linux-android/prebuilt/linux-x86_64
[root@localhost linux-x86_64]#
如上所示,我们创建了一个空的文件夹
/data/opt/android/android-ndk-r19c/toolchains/mips64el-linux-android/prebuilt/linux-x86_64
这样就可以编译成功了!
四、出现 /lib64/libc.so.6: version `GLIBC_2.15’ not found 错误
编译出现以下错误
/data/opt/android/sdk/cmake/3.6.4111459/bin/cmake: /lib64/libc.so.6: version `GLIBC_2.15' not found
(required by /data/opt/android/sdk/cmake/3.6.4111459/bin/cmake)
去 http://ftp.gnu.org/gnu/glibc/ 下载 对应的版本,解压,编译安装即可。
解决之后有了2.15
安装好了 GLIBC_2.15之后,编译成功!
:snmonitor:extractReleaseAnnotations
:snmonitor:mergeReleaseConsumerProguardFiles UP-TO-DATE
:snmonitor:mergeReleaseShaders
:snmonitor:compileReleaseShaders
:snmonitor:generateReleaseAssets
:snmonitor:packageReleaseAssets
:snmonitor:packageReleaseRenderscript NO-SOURCE
:snmonitor:processReleaseJavaRes NO-SOURCE
:snmonitor:transformResourcesWithMergeJavaResForRelease
:snmonitor:transformClassesAndResourcesWithSyncLibJarsForRelease
:snmonitor:generateJsonModelRelease UP-TO-DATE
:snmonitor:externalNativeBuildRelease
Build yhook x86
[x86] Compile : yhook <= com_xtc_snmonitor_collector_hook_HookMain.c
[x86] Compile : yhook <= trampoline.c
[x86] SharedLibrary : libyhook.so
Build yhook arm64-v8a
[arm64-v8a] Compile : yhook <= com_xtc_snmonitor_collector_hook_HookMain.c
[arm64-v8a] Compile : yhook <= trampoline.c
[arm64-v8a] SharedLibrary : libyhook.so
Build yhook armeabi-v7a
[armeabi-v7a] Compile arm : yhook <= com_xtc_snmonitor_collector_hook_HookMain.c
[armeabi-v7a] Compile arm : yhook <= trampoline.c
[armeabi-v7a] SharedLibrary : libyhook.so
:snmonitor:mergeReleaseJniLibFolders
:snmonitor:transformNativeLibsWithMergeJniLibsForRelease
:snmonitor:transformNativeLibsWithStripDebugSymbolForRelease
:snmonitor:transformNativeLibsWithSyncJniLibsForRelease
:snmonitor:bundleReleaseAar
:snmonitor:uploadArchivesCould not find metadata com.xtc.phone:monitor/maven-metadata.xml in remote (http://xxx.xxx.com:8081/nexus/content/repositories/android-release/)
五、 参考链接
- https://developer.android.google.cn/ndk/downloads/index.html
- https://developer.android.google.cn/ndk/guides/abis
- https://blog.csdn.net/qq_24118527/article/details/82867864
- https://www.jianshu.com/p/fd3d49c7f1f8
- https://github.com/android-ndk/ndk/wiki/Changelog-r18
- http://www.mingjianhua.com/post/82.html
- https://ouyangpeng.blog.csdn.net/article/details/79974407
- http://ftp.gnu.org/gnu/glibc/
作者:欧阳鹏 欢迎转载,与人分享是进步的源泉!
转载请保留原文地址:https://blog.csdn.net/qq446282412/article/details/91415049
☞ 本人QQ: 3024665621
☞ QQ交流群: 123133153
☞ github.com/ouyangpeng
☞ [email protected]