最新的 Android NDK(版本 8)允许在ndk-build
不安装额外cygwin的情况下调用。
我的问题是:我可以将它插入 CruiseControl.Net 进行定期原生构建吗?
我假设我很可能需要使用Ant作为构建方法,然后将其添加到ccnet服务器配置中。
所以问题是:
如何
ndk-build.cmd
从Ant命令调用如何配置
build.xml
文件?我尝试了几种方法,但都失败了。如果可能的话,你能给我一些线索吗?
最新的 Android NDK(版本 8)允许在ndk-build
不安装额外cygwin的情况下调用。
我的问题是:我可以将它插入 CruiseControl.Net 进行定期原生构建吗?
我假设我很可能需要使用Ant作为构建方法,然后将其添加到ccnet服务器配置中。
所以问题是:
如何ndk-build.cmd
从Ant命令调用
如何配置build.xml
文件?我尝试了几种方法,但都失败了。如果可能的话,你能给我一些线索吗?
在 Windows 上使用 CC.net 尝试直接从 build.xml 调用“ndk-build.cmd”时,我遇到了同样的问题(CreateProcess 失败等)。我想出了如何让它发挥作用,所以我觉得有必要分享我的解决方案。
首先,创建一个 1 行 Windows 命令文件,如下所示(我将其命名为“ndkwrapper.cmd”):
sh ndkwrap.sh %1 %2 %3
接下来,创建一个简单的 bash shell 脚本,如下所示(名为“ndkwrap.sh”):
#!/usr/bin/sh
# Wrapper around ndk-build script for Windows
#
NDK_PROJECT_PATH=/cygdrive/c/workspace/agnc_android
export NDK_PROJECT_PATH
/cygdrive/c/Android/android-ndk-r8b/ndk-build $1 $2 $3
当然,您的确切路径(对于您的工作区和 NDK 目录)可能会有所不同,但请特别注意,“/cygdrive/c”指的是“C:”。
在您创建上面的脚本之后,这里的一个非常重要的步骤是将行尾从 Windows 转换为 UNIX。您可以使用免费提供的名为“dos2unix.exe”的实用程序来执行此操作。我不记得我从哪里得到它,但它是移植到 Windows 的 GNU/Linux 工具的一些开源包的一部分。(谷歌在“Windows 的 UNIX 文件实用程序”上。)如果你不转换行尾,那么 sh 或 bash 将无法读取脚本,你会得到关于 "\r" 的各种错误......
因此,例如,要调用“ndk-build.cmd clean”的等效项,您需要键入“ndkwrapper.cmd clean”来删除与NDK 相关的中间和输出构建文件,为完整的NDK 构建做准备。
在 Windows 上 CC.net 的 build.xml 文件中,您可以调用 NDK 生成文件,如下所示:
<tasks>
<exec>
<executable>cmd.exe</executable>
<baseDirectory>C:\Android</baseDirectory>
<buildArgs>/C ndkwrapper.cmd clean</buildArgs>
</exec>
希望这可以帮助!
本
我也观察到将 ndk-build 作为 CCNET 任务运行的问题。我花了一段时间,但最后我注意到,你必须提供HOST_OS
ndk HOST_ARCH
-build 参数才能让它运行。
<exec>
<executable>cmd</executable>
<buildArgs>/C ndk-build HOST_OS=windows HOST_ARCH=x86 -B NDK_PROJECT_PATH=[PROJECT] APP_BUILD_SCRIPT=[ANDROIDMKFILE] NDK_APPLICATION_MK=[APPLICATIONMKFILE] NDK_LOG=1</buildArgs>
<buildTimeoutSeconds>120</buildTimeoutSeconds>
</exec>
希望它可以帮助任何人节省时间。
好的,我取得了一些进展,我能够通过 ant 或 nant 构建 jni 代码,但在这两种情况下,将其插入 cc.net 服务器配置都会出现 strane 错误:
但现在 CC.net 给了我奇怪的错误:
<builderror>
<type>NAnt.Core.BuildException</type>
<message><![CDATA[External Program Failed: G:\\android-ndk-r8b\\ndk-build.cmd (return code was 2)]]></message>
<location>
<filename>G:/MYPath/project.build</filename>
<linenumber>7</linenumber>
<columnnumber>4</columnnumber>
</location>
<stacktrace><![CDATA[ at NAnt.Core.Tasks.ExternalProgramBase.ExecuteTask()
at NAnt.Core.Tasks.ExecTask.ExecuteTask()
at NAnt.Core.Task.Execute()
at NAnt.Core.Target.Execute()
at NAnt.Core.Project.Execute(String targetName, Boolean forceDependencies)
at NAnt.Core.Project.Execute()
at NAnt.Core.Project.Run()]]></stacktrace>
</builderror>
</failure>
<duration>296.40000000000003</duration>
</buildresults>Buildfile: file:///G:/MYPath/project.build
Target framework: Microsoft .NET Framework 4.0
Target(s) specified: build
干净的:
[echo] Starting Android ndk CLEAN ...
[exec] Android NDK: Unable to determine HOST_OS from uname -s:
[exec] Android NDK: Please define HOST_OS in your environment.
[exec] process_begin: CreateProcess(NULL, uname -s, ...) failed.
[exec] G:/android-ndk-r8b/build/core/init.mk:131: *** Android NDK: Aborting. . Stop.
构建失败 - 0 个非致命错误,2 个警告
我在 cc.net 配置中的项目:
<project>
<name>MY_PROJECT_NAME</name>
<workingDirectory>PATH_TO_MY_PROJECT</workingDirectory>
<tasks>
<nant>
<executable>G:\nant-0.92\bin\Nant.exe</executable>
<baseDirectory>PATH_TO_MY_PROJECT</baseDirectory>
<buildFile>MYPROJECTNAME.build</buildFile>
<buildArgs>build</buildArgs>
<buildTimeoutSeconds>1200</buildTimeoutSeconds>
</nant>
</tasks>
</project>
还有我的 NAnt 构建文件:
<project name="my name" default="build" basedir=".">
<description>My project Build Files.</description>
<target name="clean" description="remove all generated files">
<echo message="Starting Android ndk CLEAN ..."/>
<exec program="G:\\android-ndk-r8b\\ndk-build.cmd" failonerror="true"
basedir="MY PROJECT PATH">
<arg value="clean" />
</exec>
<echo message="Android ndk CLEAN done."/>
</target>
<target name="build" description="remove all generated files" depends="clean">
<echo message="Starting Android ndk BUILD ..."/>
<exec program="G:/android-ndk-r8b/ndk-build.cmd" failonerror="true" />
<echo message="Android ndk BUILD done."/>
</target>
</project>
正如我所说,我可以为我的项目运行 Nant.exe,它可以正确清理和构建。看起来 cc.net 尝试运行另一个用于 linux 的 ndk-build 推荐,并且缺少一些命令作为 uname。你知道 cI 可能做错了什么吗?
最初的问题是询问蚂蚁构建。这个答案与 CC.NET 中的一个问题有关,ant 和 gradle 构建将以同样的方式受到影响。
我们正在使用 gradle 并且通过一些自定义 gradle 任务,也可以通过调用 ndk-build.cmd(从其中没有空格的路径)来编译项目的本机代码。
正确准备好 gradle 文件后,shell 启动的 gradle 构建将起作用,但 cc.net 启动的构建将失败。
我们的 CC.NET 任务定义如下:
<exec executable=".\gradlew.bat">
<baseDirectory>$(projSrcDir)</baseDirectory>
<buildArgs>clean assemblePlayRelease assembleProRelease</buildArgs>
<buildTimeoutSeconds>900</buildTimeoutSeconds>
</exec>
该问题与导致 shell 变量名称为小写的 CC.NET 错误有关。Windows shell 脚本不关心 shell 变量名的大小写,但是因为 NDK 启动了使变量大小写成为问题。作为构建过程一部分的 init.mk make 文件依赖于 shell 变量名称来识别主机操作系统类型。特别是 shell 变量 OS。通常 OS 值是这样定义的:
OS=Windows_NT
但是当变量从 CC.NET 传递给 gradle 时,它会变成这样:
os=Windows_NT
这会导致 init.mk 中的检测机制失败并尝试执行 unix 检测序列并查找 Windows 上不存在的 Unix uname 实用程序,从而导致:
Android NDK: Unable to determine HOST_OS from uname -s:
Android NDK: Please define HOST_OS in your environment.
make.exe: Entering directory `D:/CC.NET/svncheckout/pes/src/project/src/main/jni'
make.exe: Leaving directory `D:/CC.NET/svncheckout/pes/src/project/src/main/jni'
最终:
process_begin: CreateProcess(NULL, uname -s, ...) failed.
c:/ndk/build/core/init.mk:160: *** Android NDK: Aborting. . Stop.
FAILURE: Build failed with an exception.
解决方法不太理想,但可以完成工作。我们的想法是编辑 ndk-build.cmd 并仅在我们从 CC.NET 构建时更改传递变量的大小写。
只需在 ndk-build.cmd 中的 @echo off 行之后插入此代码:
IF DEFINED ccnetproject (
ECHO Applying Environment variable hack for CC.NET.
SET OS2=%os%
SET OS=
REM SET PATH=%path%
SET TEMP2=%temp%
SET TEMP=
)
IF DEFINED ccnetproject (
SET OS=%OS2%
SET OS2=
SET TEMP=%TEMP2%
SET TEMP2=
)
该脚本首先对小写 OS 和 TEMP 变量中的值进行临时复制。接下来,它通过清除它们的值来取消定义它们。最后完成了相反的操作。
需要两个步骤,因为只是说
SET OS=%os%
由于脚本不区分大小写,因此没有多大作用。它首先定位 OS 变量,找到一个小写版本并将自己的值赋回给自己。
这是在 CC.NET v1.6.7981.1、gradle v1.1.0 和 Android NDK v10(64 位)上测试的。