ndk-build常见错误及解决办法汇总

常见错误说明:

1make:*** Norule specified and no make file found. Stop.


错误的原因估计是(cat :Linux命令,显示文件的内容):工程名与Aplication.mk中的APP_MOUDLES不一致。


2make: *** Norule to make target  “XXXXXX”, needed by“ndk-app-XXXXX”. Stop.


这个错误的主要原因是:编译C文件为最后的so库文件需要2个文件:Application.mkAndroid.mk


MK文件如何设置,看了上面的图一目了然【详细的说明还是要去看文档】,以下几点需要注意:

·        文件的相对路径是否正确(Application.mk中的APP_PROJECT_PATH设置相对路径)
这些在AndroidNDKzhong 都有严格规范的,在android-ndk的文档中都有详细说明。

·        工程文件名Aplication.mk中的APP_MOUDLESAndroid.mk中的LOCAL_MODULE是否完全一致。Android.mk中的LOCAL_MODULE_FILENAME是输出库文件的名称【NDK会默认的加上前缀lib(如果LOCAL_MODULE_FILENAME中已经是以lib开头就不添加),以及后缀.so)。

3make:***[XXXX]Errror  1


这个错误只要大家仔细看下就明白是C的编译错误,C代码无法编译。

如何编写C文件【nativefile】中的函数说明?从Java SourceFile推导出C/C++ NativeFile,可以参考以下4步:

1)       编译java文件【Javasources:包含我们需要的native函数】 


2)       使用命令javac JNITest.jva&& javah JNITest,命令运行后增加了2个文件:


JNITest.jva编译后的文件JNITest.classJNITest.h,这个文件就是我们需要的头文件,如下图所示:


3)       修改函数名,如何修改?我们先分析Android-NDK中的例子程序:


从上面的例子发现,函数名分为4部分:

按照上面的规则修改就可以了。

4)       将上面的函数声明拷贝出来,在jni文件中创建一个*.c文件,按照上述函数结构实现函数,如下图所示:

11

这样我们就从Java SourceFile一步一步的得到C/C++ NativeFile

4、程序运行时崩溃,这个时候我们需要注意以下几个问题:

库文件的加载


编译后的so文件是libJNITest.so,而实际加载的库文件名是:JNITest【这实际上是Unix规范,在AndroidNDK的文档OVERVIEW.txt中有详细说明】;还有Linux系统区分大小写的,所以如果上面的代码中,将加载的库文件名写成jnitest,也会导致运行崩溃。

 

 

解决NDK出现error:exception handling disabled, use -fexceptions toenable的问题

问题来源:

UDTandroid平台移植过程中,在用NDK编译buffer.cpp文件时出现error: exception handling disabled, use -fexceptions toenable

问题解决:

此问题的出现是编译器的异常异常捕获被禁用了,需要在Android.mk文件中开启。在Android.mk文件中添加:LOCAL_CPPFLAGS += -fexceptions就可以了。或者在Application.mk文件中添加APP_CPPFLAGS += -fexceptions
也是可以的。

补充:

Android NDK r5C++的支持情况

android平台提供了一个最小化的C++运行库(/system/lib/libstdc++)以及与之对应的头文件。

1C++的异常支持

NDK r5就开始NDK的工具链就开始支持了C++的异常控制,只不过为了通用性的原因,所有的C++原文件被编译的时候都是默认的是-fno-exceptions,即不不支持异常控制的。

使用-fexceptions标记可以开启异常控制。所以你只需要在你的每个模块的Android.mk中添加LOCAL_CPPFLAGS += -fexceptions就可以了。

更简单的是,在你的Application.mk文件中添加APP_CPPFLAGS += -fexceptions,这种配置会自动应用到你工程的所有模块当中。

注意:

已被废弃的"arm-eabi-4.4.0"工具链提供的向后兼容的NDK是不支持异常的。

2RTTI support:

NDK r5开始,NDK工具链也开始支持C++ RTTIRuntime Type Information)了。但是,为了通用性的,所有的C++源文件被构建的时候默认是不支持RRRI的(-fno-rtti)。需要开启的话,你需要在Android.mk中添加:LOCAL_CPPFLAGS += -frtti,或者更简单的做法是在Application.mk添加APP_CPPFLAGS += -frtti

注意:

已被废弃的"arm-eabi-4.4.0"工具链提供的向后兼容的NDK是不支持RTTI的。

III. Selecting the C++ Standard LibraryImplementation:

By default, the headers and libraries for the minimal C++runtime system
library (/system/lib/libstdc++.so) are used when building C++sources.

