对移植工程的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。

对移植工程的makefile理解。

 关于-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

  目标文件参数。