您现在的位置:首页 > 博客 > Android开发 > 正文
Android NDK 入门
http://www.drovik.com/      2012-10-15 10:33:29      来源:Steersman原创      点击:
Android NDK 入门:********************************************  ndk-build --> rebuild required machine code. ndk-build clean --> clean all generated binaries. ndk-build NDK_DEBUG=1 --> generate debuggable native code. ndk-build V=1 --> launch build, displaying build commands. ndk-build -B --> force a complete rebuild. ndk-build -B V=1 --> force a complete rebuild and display build commands. ndk-build NDK_LOG=1 --> display internal NDK log messages (used for debugging the NDK itself). ndk-build NDK_DEBUG=1 --> force a debuggable build (see below) ndk-build NDK_DEBUG=0 --> force a release build (see below) ndk-build NDK_APP_APPLICATION_MK=<file> --> rebuild, using a specific Application.mk pointed to by the NDK_APP_APPLICATION_MK command-line variable. ndk-build -C <project> --> build the native code for the project path located at <project>. Useful if you don't want to 'cd' to it in your terminal.1、强制NDK编译显示所有命令:    ndk-build V=12、强制NDK重新编译所有资源:    ndk-build -B3、不进入工作目录编译程序:    ndk-build -C <project-path>4、在工程的非jni目录先建立Application.mk文件:    在工程的其他目录编译Application.mk文件    ndk-build NDK_APPLICATION_MK=/path/to/your/Application.mk5、How to properly add include directories to your module declarationIf you define several modules, it is common to need to include one module's header while compiling another one. For example, consider the following example: $PROJECT/jni/foo/ Android.mk foo.h foo.c $PROJECT/jni/bar/ Android.mk bar.c Where the 'bar.c' uses '#include <foo.h>'. You will need to add the path to the 'foo' module in jni/bar/Android.mk to build it properly.The correct line is instead: LOCAL_C_INCLUDES := $(LOCAL_PATH)/../fooIn case you absolutely need it, you can also use NDK_APP_PROJECT_PATH to point to your project directory: LOCAL_C_INCLUDES := $(NDK_APP_PROJECT_PATH)/jni/foo However, we don't recommend using this, paths relative to $(LOCAL_PATH) being better.********************************************Android.mk file syntax specification(Android.mk文件的语法规范)The file syntax is designed to allow you to group your sources into 'modules'. A module is one of the following: - a static library - a shared libraryYou can define one or more modules in each Android.mk file, and you can use the same source file in several modules.Before describing the syntax in details, let's consider the simple "hello JNI" example, i.e. the files under: apps/hello-jni/projectHere, we can see: - The 'src' directory containing the Java sources for the sample Android project. - The 'jni' directory containing the native source for the sample, i.e. 'jni/hello-jni.c' - The 'jni/Android.mk' file that describes the shared library to the NDK build system. Its content is: ---------- cut here ------------------ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := hello-jni LOCAL_SRC_FILES := hello-jni.c include $(BUILD_SHARED_LIBRARY) ---------- cut here ------------------Now, let's explain these lines: LOCAL_PATH := $(call my-dir)the macro function 'my-dir', provided by the build system, is used to return the path of the current directory (i.e. the directory containing the Android.mk file itself).    include $(CLEAR_VARS)The CLEAR_VARS variable is provided by the build system and points to a special GNU Makefile that will clear many LOCAL_XXX variables for you (e.g. LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES, etc...), with the exception of LOCAL_PATH. This is needed because all build control files are parsed in a single GNU Make execution context where all variables are global.    LOCAL_MODULE := hello-jniThe LOCAL_MODULE variable must be defined to identify each module you describe in your Android.mk. The name must be *unique* and not contain any spaces. Note that the build system will automatically add proper prefix and suffix to the corresponding generated file. In other words, a shared library module named 'foo' will generate 'libfoo.so'IMPORTANT NOTE: If you name your module 'libfoo', the build system will not add another 'lib' prefix and will generate libfoo.so as well. This is to support Android.mk files that originate from the Android platform sources, would you need to use these.    LOCAL_SRC_FILES := hello-jni.cThe LOCAL_SRC_FILES variables must contain a list of C and/or C++ source files that will be built and assembled into a module. Note that you should not list header and included files here, because the build system will compute dependencies automatically for you; just list the source files that will be passed directly to a compiler, and you should be good.Note that the default extension for C++ source files is '.cpp'. It is however possible to specify a different one by defining the variable LOCAL_CPP_EXTENSION. Don't forget the initial dot (i.e. '.cxx' will work, but not 'cxx').    include $(BUILD_SHARED_LIBRARY)The BUILD_SHARED_LIBRARY is a variable provided by the build system that points to a GNU Makefile script that is in charge of collecting all the information you defined in LOCAL_XXX variables since the latest 'include $(CLEAR_VARS)' and determine what to build, and how to do it exactly. There is also BUILD_STATIC_LIBRARY to generate a static library.This is the list of variables you should either rely on or define in an Android.mk. You can define other variables for your own usage, but the NDK build system reserves the following variable names: - names that begin with LOCAL_ (e.g. LOCAL_MODULE) - names that begin with PRIVATE_, NDK_ or APP_ (used internally) - lower-case names (used internally, e.g. 'my-dir')If you need to define your own convenience variables in an Android.mk file, we recommend using the MY_ prefix, for a trivial example: ---------- cut here ------------------ MY_SOURCES := foo.c ifneq ($(MY_CONFIG_BAR),) MY_SOURCES += bar.c endif LOCAL_SRC_FILES += $(MY_SOURCES) ---------- cut here ------------------NDK-provided variables (NDK提供的变量)CLEAR_VARSYou must include the script before starting a new module, e.g.: include $(CLEAR_VARS)BUILD_SHARED_LIBRARY Note that you must have LOCAL_MODULE and LOCAL_SRC_FILES defined, at a minimum before including this file. Example usage: include $(BUILD_SHARED_LIBRARY) note that this will generate a file named lib$(LOCAL_MODULE).soBUILD_STATIC_LIBRARYStatic libraries are not copied into your project/packages but can be used to build shared libraries (see LOCAL_STATIC_LIBRARIES and LOCAL_WHOLE_STATIC_LIBRARIES described below). Example usage: include $(BUILD_STATIC_LIBRARY)    Note that this will generate a file named lib$(LOCAL_MODULE).aPREBUILT_SHARED_LIBRARY Points to a build script used to specify a prebuilt shared library. Unlike BUILD_SHARED_LIBRARY and BUILD_STATIC_LIBRARY, the value of LOCAL_SRC_FILES must be a single path to a prebuilt shared library (e.g. foo/libfoo.so), instead of a source file.PREBUILT_STATIC_LIBRARY This is the same as PREBUILT_SHARED_LIBRARY, but for a static library file instead. See docs/PREBUILTS.html for more.TARGET_ARCH_ABI Name of the target CPU+ABI when this Android.mk is parsed. Two values are supported at the moment: armeabi For ARMv5TE armeabi-v7aNDK-provided function macros(NDK原生开发工具包提供的宏)my-dirReturns the path of the last included Makefile, which typically is the current Android.mk's directory. This is useful to define LOCAL_PATH at the start of your Android.mk as with: LOCAL_PATH := $(call my-dir)IMPORTANT NOTE: Due to the way GNU Make works, this really returns the path of the *last* *included* *Makefile* during the parsing of build scripts. Do not call my-dir after including another file.For example, consider the following example: LOCAL_PATH := $(call my-dir) ... declare one module include $(LOCAL_PATH)/foo/Android.mk LOCAL_PATH := $(call my-dir) ... declare another module The problem here is that the second call to 'my-dir' will define LOCAL_PATH to $PATH/foo instead of $PATH, due to the include that was performed before that. For this reason, it's better to put additional includes after everything else in an Android.mk, as in: LOCAL_PATH := $(call my-dir) ... declare one module LOCAL_PATH := $(call my-dir) ... declare another module # extra includes at the end of the Android.mk include $(LOCAL_PATH)/foo/Android.mk If this is not convenient, save the value of the first my-dir call into another variable, for example: MY_LOCAL_PATH := $(call my-dir) LOCAL_PATH := $(MY_LOCAL_PATH) ... declare one module include $(LOCAL_PATH)/foo/Android.mk LOCAL_PATH := $(MY_LOCAL_PATH) ... declare another moduleall-subdir-makefiles Returns a list of Android.mk located in all sub-directories of the current 'my-dir' path. For example, consider the following hierarchy: sources/foo/Android.mk sources/foo/lib1/Android.mk sources/foo/lib2/Android.mk If sources/foo/Android.mk contains the single line: include $(call all-subdir-makefiles) Then it will include automatically sources/foo/lib1/Android.mk and sources/foo/lib2/Android.mkimport-moduleModule-description variablesLOCAL_MODULE_FILENAMEYou can override this by defining LOCAL_MODULE_FILENAME, For example: LOCAL_MODULE := foo-version-1 LOCAL_MODULE_FILENAME := libfooLOCAL_SRC_FILESNote that source files names are all relative to LOCAL_PATH and you can use path components, e.g.: LOCAL_SRC_FILES := foo.c \ toto/bar.c NOTE: Always use Unix-style forward slashes (/) in build files. Windows-style back-slashes will not be handled properly.LOCAL_CPP_EXTENSIONThe default is '.cpp' but you can change it. For example: LOCAL_CPP_EXTENSION := .cxx Since NDK r7, you can list several extensions in this variable, as in: LOCAL_CPP_EXTENSION := .cxx .cpp .ccLOCAL_CPP_FEATURESThis is an optional variable that can be defined to indicate that your code relies on specific C++ features. To indicate that your code uses RTTI (RunTime Type Information), use the following: LOCAL_CPP_FEATURES := rtti To indicate that your code uses C++ exceptions, use: LOCAL_CPP_FEATURES := exceptions You can also use both of them with (order is not important): LOCAL_CPP_FEATURES := rtti featuresLOCAL_C_INCLUDES An optional list of paths, relative to the NDK *root* directory, which will be appended to the include search path when compiling all sources (C, C++ and Assembly). For example: LOCAL_C_INCLUDES := sources/foo Or even: LOCAL_C_INCLUDES := $(LOCAL_PATH)/../foo These are placed before any corresponding inclusion flag in LOCAL_CFLAGS / LOCAL_CPPFLAGSLOCAL_CFLAGSLOCAL_CXXFLAGSLOCAL_CPPFLAGSLOCAL_LDLIBS The list of additional linker flags to be used when building your module. This is useful to pass the name of specific system libraries with the "-l" prefix. For example, the following will tell the linker to generate a module that links to /system/lib/libz.so at load time: LOCAL_LDLIBS := -lzLOCAL_ALLOW_UNDEFINED_SYMBOLS By default, any undefined reference encountered when trying to build a shared library will result in an "undefined symbol" error. This is a great help to catch bugs in your source code. However, if for some reason you need to disable this check, set this variable to 'true'. Note that the corresponding shared library may fail to load at runtime.LOCAL_ARM_MODE By default, ARM target binaries will be generated in 'thumb' mode, where each instruction are 16-bit wide. You can define this variable to 'arm' if you want to force the generation of the module's object files in 'arm' (32-bit instructions) mode. E.g.: LOCAL_ARM_MODE := arm Note that you can also instruct the build system to only build specific sources in ARM mode by appending an '.arm' suffix to its source file name. For example, with: LOCAL_SRC_FILES := foo.c bar.c.arm
分享到:
发表评论(4)
1楼 荷兰网  发表于  2015-3-14 15:04:03
不错的文章,内容文风幽默. 荷兰网 http://www.zhongguohelanwang.com/
2楼 防火板  发表于  2015-4-23 1:21:47
不错的文章,内容无懈可击.禁止此消息:nolinkok@163.com 防火板 http://www.chinabomeiban.com/
3楼 365bet官网  发表于  2016-9-20 3:22:06
您好站长,我想转走您写的这篇文章内容,叨教您批准吗?我会保存原文出处的链接跟作者! 365bet官网 http://xxgc.hbust.com.cn
4楼 亚洲城娱乐  发表于  2016-9-20 14:19:27
过来求个友链 模板挺漂亮的 亚洲城娱乐 http://www.czhlcl.com/
姓名 *
评论内容 *
验证码 *图片看不清?点击重新得到验证码