You can however select a different implementation bysetting the variable
APP_STL to something else in your Application.mk, forexample:

APP_STL := stlport_static

To select the static STLport implementation provided withthis NDK.
Value APP_STL values are the following:

system -> Use the default minimal C++ runtimelibrary.
stlport_static -> Use STLport built as a static library.
stlport_shared -> Use STLport built as a sharedlibrary.

WARNING: IMPORTANT CAVEAT

AT THE MOMENT, OUR STLPORT IMPLEMENTATION DOES NOT SUPPORTEXCEPTIONS
AND RTTI. PLEASE BE SURE TO NOT USE -fexceptions OR -frtti INALL
MODULES THAT USE IT.

WARNING: END OF IMPORTANT CAVEAT

"stlport_shared" is preferred if you have several sharedlibraries in your
project that use the C++ STL, because it avoids duplication offunctions
and more importantly of global variables (e.g. std::cout) in eachone of
them, which can have surprising results.

On the other hand, you will have to load it explicitelywhen starting your
application, as in the following example:

static {
System.loadLibrary("stlport_shared");
System.loadLibrary("foo");
System.loadLibrary("bar");
}

Where both "libfoo.so" and "libbar.so" depend on"libstlport_shared.so".

Note that the shared library's name if"libstlport_shared.so" to avoid
naming conflicts with certain Android system images which includea
system-level libstlport.so (which happens to not be ABI-stableand
cannot be used from NDK-generated machine code).

"stlport_static" is preferred if you have only one sharedlibrary in your
project: only the STL functions and variables you actually needwill be
linked to your machine code, reducing its code size, and you won'tneed
to load the dynamic stlport_shared at startup.


IV. STLport-specific issues:
----------------------------

This NDK provides prebuilt static and shared libraries forSTLport,
but you can force it to be rebuilt from sources by defining thefollowing
in your environment or your Application.mk beforebuilding:

STLPORT_FORCE_REBUILD := true

STLport is licensed under a BSD-style open-source license.See
sources/cxx-stl/stlport/README for more details about thelibrary.


V. Future Plans:
----------------

- Make STLport compatible with C++ exceptions andRTTI
- Full GNU libstdc++ support

 

 

开发遇到的问题:

LOCAL_SHARED_LIBRARIES和LOCAL_SHARED_LIBRARY:注意前者是复数S形式,用于Link多个库(只有一个也可以用),后者只能添加一个链接库,可恶的文档关于Prebuilts的介绍里面给出的例子是LOCAL_SHARED_LIBRARY,使用两个库的时候第二个库死也link不上。

某些依赖关系很有问题,makefile只能clean掉jni文件夹下的obj文件;更换不同版本的C++RunTime实现必须要clean,否则会出现link错误;注意一共有四种libstdc++实现,什么都不写默认是系统自带没有STL的版本,另外三种在SDK自带文档CPLUSPLUS-SUPPORT当中列出。从系统默认libstdc++切换到带STL的版本同样需要clean

使用STL的时候,APP_STL := xxx 这句话需要写在Application.mk当中,而不是Android.mk

argumentlist toolong问题:文件很多的时候会出现这种编译或链接报错的情况,不过这个问题源自孩儿他爸Linux的遗传,某些系统命令对于输入参数长度有限制,把工程文件夹映射到一个盘符路径会好一些。对于Android有人给出了修改SDK的makefile的补丁,似乎是去掉了某个echo命令。

2012.02.26补充,NDKr7未发现此问题,可能已修正

使用$(call import-module,hello-gl2/jni) 命令import库的时候,如果发生下面的报错:

AndroidNDK: Are yousure yourNDK_MODULE_PATH variable is properly

需要注意NDK_MODULE_PATH是一个环境变量而不是makefile中的变量。不把库的搜索路径作为一个工程属性而是一个系统属性,这种方式或许更适用于系统库,而不是自己写的第三方库。

关于Android不支持wchar_t的说法:wchar_t作为一种变量类型是内置支持的,和大多数*nix实现一样,为4字节,但是wchar.h中的一系列函数在Android NDK还没有提供,也就是说你需要自己想办法计算wchar_t*的字符串长度、比较字符内容等等。推荐使用CrystaX制作的加强版NDK解决此问题,传送门如下:

http://www.crystax.net/en/android/ndk

经试验由官方NDKr7迁移到此版本(r7-4)没遇到什么问题,作者的修改最大的两个亮点,

1. 增加了GCC4.6.3的选择,可以获得c++0x的部分支持,以及更好的内存性能(这一点没有测试过)

