unpv1 Makefile 文件 简略分析

本文详细介绍了一个复杂的Makefile配置实例,包括如何定义变量、使用自动化变量、执行清理操作等。通过具体的工程文件,展示了如何构建静态库及应用程序。

       Makefile学习路径:http://www.gnu.org/software/make/manual/make.pdf     或者陈皓的《跟我一起写Makefile》,可以说是gnu 官方make文件的译文。

       unpv1工程文件下载地址:http://www.unpbook.com/src.html

       解压缩提取归档文件,执行configure脚本后如下图:

      

       

   主要分析4部分:./ Makefile    ./Make.defines   ./tcpcliserv/Makefile   ./lib/Makefile

   ./Makefile.defines   :

#
# This file is generated by autoconf from "Make.defines.in".
#
# This is the "Make.defines" file that almost every "Makefile" in the
# source directories below this directory include.
# The "../" in the pathnames actually refer to this directory, since
# "make" is executed in all the subdirectories of this directory.
#
# System = i686-pc-linux-gnu

CC = gcc
CFLAGS = -I../lib -g -O2 -D_REENTRANT -Wall
LIBS = ../libunp.a -lpthread
LIBS_XTI = ../libunpxti.a ../libunp.a -lpthread
RANLIB = ranlib

# Following is the main library, built from all the object files
# in the lib/ and libfree/ directories.
LIBUNP_NAME = ../libunp.a

# Following is the XTI library, built from all the object files
# in the libxti/ directory.
LIBUNPXTI_NAME = ../libunpxti.a

# Following are all the object files to create in the lib/ directory.
LIB_OBJS =  connect_nonb.o connect_timeo.o daemon_inetd.o daemon_init.o dg_cli.o dg_echo.o error.o get_ifi_info.o gf_time.o host_serv.o family_to_level.o mcast_leave.o mcast_join.o mcast_get_if.o mcast_get_loop.o mcast_get_ttl.o mcast_set_if.o mcast_set_loop.o mcast_set_ttl.o my_addrs.o read_fd.o readline.o readn.o readable_timeo.o rtt.o signal.o signal_intr.o sock_bind_wild.o sock_cmp_addr.o sock_cmp_port.o sock_ntop.o sock_ntop_host.o sock_get_port.o sock_set_addr.o sock_set_port.o sock_set_wild.o sockfd_to_family.o str_cli.o str_echo.o tcp_connect.o tcp_listen.o tv_sub.o udp_client.o udp_connect.o udp_server.o wraplib.o wrapsock.o wrapstdio.o wrappthread.o wrapunix.o write_fd.o writen.o writable_timeo.o

# Following are all the object files to create in the libfree/ directory.
LIBFREE_OBJS =  in_cksum.o inet_ntop.o inet_pton.o

# Following are all the object files to create in the libgai/ directory.
LIBGAI_OBJS = 

# Following are all the object files to create in the libroute/ directory.
LIBROUTE_OBJS = get_rtaddrs.o if_indextoname.o if_nameindex.o if_nametoindex.o net_rt_iflist.o net_rt_dump.o sock_masktop.o

# Following are all the object files to create in the libxti/ directory.
LIBXTI_OBJS =  wrapxti.o xti_accept.o xti_flags_str.o xti_getopt.o xti_ntop.o xti_ntop_host.o xti_rdwr.o xti_setopt.o xti_str_opts.o xti_tlook_str.o

CLEANFILES = core core.* *.core *.o temp.* *.out typescript* \
		*.lc *.lh *.bsdi *.sparc *.uw

该Makefile文件目的是为了定义一些变量方便下层Makefile文件使用,变量总是字符串的,会在读取Makefile文件时展开,但不会全部都展开,采用延迟机制,即在 若该变量所在的规则属于最终目标的依赖关系规则链中,该依赖决定被使用时,才在内部展开。


./Makefile

include ./Make.defines

all:
	@echo "Nothing to make in this directory"
	@echo "Please read the README file"

clean:
	rm -f $(CLEANFILES)
 
distclean:
	rm -f $(CLEANFILES) config.cache config.log config.status config.h Make.defines Makefile


引用上层的Make.defines文件,使用3个伪目标,all .clean .distclean   all作为第一目标,也是最终目标 所以make 总会执行echo命令,因为@,所以不会打印该命令。

通过make clean 或  make distclean  达到不同程度的清除 。


./lib/Makefile

include ../Make.defines

all:	${LIB_OBJS}
		ar rv ${LIBUNP_NAME} $?
		${RANLIB} ${LIBUNP_NAME}

clean:
		rm -f ${PROGS} ${CLEANFILES}

变量LIB_OBJS是lib下函数源文件生成的中间目标文件集,ar命令将其打包成$(LIBUNP_NAME),即../libunp.a   自动化变量 $?指代依赖目标中所有比库libunp.a新的链接文件, 然后 ranlib  libunp。

