专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
嵌入式
嵌入式系统中嵌套Makefile的编写
2019-07-12 18:49
发布
生成海报
站内文章
/
嵌入式Linux
17277
0
1642
嵌入式系统中
Makefile的作用不言而喻,下面我写一下嵌套Makefile的编写。
实验环境】
Ubuntu 8.10发行版、gcc等工具
我们要创建的目录结构如下:
一、创建顶层目录
我们首先在用户目录下创建一个
makefileTest
的文件夹:
#cd /home/linux/
#mkdir makefileTest
#cd makefileTest
创建好需要用到的文件夹
#mkdir f1 f2 main obj include
进入
include
文件夹创建一个共用头文件
#cd include
#vim myinclude.h
输入如下内容:
#include
保存退出
返回顶层目录
:
#cd ..
二、创建顶层
Makefile
文件
#vim Makefile
输入以下内容:
CC = gcc
SUBDIRS = f1
f2
main
obj
OBJS = f1.o f2.o main.o
BIN = myapp
OBJS_DIR = obj
BIN_DIR = bin
export CC OBJS BIN OBJS_DIR BIN_DIR
all : CHECK_DIR $(SUBDIRS)
CHECK_DIR :
mkdir -p $(BIN_DIR)
$(SUBDIRS) : ECHO
make -C $@
ECHO:
@echo $(SUBDIRS)
@echo begin compile
CLEAN :
@$(RM) $(OBJS_DIR)/*.o
@rm -rf $(BIN_DIR)
三、进入在
f1
目录下创建
makefile
#cd f1
#vim f1.c
输入如下测试代码:
#include “../include/myinclude.h”
void print1()
{
printf("Message from f1.c... ");
return;
}
保存退出。
#vim Makefile
输入如下内容:
../$(OBJS_DIR)/f1.o: f1.c
$(CC) -c $^ -o $@
保存退出。
进入
f2
目录
#cd ../f2
#vim f2.c
输入如下测试代码:
#include “../include/myinclude.h”
void print2()
{
printf("Message from f2.c… ");
return;
}
保存退出。
#vim Makefile
输入如下内容:
../$(OBJS_DIR)/f2.o: f2.c
$(CC) -c $^ -o $@
保存退出。
进入
main
目录
#cd ../main
#vim main.c
输入如下内容:
#include
int main()
{
print1();
print2();
return 0;
}
保存退出。
#vim Makefile
输入如下内容:
../$(OBJS_DIR)/main.o: main.c
$(CC) -c $^ -o $@
保存退出。
进入
obj
目录
#cd ../obj
#vim Makefile
输入如下内容:
../$(BIN_DIR)/$(BIN) : $(OBJS)
$(CC) -o $@ $^
好了,到此准备工作已经完毕,然我们来测试一下写的
makefile
是否好用。
进入顶层
Makefile
所在目录,即
makefileTest
目录。
#make
会出现如下信息:
目录树结构如下:
我们看到在
bin
目录下生成了我们的目标文件
myapp
,在
obj
目录下生成了
.o
的中间文件。
让我们运行下
myapp
看下结果吧。
#bin/myapp
也可以用如下命令清除中间文件和目标文件,恢复
make
之前的状态:
#make CLEAN
我们可以看到已经变为
make
之前的目录状态了。
大功告成。最后给大家解释一下顶层
makefile
中一些命令的的含义吧。
1
、我们注意到有一句
@echo $(SUBDIRS)
@echo其实是一句显示命令
通常,
make
会把其要执行的命令行在命令执行前输出到屏幕上。当我们用
“@”
字符在命令行前,那么,这个命令将不被
make
显示出来,最具代表性的例子是,我们用这个功能来像屏幕显示一些信息。如:
@echo 正在编译
XXX
模块
......
当
make
执行时,会输出
“
正在编译
XXX
模块
......”
字串,但不会输出命令,如果没有
“@”
,那么,
make
将输出:
echo 正在编译
XXX
模块
......
正在编译
XXX
模块
......
如果
make
执行时,带入
make
参数
“-n”
或
“--just-print”
,那么其只是显示命令,但不会执行命令,这个功能很有利于我们调试我们的
Makefile
,看看我们书写的命令是执行起来是什么样子的或是什么顺序的。
而
make
参数
“-s”
或
“--slient”
则是全面禁止命令的显示。
2
、
@(RM)
并不是我们自己定义的变量,那它是从哪里来的呢?
通常在清除文件的伪目标所定义的命令中“
rm
”使用选项“–
f
”(
--force
)来防止
在缺少删除文件时出错并退出,使“
make clean
”过程失败。也可以在“
rm
”之前加
上“
-
”来防止“
rm
”错误退出,这种方式时
make
会提示错误信息但不会退出。为了
不看到这些讨厌的信息,需要使用上述的第一种方式。
另外
make
存在一个内嵌隐含变量“
RM
”,它被定义为:“
RM = rm
–
f
” 。因此在书
写“
clean
”规则的命令行时可以使用变量“
$(RM)
”来代替“
rm
”,这样可以免出现一
些不必要的麻烦!这是我们推荐的用法。
3
、
make -C $@
这是一句嵌套
makefile
的语法,在一些大的工程中,我们会把我们不同模块或是不同功能的源文件放在不同的目录中,我们可以在每个目录中都书写一个该目录的
Makefile
,这有利于让我们的
Makefile
变得更加地简洁,而不至于把所有的东西全部写在一个
Makefile
中,这样会很难维护我们的
Makefile
,这个技术对于我们模块编译和分段编译有着非常大的好处。
例如,我们有一个子目录叫
subdir
,这个目录下有个
Makefile
文件,来指明了这个目录下文件的编译规则。那么我们总控的
Makefile
可以这样书写:
subsystem:
cd subdir && $(MAKE)
其等价于:
subsystem:
$(MAKE) -C subdir
定义
$(MAKE)
宏变量的意思是,也许我们的
make
需要一些参数,所以定义成一个变量比较利于维护。这两个例子的意思都是先进入
“subdir”
目录,然后执行
make
命令。
4. export CC OBJS BIN OBJS_DIR BIN_DIR
我们把这个
Makefile
叫做
“
总控
Makefile”
,总控
Makefile
的变量可以传递到下级的
Makefile
中(如果你显示的声明),但是不会覆盖下层的
Makefile
中所定义的变量,除非指定了
“-e”
参数。
如果你要传递变量到下级
Makefile
中,那么你可以使用这样的声明:
export
Ta的文章
更多
>>
嵌入式系统中嵌套Makefile的编写
0 个评论
热门文章
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