您的位置:首页 > 其它

解释一个 Makefile 文件

2015-09-11 13:09 399 查看
学习一门技术的目的就是要把它拿来使用,因此,对技术的研究不存在最高境界,只存在实不实用。Makefile的知识也杂七杂入挺多的,真讨厌GNU那帮人一天在那里没事发明新东西,虽然说都有用,但我们学起来就太麻烦啦。因此,不求把Makefile知识学完,只求能满足实际需求。而最实际的需求就是,把下面的Makefile内容看懂吧

IDENT=-D_DEBUG-D_LIBC -DMIPS -DCONS_BAUD="B115200" -DRADEON7000-DVGA_BASE="0xb0000000"

ENDIAN=EL

.SUFFIXES: .S .c .cpp .o

CROSS_COMPILE =mipsisa32-elf-

#

# Include the make variables (CC, etc...)

#

AS = $(CROSS_COMPILE)as

LD =$(CROSS_COMPILE)ld

CC = $(CROSS_COMPILE)gcc

GPP =$(CROSS_COMPILE)g++

CPP = $(CC) -E

AR =$(CROSS_COMPILE)ar

NM =$(CROSS_COMPILE)nm

STRIP =$(CROSS_COMPILE)strip

OBJCOPY =$(CROSS_COMPILE)objcopy

OBJDUMP = $(CROSS_COMPILE)objdump

RANLIB =$(CROSS_COMPILE)ranlib

SIZE = $(CROSS_COMPILE)size

OPT?= -O2

#source tree is located via $S relative to the compilation directory

ifndef S

S:=.

endif

#Defines

TARGET=${S}/init/

MACHINE=mips

MACHINE_ARCH=mips

COMPILEDIR=./include/mips/include

OBJDIR=${COMPILEDIR}

PMONDIR=${S}

INCLUDES= -I. -I${S}/include -I${S}/lib-I${S}\

-I${TARGET} -I${COMPILEDIR}-nostdinc

CPPFLAGS= ${INCLUDES} ${IDENT} -D_KERNEL-D_CNOS_\

-${ENDIAN} -mno-abicalls -mips3-mcpu=r4000 \

-fno-rtti -fomit-frame-pointer -nostdinc -nostdlib\

-fno-exceptions -fcheck-new

CWARNFLAGS= -Wall -Wstrict-prototypes \

-Wno-uninitialized -Wno-format-Wno-main \

-Wnon-virtual-dtor -Wno-parentheses\

-Wno-pmf-conversions-Wno-pointer-arith -Wno-unused-function\

-Wundef

CFLAGS= ${DEBUG} ${CWARNFLAGS} ${OPT} -G0

AFLAGS= -D_LOCORE -G0

LFLAGS= -${ENDIAN} -N -G 0-T$(S)/ldscript/ld.script -e start

STRIPFLAGS= -g -S --strip-debug

HOSTCC?= ${CC}

HOSTED_CPPFLAGS=${CPPFLAGS:S/^-nostdinc$//}

HOSTED_CFLAGS= ${CFLAGS}

#compile rules: rules are named ${TYPE}_${SUFFIX}${CONFIG_DEP}

# where TYPE is NORMAL, DRIVER, or PROFILE}; SUFFIX is the file suffix,

# capitalized (e.g. C for a .c file), and CONFIG_DEP is _C if the file

# is marked as config-dependent.

USRLAND_C= ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} -c$<

USRLAND_C_C= ${CC} ${CFLAGS}${CPPFLAGS} ${PROF} ${PARAM} -c $<

NORMAL_C= ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} -c$<

NORMAL_C_C= ${CC} ${CFLAGS}${CPPFLAGS} ${PROF} ${PARAM} -c $<

NORMAL_GPP= ${GPP} ${CFLAGS} ${CPPFLAGS} ${PROF} -c $<

DRIVER_C= ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} -c$<

DRIVER_C_C= ${CC} ${CFLAGS}${CPPFLAGS} ${PROF} ${PARAM} -c $<

NORMAL_S= ${CC} ${AFLAGS} ${CPPFLAGS} -c$<

NORMAL_S_C= ${AS} ${COPTS} ${PARAM} $< -o $@

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

##

##

##

OBJS= init.o \

Hal.o \

Serial.o \

Cnos.o \

Mm.o \

Fs.o \

interrupt.o \

mips.o \

KrnlDebug.o \

desktop.o \

surface.o \

taskbar.o \

window.o \

button.o \

Test.o

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

## LIB

##

LIBS=string.o unicodefont16.a

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

#

# dirvers

#

DIRVERS = ATIR7000.o i8042.o pci.o ohci.o

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

