Chinaunix首页 | 论坛 | 博客
  • 博客访问: 939675
  • 博文数量: 116
  • 博客积分: 3923
  • 博客等级: 中校
  • 技术积分: 1337
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-23 01:22
文章分类

全部博文(116)

文章存档

2013年(1)

2012年(17)

2011年(69)

2009年(29)

分类: LINUX

2009-04-25 00:53:52

project    : vivi makefile working.
instruction: how is the makefile working of vivi basic QQ2440 develope board.

(1) debugging makefile.

(1.1) Using the "make -f Makefile -n --debug=[basic,verbose,implicit]"
-- option:  -n == Print the commands that would be executed, but do not execute them.
-- option:  -f file == Use file as a makefile.
-- option:  -C dir == Change to directory dir before reading the makefiles or doing anything else.  If multiple -C options are specified,
          each is interpreted  relative  to  the  previous  one: -C / -C etc is equivalent to -C /etc.  This is typically used with
          recursive invocations of make.

(1.2) example for the make command:
-- $ make -f Makefile -n --debug=basic
-- GNU Make 3.80
-- Copyright (C) 2002  Free Software Foundation, Inc.
-- This is free software; see the source for copying conditions.
-- There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
-- PARTICULAR PURPOSE.
-- Reading makefiles...
-- Updating goal targets....
--  File `all' does not exist.
--    File `do-it-all' does not exist.
--      File `Version' does not exist.
--        File `dummy' does not exist.
--       Must remake target `dummy'.
--       Successfully remade target file `dummy'.
--     Must remake target `Version'.
-- rm -f include/compile.h
--     Successfully remade target file `Version'.
--        File `linuxsubdirs' does not exist.
--          File `_dir_drivers' does not exist.
--         Must remake target `_dir_drivers'.
-- ......

(2) setup the basic tool chain of project. (the first part)

VERSION = 0
PATCHLEVEL = 1
SUBLEVEL = 4
VIVIRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)
ARCH := arm

CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
    else if [ -x /bin/bash ]; then echo /bin/bash; \
    else echo sh; fi ; fi)
TOPDIR    := $(shell /bin/pwd)
#
# change this to point to the Linux include directory
#
LINUX_INCLUDE_DIR    = /usr/local/arm/2.95.3/include

VIVIPATH           = $(TOPDIR)/include

HOSTCC          = gcc
HOSTCFLAGS      = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer

CROSS_COMPILE   = /usr/local/arm/2.95.3/bin/arm-linux-
#
# 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
NM              = $(CROSS_COMPILE)nm
STRIP           = $(CROSS_COMPILE)strip
OBJCOPY         = $(CROSS_COMPILE)objcopy
OBJDUMP         = $(CROSS_COMPILE)objdump
MAKEFILES       = $(TOPDIR)/.config
MD5SUM        = md5sum
PERL            = perl
AWK        = awk


(3) Recurse invoke makefile to make module. (the second part)
when you use "make vivi" command , the make tool will automactically test
the file which need to update and need to compile.

example command: "make vivi"
(3.1) fragment code from $TOPDIR/Makefile

SUBDIRS         = drivers lib

vivi: include/version.h $(CONFIGURATION) init/main.o init/version.o linuxsubdirs
    $(LD) -v $(LINKFLAGS) \
        $(HEAD) \
        $(CORE_FILES) \
        $(DRIVERS) \
        $(LIBS) \
        -o vivi-elf $(CLIBS)
    $(NM) -v -l vivi-elf > vivi.map
    $(OBJCOPY) -O binary -S vivi-elf vivi $(OBJCOPYFLAGS)

linuxsubdirs: $(patsubst %, _dir_%, $(SUBDIRS))

$(patsubst %, _dir_%, $(SUBDIRS)) : include/version.h
    $(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" -C $(patsubst _dir_%, %, $@)


(3.2) First step: Suppose that the depandence objects "include/version.h $(CONFIGURATION) init/main.o init/version.o"
      are all the latest one, need not update. we are now focus on "linuxsubdirs".

(3.2.1) Because of "linuxsubdirs: $(patsubst %, _dir_%, $(SUBDIRS))", will replace by make tool as like that
        "linuxsubdirs: _dir_drivers _dir_lib", and we known that dependence object "_dir_drivers _dir_lib"
        is prefix by make buildin function, so we must check the "_dir_drivers _dir_lib" should be create, and
        if the dependence object "include/version.h" have updated, and then execute command
        "$(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" -C $(patsubst _dir_%, %, $@)".

(3.2.2) command "$(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" -C $(patsubst _dir_%, %, $@)" is the key to recurly invoke
        every subdirectory Makefile. this command should be translate as
        "$(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" -C drivers lib". so execute every sub-makefile automactically.

(3.3) Second step: Makefile under driver direcotry show as bellow
===================================================================
#
# Makefile for the Linux kernel device drivers.
#
# 15 Sep 2000, Christoph Hellwig
# Rewritten to use lists instead of if-statements.
#

subdir-y :=     serial
subdir-$(CONFIG_MTD) += mtd

include $(TOPDIR)/Rules.make

===================================================================

this makefile is resposible for indicating include sub directory for make.
and then will deliver the job to $(TOPDIR)/Rules.make.

Let us to view the common makefile "$(TOPDIR)/Rules.make" how to invoke their
compiler to work.

(3.4) Third step: Makefile under $(TOPDIR)/Rules.make show as following.

===================================================================
(part A)
#
# Get things started.
#
first_rule: sub_dirs
    $(MAKE) all_targets

....... (ellipsis)

SUB_DIRS    := $(subdir-y)

....... (ellipsis)

===================================================================
(part B)

#
# Common rules
#

%.s: %.c
    $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -S $< -o $@

....... (ellipsis)

%.o: %.c
    $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -c -o $@ $<
    @ ( \
        echo 'ifeq ($(strip $(subst $(comma),:,$(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@))),$$(strip $$(subst $$(comma),:,$$(CFLAGS) $$(EXTRA_CFLAGS) $$(CFLAGS_$@))))' ; \
        echo 'FILES_FLAGS_UP_TO_DATE += $@' ; \
        echo 'endif' \
    ) > $(dir $@)/.$(notdir $@).flags

%.o: %.s
    $(AS) $(AFLAGS) $(EXTRA_CFLAGS) -o $@ $<

%.s: %.S
    $(CPP) $(AFLAGS) $(EXTRA_AFLAGS) $(AFLAGS_$@) $< > $@

%.o: %.S
    $(CC) $(AFLAGS) $(EXTRA_AFLAGS) $(AFLAGS_$@) -c -o $@ $<

....... (ellipsis)

===================================================================
(part C)

all_targets: $(O_TARGET) $(L_TARGET)

===================================================================
(part D)

#
# Rule to compile a set of .o files into one .o file
#
ifdef O_TARGET
$(O_TARGET): $(obj-y)
    rm -f $@
    ifneq "$(strip $(obj-y))" ""
    $(LD) $(EXTRA_LDFLAGS) -r -o $@ $(filter $(obj-y), $^)
    else
    $(AR) rcs $@
    endif
    @ ( \
        echo 'ifeq ($(strip $(subst $(comma),:,$(EXTRA_LDFLAGS) $(obj-y))),$$(strip $$(subst $$(comma),:,$$(EXTRA_LDFLAGS) $$(obj-y))))' ; \
        echo 'FILES_FLAGS_UP_TO_DATE += $@' ; \
        echo 'endif' \
    ) > $(dir $@)/.$(notdir $@).flags
endif # O_TARGET

===================================================================
(part E)

#
# A rule to make subdirectories
#
subdir-list = $(sort $(patsubst %,_subdir_%,$(SUB_DIRS)))
sub_dirs: dummy $(subdir-list)

ifdef SUB_DIRS
$(subdir-list) : dummy
    $(MAKE) -C $(patsubst _subdir_%,%,$@)
endif

===================================================================

Here focus on the part E, how to invoke sub-drictory's makefile.
we can see that looks like aforementioned makefile, but it have additional part
for invoke recursively, "ifdef SUB_DIRS" sentence says that if define SUB_DIRS,
then invoke sub-directory's makefile, otherwise according the Part B
"Common rules" to create the *.o object.

阅读(1191) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~