IMX6ULL学习笔记(17)——工程管理

Posted Leung_ManWah

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IMX6ULL学习笔记(17)——工程管理相关的知识,希望对你有一定的参考价值。

一、简介

之前我们把所有源码文件放在一个文件夹下。 这样做存在两个主要问题,第一,代码存放混乱不易阅读。第二,程序可移植性差。如果工程源文件达到几十、甚至数百个的时候,这样一股脑全部放到根目录下就会使工程显得混乱不堪。所以我们必须对工程文件做管理,将不同功能的源码文件放到不同的目录中。另外我们也需要将源码文件中,所有完成同一个功能的代码提取出来放到一个单独的文件中,也就是对程序分功能管理。

如何对一个工程进行整理,使其美观、功能模块清晰、易于阅读。

  • 创建文件夹分类存储代码
  • 修改makefile

二、分类存储代码

修改前的程序结构:

修改后的程序结构:

  • base.lds :将led.lds更改为base.lds。连接脚本与具体的外设无关,并且后面的程序我们几乎不会去修改链接脚本,这里把它修改为base.lds,你也可以根据自己喜好命令,只要和makefile中一致即可。
  • device文件夹 :保存外设驱动的源文件(.c文件)。
  • include文件夹 :保存程序中使用的头文件。
  • makefile :主makefile 。在主makefile中会调用“device”文件夹下的子makefile。

三、修改makefile

修改makefile主要包括两部分

  • 第一部分,在“device”文件夹下添加并编写子makefile。
  • 第二部分,修改主makefile。

3.1 编写子makefile

子makefile: 用于将“device”文件夹下的驱动源文件编译为一个“.o”文件

all : button.o  led.o
  arm-none-eabi-ld -r $^  -o device.o

%.o : %.c
  arm-none-eabi-gcc $header_file -c $^

%.o : %.S
  arm-none-eabi-gcc $header_file -c $^

.PHONY: clean
clean:
  -rm -f *.o *.bak
  • 添加最终目标以及依赖文件
    生成最终目标“device.o”。如果程序中新增了某个外设驱动程序,只需要将对应的“.o”文件填入“依赖”处即可。
    “$^” 代表所有的依赖文件。
    “-o” 指定输出文件名。
all : button.o  led.o
  arm-none-eabi-ld -r $^  -o device.o
  • 添加编译C文件的命令
    编译“device”文件夹下的所有“.c”文件并生成对应的“.o”文件,其中“header_file”是头文件路径,它是定义在主makefile的变量。
    “$^” 替代要编译的源文件。
%.o : %.c
  arm-none-eabi-gcc $header_file -c $^
  • 添加汇编文件编译命令
    编译“device”文件夹下的所有“.S”文件并生成对应的“.o”文件,其中“header_file”是头文件路径,它是定义在主makefile的变量。
    “$^” 替代要编译的源文件。
%.o : %.S
  arm-none-eabi-gcc $header_file -c $^
  • 添加清理命令
    “.PHONY” 定义了伪目标“clean”。伪目标一般没有依赖,并且 “clean” 伪目标一般放在Makefile文件的末尾。
    “clean” 为目标用于删除make生成的文件。
.PHONY: clean
clean:
  -rm -f *.o *.bak

3.2 修改主makefile

主makefile的改动主要有两点:

  1. 在编译命令中指明头文件位置。
  2. 使用命令调用子makefile,生成依赖文件。
#定义变量,用于保存编译选项和头文件保存路径
header_file := -fno-builtin -I$(shell pwd)/include
export header_file

all : start.o main.o device/device.o
  arm-none-eabi-ld -Tbase.lds $^ -o base.elf
  arm-none-eabi-objcopy -O binary -S -g base.elf base.bin

%.o : %.S
  arm-none-eabi-gcc -g -c $^
%.o : %.c
  arm-none-eabi-gcc $(header_file) -c $^

#调用其他文件的makefile
device/device.o :
  make -C device all

#定义清理伪目标
.PHONY: clean
clean:
  make -C device clean
  -rm -f *.o *.elf *.bin
  • 添加编译选项和头文件保存路径
    定义变量 “header_file”。在makefile中“变量”更像C原因中的宏定义。
    “-fno-builtin” 是一个编译选项,用于解决库函数与自己编写函数同名问题。
    “-I$(shell pwd)/include” 用于指定头文件路径。
    “export header_file” 声明后可以在其他makefile中调用。
header_file := -fno-builtin -I$(shell pwd)/include
export header_file
  • 添加最终目标以及依赖文件
all : start.o main.o device/device.o
  • 添加链接命令
    “-Tbase.lds” 表示使用base.lds链接脚本链接程序。
    “$^” 代表所有的依赖文件。
    “-o” 指定输出文件名。
arm-none-eabi-ld -Tbase.lds $^ -o base.elf
  • 添加格式转换命令
    “-O binary” 指定输出二进制文件。
    “-S” 不从源文件中复制重定位信息和符号信息。
    “-g” 不从源文件中复制可调试信息。
arm-none-eabi-objcopy -O binary -S -g base.elf base.bin
  • 添加汇编文件编译命令
    “$^” 替代要编译的源文件。
%.o : %.S
  arm-none-eabi-gcc -g -c $^
  • 添加编译C文件的命令
    “$^” 替代要编译的源文件。
%.o : %.c
  arm-none-eabi-gcc $(header_file) -c $^
  • 添加调用其他文件的makefile
    定义生成“device/device.o”的命令,“device.o”文件由子makefile生成,所以这里只需要调用子makefile即可。
device/device.o :
  make -C device all
  • 添加清理命令
    在清理命令中不但要清理主makefile所在文件夹的内容还要调用子makefile的清理命令以清理子makefile所在文件夹的内容。
    “.PHONY” 定义了伪目标“clean”。伪目标一般没有依赖,并且 “clean” 伪目标一般放在Makefile文件的末尾。
    “clean” 为目标用于删除make生成的文件。
.PHONY: clean
clean:
  make -C device clean
  -rm -f *.o *.elf *.bin

• 由 Leung 写于 2023 年 2 月 21 日

• 参考:9. 整理工程文件
    i.MX6ULL裸机开发 四:BSP 工程管理
    IMX6ULL——BSP工程管理Makefile文件格式
    【Linux裸机开发】-C语言点灯-基于NXP官方库及BSP项目工程管理
    IMX6Ull_BSP工程整理

以上是关于IMX6ULL学习笔记(17)——工程管理的主要内容,如果未能解决你的问题,请参考以下文章

IMX6ULL学习笔记——获取和编译Linux内核

IMX6ULL学习笔记——获取和编译Linux内核

IMX6ULL学习笔记——获取和编译Linux内核

linu学习笔记--进程基础

IMX6ULL学习笔记——通过SD卡启动Linux内核

IMX6ULL学习笔记——通过SD卡启动Linux内核