一、概述

  笔者已经写了一篇实现目标文件与源码分开的makefile测试实验,但是觉得不够完美,没有更多的体现u-boot Makefile的工作原理和特点。所以,决定重新修订,使之更加充分的接近u-boot Makfefile的原貌。

  至于,u-boot Makfefile的整体论述和特点,笔者在u-boot Makefile整体解析文中已经详细论述,不在多言。

二、测试源码构成

  整个测试源码,由四个文件夹构成,三个是源文件夹,分别包含源程序(.c)和Makefile。顶层目录中包含config.mk和rules.mk文件。

三、测试源码注释

1、顶层Makfile

ifneq ($(BUILD_DIR),)    #此变量在命令行选择定义,定义了就是目标文件和源码文件分开,否则是同一个
saved-output := $(BUILD_DIR)
# Attempt to create a output directory.
$(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR}) #创建目录BUILD_DIR
# Verify if it was successful.
BUILD_DIR := $(shell cd $(BUILD_DIR) && /bin/pwd)
$(if $(BUILD_DIR),,$(error output directory "$(saved-output)" does not exist))
endif # ifneq ($(BUILD_DIR),)
OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR)) #目标文件生成的根目录,可以认为是一个常量,\
区别于obj
SRCTREE := $(CURDIR) #CURDIR是当前目录的路径,目录改变,它随之改变
TOPDIR := $(SRCTREE)
LNDIR := $(OBJTREE)
export SRCTREE OBJTREE TOPDIR ifneq ((OBJTREE),(SRCTREE))
REMOTE_BUILD :=
export REMOTE_BUILD #此变量会被config.mk所调用
endif include $(TOPDIR)/config.mk #config.mk中定义了obj、CC等变量,下边的内容需要调用 CROSS_COMPILE =
export CROSS_COMPILE OBJS = add/add.o sub/sub.o test/test.o #需要生成的目标文件
OBJS := $(addprefix $(obj),$(OBJS)) #需要生成目标文件的完整路径
.PHONY : $(OBJS) #确保源文件修改了,目标文件能够自动重建 ALL = $(obj)program #在program前边也加上了前缀obj
all: $(ALL) $(obj)program: $(OBJS)
$(CC) $^ -o $@ $(OBJS):
make -C $(dir $(subst $(obj),,$@)) #依次执行各个子目录中的makefile SUBDIRS = add/ sub/ test/
.PHONY: clean distclean
clean:
for f in $(SUBDIRS); do make -C $$f clean; done //依次在各个子目录中删除
rm -f $(ALL) distclean:
for f in $(SUBDIRS); do make -C $$f distclean; done
rm -f $(ALL)

2、config.mk

ifneq ($(OBJTREE),$(SRCTREE)) #判断是否选择目标文件生成目录和源码目录分开
ifeq ($(CURDIR),$(SRCTREE)) #以下内容是目标文件生成目录和源码目录分开的情况
dir :=
else
dir := $(subst $(SRCTREE)/,,$(CURDIR))
endif obj := $(if $(dir),$(OBJTREE)/$(dir)/,$(OBJTREE)/) #确定要生成目标文件的完整路径,
#注意这是个变量,在不同的子目录中,执行makefile,obj的值相应的发生变化
src := $(if $(dir),$(SRCTREE)/$(dir)/,$(SRCTREE)/) #确定当前源文件的目录 $(shell mkdir -p $(obj)) #创建目标文件的完整路径,注意gcc命令并不能自动生成缺少的路径,所以需要事先创建
else #以下内容是目标文件生成目录和源码目录同一的情况
obj := #目标文件与源文件目录相同时,obj没有必要赋值
src :=
endif #以下的规则将用来编译子目录中的源文件
# Include the make variables (CC, etc...)
#
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump ######################################################################### ifndef REMOTE_BUILD %.s: %.S
$(CPP) $(AFLAGS) -o $@ $<
%.o: %.S
$(CC) $(AFLAGS) -c -o $@ $<
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $< else $(obj)%.s: %.S
$(CPP) $(AFLAGS) -o $@ $<
$(obj)%.o: %.S
$(CC) $(AFLAGS) -c -o $@ $<
$(obj)%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
endif #########################################################################

3、rules.mk

#########################################################################

$(obj).depend: $(src)Makefile $(TOPDIR)/config.mk $(SRCS) #SRCS在子目录Makefile中定义
@rm -f $@
@for f in $(SRCS); do \
g=`basename $$f | sed -e 's/\(.*\)\.\w/\1.o/'`; \
$(CC) -M $(HOST_CFLAGS) $(CPPFLAGS) -MQ $(obj)$$g $$f >> $@ ; \
done

#########################################################################

4、子目录Makefile

include $(TOPDIR)/config.mk #包含config.mk

