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.
阅读(1243) | 评论(0) | 转发(0) |