zoukankan      html  css  js  c++  java
  • 第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
  • 相关阅读:
    projecthashing
    Windows 环境 gRPC环境搭建
    gitlab 适配性问题
    对 Golang 简洁架构实战的理解,以及 Golang 开源项目包定义的解惑
    Golang 关于百分比,小数点为数的问题
    Golang net/http 库日常 http 请求操作
    解决mysql建立事件时出现 “Cannot proceed because system tables used by Event Scheduler were found damaged at server start” 的错误
    如何在Linux安装Wine
    Public key for *.rpm is not installed
    从 IClassFactory 为 CLSID 为 {AA40D1D6CAEF4A56B9BBD0D3DC976BA2} 的 COM 组件创建实例失败,原因是出现以下错误: c001f011。
  • 原文地址:https://www.cnblogs.com/huangdengtao/p/12091405.html
Copyright © 2011-2022 走看看