对移植工程的makefile理解。
本文的目的已在对于makefile结构和其参数的理解。
该工程的编译类型为交叉编译。
工程一共包含5个makefile文件,分别是:
./makefile
./api/compile.cfg
./api/archdef.cfg
./api/rules.cfg
./sudir.cfg
还有一个makefile中的include文件为:./config/ME21/config.mk,但由于其内容为空,对其忽略。
先看先用编译工具的编译信息。
Start Compiling: arm-none-eabi-gcc -mthumb -Wall -Os -fno-common -mcpu=cortex-m4 -msoft-float -I. -Iapi -Iapi/libc_inc -isystem "e:/nlcompiler/bin/../lib/gcc/arm-none-eabi/4.7.3/include" -nostdinc -D__DEBUG__ -c -o C:\Users\thinkpad\Documents\GitHub\minipay1\build/main.o arm-none-eabi-gcc -mthumb -Wall -Os -fno-common -mcpu=cortex-m4 -msoft-float -I. -Iapi -Iapi/libc_inc -isystem "e:/nlcompiler/bin/../lib/gcc/arm-none-eabi/4.7.3/include" -nostdinc -D__DEBUG__ -c -o C:\Users\thinkpad\Documents\GitHub\minipay1\build/display.o display.c arm-none-eabi-gcc -mthumb -Wall -Os -fno-common -mcpu=cortex-m4 -msoft-float -I. -Iapi -Iapi/libc_inc -isystem "e:/nlcompiler/bin/../lib/gcc/arm-none-eabi/4.7.3/include" -nostdinc -D__DEBUG__ -c -o C:\Users\thinkpad\Documents\GitHub\minipay1\build/cmd_trans.o cmd_trans.c arm-none-eabi-gcc -mthumb -Wall -Os -fno-common -mcpu=cortex-m4 -msoft-float -I. -Iapi -Iapi/libc_inc -isystem "e:/nlcompiler/bin/../lib/gcc/arm-none-eabi/4.7.3/include" -nostdinc -D__DEBUG__ -c -o C:\Users\thinkpad\Documents\GitHub\minipay1\build/cmd_mana.o cmd_mana.c arm-none-eabi-gcc -mthumb -Wall -Os -fno-common -mcpu=cortex-m4 -msoft-float -I. -Iapi -Iapi/libc_inc -isystem "e:/nlcompiler/bin/../lib/gcc/arm-none-eabi/4.7.3/include" -nostdinc -D__DEBUG__ -c -o C:\Users\thinkpad\Documents\GitHub\minipay1\build/cmd_channel.o cmd_channel.c arm-none-eabi-gcc -mthumb -Wall -Os -fno-common -mcpu=cortex-m4 -msoft-float -I. -Iapi -Iapi/libc_inc -isystem "e:/nlcompiler/bin/../lib/gcc/arm-none-eabi/4.7.3/include" -nostdinc -D__DEBUG__ -c -o C:\Users\thinkpad\Documents\GitHub\minipay1\build/cmd_common.o cmd_common.c arm-none-eabi-gcc -mthumb -Wall -Os -fno-common -mcpu=cortex-m4 -msoft-float -I. -Iapi -Iapi/libc_inc -isystem "e:/nlcompiler/bin/../lib/gcc/arm-none-eabi/4.7.3/include" -nostdinc -D__DEBUG__ -c -o C:\Users\thinkpad\Documents\GitHub\minipay1\build/cmd_deals.o cmd_deals.c cmd_deals.c: In function 'credit_for_load': cmd_deals.c:97:22: warning: 'nCMDLen' may be used uninitialized in this function [-Wuninitialized] arm-none-eabi-gcc -mthumb -Wall -Os -fno-common -mcpu=cortex-m4 -msoft-float -I. -Iapi -Iapi/libc_inc -isystem "e:/nlcompiler/bin/../lib/gcc/arm-none-eabi/4.7.3/include" -nostdinc -D__DEBUG__ -c -o C:\Users\thinkpad\Documents\GitHub\minipay1\build/k21_icc_app.o k21_icc_app.c k21_icc_app.c:36:14: warning: 'psICC_SW_Msg' defined but not used [-Wunused-variable] arm-none-eabi-gcc -mthumb -Wall -Os -fno-common -mcpu=cortex-m4 -msoft-float -I. -Iapi -Iapi/libc_inc -isystem "e:/nlcompiler/bin/../lib/gcc/arm-none-eabi/4.7.3/include" -nostdinc -D__DEBUG__ -c -o C:\Users\thinkpad\Documents\GitHub\minipay1\build/k21_icc_op.o k21_icc_op.c arm-none-eabi-gcc -mthumb -Wall -Os -fno-common -mcpu=cortex-m4 -msoft-float -I. -Iapi -Iapi/libc_inc -isystem "e:/nlcompiler/bin/../lib/gcc/arm-none-eabi/4.7.3/include" -nostdinc -D__DEBUG__ -c -o C:\Users\thinkpad\Documents\GitHub\minipay1\build/tlv.o tlv.c arm-none-eabi-gcc -mthumb -Wall -Os -fno-common -mcpu=cortex-m4 -msoft-float -I. -Iapi -Iapi/libc_inc -isystem "e:/nlcompiler/bin/../lib/gcc/arm-none-eabi/4.7.3/include" -nostdinc -D__DEBUG__ -c -o C:\Users\thinkpad\Documents\GitHub\minipay1\build/k21_debug.o k21_debug.c arm-none-eabi-ld C:\Users\thinkpad\Documents\GitHub\minipay1\build/main.o C:\Users\thinkpad\Documents\GitHub\minipay1\build/display.o C:\Users\thinkpad\Documents\GitHub\minipay1\build/cmd_trans.o C:\Users\thinkpad\Documents\GitHub\minipay1\build/cmd_mana.o C:\Users\thinkpad\Documents\GitHub\minipay1\build/cmd_channel.o C:\Users\thinkpad\Documents\GitHub\minipay1\build/cmd_common.o C:\Users\thinkpad\Documents\GitHub\minipay1\build/cmd_deals.o C:\Users\thinkpad\Documents\GitHub\minipay1\build/k21_icc_app.o C:\Users\thinkpad\Documents\GitHub\minipay1\build/k21_icc_op.o C:\Users\thinkpad\Documents\GitHub\minipay1\build/tlv.o C:\Users\thinkpad\Documents\GitHub\minipay1\build/k21_debug.o configs/ME21/NDK_Sysdep_ME21.o -nostdlib -static -L"e:/nlcompiler/bin/../lib/gcc/arm-none-eabi/4.7.3/armv7e-m/" -lgcc -Tconfigs/ME21/minipay.ld --start-group api/libc_Cortex-M4_nofpu.a api/libemvNDK_POS.a --end-group -Map C:\Users\thinkpad\Documents\GitHub\minipay1\build/minipay_ME21.map -o C:\Users\thinkpad\Documents\GitHub\minipay1\build/minipay_ME21.elf
除了最后一条为链接信息,其他的编译信息都为由各个.c生成.o文件的信息。
首先查看生成.o文件的信息:
arm-none-eabi-gcc -mthumb -Wall -Os -fno-common -mcpu=cortex-m4 -msoft-float -I. -Iapi -Iapi/libc_inc -isystem "e:/nlcompiler/bin/../lib/gcc/arm-none-eabi/4.7.3/include" -nostdinc -D__DEBUG__ -c -o C:\Users\thinkpad\Documents\GitHub\minipay1\build/main.o
以main.c文件的信息为例。因为其他文件的信息都是类似的。
arm-none-eabi-gcc
为交叉编译工具链的标识,交叉编译多使用在PC为其他系统小型cpu环境使用的代码,比如ARM等。
交叉编译工具也会根据具体使用的环境而有所不同,如:
对于linux系统的ARM,使用arm-unknown-linux-xxx;
对于没有系统文件的ucos系统,如此工程使用arm-none-eabi-gcc。
当然针对其他的系统也会有其他不同的交叉编译工具。需要交叉编译工具的可以去sourcery官网下载。
arm-none-eabi-gcc后面就是编译参数了,可以分成以下几块:
-mthumb -Wall -Os -fno-common -mcpu=cortex-m4 -msoft-float
-I. -Iapi -Iapi/libc_inc -isystem "e:/nlcompiler/bin/../lib/gcc/arm-none-eabi/4.7.3/include -nostdinc
-D__DEBUG__ -c -o C:\Users\thinkpad\Documents\GitHub\minipay1\build/main.o main.c
第一块:
i. -mthumb
该参数是为代码指定指令的类型为thumb类型,简单提下thumb指令的概念和优缺点。
其概念是与arm指令相对的,thumb指令为16位指令。与32位的arm指令相比,大大节省了使用空间。所有的Thumb指令都有对应的ARM指令,而且Thumb的编程模型也对应于ARM的编程模型,在应用程序的编写过程中,只要遵循一定调用的规则,Thumb子程序和ARM子程序就可以互相调用。当处理器在执行ARM程序段时,称ARM处理器处于ARM工作状态,当处理器在执行Thumb程序段时,称ARM处理器处于Thumb工作状态。 与ARM指令集相比较,Thumb指令集中的数据处理指令的操作数仍然是32位,指令地址也为32位,但Thumb指令集为实现16位的指令长度,舍弃了ARM指令集的一些特性,如大多数的Thumb指令是无条件执行的,而几乎所有的ARM指令都是有条件执行的;大多数的Thumb数据处理指令的目的寄存器与其中一个源寄存器相同。 由于Thumb指令的长度为16位,即只用ARM指令一半的位数来实现同样的功能,所以,要实现特定的程序功能,所需的Thumb指令的条数较ARM指令多。在一般的情况下,Thumb指令与ARM指令的时间效率和空间效率关系为: - Thumb代码所需的存储空间约为ARM代码的60% ~ 70% - Thumb代码使用的指令数比ARM代码多约30%~40% - 若使用32位的存储器,ARM代码比Thumb代码快约40% - 若使用16位的存储器,Thumb代码比ARM代码快约40% ~50% - 与ARM代码相比较,使用Thumb代码,存储器的功耗会降低约30% 显然,ARM指令集和Thumb指令集各有其优点,若对系统的性能有较高要求,应使用32位的存储系统和ARM指令集,若对系统的成本及功耗有较高要求,则应使用16位的存储系统和Thumb指令集。当然,若两者结合使用,充分发挥其各自的优点,会取得更好的效果。
其中有一篇blog说-mthumb-interwork可以实现arm指令和thumb指令互相调用。
在工程中将-mthumb改成-mthumb-interwork,编译显示
Error: selected processor does not support ARM mode `bx lr'
估计原因有两个:
1.arm-none-eabi-gcc交叉编译工具不支持ARM指令。
2.mcpu=cortex-m4:该类型芯片不支持ARM指令。
求证之后:cortex-m4只支持thumb及thumb2指令。但第一点是否也是原因之一,并咩有得到有利的证据,希望懂的人给与解答。
这里再提一句,-m开头的参数都是为ARM结构定义的开关。这里有一个相关参数说明的链接:
http://wenku.baidu.com/link?url=6GDZnF3ciJde91ehI8HhP9bKy_2Fnfh8kci_7CIUjYx4CzAAB11P-r3-lVL60UtdE5gLC5xNySEHqYLUbQJ8Az437WY9CYAtIA0zN_M2Pha
ii.-Wall
这个大家应该都很熟悉,显示所有的警告信息。
iii. -Os
这个参数是编译的优化选项。相当于-O2, -O3之间的-O2.5。
关于-O参数的说明以下这篇文章应该是是不二选择了:
http://www.linuxjournal.com/article/7269?page=0,1
iv. -fno-common
根据GCC中文手册中的说明:
即使未初始化的全局变量也分配在目标文件的bss段,而不是把它们当做普通块(common block)建立.这样的 结果是,如果在两个不同的编译结果中声明了同一个变量(没使用extern ),连接它们时会产生错误. 这个选项可能有用的唯一情况是,你希望确认程序能在其他系统上运行,而其他系统总是这么做.
没怎么看懂到该参数底有什么用,而且在去掉之后对编译结果也没有影响。或许是为了引导coder规范的使用extern来定义和使用全局变量吧。
v.-mcpu=cortex-m4
该参数和-mthumb是一个类型的,之前有过介绍。
-mcpu指明了cpu的类型,cortex-m4。
vi. -msoft-float
输出包含浮点库调用的目标码.
警告:所需的库不是GNU
CC的组成部分.一般说来GCC使用该机型本地C 编译器的相应部件,但是作交叉编译时却不能直接使用.你必须自己管理提供合适的函数库用于交叉编译.
第二块:
-I. -Iapi -Iapi/libc_inc -isystem "e:/nlcompiler/bin/../lib/gcc/arm-none-eabi/4.7.3/include" -nostdinc
-I 大家应该不陌生,表示库文件地址的包含。
后面的-isystem dir
这篇blog给出了解答:
-isystem dir
Search dir for header files, after all directories specified by -I but before the standard system directories. Mark it as a system directory, so that it gets the same special treatment as is applied to the standard system directories. If dir begins with =, then the = will be replaced by the sysroot prefix; see --sysroot and -isysroot.
-nostdinc
表示不在标准系统目录中搜索头文件,只在-I指定的目录中搜索。
第三块:
-D__DEBUG__ -c -o C:\Users\thinkpad\Documents\GitHub\minipay1\build/main.o main.c
-D_DEBUG_是在makefile中控制是否输出调试信息的开关,出现就表示代码为调试版。
后面的两个 -c -o就不用说了,最基本的gcc参数。
下面部分为链接的编译信息:
arm-none-eabi-ld C:\Users\thinkpad\Documents\GitHub\minipay1\build/main.o C:\Users\thinkpad\Documents\GitHub\minipay1\build/display.o C:\Users\thinkpad\Documents\GitHub\minipay1\build/cmd_trans.o C:\Users\thinkpad\Documents\GitHub\minipay1\build/cmd_mana.o C:\Users\thinkpad\Documents\GitHub\minipay1\build/cmd_channel.o C:\Users\thinkpad\Documents\GitHub\minipay1\build/cmd_common.o C:\Users\thinkpad\Documents\GitHub\minipay1\build/cmd_deals.o C:\Users\thinkpad\Documents\GitHub\minipay1\build/k21_icc_app.o C:\Users\thinkpad\Documents\GitHub\minipay1\build/k21_icc_op.o C:\Users\thinkpad\Documents\GitHub\minipay1\build/tlv.o C:\Users\thinkpad\Documents\GitHub\minipay1\build/k21_debug.o configs/ME21/NDK_Sysdep_ME21.o -nostdlib -static -L"e:/nlcompiler/bin/../lib/gcc/arm-none-eabi/4.7.3/armv7e-m/" -lgcc -Tconfigs/ME21/minipay.ld --start-group api/libc_Cortex-M4_nofpu.a api/libemvNDK_POS.a --end-group -Map C:\Users\thinkpad\Documents\GitHub\minipay1\build/minipay_ME21.map -o C:\Users\thinkpad\Documents\GitHub\minipay1\build/minipay_ME21.elf
可以分为:
1. .o文件的说明。
2. 编译条件的说明(-nostdlib -nostdinc)
-nostdlib 类似的-nostdinc
-static 表示为静态编译,用来生成静态链接文件。与其相对应的参数为-shared,用来生成.so等类型的动态链接文件。
3.-L.... -lgcc
表明lib的地址。
4.-Tconfigs/ME21/minipay.ld
指明链接地址。
5.--start-group ** --end-group
手动指定的静态链接库。
6.-Map C:\Users\thinkpad\Documents\GitHub\minipay1\build/minipay_ME21.map
这是生成map映射文件,map文件的作用在于,它记录了这个工程各个部分(变量,函数)的内存映射情况。对于工程的内存占用情况有很详细的说明。是一份很好的参考文档。
7.-o obj
目标文件参数。