一、概述

  笔者已经写了一篇实现目标文件与源码分开的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. MySQL数据库事务剖析

    MySQL数据库事务剖析 事务就是一组原子性的SQL查询,是一个独立的执行单元.事务内的语句,要么全部执行成功,要么全部执行失败. 1.事务的标准特征 一个运行良好的事务处理系统,必须具备原子性.一致 ...

  2. jquerymobile知识点:实现toolbar下方显示,自定义图标!

    css: .nav-glyphish-example .ui-btn .ui-btn-inner { padding-top: 40px !important; } .nav-glyphish-exa ...

  3. way/XMPP

    http://git.oschina.net/way/XMPP

  4. [TypeScript] Generating Definition Files

    TypeScript allows you to generate definition files for your own libraries. This lesson shows you how ...

  5. MyEclipse10.0安装jad反编译插件

    1.下载反编译工具jad(下面提供下载) 将下载下来的jadstar158.zip解压缩,将jad.exe文件放入jdk安装目录下 如:C:\Program Files\Java\jdk1.6.0_2 ...

  6. 通过查看mysql 配置参数、状态来优化你的mysql

    mysql的监控方法大致分为两类: 1.连接到mysql数据库内部,使用show status,show variables,flush status 来查看mysql的各种性能指标. 2. 直接使用 ...

  7. APUE 读书笔记 -----孤儿进程与僵尸进程[总结] +数据结构+C

    http://www.cnblogs.com/Anker/p/3271773.html

  8. java 流程执行 循环 foreach循环

    一. if分支 1. 结构  if  else if   else 2.执行原则 if  if  if 结构  会一直去执行()里的判断语句 if else if  else if 结构  只要一条( ...

  9. android之AlertDialog 点击其他区域自动消失

    遇到一个问题记录下来,在开发中使用了AlertDialog,想点击屏幕其他区域的时候让这个dialog消失,一开始不做任何设置,在小米手机可以正常显示,但是在三星中却有问题,后来发现少了一个属性: V ...

  10. as3 打开窗口类

    package FlashCode.utils{ import flash.display.Sprite; import flash.net.URLRequest; import flash.net. ...