这篇文章是我阅读《嵌入式实时操作系统μCOS-II原理及应用》后的读书笔记,记录目的是为了个人后续回顾复习使用。
前置内容:
工程管理工具make及makefile
文章目录
- 1 批处理文件与makefile的综合使用
- 1.1 批处理文件
- 1.2 运行
- 2 复杂工程管理示例
- 2.1 文件体系结构
- 2.2 批处理文件
- 2.3 makefile 文件
- 2.4 源文件、头文件和链接文件
- 2.5 运行结果
1 批处理文件与makefile的综合使用
使用链接文件、makefile脚本文件和批处理文件完成下面具有3个源程序的应用程序的编译、链接。
头文件 printA.h
#ifndef _PRINTA_H_
#define _PRINTA_H_
extern const char *msgA;
#endif
源文件 printA.c
#include "printA.h"
const char *msgA = "AAAAA";
头文件 printB.h
#ifndef _PRINTB_H_
#define _PRINTB_H_
extern const char *msgB;
#endif
源文件 printB.c
#include "printB.h"
const char *msgB = "BBBBB";
源文件 test.c
#include <stdio.h>
#include "printA.h"
#include "printB.h"
int main(void)
{
unsigned char i = 0;
for (i=0; i<5; i++)
{
printf("%s\n", msgA);
printf(" %s\n", msgB);
}
return 0;
}
链接文件 TEST.LNK
C:\BC\LIB\C0L.OBJ +
PRINTA.OBJ +
PRINTB.OBJ +
TEST.OBJ
TEST
TEST
C:\BC\LIB\CL.LIB
make 脚本文件 TEST.MAK
##############################################
# 创建可执行文件(exe)
TEST.EXE:
TLINK @TEST.LNK
##############################################
# 创建各个目标文件(obj)
PRINTA.OBJ:
BCC -c -ml -IC:\BC\INCLUDE -LC:\BC\LIB PRINTA.C
PRINTB.OBJ:
BCC -c -ml -IC:\BC\INCLUDE -LC:\BC\LIB PRINTB.C
TEST.OBJ:
BCC -c -ml -IC:\BC\INCLUDE -LC:\BC\LIB TEST.C
1.1 批处理文件
批处理文件 MAKETEST.BAT
ECHO OFF
ECHO ***************************************
ECHO * BATCH FILE
ECHO ***************************************
ECHO ON
C:\BC\BIN\MAKE.EXE -f TEST.MAK
1.2 运行
使用 MAKETEST.BAT
命令即可启动批处理,如下图所示:
2 复杂工程管理示例
在实际工程项目的创建和管理中,众多的各种文件常会因各种原因而分别放在不同的文件夹中。
例如,第三方代码文件通常不会与系统代码文件放置于同一个文件夹下,用户代码文件也不会与系统代码文件或第三方等其他代码文件混杂在一起。
不仅如此,即使同是用户代码文件,在编译过程中所产生的各种临时的中间文件也会被单独分类放置。
总之,为了清楚有序,我们应该为工程设置多个文件夹目录,从而使不同的代码各有其所。也就是说,我们应该充分利用批处理文件和makefile的强大功能,负起对各个目录的管理责任,使工程的创建工作规范有序,从而尽可能减少不必要的错误,提高工作效率。
接下来我们就使用一个示例工程来说明批处理文件和makefile文件在工程管理上的作用。
2.1 文件体系结构
exp2_7. 本次示例工程文件夹
├─MAIN
│ ├─OBJ 临时目录,中间文件存放在这里
│ ├─SOURCE 用户源文件和链接文件
│ ├─TEST 批处理和makefile脚本存放在这里
│ └─WORK 临时目录,用于编译、链接工作场所
├─PC 第三方源文件
└─PORT
└─PT 另外的第三方源文件
从文件树可以看到,用户的两个文件夹 SOURCE
和 TEST
作为子文件夹存放在 MAIN
文件夹下,这样是为了让文件结构层次更加清晰。
MAIN
文件夹下将会由批处理文件创建两个临时文件夹 WORK
和 OBJ
,其中的 WORK
文件夹为源文件编译、链接提供工作场所,OBJ
文件夹用于暂存编译后产生的中间临时文件。之所以如此,是因为某些工程项目可能不会使用到所有的基础文件(源文件、已经存在的目标文件、头文件等),为了防止混乱,我们常常会把一个工程所需要的基础文件事先复制到 WORK
文件夹,然后就在这个文件夹中进行编译、连接,而把得到的中间目标文件复制到 OBJ
文件夹以备查询。
2.2 批处理文件
MAKETEST.BAT
存放路径:E:\Dosbox\exp2_7\MAIN\TEST\MAKETEST.BAT
ECHO OFF
ECHO ***************************************
ECHO * batch file filename:MAKETEST.BAT
ECHO ***************************************
ECHO ON
MD ..\WORK
MD ..\OBJ
CD ..\WORK
COPY ..\TEST\MAKETEST.MAK TEST.MAK
C:\BC\BIN\MAKE.EXE -f TEST.MAK
CD ..\
DEL WORK
DEL OBJ
RD .\WORK
DEL .\OBJ
2.3 makefile 文件
MAKETEST.MAK
存放路径:E:\Dosbox\exp2_7\MAIN\TEST\MAKETEST.MAK
##############################################
# makefile filename:MAKETEST.MAK
##############################################
# 用变量表示我们使用到的开发工具
BORLAND = C:\BC
CC = $(BORLAND)\BIN\BCC
LINK = $(BORLAND)\BIN\TLINK
##############################################
# 编译选项说明
#
# -l 生成80286实模式代码
# -c 编译为.obj文件
# -I 指示包含头文件所在路径
# -k 采用标准栈帧
# -L 指示库文件所在路径
# -ml Large memory内存模式
# -n 指示生成目标文件的位置
##############################################
# 用变量表示我们使用到的文件路径
SOURCE = ..\SOURCE
PC = ..\..\PC
PT = ..\..\PORT\PT
TARGET = ..\TEST
WORK = ..\WORK
OBJ = ..\OBJ
##############################################
# C编译参数选项变量
C_FLAGS = -c -ml -l -n.\$(OBJ) -k -I$(BORLAND)\INCLUDE -L$(BORLAND)\LIB
##############################################
# 链接参数选项变量
LINK_FLAGS =
##############################################
# 包含头文件变量
INCLUDES = $(SOURCE)\INCLUDES.H \
$(PC)\PC.H \
$(PT)\PT.H
##############################################
# 创建可执行文件(exe)
$(TARGET)\TEST.EXE: \
$(WORK)\INCLUDES.H \
$(OBJ)\TEST.OBJ \
$(OBJ)\PC.OBJ \
$(OBJ)\PT.OBJ \
$(SOURCE)\LINK.LNK
COPY $(SOURCE)\LINK.LNK
$(LINK) $(LINK_FLAGS) @LINK.LNK
COPY $(OBJ)\TEST.EXE $(TARGET)\TEST.EXE
DEL TEST.MAK
##############################################
# 创建各个目标文件(obj)
$(OBJ)\TEST.OBJ: \
$(SOURCE)\TEST.C \
$(SOURCE)\INCLUDES.H
COPY $(SOURCE)\TEST.C
$(CC) $(C_FLAGS) TEST.c
$(OBJ)\PC.OBJ: \
$(PC)\PC.C \
$(PC)\PC.H
COPY $(PC)\PC.C
$(CC) $(C_FLAGS) PC.C
$(OBJ)\PT.OBJ: \
$(PT)\PT.C \
$(PT)\PT.H
COPY $(PT)\PT.C
$(CC) $(C_FLAGS) PT.C
# 完成头文件的复制
$(WORK)\INCLUDES.H: \
$(INCLUDES)
COPY $(SOURCE)\INCLUDES.H
COPY $(PC)\PC.H
COPY $(PT)\PT.H
2.4 源文件、头文件和链接文件
头文件 PC.H
存放路径:E:\Dosbox\exp2_7\PC\PC.H
#ifndef _PC_H_
#define _PC_H_
extern const char *msgC;
#endif
源文件 PC.C
存放路径:E:\Dosbox\exp2_7\PC\PC.C
#include "PC.h"
const char *msgC = "CCCCC";
头文件 PT.H
存放路径:E:\Dosbox\exp2_7\PORT\PT\PT.H
#ifndef _PT_H_
#define _PT_H_
extern const char *msgT;
#endif
源文件 PT.C
存放路径:E:\Dosbox\exp2_7\PORT\PT\PT.C
#include "PT.h"
const char *msgT = "TTTTT";
头文件 INCLUDES.H
存放路径:E:\Dosbox\exp2_7\MAIN\SOURCE\INCLUDES.H
#include "PC.h"
#include "PT.H"
源文件 TEST.C
存放路径:E:\Dosbox\exp2_7\MAIN\SOURCE\TEST.C
#include <stdio.h>
#include "PC.h"
#include "PT.h"
int main(void)
{
unsigned char i = 0;
for (i=0; i<5; i++)
{
printf("%s\n", msgC);
printf(" %s\n", msgT);
}
return 0;
}
链接文件 LINK.LNK
存放路径:E:\Dosbox\exp2_7\MAIN\SOURCE\LINK.LNK
C:\BC\LIB\C0L.OBJ +
..\OBJ\PC.OBJ +
..\OBJ\PT.OBJ +
..\OBJ\TEST.OBJ
..\OBJ\TEST
..\OBJ\TEST
C:\BC\LIB\CL.LIB
2.5 运行结果
启动批处理脚本:
执行可执行文件 TEST.EXE
参考资料:
《嵌入式实时操作系统μCOS-II原理及应用》