2

我曾尝试搜索 Internet 和 StackOverflow(文章太多,数不清),但找不到所有这些内容的帮助:

  1. 比 2013 年更近
  2. 如果在 Windows 上开发,则不需要 Cygwin
  3. 适用于 Android Studio,而不是 Eclipse。

我是第一次涉足 Android 开发,而我新加入的项目依赖于使用 NDK 进行开发。我一直在阅读 NDK 附带的文档,但遇到了这个示例的石墙。

我正在尝试构建hello-jniNDK 中的示例项目。这是我的环境:

  • Android Studio 1.4(最新,目前可用的稳定版本)
  • NDK 版本:r10e
  • 操作系统:Windows 7

Application.mk 文件的内容:

APP_ABI := all64 // Came with 'all', read somewhere on SO that it 
                 // should be 'all64'. Result is the same.

Android.mk 文件内容:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := hello-jni
LOCAL_SRC_FILES := hello-jni.c

include $(BUILD_SHARED_LIBRARY)

我的 PATH 环境变量包括我的 NDK 根文件夹和路径\prebuilt\windows-x86_64\bin(因为我阅读了它应该阅读的许多文章之一。)当我导航到 hello-jni 根文件夹并调用 ndk-build 时,我只出现有错误。

c:\NDK\android-ndk-r10e\build\core\build-local.mk:40: c:/NDK/android-ndk-r10e/build/core/build/core/init.mk: No such file or directory
c:\NDK\android-ndk-r10e\build\core\build-local.mk:191: \add-application.mk: No such file or directory
c:\NDK\android-ndk-r10e\build\core\build-local.mk:206: \setup-imports.mk: No such file or directory
c:\NDK\android-ndk-r10e\build\core\build-local.mk:223: \build-all.mk: No such file or directory
make.exe: *** No rule to make target `\build-all.mk'.  Stop.

如果人们还需要其他什么来帮助我,请说我会尽我所能。所有帮助将不胜感激。

编辑:我在 Windows 上看到的大多数文章都提到了 Cygwin,但根据文档,它不是必需的。如果这是不正确的,请纠正我?

除了从\android-ndk-r10e\docs\Programmers_Guide\html\md_3__key__topics__building__s_t_a_n_d_a_l_o_n_e-_t_o_o_l_c_h_a_i_n.html

视窗支持

Windows 二进制文件不依赖于 Cygwin。好消息是它们因此更快,坏消息是它们不理解 Cygwin 路径规范,例如 /cygdrive/c/foo/bar(而不是 C:/foo/bar)。

NDK 构建系统确保从 Cygwin 传递到编译器的所有路径都被自动翻译,并为您处理其他可怕的事情。如果您有自定义构建系统,您可能需要自己处理问题。

4

2 回答 2

2

我不能把这个答案归功于我,一位同事好心地为我揭开了它。当他找到答案时,我要求知道他还做了什么,因为显然我一定错过了一些魔法?我只看到他在一个make文件中切换了两行,必须有更多吗?唉,没有。仅这一点就是我痛苦的根源。

虽然我不愿将其称为 NDK 中的错误,因为我不知道它如何与 Cygwin 一起工作,但我们都无法理解这对于在本机 Windows 中构建的任何人来说是如何工作的,因为我将引用的行是在 2011 年或 2010 年添加回 git 存储库中记录。(https://android.googlesource.com/platform/ndk/+/master/build/core/build-local.mk

为了帮助解释,这里再次是我的错误的第一行:

c:\NDK\android-ndk-r10e\build\core\build-local.mk:40: c:/NDK/android-ndk-r10e/build/core/build/core/init.mk: No such file or directory

第一个找不到的文件是...build/core/build/core/init.mk,当然不存在,因为build/core不应该重复。

开始构建的命令ndk-build.cmd调用build\core\build-local.mk以开始该过程。在此文件中,环境变量 NDK_ROOT在进入时重新创建。无论我的NDK_ROOT 是什么,都无关紧要。

NDK_ROOT := $(dir $(lastword $(MAKEFILE_LIST)))
NDK_ROOT := $(strip $(NDK_ROOT:%build/core/=%))
NDK_ROOT := $(subst \,/,$(NDK_ROOT))
NDK_ROOT := $(NDK_ROOT:%/=%)
.
.
.

第二行build/core/从我的新 NDK_ROOT 的末尾删除当前目录的末尾 (the ),因为真正的根目录应该是它的父目录,build并且稍后会添加回来以查找所有那些“丢失”的文件。没关系,除了注意/搜索中使用的正斜杠 ( )。Windows 不使用(或至少根据我的经验,通常不返回)正斜杠,但如果这是给定的,它通常会解析它们。(例如,在更改目录时,只要我已经知道需要去哪里,我就可以接受。如果我的路径以 . 结尾,则选项卡完成似乎不起作用/。)

哦,但是看看第三行(早在 2011 年就添加了)!对 NDK_ROOT中的每个反斜杠 ( \) 进行替换,替换为正斜杠 ( /)。所以更换build/core/应该顺利进行,对吧?问题:为时已晚。

strip 调用已经发生,如果 NDK_ROOT 收到带有反斜杠而不是正斜杠的路径,build/core/则永远不会找到并从变量中剥离。我的同事是怎么解决的?简单的。他换了句台词:

NDK_ROOT := $(dir $(lastword $(MAKEFILE_LIST)))
NDK_ROOT := $(subst \,/,$(NDK_ROOT))
NDK_ROOT := $(strip $(NDK_ROOT:%build/core/=%))
NDK_ROOT := $(NDK_ROOT:%/=%)

我的hello-jni项目现在与 NDK 中的另一个示例一起构建,Teapot我尝试确定。native-audio, native-codec,native-media和 也是如此More Teapots。还没有尝试运行它们......但我没有构建错误。

我不知道这个修复是否会破坏 Cygwin 用户,我的盒子上没有。我也不知道它是否会破坏 Linux 环境,因为我的盒子上没有 Linux。但这可能对 Windows 本地用户有所帮助,我希望如此,因为我在这 3 或 4 天里毫无用处地在这方面绞尽脑汁,并且一次阅读的 SO 文章比我曾经关心的还要多。

于 2015-10-23T22:48:33.830 回答
1

使用 Windows 机器我遇到了这个错误,但它说 clear-vars.mk :没有这样的文件或目录。在我查看了目录中的 ndk-build.cmd 之后

C:\Users\\AppData\Local\Android\Sdk\ndk-bundle\build

文件看起来像这样

@echo off
set NDK_ROOT=%~dp0\..
set PREBUILT_PATH=%NDK_ROOT%\prebuilt\windows-x86_64
if exist %PREBUILT_PATH% goto FOUND
set PREBUILT_PATH=%NDK_ROOT%\prebuilt\windows
:FOUND
"%PREBUILT_PATH%\bin\make.exe" -f "%NDK_ROOT%\build\core\build-local.mk" SHELL=cmd %*

但是您也会在目录下找到相同的文件名

C:\Users\jmatthews\AppData\Local\Android\Sdk\ndk-bundle

文件看起来像这样

@echo off
%~dp0\build\ndk-build.cmd %*

删除第二行,使其看起来像这样,只有 1 行回显关闭

@echo off

该文件被调用并弄乱了 Windows 目录结构。之后我就可以在windows上编译了。此外,我在使用目录中的空格时遇到了项目问题,因此将项目位置移动到没有空格的目录中。

于 2019-07-31T16:31:07.350 回答