# load lines for config "xxx" will be emitted as:

# xxx: ${SYSTEM_DEP}

# ${SYSTEM_LD_HEAD}

# ${SYSTEM_LD}

# ${SYSTEM_LD_TAIL}

SYSTEM_OBJ= start.o ${OBJS} ${LIBS} ${DIRVERS}

SYSTEM_DEP= Makefile${SYSTEM_OBJ}

SYSTEM_LD_HEAD= rm -f$@

SYSTEM_LD= @echo ${LD} ${LFLAGS} -o $@'$${SYSTEM_OBJ}'; \

${LD} ${LFLAGS} -o $@${SYSTEM_OBJ}

SYSTEM_LD_TAIL= @${SIZE} $@; chmod 755$@ ; \

${OBJCOPY} -O binary $@ $@.bin

DEBUG?=

ifeq (${DEBUG}, "-g")

LFLAGS+= -X

SYSTEM_LD_TAIL+=; \

echo cp $@ $@.gdb; rm -f $@.gdb;cp $@ $@.gdb; \

echo ${STRIP} ${STRIPFLAGS} $@;${STRIP} ${STRIPFLAGS} $@

else

LFLAGS+= -S

endif

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

all: cnos Makefile

cnos:${SYSTEM_DEP}

${SYSTEM_LD_HEAD}

${SYSTEM_LD}

${SYSTEM_LD_TAIL}

clean::

rm -f tags *.[io] [a-z]*.s\

cnos cnos.bin cnos.txtcnos_elf.txt

dump:

$(OBJDUMP) -DS cnos >cnos.txt

tags:

@echo "see $S/kern/Makefile fortags"

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

# %.S

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

start.o: $S/init/start.S Makefile

${NORMAL_S}

mips.o: $S/kern/ke/mips.S

${NORMAL_S}

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

# %.CPP

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

init.o: $S/init/init.cpp

${NORMAL_GPP}

Hal.o: $S/hal/Hal.cpp

${NORMAL_GPP}

Serial.o: $S/hal/Serial.cpp

${NORMAL_GPP}

Cnos.o: $S/kern/ke/Cnos.cpp

${NORMAL_GPP}

Mm.o: $S/mm/Mm.cpp

${NORMAL_GPP}

Fs.o: $S/fs/Fs.cpp

${NORMAL_GPP}

interrupt.o: $S/kern/ke/interrupt.cpp

${NORMAL_GPP}

Test.o: $S/test/Test.cpp

${NORMAL_GPP}

KrnlDebug.o:$S/kern/kd/KrnlDebug.cpp

${NORMAL_GPP}

desktop.o:$S/subsystems/gdi/desktop.cpp

${NORMAL_GPP}

surface.o:$S/subsystems/gdi/surface.cpp

${NORMAL_GPP}

taskbar.o:$S/subsystems/gdi/taskbar.cpp

${NORMAL_GPP}

window.o:$S/subsystems/gdi/window.cpp

${NORMAL_GPP}

button.o:$S/subsystems/gdi/button.cpp

${NORMAL_GPP}

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

#

# libfile

#

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

string.o: $S/lib/string.cpp

${NORMAL_GPP}

unicodefont16.a: $S/media/font/unicodefont16.cpp

${GPP} ${CFLAGS} ${CPPFLAGS}${PROF} -o unicodefont16.a -c $<

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

#

# driverfile

#

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

ATIR7000.o: $S/dev/video/atir7000/ATIR7000.cpp

${NORMAL_GPP}

i8042.o: $(S)/dev/input/i8042/i8042.cpp

${NORMAL_GPP}

pci.o: $(S)/dev/bus/pci/pci.cpp

${NORMAL_GPP}

ohci.o: $(S)/dev/bus/usb/ohci.cpp

${NORMAL_GPP}

这个Makefile不算复杂(还算是人写给人看的,没有使用GNU提供的autoconf,automake工具,它们产生的文件太恐怖了,不是给人看的~~)下面来一行一行讲解。

IDENT=-D_DEBUG-D_LIBC -DMIPS -DCONS_BAUD="B115200" -DRADEON7000-DVGA_BASE="0xb0000000"

ENDIAN=EL

定义了两个字符串 IDENT 和 ENDIAN,IDENT的内容代表的意义后面再讲解;

.SUFFIXES: .S .c .cpp .o

这句定义make工具隐含规则准备操作的文件的后缀名;

CROSS_COMPILE =mipsisa32-elf-

定义一个字符串变量CROSS_COMPILE,一般在交叉编译环境中会经常看到这样的定义;

#

# Include the make variables (CC, etc...)