2. 完善了wchar_t一族函数的支持,当然,需要启动之后setlocale一下才能够正确的swprintf汉字的字符串。这一点多说两句,虽然很多人骂微软,但是的确windows才是对开发人员最友好的平台,大家的locale默认都是"C",但是win32上面啥都不用改就能swprintf汉字文本,*niux、iOS都做不到。

NDK代码编译完毕后,需要在Eclipse中选中工程按F5refresh一下,在Eclipse之外的任何代码资源改动都需要此步骤。有些时候还会出现莫名其妙的编译错误需要clean,嗯,是不是想起了XCode?

资源组织方式,可以使用AssetManager,需要注意不要让SDK的打包apk工具把asset目录的文件压缩,否则在AssetManager Open文件的时候可能会抛异常(具体情况取决于android系统版本,在某些机器上正常读取,某些机器会抛异常。根据某些人的说法,读取带有压缩的asset文件,AssetManager会把文件解压到内存中,如果系统内存不足就会抛异常;对于非压缩文件,直接读取数据即可没有这一道开销)。通常在asset目录容量超过1M的文件会被压缩,但是有几种扩展名的文件可以确保不会被压缩,打包工具认为这些类型的文件已经过压缩,无需再压,常见的.zip.mp3都没有问题(2012.03.11 更正:".zip"不行,如果是真正的zip文件不会被压缩,如果其他格式文件改后缀伪装成zip仍然会被压缩,使用mp3后缀名看来是最好的选择)

例子:如果你在asset文件夹下面放了一个2M的a.wav文件,改成a.mp3或者a.zip即可(当然你读取的时候还是按照wav读)。具体有没有被压缩,用zip文件管理工具(譬如7zip)打开apk文件,看原始大小和压缩后大小即可。

HelperScene.obj : error LNK2019:无法解析的外部符号 "public: staticclass cocos2d::CCLuaEngine * __cdeclcocos2d::CCLuaEngine::engine(void)"(?engine@CCLuaEngine@cocos2d@@SAPAV12@XZ),该符号在函数"public: virtual bool __thiscall HelperScene::init(void)"(?init@HelperScene@@UAE_NXZ) 中被引用

这个错误,我是通过把luaEngine文件考到自己的工程下解决的

Error 1:
$ ndk-build
/cygdrive/c/andy/abc/obj/local/armeabi-v7a/objs/abc//hellow.o.d:1:*** [color=#FF0000]multiple target patterns[/color].Stop.

quick fix: Delete Objfolder from “C:\andy\prjM\obj\local\armeabi-v7a” then runndk-build
or refer this


