`
Jason_gang
  • 浏览: 16724 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

mkfile

阅读更多

                            
                                                           译者:ChrixLee 2010.5.12
       
序言:
-------------
此文档旨在描述Android.mk文件的语法,Android.mk文件为Android NDK(原生开发)描述了你C/C++源文件。
为了明白下面的内容,你必须已经阅读了docs/OVERVIEW.TXT的内容,它解释了Android.mk文件扮演的角色
和用途。
概述:
---------

写一个Android.mk文件是为了向生成系统描述你的源代码。更明确的说:
- 这个文件实际上是GNU Make文件的一小片段,它会被生成系统解析一次或多次。
因此,你应该在Android.mk里尽量少地声明变量,而不要误以为在解析的过程中
没有任何东西被定义。

- 该文件的语法的明的人为了让你能将你的源代码组织为组件(module).一个组件指的是下面的一项:
     - 一个静态库(static library)
     - 一个共享库(shared library)
  
只有一个动态库会被安装/拷贝至你的application package中。但是静态库可用来
生成动态库。

你可以在每个Android.mk文件定义一个或多个组件,并且我可以在几个组件中使用
相同的源文件。

- 生成系统为你处理了一些琐碎之事。比如,在你的Android.mk里,你不须要列出头文件或
列出生成的文件之间的明确认依赖关系。NDK生成系统会为你自动生成。

这也意味着,当更新至新的NDK版本时,你能得到新的工具链/平台支持(toolchain/platform support)
的好处,而无须修改你的android.mk文件。

需要注意的是,此语法与完全开源的Android平台的Android.mk文件的语法非常相似,但使用它们的
生成系统的实现不同,这个为了让开发者能更容易的复用“外部”库的源代码。

简单例子:
---------------

在详细描述语法之前,让我们探究一个简单的“hello JNI”例子,它的文件位于:
    apps/hello-jni/projec
这里,我们能看到:
- 放有Java源文件的src文件夹。
- 放有本地源文件,即jni/hello-jni.c的jni文件夹。
    这个源文件实现一个简单的共享库。这个共享库有一个本地方法(native method),它将一个字符串
    返回给虚拟机应用(著:即Java层应用程序)
- jni/Anroid.mk文件为NDK生成系统描述了这个共享库。它的内容为:
   ---------- 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 ------------------
现在,让我们逐行解释:
LOCAL_PATH := $(call my-dir)

每个Android.mk文件都必须以定义LOCAL_PATH变量开始。其目的是为了定位源文件的位置。在这个例子,
生成系统提供的宏函数(macro function)‘my-dir'用来返回当前路径(即放有Android.mk文件的文件夹)

include $(CLEAR_VARS)

CLEAR_VARS变量是生成系统提供的,它指向一个特殊的GNU Makefile.这个Makefile将会为你自动清除
许多名为LOCAL_XXX的变量(比如:LOCAL_MODULE,LOCAL_SRC_FILES,LOCAL_STATIC_LIBRARIES,等),
但LOCAL_PATH是例外,它不会被清除。这些变量的清除是必须的,因为所有的控制文件是在单一的GNU make
执行环境中解析的,在这里所有的变量都是全局的。

LOCAL_MODULE := hello-jni

为了在你的Android.mk文件标识每个组件,必须定义LOCAL_MODULE变量。这个名字必须要唯一的并且不能
包含空格。注意:生成系统会自动地为相应生成的文件加入前缀或后缀。换言之,一个名叫foo的共享库组件
会生成'libfoo.so'.
重要注意事项:
如果你把组件取名为‘libfoo',生成系统将不会加上‘lib'前缀,还是
生成libfoo.so。这是为了支持源于Android平台源代码的Android.mk文件。

LOCAL_SRC_FILES := hello-jni.c

LOCAL_SRC_FILES变量必须包含一系列将被构建和组合成组件的C/C++源文件。注意:你
不需要列出头文件或include文件,因为生成系统会为你自动计算出源文件的依赖关系。
仅仅列出那些将直接传给编译器的源文件足矣。

注意,默认的C++源文件的扩展名是‘.cpp'。但你可以通过定义LOCAL_DEFAULT_EXTENSION
来指定一个扩展名。别忘了扩展名开始的那一点(比如,‘.cxx’,能行,但‘cxx'不行)。

include $(BUILD_SHARED_LIBRARY)

生成系统提供的BUIL_SHARED_LIBRARY变量指向一个GNU Makefile脚本,这个脚本主管
收集在最近的一次#include $(CLEAR_VARS)(著:即清除'本地'变量)之后你所定义的
LOCAL_XXX变量的信息,并决定生成什么,如何准确的生成。BUILD_STATIC_LIBRARY可
生成一个静态库。

在apps文件下有一些复杂点的例子,它带有注释的Android.mk文件以供你学习。

参考:
-----------
以下列出你在Android.mk里应该依赖或定义的变量。你能定义其它变量,但下列的变量名是
由NDK生成系统保留的。
- 以LOCAL_ 开头的变量名 (比如,LOCAL_MODULE)
- 以PRIVATE_ ,NDK_ 或 APP_ (内部使用)开头的量名
_ 小写字母变量名(内部使用,如 my-dir).

如果你需要在Android.mk里定义方便自己使用的变量名,我们建议使用MY_ 前缀,
如下面一个简单例子:
   ---------- cut here ------------------
    MY_SOURCES := foo.c
    ifneq ($(MY_CONFIG_BAR),)
      MY_SOURCES += bar.c
    endif
    LOCAL_SRC_FILES += $(MY_SOURCES)
   ---------- cut here ------------------
 
So, here we go:

NDK提供的变量:
- - - - - - - - - - - - - -
下列的这些GNU Make变量是在你的Android.mk被解析之前,就被生成系统事先定义
的了.注意,在某些情况下,NDK可能会多次解析你的Android.mk,每次对其中一些变量的
定义不同。
CLEAR_VARS
    指向一个生成脚本,这个脚本取消几乎所有LOCAL_XXX变量的定义(译者注:除了LOCAL_PATH)。
    在开始描述一个新的组件之前,你必须include这个脚本,e.g.:
   
      include $(CLEAR_VARS)
   
   
BUILD_SHARED_LIBRARY
   指向一个生成脚本,这个脚本通过LOCAL_XXX变量收集关于组件的信息,并决定如何
   根据你列出来的源文件生成目标分享库。注意,在include这个脚本文件之前你必须
   至少已经定义了LOCAL_MODULE和LOCAL_SRC_FILES。用法举例:
     include $(BUILD_SHARED_LIBRARY)
    
   注意,这会生成一个名为 lib$(LOCAL_MODULE).so的文件。(译者注:$(BUILD_SHARED_MODULE)为文件名)

   
BUILD_STATIC_LIBRARY
    与BUILD_SHARED_LIBRARY类似,但用来生成目标静态库。静态库不会被拷贝至你的
    project/packages文件夹下,但可用来生成分享库(参考 LOCAL_STATIC_LIBRARIES
    和LOCAL_STATIC_WHOLE_LIBRARIES,将在后面描述)
    用法示例:

       include $(BUILD_STATIC_LIBRARY)
    注意,这会生成一个方件名叫lib$(LOCAL_MODULE).a
  
TARGET_ARCH
   目标CPU的名字,在完整的Android开源代码的生成中指定。对于基于ARM兼容的CPU,
   它被指定为'arm',与CPU架构的修订无关。
   
  
TARGET_PLATFORM
   当解析该Android.mk文件时用它来指定Andoid目标平台的名称。譬如,'android-3'与
   Android 1.5系统镜像相对应。若要了解所有的平台名称及其相应的Android系统镜像,
   请阅读docs/STABLE-APIS.TXT
   
TARGET_ARCH_ABI
    当解析该Android.mk时,CPU+ABI的名称。目前只有一个值。
    (译者注:ABI,Application Binary Interface,二进制应用程序接口)
       armeabi    For Armv5TE
      
       armeabi    指定Armv5TE
         
    注意:到NDK 1.6_r1为止,仅简单的定义这个变量为'arm'。但为了更好地配合
    Android平台的内部使用,该值已重定义。
   
    关于ABI与相应的兼容问题更多详情,请阅读docs/CPU-ARCH-ABIS.TXT
    未来的NDK版本将会引入其它的平台的ABI并会有不同的名称。注意,所有基于ARM的ABI会
    使TARGET_ARCH定义为'arm',但可能拥有不同的TARGET_ARCH_ABI
  
   
TARGET_ABI  
    目标平台与abi的连接,它实际上被定义为 $(TARGET_PLATFORM)-$(TARGET_ARCH_ABI),
    当你想在一个真实的装置上测试特定的目标系统镜像时,它就很有用了。
   
    默认下,它的值为'android-3-armeabi'
   
    (在Android NDK 1.6_r1及之前的版本,它的默认值为'android-3-arm')
   
  
NDK提供的宏函数:
----------------------------
以下是一些GNU Make的宏‘函数’,必须通过这样的形式调用:'$(call <function>)'。
函数返回文本信息。
       
my-dir
    返回放置当前Android.mk的文件夹相对于NDK生成系统根目录的路径。可用来
    在Android.mk的开始处定义LOCAL_PATH的值:
   
       LOCAL_PATH := $(call my-dir)     
       
all-subdir-makefiles
      返回‘my-dir’子目录下的所有Android.mk。比如,代码的结构如下:
     sources/foo/Android.mk
        sources/foo/lib1/Android.mk
        sources/foo/lib2/Android.mk
       
    如果sources/foo/Android.mk里有这样一行:
       
        include $(call all-subdir-makefiles)
   
    那么,它将会自动地includesources/foo/lib1/Android.mk和sources/foo/lib2/Android.mk
   
    这个函数能将深层嵌套的代码文件夹提供给生成系统。注意,默认情况下,NDK仅在
    source/*/Android.mk里寻找文件。
   
this-makefile
     返回当前Makefile(译者注:指的应该是GNU Makefile)的路径(即,这个函数是在哪里调用的)

parent-makefile
     返回在列入树(inclusion tree)中的父makefile的路径。
    即,包含当前makefile的那个makefile的路径。 

grand-parent-makefile
    猜猜看...(译者注:原文为Guess what...)

组件描述相关的变量:
- - - - - - - - - -

以下的变量是用来向生成系统描述你的组件的。你应该在'include $(CLEAR_VARS)'
和'include $(BUILD_XXXXX)'之间定义其中的一些变量。正如在前面所说的,$(CLEAR_VARS)
是一个将会取消所有这些变量的脚本,除非在对变量的描述时有显式的说明。
   
LOCAL_PATH
   这个变量用来设置当前文件的路径。你必须在Android.mk的开始处定义它,比如:
    
    LOCAL_PATH := $(call my-dir)
   
   这个变量不会被$(CLEAR_VARS)消除,所以每个Android.mk仅需一个定义(以防你在
   同一个文件里定义几个组件)。
 
   
LOCAL_MODULE
   定义组件的名称。对于所有的组件名,它必须是唯一,且不能包含空格。
   在include $(BUILD_XXX)之前你必须定义它。
 
   这个组件名决定生成的文件(译者注:即库名)。比如,lib<foo>,即这个组件的名称
   为<foo>。但是在你的NDK生成文件(不管是Android.mk还是Application.mk)中
   你只能通过‘正常’的名称(如,<foo>)来引用其它的组件。
 
         
LOCAL_SRC_FILES
   用它来定义所有用来生成组件的源文件。仅须列出传给编译器的文件,因为
   生成系统会自动地计算它们的相互依赖关系。
 
   注意,所有文件名都是相对于LOCAL_PATH的,你可以用到路径组件(path component)
   如:
     LOCAL_SRC_FILES := foo.c \ (译者注:‘\’为连接符)
                         toto/bar.c
       
LOCAL_CPP_EXTENSION
   这是一个可选的变量,可用它来指明C++源文件的扩展名。默认情况下是'.cpp',
   但你可以改变它。比如:
   
     LOCAL_CPP_EXTENSION := .cxx
     
   
LOCAL_C_INCLUDES
   一个相对于相对于NDK*根*目录可选的路径名单,当编译所有的源文件(C,C++和汇编)时,
   它将被添加进include搜索路径。例如:
  
      LOCAL_C_INCLUDES := sources/foo
 
     或者甚至:
    
      LOCAL_C_INCLUDES := $(LOCAL_PATH)/../foo

LOCAL_CFLAGS
    一个可选的编译标记集,在生成C与C++源文件时,将解析它。
   
    对指定额外的宏定义或编译选项很有用。
              
    重要:不要试图改变你Android.mk里的optimization/debuggin level,通过
          在你的Android.mk里指定合适的信息,它将被自动处理,并使NDK生成
          调试时可用的有用的数据文件。
         
    注意:在android-ndk-1.5_r1,相应的标记(flags)只适用于C源文件,对C++
        源文件并不适用。为了适用于完整的Android生成系统的特性,已作了修
        正。(现在,你可以使用LOCAL_CPPFLAGS为C++文件指定标记)

LOCAL_CXXFLAGS
    LOCAL_CPPFLAGS的别名。注意,不建议使用这个变量,因为在未来的NDK版本中,
    它可能会消失。

LOCAL_CPPFLAGS
     一个可选的编译标记集,*仅*在生成C++源文件时解析它。在编译器的命令行里
     它将在LOCAL_CFLAGS之后出现。
    注意:在android-ndk-1.5_r1,相应的标记(flags)适用于C与C++源文件。
        为了适用于完整的Android生成系统的特性,已作了修
        正。(现在,你可以使用LOCAL_CFLAGS为C和C++源文件指定标记)

LOCAL_STATIC_LIBRARIES
    一份static libraries组件的名单(以BUILD_STATIC_LIBRARY的方式生成),它将被
    连接到欲生成的组件上。这仅在生成shared library组件时有意义。(译者注:将指定
    的一个或多个static library module转化为一个shared library module)

LOCAL_SHARED_LIBRARIES
    一份该组件在运行期依赖于它的shared libraries *组件*。在连接时间(link time)里
    与及为该生成的文件嵌入相应的信息都要用到它。
    注意,它并不将这份组件名单添加入生成图表(build graph)。即,在你的Android.mk
    里,你仍应该将它们加入到你的应用程序要求的组件。

LOCAL_LDLIBS
    一份能在生成你的组件时用到的额外的连接器标记(linkerflags)的名单。在传递
    有“-l”前缀的特殊系统库的名称时很有用。比如,下面的语句会告诉连接器在装载
    时间(load time)里生成连接到/system/lib/libz.so的组件。
      LOCAL_LDLIBS := -lz
    若想知道在这个NDK版本可以连接哪些暴露的系统库(exposed system libraries),
    请参见docs/STABLE-APIS。

LOCAL_ALLOW_UNDEFINED_SYMBOLS
    缺省值情况下,当尝试生成一个shared library遇到没有定义的引用时,会导致“undefined
    symbol”error。这对在你的源代码里捕捉bugs有很大的帮助。
   
    但是,因为一些原因你须要disable这个检查,将这个变量设置为'true’。注意,相应
    的shared library可能在运行期装载失败。

LOCAL_ARM_MODE
    缺省值情况下,ARM目标二进制将会以‘thumb’模式生成,这时每个指令都是16-bit宽的。
    如果你想强迫组件的object文件以‘arm’(32位的指令)的模式生成,你可以将这个变量
    定义为'arm'。即:
      LOCAL_ARM_MODE := arm
    注意,你也可以通过将‘.arm’后缀添加到源文件名字的后面指示生成系统将指定的
    源文件以arm模式生成。例如:
   
       LOCAL_SRC_FILES := foo.c bar.c.arm
    告诉生成系统总是以arm模式编译‘bar.c’,但根据LOCAL_ARM_MODE的值生成foo.c
    注意:在你的Application.mk里将APP_OPTIM设置为'debug',这也会强迫生成ARM二进制
    代码。这是因为工具链的调度器有bugs,它对thumb码的处理不是很好。
分享到:
评论

相关推荐

    Mac终端创建文件教程.docx

    mkfile 命令的格式为:mkfile -n size[b|k|m|g] 文件名。例如,要创建一个 1GB 容量的文件,只需使用以下命令:mkfile -n 1g ~/Desktop/大容量测试文件。 然而,mkfile 命令也存在不足的地方,因为这条命令只支持 ...

    mpich2-1.5.tar.gz

    cd /home/yonghu mkdir mpiexe ,创建完成后,就执行 ./configure -prefix=/home/yonghu/mpiexe 就是配置我们的安装目录,这里同样会等待一段时间,等成功执行后,在mpich2-1.5下会生成mkfile文件,这里我们执行的...

    mac命令行终端怎么创建文件 mac命令行终端创建文件教程.docx

    mkfile 命令是一个简单且快速的命令,可以帮助用户创建大容量空白文件。该命令的格式如下: mkfile -n size[b|k|m|g] 文件名 其中,size 代表文件的大小,b 代表字节,k 代表千字节,m 代表兆字节,g 代表千兆字节...

    操作系统——简单文件系统模拟实验

    (1)新建文件,格式:mkfile filename filecontent filename:文件名 filecontent:文件内容(字符) 实现按FAT格式写FAT表和目录表,以及文件内容。 (2)列出文件,格式:dir 列出目录里所有的文件信息和...

    山东大学数据结构与算法课程设计实验模拟文件目录系统(有详细注释)源代码和操作文件

    当前目录变为当前目录的父目录 ④ cd str当前目录变为 str 所表示路径的目录 ⑤ mkdir str 在(当前目录下)创建一个子目录(名为 str)⑥ mkfile str ——在(当前目录下)创建一个文件(名为 str) ⑦ delete str删除(当前...

    IBM AIX5L3命令详细解释

    例如,`mkfile 100m /tmp/testfile` 将在 `/tmp` 目录下创建一个100MB大小的文件,名为 `testfile`。 #### 8. `smitty` `smitty` 是AIX系统中的图形化管理工具,提供了一个用户友好的界面来执行系统管理任务,如...

    一个c++转c的工具(cfront源码)

    2. `mkfile`:通常用于生成Makefile,这是一个自动化构建工具,可以简化编译和链接过程。 3. `munch`:可能是一个词法分析器或者预处理器,用于处理C++源代码中的宏和特殊符号。 4. `cc`:通常是C编译器的别名,可能...

    solaris 常用命令 100例

    9. **mkfile**:`mkfile` 创建指定大小的文件,如`mkfile 1k 1.txt` 创建1KB的文件1.txt。 10. **chmod**:`chmod` 修改文件或目录的权限。如`chmod 755 file` 设置权限为rwxr-xr-x,`-r` 递归应用权限,`u+x` 添加...

    模拟文件管理和进程调度的仿真操作系统设计.doc

    例如,`mkdir`用于创建目录,`mkfile`用于创建常规文件,两者都需要提供上级目录地址和文件名。函数`mkfile`首先检查同名文件是否存在,若不存在则创建新文件节点并插入目录中。`rmdir`和`rmfile`用于删除目录和文件...

    Linux运维常用命令.doc

    * mv mytouch mkfile * mv mkfile public_html/ rename 命令 rename 命令用于批量修改文件名。格式为:rename [旧名称] [新名称] [文件名] 示例: * rename jpg gif *.jpg which 命令 which 命令用于搜索命令...

    10.0 init.rc中data下创建文件节点失败.zip

    - `mkfile` 命令用于创建文件,`/data/path/to/file` 是文件路径,`0644` 是权限设置(rw-r--r--),`system system` 是所有者和组,`"initial content"` 是文件的初始内容。 然而,如果在Android 10.0的`init.rc` ...

    oracle数据库安装教程.doc

    * 使用mkfile命令创建临时交换空间 * 使用swap命令设置临时交换空间 * 使用swap命令查看交换空间的状态 七、安装 Oracle 数据库 * 使用cd命令进入安装目录 * 使用./runInstaller命令启动安装程序 八、常见错误...

    ffmpeg_android_mkfiles

    "ffmpeg_android_mkfiles"这个主题主要是关于在Android平台上使用FFmpeg时涉及的构建文件,即mkfile。在Android开发中,由于系统安全性和兼容性的限制,直接使用FFmpeg的原生库可能较为复杂,因此需要特别的编译和...

    Solaris9下安装Oracle9操作指南.doc

    mkfile 1000m /tmpswap swap –a /tmpswap swap -l 四、安装 Oracle 9 在安装 Oracle 9 之前,需要准备好所有的参数和配置。按照 Oracle 官方提供的安装手册和本指南的步骤来安装 Oracle 9。安装完成后,需要进行...

    solaris速查手册

    动态创建Swap文件,例如`mkfile 100m /home/swapfile`创建一个100MB的文件,然后通过`/usr/sbin/swap -a /path/filename`激活,`/usr/sbin/swap -l`验证,`/usr/sbin/swap -d /path/filename`取消,最后`rm -rf /...

    重庆大学通院数字图像处理实验五

    6. **函数编写**:`lvbo.m`和`mkfile.m`可能是实验中自定义的辅助函数,它们可能实现了特定的图像处理功能或者用于数据管理和文件操作。 7. **图像格式**:实验中使用的`.tif`和`.png`都是常见的图像文件格式,`....

    solaris迅速查找手册

    - 创建一个指定大小的SWAP文件,例如:`mkfile 100m /home/swapfile`,这将创建一个100MB的SWAP文件。 - 激活SWAP文件:`/usr/sbin/swap -a /path/filename`。 - 验证SWAP文件是否成功激活:`/usr/sbin/swap -l`...

    solaris10文件系统简介.doc

    - SWAPFS:由mkfile和swap命令创建的交换区使用的文件系统。 3. **基于磁盘的文件系统**:这是最常见的一类,包括: - UFS(Unix File System):Solaris的默认文件系统,支持日志记录功能,能够处理TB级别的大...

Global site tag (gtag.js) - Google Analytics