arm-linux-androideabi-gcc cdefs.h,使用Android NDK编译器写Makefile研究

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值