Error 2:
Android.mk:44: ***[color=#FF0000]commands commence before first target[/color].Stop.
fix: Check thereare nocomments,no space ,no empty line in the src includes ofAndroid.mk

For example:
wrong:
[code]LOCAL_SRC_FILES:=file1.cpp\
file1al.cpp\
#file1atures.cpp\
file1r.cpp\

file1le.cpp\
Satfile1.cpp\
Sfile1l.cpp\
file1e.cpp\
Sfile1face.cpp\[/code]
3rd line has #, 4th line hasspace(check with cursor),5th line is empty line

Right:
[code]LOCAL_SRC_FILES:=file1.cpp\
file1al.cpp\
file1atures.cp\
file1r.cpp\
file1le.cpp\
Satfile1.cpp\
Sfile1l.cpp\
file1e.cpp\
Sfile1face.cpp\[/code]

Error3:
$ ndk-buildclean
Android NDK: Could not findapplication project directory !
Android NDK: Please define theNDK_PROJECT_PATH variable to point to it.
/cygdrive/c/android-ndk-r4b/build/core/build-local.mk:85:*** [color=#FF0000]Android NDK: Aborting[/color] .Stop.

Fix: include Android.mklocation inside global application.mk andAndroid.mk
Run the command from the parentdirectory with app.mk and and.mk resides


Error 4:

Please define ANDROID_NDK_ROOT topoint to the root of your Android NDK installation.
Use case while executing shellscript xxx-desktop:~/bin/u/android-ndk-r5/build/tools$./rebuild-all-prebuilt.sh
Please define ANDROID_NDK_ROOT topoint to the root of your Android NDK installation.

// Run the script insideNDK root directory like shown below
xxx-desktop:~/bin/u/android-ndk-r5/build/tools$cd ..
xxx-desktop:~/bin/u/android-ndk-r5/build$ cd..
xxxx-desktop:~/bin/u/android-ndk-r5$./build/tools/rebuild-all-prebuilt.sh

Error 5:

NDK r5app(native-activity,native-audio,native-plasma) build problemCompiling native-activity,native-audio,native-plasma on ndk-r5 givecompile errors stating header not found and so on……

Quick fix: Rebuild allprebuilt

i;e execute shell scriptrebuild-all-prebuilt.sh to build on latest toolchain provided byandroid which will take for a while (atleast on my pc)

xxx-desktop:~/bin/u/android-ndk-r5$./build/tools/rebuild-all-prebuilt.sh
To follow build in another terminal,please use: tail -F/tmp/ndk-toolchain/build-CtAG7s/log.txt
Download sources fromandroid.git.kernel.org
Using git clone prefix:git://android.git.kernel.org/toolchain
downloading sources fortoolchain/binutils
downloading sources fortoolchain/build
downloading sources fortoolchain/gcc
downloading sources fortoolchain/gdb
downloading sources fortoolchain/gmp
downloading sources fortoolchain/gold
downloading sources fortoolchain/mpfr
Patching toolchainsources
Toolchain sources downloaded andcopied to /tmp/ndk-toolchain/build-CtAG7s/src
Cleaning up...
Done.
Building arm-eabi-4.4.0 toolchain...(this can be long)


ERROR: Could bot build arm-eabi-4.4.0toolchain!
xxxx-desktop:~/bin/u/android-ndk-r5$

Now change to native-activity folderand call ndk-build for successfullibnative-activity.so

xxx-desktop:~/bin/u/android-ndk-r5/samples/native-activity$ndk-build
Compile thumb : native-activity<= main.c
Compile thumb :android_native_app_glue <=android_native_app_glue.c
StaticLibrary :libandroid_native_app_glue.a
SharedLibrary :libnative-activity.so
Install : libnative-activity.so=> libs/armeabi/libnative-activity.so

 

 

undefined reference toerror解决方法

1 没有指定对应的库(.o/.a/.so

使用了库中定义的实体,但没有指定库(-lXXX)或者没有指定库路径(-LYYY),会导致该错误,

 

2 连接库参数的顺序不对

在默认情况下,对于-l 使用库的要求是越是基础的库越要写在后面,无论是静态还动态

 

3 gcc/ld 版本不匹配

gcc/ld的版本的兼容性问题,由于gcc2 到gcc3大版本的兼容性存在问题(其实gcc3.2到3.4也一定程度上存在这样的问题) 当在高版本机器上使用低版本的机器就会导致这样的错误, 这个问题比较常见在32位的环境上,另外就在32位环境不小心使用了64位的库或者反过来64位环境使用了32位的库.

 

4 C/C++相互依赖和链接

gcc和g++编译结果的混用需要保证能够extern "C" 两边都可以使用的接口,在我们的64位环境中gcc链接g++的库还需要加上-lstdc++,具体见前文对于混合编译的说明

 

5 运行期报错

这个问题基本上是由于程序使用了dlopen方式载入.so, 但.so没有把所有需要的库都链接上,具体参加上文中对于静态库和动态库混合使用的说明

工作积累之NDK编译STL

方法:

1.jni目录下新建Application.mk;加入APP_STL := stlport_static  右边的值还可以换成下面几个:

system -使用默认最小的C++运行库,这样生成的应用体积小,内存占用小,但部分功能将无法支持

stlport_static -使用STLport作为静态库,这项是Android开发网极力推荐的

stlport_shared - STLport作为动态库,这个可能产生兼容性和部分低版本的Android固件,目前不推荐使用。

gnustl_static  - 使用 GNU libstdc++ 作为静态库

默认情况下STLPORT是不支持C++异常处理和RTTI,所以不要出现-fexceptions-frtti ,如果真的需要可以使用gnustl_static来支持标准C++的特性,但生成的文件体积会偏大,运行效率会低一些。

支持C++异常处理,在Application.mk中加入LOCAL_CPPFLAGS += -fexceptions这句,同理支持RTTI,则加入LOCAL_CPPFLAGS += -frtti,这里再次提醒大家,第二条说的使用gnustl静态库,而不是stlport

 强制重新编译STLPort,在Application.mk中加入STLPORT_FORCE_REBUILD := true可以强制重新编译STLPort源码,由于一些原因可能自己需要修改下STLPort库,一般普通的开发者无需使用此项

2.在要使用STLcpp文件中包含相关的头文件,并且使用usingnamespace std;


原文地址:http://blog.sina.com.cn/s/blog_727bd1560101gmdr.html

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值