zoukankan      html  css  js  c++  java
  • makefile及其相关知识介绍

    makefile是用来管理工程的。

    示例1:

    1 exe: a.c b.c
    2         gcc a.c b.c -o exe
    3 
    4 clean:
    5         rm exe

    基本概念:

    目标:顶格写,在:前面

    依赖: 在:后面,用来产生目标的原材料

    命令:前面一定是table,不能是多个空格。命令是生成目标所做的动作

    示例2:

     1 led.bin: start.o 
     2         arm-linux-ld -Ttext 0x0 -o led.elf $^
     3         arm-linux-objcopy -O binary led.elf led.bin
     4         arm-linux-objdump -D led.elf > led_elf.dis 
     5         gcc mkv210_image.c -o mkx210   // 该处生成的mkx210是为了在Linux下执行的,这里的gcc和交叉编译工具链的gcc不相同
     6         ./mkx210 led.bin 210.bin  
     7     
     8 %.o : %.S
     9         arm-linux-gcc -o $@ $< -c
    10 
    11 %.o : %.c
    12         arm-linux-gcc -o $@ $< -c 
    13 
    14 clean:
    15         rm *.o *.elf *.bin *.dis mkx210 -f

    示例分析:

    (1)Makefile有三个非常有用的变量。分别是$@,$^,$<代表的意义分别是: 

    $@--目标文件,$^--所有的依赖文件,$<--第一个依赖文件

    (2)交叉编译工具链工具及作用

    先决条件:linux系统下面有一个环境变量叫PATH,必须把该工具链的地址导入到该环境变量下面,export PATH=工具链地址:$PATH

    最好是该语句加到~/.bash文件中,这样每次启动终端都会执行该语句。

    arm-linux-gcc:

    用来编译源文件

    arm-linux-ld:

    用来链接,其中,-Ttest是用来指定链接地址的,在该处也可以使用链接脚本来去进行链接。在该处生成的elf文件还不能烧录执行。

    objcopy:

    作用以led.elf为源材料为源材料制作镜像的工具。

    解释:led.elf已经是可执行程序,在操作系统下已经可以执行,裸机中需要的是可以烧录的二进制文件(镜像image)。

    以led.elf为源材料为源材料制作镜像

    objdump:

    作用:反汇编,将elf格式的可执行程序反过来得到其汇编源代码。

    mkx210(由mkv210_image.c得到):

    作用:以led.bin为源材料得到210.bin(为BL1添加校验头)

    解释:usb启动时不需要头校验,SD卡启动时需要,让led.bin加上header(校验头)成为210.bin。

    附:mkv210_image.c源程序:

      1 /*
      2  * mkv210_image.c的主要作用就是由usb启动时使用的led.bin制作得到由sd卡启动的镜像210.bin
      3  *
      4  * 本文件来自于友善之臂的裸机教程,据友善之臂的文档中讲述,本文件是一个热心网友提供,在此表示感谢。
      5  */
      6 /* 在BL0阶段,Irom内固化的代码读取nandflash或SD卡前16K的内容,
      7  * 并比对前16字节中的校验和是否正确,正确则继续,错误则停止。
      8  */
      9 #include <stdio.h>
     10 #include <string.h>
     11 #include <stdlib.h>
     12 
     13 #define BUFSIZE                 (16*1024)
     14 #define IMG_SIZE                (16*1024)
     15 #define SPL_HEADER_SIZE         16
     16 //#define SPL_HEADER              "S5PC110 HEADER  "
     17 #define SPL_HEADER              "****************"
     18 
     19 int main (int argc, char *argv[])
     20 {
     21     FILE        *fp;
     22     char        *Buf, *a;
     23     int        BufLen;
     24     int        nbytes, fileLen;
     25     unsigned int    checksum, count;
     26     int        i;
     27     
     28     // 1. 3个参数
     29     if (argc != 3)
     30     {
     31         printf("Usage: %s <source file> <destination file>
    ", argv[0]);
     32         return -1;
     33     }
     34 
     35     // 2. 分配16K的buffer,并且全部填充为0
     36     BufLen = BUFSIZE;
     37     Buf = (char *)malloc(BufLen);
     38     if (!Buf)
     39     {
     40         printf("Alloc buffer failed!
    ");
     41         return -1;
     42     }
     43 
     44     memset(Buf, 0x00, BufLen);
     45 
     46     // 3. 读源bin到buffer
     47     // 3.1 打开源bin
     48     fp = fopen(argv[1], "rb");
     49     if( fp == NULL)
     50     {
     51         printf("source file open error
    ");
     52         free(Buf);
     53         return -1;
     54     }
     55     // 3.2 获取源bin长度
     56     fseek(fp, 0L, SEEK_END);                                // 定位到文件尾
     57     fileLen = ftell(fp);                                    // 得到文件长度
     58     fseek(fp, 0L, SEEK_SET);                                // 再次定位到文件头
     59     // 3.3 源bin长度不得超过16K-16byte
     60     count = (fileLen < (IMG_SIZE - SPL_HEADER_SIZE))
     61         ? fileLen : (IMG_SIZE - SPL_HEADER_SIZE);
     62     // 3.4 buffer[0~15]存放"S5PC110 HEADER  "
     63     memcpy(&Buf[0], SPL_HEADER, SPL_HEADER_SIZE);
     64     // 3.5 读源bin到buffer[16]
     65     nbytes = fread(Buf + SPL_HEADER_SIZE, 1, count, fp);
     66     if ( nbytes != count )
     67     {
     68         printf("source file read error
    ");
     69         free(Buf);
     70         fclose(fp);
     71         return -1;
     72     }
     73     fclose(fp);
     74 
     75     // 4. 计算校验和
     76      // 4.1 从第16byte开始统计buffer中共有几个1
     77     // 4.1 从第16byte开始计算,把buffer中所有的字节数据加和起来得到的结果
     78     a = Buf + SPL_HEADER_SIZE;
     79     for(i = 0, checksum = 0; i < IMG_SIZE - SPL_HEADER_SIZE; i++)
     80         checksum += (0x000000FF) & *a++;
     81     // 4.2 将校验和保存在buffer[8~15]
     82     a = Buf + 8;                            // Buf是210.bin的起始地址,+8表示向后位移2个字,也就是说写入到第3个字
     83     *( (unsigned int *)a ) = checksum;
     84 
     85     // 5. 拷贝buffer中的内容到目的bin
     86     // 5.1 打开目的bin
     87     fp = fopen(argv[2], "wb");
     88     if (fp == NULL)
     89     {
     90         printf("destination file open error
    ");
     91         free(Buf);
     92         return -1;
     93     }
     94     // 5.2 将16k的buffer拷贝到目的bin中
     95     a = Buf;
     96     nbytes    = fwrite( a, 1, BufLen, fp);
     97     if ( nbytes != BufLen )
     98     {
     99         printf("destination file write error
    ");
    100         free(Buf);
    101         fclose(fp);
    102         return -1;
    103     }
    104 
    105     free(Buf);
    106     fclose(fp);
    107 
    108     return 0;
    109 }
    View Code

    (3)指令解释

    -c: 只编译不链接

    -o: 用来指定名字

    -D: 表示反汇编(反汇编工具有多种用法,-D表示反汇编用法)

    -Ttext: 指定代码段的起始地址(链接地址)

    (4)其它

    第8行到第12行叫做makefile的规则,当看到.S和.c文件会自动转化为.o文件。

    printf移植中用到的makefile

     1 CC         = arm-linux-gcc
     2 LD         = arm-linux-ld
     3 OBJCOPY = arm-linux-objcopy
     4 OBJDUMP = arm-linux-objdump
     5 AR         = arm-linux-ar
     6 
     7 INCDIR := $(shell pwd)
     8 
     9 # c预处理器的flag,flag就是编译器可选的选项
    10 CPPFLAGS    := -nostdlib -nostdinc -I$(INCDIR)/include
    11 # C编译器的flag
    12 CFLAGS        := -Wall -O2 -fno-builtin                
    13 
    14 # 导出这些变量到全局,其实就是给子文件下面的makefile使用
    15 export CC LD OBJCOPY OBJDUMP AR CPPFLAGS CFLAGS
    16 
    17 
    18 objs := start.o led.o clock.o uart.o main.o
    19 objs += lib/libc.a
    20 
    21 uart.bin: $(objs) 
    22     $(LD) -Tlink.lds -o uart.elf $^
    23     $(OBJCOPY) -O binary uart.elf uart.bin
    24     $(OBJDUMP) -D uart.elf > uart_elf.dis
    25     gcc mkv210_image.c -o mkx210
    26     ./mkx210 uart.bin 210.bin
    27     
    28 lib/libc.a:
    29     cd lib; make; cd ..
    30     
    31 
    32     
    33 %.o : %.S
    34     $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $< -c 
    35 
    36 %.o : %.c
    37     $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $< -c 
    38 
    39 clean:
    40     rm *.o *.elf *.bin *.dis mkx210 -f
    41     cd lib; make clean; cd ..

     -nostdlib 不用标准库

    -nostdinc 不用标准的头文件

    -O2   编译器的优化等级

    -Wall  显示所有警告

    -I           用来表示寻找头文件的目录(一般用相对路径表示)

  • 相关阅读:
    CF 142B Tprimes
    CF 231A Team
    poj 2001 Shortest Prefixes ——字典树入门
    hdu 1039 Easier Done Than Said?
    poj 2528 Mayor's posters
    hdu 1061 Rightmost Digit
    poj 2503 Babelfish
    CF271 A. Beautiful Year
    poj 2752
    CF271 B. Prime Matrix
  • 原文地址:https://www.cnblogs.com/zou27/p/5021360.html
Copyright © 2011-2022 走看看