3.4.5 实践演练——演示两种编译Android程序的方法(1)
Android编译环境本身比较复杂,并且不像普通的编译环境那样只有顶层目录下才有Makefile文件,而其他每个component都使用统一的Android.mk. Android.mk文件。不过这并不是我们熟悉的Makefile,而是经过Android自身编译系统进行过很多处理。所以说要真正理清其中的联系还比较复杂,不过这种方式的好处在于,编写一个新的Android.mk给Android增加一个新的Component会较简单。为了使读者更加深入地理解在Linux环境下编译Android程序的方法,下面将分别演示两种编译Android程序的方法。
1.编译Native C(本地C程序)的helloworld模块
编译Java程序可以直接采用Eclipse的集成环境来完成,实现方法非常简单,在这里就不再重复了。接下来将主要针对C/C++进行说明,通过一个例子来讲解在Android 中增加一个C程序的Hello World的方法。
① 在$(YOUR_ANDROID)/development目录下创建一个名为hello的目录,并用$(YOUR_ANDROID)指向Android源代码所在的目录。
- # mkdir $(YOUR_ANDROID)/development/hello
② 在目录$(YOUR_ANDROID)/development/hello/下编写一个名为hello.c的C语言文件,文件hello.c的实现代码如下。
#include
int main()
{
printf("Hello World!\n");//输出Hello World
return 0;
}
③ 在目录$(YOUR_ANDROID)/development/hello/下编写Android.mk文件。这是Android Makefile的标准命名,不能更改。文件Android.mk的格式和内容可以参考其他已有的Android.mk文件的写法,针对helloworld程序的Android.mk文件内容如下。
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
hello.c
LOCAL_MODULE:=helloworld
include $(BUILD_EXECUTABLE)
上述各个内容的具体说明如下。
a.LOCAL_SRC_FILES。用来指定源文件。
b.LOCAL_MODULE。用来指定要编译的模块的名字,在下一步骤编译时将会用到。
c.include $(BUILD_EXECUTABLE)。表示要编译成一个可执行文件,如果想编译成动态库则可用BUILD_SHARED_LIBRARY,这些具体用法可以在$(YOUR_ANDROID)/build/core/config.mk查到。
④ 回到Android源代码顶层目录进行编译。
# cd $(YOUR_ANDROID) && make helloworld
在此需要注意,make helloworld中的目标名helloworld就是上面Android.mk文件中由LOCAL_MODULE指定的模块名。最终的编译结果如下。
target thumb C: helloworld<= development/hello/hello.c
target Executable: helloworld (out/target/product/generic/obj/EXECUTABLES/helloworld_ intermediates/LINKED/helloworld)
target Non-prelinked: helloworld (out/target/product/generic/symbols/system/bin/ helloworld)
target Strip: helloworld (out/target/product/generic/obj/EXECUTABLES/helloworld_ intermediates/helloworld)
Install: out/target/product/generic/system/bin/helloworld
⑤ 如果和上述编译结果相同,则编译后的可执行文件存放在如下目录。
out/target/product/generic/system/bin/helloworld
这样通过adb push将它传送到模拟器上,再通过adb shell登录到模拟器终端后就可以执行了。
2.手工编译C模块
在前面讲解了通过标准的Android.mk文件来编译C模块的具体流程,其实我们可以直接运用gcc命令行来编译C程序,这样可以更好地了解Android编译环境的细节。具体流程如下。
① 在Android编译环境中,提供了showcommands选项来显示编译命令行,我们可以通过打开这个选项来查看一些编译时的细节。
② 在具体操作之前需要使用如下命令把前面中的helloworld模块清除。
# make clean-helloworld
make clean-$(LOCAL_MODULE)命令是Android编译环境提供的make clean的方式。
③ 使用showcommands选项重新编译helloworld,具体命令如下。
# make helloworld showcommands
build/core/product_config.mk:229: WARNING: adding test OTA key
target thumb C: helloworld<= development/hello/hello.c
prebuilt/linux-x86/toolchain/arm-eabi-4.3.1/bin/arm-eabi-gcc -I system/core/include -I hardware/libhardware/include -I hardware/ril/include -I dalvik/libnativehelper/ include -I frameworks/base/include -I external/skia/include -I out/target/ product/generic/obj/include -I bionic/libc/arch-arm/include -I bionic/libc/include -I bionic/libstdc++/include -I bionic/libc/kernel/common -I bionic/libc/kernel/ arch-arm -I bionic/libm/include -I bionic/libm/include/arch/arm -I bionic/ libthread_db/include -I development/hello -I out/target/product/generic/obj/ EXECUTABLES/helloworld_intermediates -c -fno-exceptions -Wno-multichar-march=armv5te-mtune=xscale-msoft-float -fpic -mthumb-interwork -ffunction-sections -funwind- tables -fstack-protector -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ ARCH_5TE__ -include system/core/include/arch/linux-arm/AndroidConfig.h -DANDROID -fmessage-length=0-W -Wall -Wno-unused -DSK_RELEASE -DNDEBUG -O2 -g-Wstrict-aliasing=2-finline-functions -fno-inline-functions-called-once -fgcse-after-reload -frerun-cse- after-loop -frename-registers -DNDEBUG -UDEBUG -mthumb -Os -fomit-frame-pointer -fno- strict-aliasing-finline-limit=64-MD -o out/target/product/generic/obj/EXECUTABLES/ helloworld_intermediates/hello.o development/hello/hello.c
target Executable: helloworld (out/target/product/generic/obj/EXECUTABLES/helloworld_ intermediates/LINKED/helloworld)
prebuilt/linux-x86/toolchain/arm-eabi-4.3.1/bin/arm-eabi-g++ -nostdlib -Bdynamic -Wl,-T,build/core/armelf.x -Wl,-dynamic-linker,/system/bin/linker -Wl,--gc-sections -Wl,-z,nocopyreloc -o out/target/product/generic/obj/EXECUTABLES/helloworld_ intermediates/LINKED/helloworld -Lout/target/product/generic/obj/lib -Wl,-rpath-link=out/target/product/generic/obj/lib -lc -lstdc++ -lm out/target/product/generic/obj/ lib/crtbegin_dynamic.o out/target/product/generic/obj/EXECUTABLES/helloworld_ intermediates/hello.o -Wl,--no-undefined prebuilt/linux-x86/toolchain/arm-eabi- 4.3.1/bin/../lib/gcc/arm-eabi/4.3.1/interwork/libgcc.a out/target/product/generic/obj/ lib/crtend_android.o
target Non-prelinked: helloworld (out/target/product/generic/symbols/system/bin/ helloworld)
out/host/linux-x86/bin/acp -fpt out/target/product/generic/obj/EXECUTABLES/ helloworld_intermediates/LINKED/helloworld out/target/product/generic/symbols/system/ bin/helloworld
target Strip: helloworld (out/target/product/generic/obj/EXECUTABLES/helloworld_ intermediates/helloworld)
out/host/linux-x86/bin/soslim --strip --shady --quiet out/target/product/generic/ symbols/system/bin/helloworld --outfile out/target/product/generic/obj/EXECUTABLES/ helloworld_intermediates/helloworld
Install: out/target/product/generic/system/bin/helloworld
out/host/linux-x86/bin/acp -fpt out/target/product/generic/obj/EXECUTABLES/helloworld_ intermediates/helloworld out/target/product/generic/system/bin/helloworld
【责任编辑:book TEL:(010)68476606】
点赞 0