#

AS = $(CROSS_COMPILE)as

LD =$(CROSS_COMPILE)ld

CC = $(CROSS_COMPILE)gcc

GPP =$(CROSS_COMPILE)g++

CPP = $(CC) -E

AR =$(CROSS_COMPILE)ar

NM =$(CROSS_COMPILE)nm

STRIP =$(CROSS_COMPILE)strip

OBJCOPY =$(CROSS_COMPILE)objcopy

OBJDUMP = $(CROSS_COMPILE)objdump

RANLIB =$(CROSS_COMPILE)ranlib

SIZE = $(CROSS_COMPILE)size

这一段定义了一套编译工具变量,这里引用了前面定义的变量 CROSS_COMPILE(可以看到定义变量的好处了,以后修改可以很方便);

OPT?= -O2

这句定义优化级别,加个?号表示如果此变量以前被定义过,就不再赋值了,否则要赋值;

#source tree is located via $S relative to the compilation directory

ifndef S

S:=.

endif

这里也用到了类似C语言的条件编译命令,这里是想定义一个变量,用来指示当前的编译根目录。:=也是赋值号, . 号表示当前目录;

#Defines

TARGET=${S}/init/

MACHINE=mips

MACHINE_ARCH=mips

COMPILEDIR=./include/mips/include

OBJDIR=${COMPILEDIR}

PMONDIR=${S}

继续定义一些方便编译操作的变量。${}和 $() 功能都是引用字符串变量的值。

INCLUDES= -I. -I${S}/include -I${S}/lib-I${S}\

-I${TARGET} -I${COMPILEDIR}-nostdinc

这一句定义编译时要包含的头文件的路径,实际上是定义的搜索路径。-I 是gcc定义的要找一个路径的语法前缀。-nostdinc表示不要把系统提供的头文件路径给包含进来,这样就防止了系统头文件对我们自己开发的系统头文件的干扰;

CPPFLAGS= ${INCLUDES} ${IDENT} -D_KERNEL-D_CNOS_\

-${ENDIAN} -mno-abicalls -mips3-mcpu=r4000 \

-fno-rtti -fomit-frame-pointer -nostdinc -nostdlib\

-fno-exceptions -fcheck-new

这里定义一些gcc编译时的参数,用到了前面定义的一些字符串变量。现在还不懂 -D_KERNEL -D_CNOS_ 是啥意思;

CWARNFLAGS= -Wall -Wstrict-prototypes \

-Wno-uninitialized -Wno-format-Wno-main \

-Wnon-virtual-dtor -Wno-parentheses\

-Wno-pmf-conversions-Wno-pointer-arith -Wno-unused-function\

-Wundef

这里设置gcc编译时的警告级别,参数的意义要看gcc手册才能清楚;

CFLAGS= ${DEBUG} ${CWARNFLAGS} ${OPT} -G0

AFLAGS= -D_LOCORE -G0

LFLAGS= -${ENDIAN} -N -G 0-T$(S)/ldscript/ld.script -e start

STRIPFLAGS= -g -S --strip-debug

这里定义标准的几个编译时环境变量,用到了前面的定义;

HOSTCC?= ${CC}

HOSTED_CPPFLAGS=${CPPFLAGS:S/^-nostdinc$//}

HOSTED_CFLAGS= ${CFLAGS}

(???)这一块功能不知道是干什么用的;

#compile rules: rules are named ${TYPE}_${SUFFIX}${CONFIG_DEP}

# where TYPE is NORMAL, DRIVER, or PROFILE}; SUFFIX is the file suffix,

# capitalized (e.g. C for a .c file), and CONFIG_DEP is _C if the file

# is marked as config-dependent.

USRLAND_C= ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} -c$<

USRLAND_C_C= ${CC} ${CFLAGS}${CPPFLAGS} ${PROF} ${PARAM} -c $<

NORMAL_C= ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} -c$<

NORMAL_C_C= ${CC} ${CFLAGS}${CPPFLAGS} ${PROF} ${PARAM} -c $<

NORMAL_GPP= ${GPP} ${CFLAGS} ${CPPFLAGS} ${PROF} -c $<

DRIVER_C= ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} -c$<

DRIVER_C_C= ${CC} ${CFLAGS}${CPPFLAGS} ${PROF} ${PARAM} -c $<

NORMAL_S= ${CC} ${AFLAGS} ${CPPFLAGS} -c$<

NORMAL_S_C= ${AS} ${COPTS} ${PARAM} $< -o $@

(???)难~~~这一段好像是定义不同的编译规则的,分几种不同的目的。

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

##

##

##

OBJS= init.o \

