常见错误说明:
1、make:*** Norule specified and no make file found. Stop.
错误的原因估计是(cat :Linux命令,显示文件的内容):工程名与Aplication.mk中的APP_MOUDLES不一致。
2、make: *** Norule to make target
这个错误的主要原因是:编译C文件为最后的so库文件需要2个文件:Application.mk、Android.mk
MK文件如何设置,看了上面的图一目了然【详细的说明还是要去看文档】,以下几点需要注意:
·
这些在AndroidNDKzhong 都有“严格”规范的,在android-ndk的文档中都有详细说明。
·
3、make:***[XXXX]Errror
这个错误只要大家仔细看下就明白是C的编译错误,C代码无法编译。
如何编写C文件【nativefile】中的函数说明?从Java SourceFile推导出C/C++ NativeFile,可以参考以下4步:
1)
2)
JNITest.jva编译后的文件JNITest.class、JNITest.h,这个文件就是我们需要的头文件,如下图所示:
3)
从上面的例子发现,函数名分为4部分:
按照上面的规则修改就可以了。
4)
这样我们就从Java SourceFile一步一步的得到C/C++ NativeFile。
4、程序运行时崩溃,这个时候我们需要注意以下几个问题:
库文件的加载:
编译后的so文件是libJNITest.so,而实际加载的库文件名是:JNITest【这实际上是Unix的“规范”,在AndroidNDK的文档OVERVIEW.txt中有详细说明】;还有Linux系统区分大小写的,所以如果上面的代码中,将加载的库文件名写成jnitest,也会导致运行崩溃。
解决NDK出现error:exception handling disabled, use -fexceptions toenable的问题
问题来源:
UDT的android平台移植过程中,在用NDK编译buffer.cpp文件时出现error: exception handling disabled, use -fexceptions toenable。
问题解决:
此问题的出现是编译器的异常异常捕获被禁用了,需要在Android.mk文件中开启。在Android.mk文件中添加:LOCAL_CPPFLAGS += -fexceptions就可以了。或者在Application.mk文件中添加APP_CPPFLAGS += -fexceptions
也是可以的。
补充:
Android NDK r5对C++的支持情况
android平台提供了一个最小化的C++运行库(/system/lib/libstdc++)以及与之对应的头文件。
1、C++的异常支持:
从NDK r5就开始NDK的工具链就开始支持了C++的异常控制,只不过为了通用性的原因,所有的C++原文件被编译的时候都是默认的是-fno-exceptions,即不不支持异常控制的。
使用-fexceptions标记可以开启异常控制。所以你只需要在你的每个模块的Android.mk中添加LOCAL_CPPFLAGS += -fexceptions就可以了。
更简单的是,在你的Application.mk文件中添加APP_CPPFLAGS += -fexceptions,这种配置会自动应用到你工程的所有模块当中。
注意:
已被废弃的"arm-eabi-4.4.0"工具链提供的向后兼容的NDK是不支持异常的。
2、RTTI support:
从NDK r5开始,NDK工具链也开始支持C++ RTTI(Runtime 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没有把所有需要的库都链接上,具体参加上文中对于静态库和动态库混合使用的说明
方法:
1.在jni目录下新建Application.mk;加入APP_STL :=
system
stlport_static
stlport_shared
gnustl_static
默认情况下STLPORT是不支持C++异常处理和RTTI,所以不要出现-fexceptions或-frtti ,如果真的需要可以使用gnustl_static来支持标准C++的特性,但生成的文件体积会偏大,运行效率会低一些。
支持C++异常处理,在Application.mk中加入LOCAL_CPPFLAGS += -fexceptions这句,同理支持RTTI,则加入LOCAL_CPPFLAGS += -frtti,这里再次提醒大家,第二条说的使用gnustl静态库,而不是stlport。
2.在要使用STL的cpp文件中包含相关的头文件,并且使用usingnamespace std;
原文地址:http://blog.sina.com.cn/s/blog_727bd1560101gmdr.html