Android编译环境本身比较复杂,并且不像普通的编译环境只有顶层目录下才有Makefile文件,而其他的每个Component(组件)都使用统一标准的Android.mk文件。不过这并不是我们熟悉的Makefile,而是经过Android自身编译系统处理的文件。所以说要真正理清楚其中的联系还比较复杂,不过这种方式的好处在于,编写一个新的Android.mk给Android增加一个新的Component会变得比较简单。为了使读者更加深入地理解在Linux环境下编译Android程序的方法,在接下来的内容中,将分别演示两种编译Android程序的方法。
1.编译Native C的helloworld模块
编译Java程序可以直接采用Eclipse的集成环境来完成,实现方法非常简单,在这里就不再重复了。接下来主要针对C/C++来说明,将通过一个例子来说明如何在Android中增加一个C程序的Hello World。
(1)在“$(YOUR_ANDROID)/development”目录下创建一个名为“hello”的目录,并用“$(YOUR_ANDROID)”指向Android源代码所在的目录。
(2)在目录“$(YOUR_ANDROID)/development/hello/”下编写一个名为“hello.c”的C语言文件,文件hello.c的代码如下。
(3)在目录“$(YOUR_ANDROID)/development/hello/”下编写Android.mk文件。这是Android Makefile的标准命名,不能更改。文件Android.mk的格式和内容可以参考其他已有的Android.mk文件的写法,针对helloworld程序的Android.mk文件内容如下。
LOCAL_SRC_FILES:用来指定源文件。
LOCAL_MODULE:指定要编译的模块的名字,在下一步编译时将会用到。
include$(BUILD_EXECUTABLE):表示要编译成一个可执行文件,如果想编译成动态库则可用BUILD_SHARED_LIBRARY,这些具体用法可以在“$(YOUR_ANDROID)/build/core/config.mk”查到。
(4)回到Android源代码顶层目录进行编译。
在此需要注意,“make helloworld”命令中的参数helloworld就是上面Android.mk文件中由LOCAL_MODULE指定的模块名。最终的编译结果如下。
(5)如果和上述编译结果相同,则编译后的可执行文件存放在如下目录:
这样通过“adb push”命令将它传送到模拟器上,再通过“adb shell”命令登录到模拟器终端后就可以执行了。
2.手工编译C模块
在前面讲解了通过标准的Android.mk文件来编译C模块的具体流程,其实可以直接运用gcc命令行来编译C程序,这样可以更好地了解Android编译环境的细节。具体流程如下。(www.daowen.com)
(1)在Android编译环境中,提供了“showcommands”选项来显示编译命令行,可以通过打开这个选项来查看一些编译时的细节。
(2)在具体操作之前,需要使用如下命令把前面的helloworld模块清除。
上面的“make clean-$(LOCAL_MODULE)”命令是Android编译环境提供的make clean方式。
(3)使用showcommands选项重新编译helloworld,具体命令如下。
从上述命令行可以看到,Android编译环境所用的交叉编译工具链如下:
其中参数“-I”和“-L”分别指定了所用的C库头文件和动态库文件路径分别是“bionic/libc/include”和“out/target/product/generic/obj/lib”,其他还包括很多编译选项以及“-D“所定义的预编译宏。
(4)此时就可以利用上面的编译命令来手工编译helloworld程序,首先手工删除上次编译得到的helloworld程序。
然后再用gcc编译,以生成目标文件。
如果此时与Android.mk编译参数进行比较,会发现上面主要减少了不必要的参数“-I”。
(5)接下来开始生成可执行文件。
在此需要特别注意的是参数“-Wl,-dynamic-linker,/system/bin/linker”,它指定了Android专用的动态链接器是“/system/bin/linker”,而不是平常使用的ld.so。
(6)最后可以使用命令file和readelf来查看生成的可执行程序。
这就是ARM格式的动态链接可执行文件,在运行时需要libc.so和libm.so动态库。当提示“not stripped”时表示它还没被STRIP(剥离)。嵌入式系统中为节省空间通常将编译完成的可执行文件或动态库进行剥离,即去掉其中多余的符号表信息。在前面“make helloworld showcommands”命令的最后我们也可以看到,Android编译环境中使用了“out/host/linux-x86/bin/soslim”工具进行剥离。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。