COBJS    := add.o #.c文件生成的目标文件
SOBJS := #.S文件生成的目标文件 SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) #所有参与编译的源文件(.c、.S)
OBJS := $(addprefix $(obj),$(COBJS))#添加目录obj
SOBJS := $(addprefix $(obj),$(SOBJS)) all: $(obj).depend $(OBJS) #先生成依赖文件,然后才能编译源程序 clean:
rm -f $(SOBJS) $(OBJS) distclean: clean
rm -f $(LIB) $(obj).depend ######################################################################### # defines $(obj).depend target
include $(SRCTREE)/rules.mk #包含rules.mk sinclude $(obj).depend #包含.depend文件 #########################################################################

 四、编译方法

1、目标文件与源码混在一起

直接在顶层目录中执行:#make

2、目标文件与源码分开

方法一:

先声明个环境变量:#exprort BUILD_DIR=/tmp/build    //这里以/tmp/build为例

然后在顶层目录中执行:#make

方法二:

直接在顶层目录中执行:#make BUILD_DIR=/tmp/build

附:U-bootMakefileTest.zip

u-boot Makefile Source Test的更多相关文章

  1. linux内核的makefile.txt讲解

    linux内核的linux-3.6.5\Documentation\kbuild\makefiles.txt Linux Kernel Makefiles This document describe ...

  2. Linux内核Makefile文件(翻译自内核手册)

    --译自Linux3.9.5 Kernel Makefiles(内核目录documention/kbuild/makefiles.txt) kbuild(kernel build) 内核编译器 Thi ...

  3. Linux Kernel的Makefile与Kconfig文件的语法

    https://www.kernel.org/doc/Documentation/kbuild/kconfig-language.txt Introduction ------------ The c ...

  4. kernel Makefile Kconfig说明

    实际文档位置:Documentation/kbuild/makefiles.txt,此为翻译稿. *************************************************** ...

  5. Linux 2.6内核Makefile浅析

    1 概述 Makefile由五个部分组成: Makefile:根目录Makefile,它读取.config文件,并负责创建vmlinux(内核镜像)和modules(模块文件). .config:内核 ...

  6. 【linux】 Makefile之make menuconfig /uImage

      欢迎转载,转载时请保留作者信息,谢谢. 邮箱:tangzhongp@163.com 博客园地址:http://www.cnblogs.com/embedded-tzp Csdn博客地址:http: ...

  7. Makefile常用万能模板(包括静态链接库、动态链接库、可执行文件)

    本文把makefile 分成了三份:生成可执行文件的makefile,生成静态链接库的makefile,生成动态链接库的makefile. 这些makefile都很简单,一般都是一看就会用,用法也很容 ...

  8. Spring Boot Reference Guide

    Spring Boot Reference Guide Authors Phillip Webb, Dave Syer, Josh Long, Stéphane Nicoll, Rob Winch,  ...

  9. makefile  模板 (template)

    本文把makefile 分成了三份:生成可执行文件的makefile,生成静态链接库的makefile,生成动态链接库的makefile. 这些makefile都很简单,一般都是一看就会用,用法也很容 ...

随机推荐

  1. 我最喜欢的visual studio 2013的新特性

    博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:我最喜欢的visual studio 2013的新特性.

  2. Sublime_text3怎么运行php代码

    开发神奇sublime写代码真的好爽,之前听说是神器,但是没去用,觉得用eclipse写php代码,用dw写html够用了,用了一下sublime,哈哈,爽爆了. 除了写前端代码外,还需要写php代码 ...

  3. WDCP是什么 关于WDCP的详细介绍

    WDCP是WDlinux Control Panel的简称,是一套用PHP开发的Linux服务器管理系统以及虚拟主机管理系统,,旨在易于使用Linux系统做为我们的网站服务器,以及平时对Linux服务 ...

  4. MVC中一般为什么用IQueryable而不是用IList

    IList(IList<T>)会立即在内存里创建持久数据,这就没有实现“延期执行(deferred execution)”,如果被加载的实体有关联实体(associations),此关联实 ...

  5. LabVIEW设计模式系列——各种各样的状态机

  6. Flume NG中的Netcat Source

    NetCat是一个非常简单的Unix工具,可以读.写TCP或UDP网络连接(network connection)中数据 在Flume中的netcat支持Flume与NetCat整合,flume可以使 ...

  7. PureMVC(JS版)源码解析(九):View类

    在讲解View类之前,我们先回顾一下PureMVC的模块划分:      在PureMVC中M.V.C三部分由三个单例类管理,分别是Model/View/Controller.PureMVC中另外一个 ...

  8. php跨服务器信息获取之cURL

    原文地址:php跨服务器信息获取之cURL作者:陌上花开 其实有几种方式 $content = file_get_contents("http://www.nettuts.com" ...

  9. css hack方法总结

    IE6识别:下划线 _ 和 星号 *IE7识别:星号 *IE6-IE10识别: \9 css hack方式,条件注释法<!--[if IE]>这段文字只在IE浏览器显示<![endi ...

  10. navicat 数据库管理工具快捷键

    最近在使用navicat 管理数据库中,因为经常要写一些sql的,但是每次都要鼠标点击运行,感觉很不爽,于是找到navicat(以下) 快捷键(最常用的): ctrl + q 打开查询窗口 ctrl ...