Hal.o \

Serial.o \

Cnos.o \

Mm.o \

Fs.o \

interrupt.o \

mips.o \

KrnlDebug.o \

desktop.o \

surface.o \

taskbar.o \

window.o \

button.o \

Test.o

普通文件目标定义

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

## LIB

##

LIBS=string.o unicodefont16.a

库文件目标(包括中文字库)

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

#

# dirvers

#

DIRVERS = ATIR7000.o i8042.o pci.o ohci.o

驱动程序目标

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

# load lines for config "xxx" will be emitted as:

# xxx: ${SYSTEM_DEP}

# ${SYSTEM_LD_HEAD}

# ${SYSTEM_LD}

# ${SYSTEM_LD_TAIL}

SYSTEM_OBJ= start.o ${OBJS} ${LIBS} ${DIRVERS}

SYSTEM_DEP= Makefile${SYSTEM_OBJ}

SYSTEM_LD_HEAD= rm -f$@

SYSTEM_LD= @echo ${LD} ${LFLAGS} -o $@'$${SYSTEM_OBJ}'; \

${LD} ${LFLAGS} -o $@${SYSTEM_OBJ}

SYSTEM_LD_TAIL= @${SIZE} $@; chmod 755$@ ; \

${OBJCOPY} -O binary $@ $@.bin

DEBUG?=

ifeq (${DEBUG}, "-g")

LFLAGS+= -X

SYSTEM_LD_TAIL+=; \

echo cp $@ $@.gdb; rm -f $@.gdb;cp $@ $@.gdb; \

echo ${STRIP} ${STRIPFLAGS} $@;${STRIP} ${STRIPFLAGS} $@

else

LFLAGS+= -S

endif

晕死,看不懂是做什么用的;

前面都在定义编译时的规则,后面才是真正的文件编译区。

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

all: cnos Makefile

cnos:${SYSTEM_DEP}

${SYSTEM_LD_HEAD}

${SYSTEM_LD}

${SYSTEM_LD_TAIL}

clean::

rm -f tags *.[io] [a-z]*.s\

cnos cnos.bin cnos.txtcnos_elf.txt

dump:

$(OBJDUMP) -DS cnos >cnos.txt

tags:

@echo "see $S/kern/Makefile fortags"

这一段总算是比较规则的了,要生成一个 cnos 二进制文件;

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

# %.S

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

start.o: $S/init/start.S Makefile

${NORMAL_S}

mips.o: $S/kern/ke/mips.S

${NORMAL_S}

这是接下来的依赖关系,这里是两个汇编文件,正常编译;

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

# %.CPP

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

init.o: $S/init/init.cpp

${NORMAL_GPP}

Hal.o: $S/hal/Hal.cpp

${NORMAL_GPP}

Serial.o: $S/hal/Serial.cpp

${NORMAL_GPP}

Cnos.o: $S/kern/ke/Cnos.cpp

${NORMAL_GPP}

Mm.o: $S/mm/Mm.cpp

${NORMAL_GPP}

Fs.o: $S/fs/Fs.cpp

${NORMAL_GPP}

interrupt.o: $S/kern/ke/interrupt.cpp

${NORMAL_GPP}

Test.o: $S/test/Test.cpp

${NORMAL_GPP}

KrnlDebug.o:$S/kern/kd/KrnlDebug.cpp

${NORMAL_GPP}

desktop.o:$S/subsystems/gdi/desktop.cpp

${NORMAL_GPP}

surface.o:$S/subsystems/gdi/surface.cpp

${NORMAL_GPP}

taskbar.o:$S/subsystems/gdi/taskbar.cpp

${NORMAL_GPP}

window.o:$S/subsystems/gdi/window.cpp

${NORMAL_GPP}

button.o:$S/subsystems/gdi/button.cpp

${NORMAL_GPP}

系统的主体C++代码文件的编译;

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

#

# libfile

#

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

string.o: $S/lib/string.cpp

${NORMAL_GPP}

unicodefont16.a: $S/media/font/unicodefont16.cpp

${GPP} ${CFLAGS} ${CPPFLAGS}${PROF} -o unicodefont16.a -c $<

库文件的编译;

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

#

# driverfile

#

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

ATIR7000.o: $S/dev/video/atir7000/ATIR7000.cpp

${NORMAL_GPP}

i8042.o: $(S)/dev/input/i8042/i8042.cpp

${NORMAL_GPP}

pci.o: $(S)/dev/bus/pci/pci.cpp

${NORMAL_GPP}

ohci.o: $(S)/dev/bus/usb/ohci.cpp

${NORMAL_GPP}

驱动文件的编译。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: