Quantcast
Channel: Sam的技术Blog
Viewing all articles
Browse latest Browse all 158

使用Android NDK编译器写Makefile研究

$
0
0

作者: Sam (甄峰)  sam_code@hotmail.com

 

0. 基础介绍:

Android推出NDK,是为了可以编译JNI和Native程序。它提供了一系列脚本:ndk-build, ndk-stack, ndk-dbg, ndk-which.  用来帮助用户编译,调试程序。

 

有了这些脚本,尤其是ndk-build, 它和Android.mk,  Application.mk结合,可以快速的产生需要的库或可执行程序。但他们也隐藏了很多信息。例如:编译器用的是哪个,使用什么编译选项,什么链接选项等。头文件使用哪些,库文件使用哪些。无从得知。

 

如果我们不想利用ndk-build系列脚本,而是想直接使用编译器,添加相关编译选项,理论上完全可以编译出Native库和可执行程序。 

 

但这样做,有什么意义呢?Sam工作中会遇到这样的需求:有些第三方库,采用Makefile或CMake编译。若要使用NDK脚本编译,需要重新了解编译思路,哪些源码生成那些库,哪些可执行程序依赖哪些库,然后根据这个写Android.mk.   这样做比较麻烦,尤其对比较庞大复杂的第三方库来说,就不是一个好办法。则可以直接使用NDK的编译器,添加必要的编译选项,修改Makefile或CMakefiles.txt,则可以简单的生成库了。

 

 

1. 寻找编译器:

首先要知道,不同版本的NDK, 所用到的编译器并不相同. Sam手头使用的是NDK-R9。就以它为例分析。

/opt/android-ndk-r9/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin/ 目录下,就是交叉编译器。

 

 

2. 编译选项的添加:

2.1: 头文件系列选项:

-MMD -MP -MF

说明:

-M : 生成文件依赖关系.  显示文件依赖什么头文件,头文件又依赖什么头文件. 仅仅显示依赖关系,不会真编译

-MM: 显示文件依赖关系,但不显示依赖的系统头文件。

-MMD:同-MM。 但存储在.d文件中

 

例子:

gcc -M main.cpp -I../Include
main.o: main.cpp /usr/include/stdc-predef.h /usr/include/stdio.h \
 /usr/include/features.h /usr/include/sys/cdefs.h \
 /usr/include/bits/wordsize.h /usr/include/gnu/stubs.h \
 /usr/include/gnu/stubs-64.h \
 /usr/lib/gcc/x86_64-redhat-linux/4.8.3/include/stddef.h \
 /usr/include/bits/types.h /usr/include/bits/typesizes.h \
 /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \
 /usr/lib/gcc/x86_64-redhat-linux/4.8.3/include/stdarg.h \
 /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h \
 /usr/include/unistd.h /usr/include/bits/posix_opt.h \
 /usr/include/bits/environments.h /usr/include/bits/confname.h \
 /usr/include/getopt.h ../Include/Input_Event.h

 

 gcc -M main.cpp -I../Include

main.o: main.cpp ../Include/Input_Event.h

 

 

 

gcc -MMD  main.cpp -I../Include -c

注意,-MMD与 -M  -MM 不同,它不会阻止编译。它会真正的编译下去。

 

-MP:

生成的依赖文件里面,依赖规则中的所有.h依赖项都会在该文件中生成一个伪目标,其不依赖任何其他依赖项。该伪规则将避免删除了对应的头文件而没有更新”Makefile”去匹配新的依赖关系而导致make出错的情况出现。 

 

 

-MF:指定依赖文件。

-MF /home/sam/work/Jeenon/Source/Input_Event_2_Tony/obj/local/armeabi-v7a/objs/Input_Event/Input_Event.o.d

 

感觉以上选项,是否加入意义不大,但为和NDK保持一致,还是加上, 但 -MF不准备加入了:

 

CXXFLAGS := -MMD -MP

 

2.2: fpic:

CXXFLAGS += -fpic

 

2.3:setion:

CXXFLAGS += -ffunction-sections

将每一个function建立一个新的Sections.

 

2.4: 为stack信息跟踪作准备:

CXXFLAGS += -funwind-tables -fstack-protector -no-canonical-prefixes

-funwind-tables:为GDB Stack dump做准备。

 -fstack-protector :选项能够检测出 stack smashing 问题,并在测到问题时通过 abort 方式触发 core dump

 

 

 2.5:指令集和浮点设置:

CXXFLAGS += -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16

 

2.6: 优化:

 CXXFLAGS += -O2

 

2.7:  define:

CXXFLAGS += -DNDEBUG -Dlinux -D_GLIBCXX_USE_WCHAR_T

 

2.8: 异常,RTTI,signed-char

CXXFLAGS += -fexceptions -frtti  -fsigned-char

 

 2.9: 头文件路径:

 CXXFLAGS += -I/opt/android-ndk-r9/sources/cxx-stl/gnu-libstdc++/4.6/include

CXXFLAGS += -I/opt/android-ndk-r9/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi-v7a/include

CXXFLAGS += -I/opt/android-ndk-r9/sources/cxx-stl/gnu-libstdc++/4.6/include/backward

CXXFLAGS += -I./

CXXFLAGS += -I/opt/android-ndk-r9/platforms/android-8/arch-arm/usr/include

 

 2.10: 几个优化:

CXXFLAGS += -fomit-frame-pointer -fstrict-aliasing -funswitch-loops -finline-limit=300

 

2.11: PIE问题:

CXXFLAGS += -pie -fPIE

 

 3. 链接选项的添加:

LFLAGS += -shared -fpic

 

指定了-sysroot就是为编译时指定了逻辑目录。编译过程中需要引用的库,头文件,如果要到/usr/include目录下去找的情况下,则会在前面加上逻辑目录。
LFLAGS += --sysroot=/opt/android-ndk-r9/platforms/android-8/arch-arm

 


LFLAGS += -lgcc -no-canonical-prefixes -march=armv7-a

 

如果so里有未定义符号,这编译不通过

LFLAGS += -Wl,--fix-cortex-a8  -Wl,--no-undefined 

 

LFLAGS += -lc -lm
LFLAGS += -L/opt/android-ndk-r9/platforms/android-8/arch-arm/usr/lib

LFLAGS += /opt/android-ndk-r9/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi-v7a/libsupc++.a
LFLAGS += /opt/android-ndk-r9/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi-v7a/libgnustl_shared.so

 

 

这个结论还不对,下一步继续研究.




注:Android编译动态库时,会加入:

-Wl,-soname,libInput_Event.so



 

Viewing all articles
Browse latest Browse all 158

Trending Articles