当给静态库增建一个成员时(加入一个.o文件到静态库中),“ar”可直接 将需要增加的.o文件简单的追加到静态库的末尾。之后当我们使用这个库进行连接生成可执行文件时,链接程序“ld”却提示错误,这可能是:主程序使用了之 前加入到库中的.o文件中定义的一个函数或者全局变量,但连接程序无法找到这个函数或者变量。 


这个问题的原因是:之前我们将编译完成 的.o文件直接加入到了库的末尾,却并没有更新库的有效符号表。链接程序进行链接时,在静态库的符号索引表中无法定 位刚才加入的.o文件中定义的函数或者变量。这就需要在完成库成员追加以后让加入的所有.o文件中定义的函数(变量)有效,完成这个工作需要使用另外一个 工具“ranlib”来对静态库的符号索引表进行更新。 


我们所使用到的静态库(文档文件)中,存在这样一个特殊的成员,它的名字是 “__.SYMDEF”。它包含了静态库中所有成员所定义的有效符号(函数名、 变量名)。因此,当为库增加了一个成员时,相应的就需要更新成员“__.SYMDEF”,否则所增加的成员中定义的所有的符号将无法被连接程序定位。完成 更新的命令是: 
ranlib ARCHIVEFILE 


./tcpcliserv/Makefile

include ../Make.defines

PROGS =	tcpcli01 tcpcli04 tcpcli05 tcpcli06 \
		tcpcli07 tcpcli08 tcpcli09 tcpcli10 \
		tcpserv01 tcpserv02 tcpserv03 tcpserv04 \
		tcpserv08 tcpserv09 tcpservselect01 tcpservpoll01 tsigpipe

all:	${PROGS}

tcpcli01:	tcpcli01.o
		${CC} ${CFLAGS} -o $@ tcpcli01.o ${LIBS}

tcpcli04:	tcpcli04.o
		${CC} ${CFLAGS} -o $@ tcpcli04.o ${LIBS}

tcpcli05:	tcpcli05.o
		${CC} ${CFLAGS} -o $@ tcpcli05.o ${LIBS}

tcpcli06:	tcpcli06.o
		${CC} ${CFLAGS} -o $@ tcpcli06.o ${LIBS}

tcpcli07:	tcpcli07.o
		${CC} ${CFLAGS} -o $@ tcpcli07.o ${LIBS}

tcpcli08:	tcpcli08.o str_cli08.o
		${CC} ${CFLAGS} -o $@ tcpcli08.o str_cli08.o ${LIBS}

tcpcli09:	tcpcli09.o str_cli09.o
		${CC} ${CFLAGS} -o $@ tcpcli09.o str_cli09.o ${LIBS}

tcpcli10:	tcpcli10.o
		${CC} ${CFLAGS} -o $@ tcpcli10.o ${LIBS}

tcpcli11:	tcpcli11.o str_cli11.o
		${CC} ${CFLAGS} -o $@ tcpcli11.o str_cli11.o ${LIBS}

tcpserv01:	tcpserv01.o
		${CC} ${CFLAGS} -o $@ tcpserv01.o ${LIBS}

tcpserv02:	tcpserv02.o sigchldwait.o
		${CC} ${CFLAGS} -o $@ tcpserv02.o sigchldwait.o ${LIBS}

tcpserv03:	tcpserv03.o sigchldwait.o
		${CC} ${CFLAGS} -o $@ tcpserv03.o sigchldwait.o ${LIBS}

tcpserv04:	tcpserv04.o sigchldwaitpid.o
		${CC} ${CFLAGS} -o $@ tcpserv04.o sigchldwaitpid.o ${LIBS}

tcpserv08:	tcpserv08.o str_echo08.o sigchldwaitpid.o
		${CC} ${CFLAGS} -o $@ tcpserv08.o str_echo08.o sigchldwaitpid.o \
			${LIBS}

tcpserv09:	tcpserv09.o str_echo09.o sigchldwaitpid.o
		${CC} ${CFLAGS} -o $@ tcpserv09.o str_echo09.o sigchldwaitpid.o \
			${LIBS}

tcpservselect01:	tcpservselect01.o
		${CC} ${CFLAGS} -o $@ tcpservselect01.o ${LIBS}

tcpservpoll01:	tcpservpoll01.o
		${CC} ${CFLAGS} -o $@ tcpservpoll01.o ${LIBS}

tsigpipe:	tsigpipe.o
		${CC} ${CFLAGS} -o $@ tsigpipe.o ${LIBS}

clean:
		rm -f ${PROGS} ${CLEANFILES}

使用all 来 完成链接成多个最终目标$(PROGS),而且指定每一个目标的规则。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值