第9课.gcc和arm-linux-gcc和Makefile

1.gcc编译器和arm-linux-gcc编译器

PC上的编译工具:gcc,ld,objcopy,objdump
ARM平台上必须使用交叉编译工具:arm-linux-gcc

A.一个C/C++文件处理过程:

        预处理---> 编译 ---> 汇编 ---> 链接
.c/.cpp ----- .i  ---- .S  ----- .o  ----

a.预处理

以"#"开头的命令被称为预处理命令,得到.i文件

b.编译

把.i文件翻译成汇编代码(.S)

c.汇编

将汇编代码(.S)翻译成符合一定格式的机器码(.o)

d.链接

将上步产生的文件和系统库的OBJ文件,库文件连接起来

B.arm-linux-gcc和gcc的一些常用选项

a.总体选项

-E            只预处理,不会编译、汇编、链接
-S            只编译,不会汇编、链接
-c            编译和汇编,不会链接   
-o <file>     指定输出文件名为file,这个名称不能跟源文件名同名
-v            查看gcc编译器的版本,显示gcc执行时的详细过程

b.警告选项

-Wall        打开所有需要注意的警告信息
eg:
    gcc -Wall -c main.c

C.arm-linux-ld

arm-linux-ld用于将多个目标文件,库文件连接成可执行文件

-T:    用于指定代码段,数据段,bss段的起始位置,也可以用来指定一个链接脚本,在脚本中进行复杂设置
eg:
    -Ttext startaddr        指定代码段起始位置
    -Tdata startaddr        指定数据段起始位置
    -Tbss  startaddr        指定bss段起始位置

    注:startaddr是一个16进制的数
    
eg:
    arm-linux-ld -Ttext 0x00000000 -g led_on.o -o led_on.elf
解析:代码段的地址为0x00000000,由于没有定义数据段,bss段的起始位置,它们被放在代码段的后面

D.arm-linux-objcopy

arm-linux-objcopy被用来复制一个目标文件的内容到另一个文件中,可以进行格式转换(常用来elf转二进制文件)

-O        使用指定的格式来输出文件
    eg:
        -O binary        以二进制格式输出
-S        不从源文件中复制重定位信息和符号信息到目标文件中去

E.arm-linux-objdump

arm-linux-objdump用于显示二进制文件信息,常用来查看反汇编代码。

-d/-D        反汇编可执行段/反汇编所有段

F.示例

all:
	arm-linux-gcc -c -o led.o led.c
            解析:
                arm-linux-gcc -c:预处理,编译,汇编。把led.c->.o文件
                -o:把产生的结果文件命名为led.o

    arm-linux-gcc -c -o start.o start.S

	arm-linux-ld -Ttext 0 start.o led.o -o led.elf
            解析:
                -Ttext 0:指定代码段的起始位置为0(16进制)
                把文件链接在一起,并把目标文件命名为led.elf

	arm-linux-objcopy -O binary -S led.elf led.bin
            解析:
                -O binary:转换为二进制文件
                -S:不复制重定位信息和符号
                把上面产生的文件转换为二进制的机器码

	arm-linux-objdump -D led.elf > led.dis
            解析:
                -D:反汇编所有段
                >:新建文件
                <:原文件上添加
                把连接文件,转换为反汇编代码

2.Makefile

A.Makefile规则

目标:依赖1 依赖2 ...
[TAB]命令

使用规则

make [目标]
a.如果无目标,默认执行第一个目标。
b.依赖文件比目标文件新时才会去执行命令
c.如果没有依赖,则它的命令会被强制执行

B.Makefile的语法

a.通配符:

%.*        所有的.*文件
$@         表示目标
$<         表示第一个依赖
$^         表示所有依赖
eg:
    %.o: %.c                // 所有的.o文件依赖于所有的%.c文件
        gcc -c -o $@ $^     // 把所有的依赖预处理,编译,汇编处理为目标文件

b.假想目标:.PHONY

可避免文件已经存在而不能进行目标名操作
eg:
    clean:
        rm *.o test
    .PHONY: clean
    解析:此时Makefil外存在一个clean文件,会影响到clean这个目标的使用。这时使用PHONY

c.即使变量,延时变量

即使变量:在定义时它的值就确定了
延时变量:在使用这个变量时才会被确定

:=        即时变量
=         延时变量
?=        延时变量,但这个仅仅在变量还没有定义的情况下有效,如果变量前面已经被定义了,则忽略词条语句
+=        附加,是即时变量还是延时变量,取决于前面的定义

C.Makefile常用函数

a. $(foreach var,list,text)
b. $(filter pattern...,text)      # 在text中取出符合patten格式的值
   $(filter-out pattern...,text)  # 在text中取出不符合patten格式的值

c. $(wildcard pattern)            # pattern定义了文件名的格式,
								  # wildcard取出其中存在的文件
d. $(patsubst pattern,replacement,$(var))  # 从列表中取出每一个值
										   # 如果符合pattern
										   # 则替换为replacement
posted @ 2019-12-24 14:41  人民广场的二道贩子  阅读(1528)  评论(0编辑  收藏  举报