FFmpeg源代码简单分析:makefile

来源:互联网 发布:googlenet tensorflow 编辑:程序博客网 时间:2024/06/07 23:04

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

FFmpeg的库函数源代码分析文章列表:

【架构图】

FFmpeg源代码结构图 - 解码

FFmpeg源代码结构图 - 编码

【通用】

FFmpeg 源代码简单分析:av_register_all()

FFmpeg 源代码简单分析:avcodec_register_all()

FFmpeg 源代码简单分析:内存的分配和释放(av_malloc()av_free()等)

FFmpeg 源代码简单分析:常见结构体的初始化和销毁(AVFormatContextAVFrame等)

FFmpeg 源代码简单分析:avio_open2()

FFmpeg 源代码简单分析:av_find_decoder()av_find_encoder()

FFmpeg 源代码简单分析:avcodec_open2()

FFmpeg 源代码简单分析:avcodec_close()

【解码】

图解FFMPEG打开媒体的函数avformat_open_input

FFmpeg 源代码简单分析:avformat_open_input()

FFmpeg 源代码简单分析:avformat_find_stream_info()

FFmpeg 源代码简单分析:av_read_frame()

FFmpeg 源代码简单分析:avcodec_decode_video2()

FFmpeg 源代码简单分析:avformat_close_input()

【编码】

FFmpeg 源代码简单分析:avformat_alloc_output_context2()

FFmpeg 源代码简单分析:avformat_write_header()

FFmpeg 源代码简单分析:avcodec_encode_video()

FFmpeg 源代码简单分析:av_write_frame()

FFmpeg 源代码简单分析:av_write_trailer()

【其它】

FFmpeg源代码简单分析:日志输出系统(av_log()等)

FFmpeg源代码简单分析:结构体成员管理系统-AVClass

FFmpeg源代码简单分析:结构体成员管理系统-AVOption

FFmpeg源代码简单分析:libswscalesws_getContext()

FFmpeg源代码简单分析:libswscalesws_scale()

FFmpeg源代码简单分析:libavdeviceavdevice_register_all()

FFmpeg源代码简单分析:libavdevicegdigrab

【脚本】

FFmpeg源代码简单分析:makefile

FFmpeg源代码简单分析:configure

【H.264】

FFmpegH.264解码器源代码简单分析:概述

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


本文记录FFmpeg的Makefile的源代码。Makefile用于编译FFmpeg的源代码。通过分析Makefile文件,可以了解FFmpeg的源代码生成的流程。有关Makefile这部分我本身基础不算很牢,很多地方还在慢慢摸索,所以分析的内容不能保证完全准确。以后有时间和其他朋友多交流再慢慢完善这篇文章。

PS:make有一个很有用的命令:“make -n”。该选项会显示命令,但不会执行命令,十分有助于分析Makefile


FFmpeg中与Makefile相关的文件

FFmpeg中与Makefile相关的文件主要有以下几个:
根目录Makefile:最基本的Makefile;
config.mak:由configure生成的Makefile,保存了Configure的设置信息;
libavXXXX/Makefile:每个类库的Makefile(仅仅设置了几个变量);
library.mak:编译类库的Makefile(和libavXXXX/Makefile配合使用);
common.mak:包含一些通用代码的Makefile;

它们之间的关系如下图所示。


图中除了画出了Makefile之外,还画出了和Makefile有关的一些文件:
XXX.c:C语言文件;
XXX.h:C语言文件用到的头文件;
XXX.o:C语言文件对应的目标文件;
XXX.d:C语言文件对应的依赖关系文件;

Make Install 之间的关系

简单分析了一下Makefile中的make install之间的关系,如下图所示(使用的是MinGW编译器)。

从图中可以看出,install伪目标依赖于4个伪目标:

install-progs:安装应用程序ffmpeg.exe,ffplay.exe,ffprobe.exe;
install-data:安装数据(*.ffpreset之类的文件,没研究过)
install-libs:安装类库(libavcodec.dll等文件)
install-headers:安装头文件(libavcodec/avcodec.h等文件)

install-progs依赖于ffmpeg.exe,ffplay.exe,ffprobe.exe以及install-progs-yes伪目标。在CONFIG_SHARED取值为yes的情况下,install-progs-yes依赖于install-libs。

install-libs依赖于伪目标install-libs-yes。install-libs-yes的依赖关系位于library.mak文件中。如果CONFIG_STATIC取值为yes,install-libs-yes依赖于install-lib$(NAME)-static(其中${NAME}为类库文件名,例如avformat);如果CONFIG_SHARED取值为yes,install-libs-yes依赖于install-lib$(NAME)-shared。

install-headers依赖于伪目标install-lib$(NAME)-headers和install-lib$(NAME)-pkgconfig。

和install相对应,uninstall伪目标依赖于4个伪目标:
uninstall-progs:卸载应用程序;
uninstall-data:卸载数据;
uninstall-libs:卸载类库;
uninstall-headers:卸载头文件;

其中uninstall-libs和uninstall-headers的依赖关系位于library.mak中。


根目录Makefile

根目录Makefile是最重要的。简单注释过的Makefile如下所示。

# FFmpeg Main Makefile## 注释:雷霄骅# leixiaohua1020@126.com# http://blog.csdn.net/leixiaohua1020## FFmpeg的 Main Makefile。最重要。MAIN_MAKEFILE=1#重要:包含了configure信息include config.mak#config.mak中:#SRC_PATH=.#在SRC_PATH搜索各种类型的文件vpath %.c    $(SRC_PATH)vpath %.cpp  $(SRC_PATH)vpath %.h    $(SRC_PATH)vpath %.S    $(SRC_PATH)vpath %.asm  $(SRC_PATH)vpath %.v    $(SRC_PATH)vpath %.texi $(SRC_PATH)vpath %/fate_config.sh.template $(SRC_PATH)#CONFIG_XXX取值为yes#PROGS-yes= ffmpeg ffplay ffprobePROGS-$(CONFIG_FFMPEG)   += ffmpegPROGS-$(CONFIG_FFPLAY)   += ffplayPROGS-$(CONFIG_FFPROBE)  += ffprobePROGS-$(CONFIG_FFSERVER) += ffserver#config.mak中:#EXESUF=.exe#PROGSSUF=#$(var:%.c=%.o)意思是把.c 为结尾的变量替换成.o。#没有“.c”的时候,代表匹配所有PROGS      := $(PROGS-yes:%=%$(EXESUF))INSTPROGS   = $(PROGS-yes:%=%$(PROGSSUF)$(EXESUF))OBJS        = $(PROGS-yes:%=%.o) cmdutils.oTESTTOOLS   = audiogen videogen rotozoom tiny_psnr base64HOSTPROGS  := $(TESTTOOLS:%=tests/%)TOOLS       = qt-faststart trasherTOOLS-$(CONFIG_ZLIB) += cws2fws#PROGS= ffmpeg.exe ffplay.exe ffprobe.exe#INSTPROGS= ffmpeg.exe ffplay.exe ffprobe.exe#OBJS= ffmpeg.o ffplay.o ffprobe.oBASENAMES   = ffmpeg ffplay ffprobe ffserverALLPROGS    = $(BASENAMES:%=%$(PROGSSUF)$(EXESUF))ALLPROGS_G  = $(BASENAMES:%=%$(PROGSSUF)_g$(EXESUF))ALLMANPAGES = $(BASENAMES:%=%.1)#ALLPROGS= ffmpeg.exe ffplay.exe ffprobe.exe ffserver.exe#ALLPROGS_G= ffmpeg_g.exe ffplay_g.exe ffprobe_g.exe ffserver_g.exe#ALLMANPAGES=ffmpeg.1 ffplay.1 ffprobe.1 ffserver.1FFLIBS-$(CONFIG_AVDEVICE) += avdeviceFFLIBS-$(CONFIG_AVFILTER) += avfilterFFLIBS-$(CONFIG_AVFORMAT) += avformatFFLIBS-$(CONFIG_AVCODEC)  += avcodecFFLIBS-$(CONFIG_POSTPROC) += postprocFFLIBS-$(CONFIG_SWRESAMPLE)+= swresampleFFLIBS-$(CONFIG_SWSCALE)  += swscale#FFLIBS-yes= avdevice avfilter avformat avcodec postproc swresample swscale#一定需要libavutilFFLIBS := avutil#让通配符在变量中展开,需要使用wildcard关键字DATA_FILES := $(wildcard $(SRC_PATH)/presets/*.ffpreset) $(SRC_PATH)/doc/ffprobe.xsdSKIPHEADERS = cmdutils_common_opts.h#重要include $(SRC_PATH)/common.mak#依赖的类库FF_EXTRALIBS := $(FFEXTRALIBS)FF_DEP_LIBS  := $(DEP_LIBS)#伪目标#all是最关键的,生成最后的程序#all: ffmpeg.exe ffplay.exe ffprobe.exe#all: $(PROGS)#config.mak中:#EXESUF=.exe#PROGSSUF=#$@是一个自动化变量。可以简单理解为目标的集合。#$<是一个自动化变量。可以简单理解为依赖目标的集合。#%是通配符#两个冒号,“静态模式规则”。#ffmpeg_g.exe生成ffmpeg.exe;ffplay_g.exe生成ffplay.exe;ffprobe_g.exe生成ffprobe.exe#strip经常用来去除目标文件中的一些符号表、调试符号表信息,以减小程序的大小$(PROGS): %$(EXESUF): %$(PROGSSUF)_g$(EXESUF)$(CP) $< $@$(PROGSSUF)$(STRIP) $@$(PROGSSUF)$(TOOLS): %$(EXESUF): %.o$(LD) $(LDFLAGS) -o $@ $< $(ELIBS)tools/cws2fws$(EXESUF): ELIBS = -lzconfig.h: .config.config: $(wildcard $(FFLIBS:%=$(SRC_PATH)/lib%/all*.c))@-tput bold 2>/dev/null@-printf '\nWARNING: $(?F) newer than config.h, rerun configure\n\n'@-tput sgr0 2>/dev/null#给子目录中的Makefile使用的变量SUBDIR_VARS := OBJS FFLIBS CLEANFILES DIRS TESTPROGS EXAMPLES SKIPHEADERS \               ALTIVEC-OBJS MMX-OBJS NEON-OBJS X86-OBJS YASM-OBJS-FFT YASM-OBJS \               HOSTPROGS BUILT_HEADERS TESTOBJS ARCH_HEADERS ARMV6-OBJS TOOLSdefine RESET$(1) :=$(1)-yes :=endef#$(call <expression>,<parm1>,<parm2>,<parm3>...)#当make执行这个函数时,<expression>参数中的变量,如$(1),$(2),$(3)等,会被参数#<parm1>,<parm2>,<parm3>依次取代。而<expression>的返回值就是call函数的返回值。#命令包===========================#用于编译每个库#$(1)取值为libavcodec,libavcodec等等define DOSUBDIR$(foreach V,$(SUBDIR_VARS),$(eval $(call RESET,$(V))))SUBDIR := $(1)/#每个库目录下的Makefileinclude $(SRC_PATH)/$(1)/Makefile#注:make一般情况下如果在中途检测到有执行出错的情况(返回非 0 状态),那么就会放弃对当前规则后续命令的执行。#在命令前面加上“-”号之后,就算执行错误了,也会继续执行下去-include $(SRC_PATH)/$(1)/$(ARCH)/Makefile#编译类库include $(SRC_PATH)/library.makendef#=================================#$(foreach <var>,<list>,<text>)#把参数<list>中的单词逐一取出放到参数<var>所指定的变量中,#然后再执行<text>所包含的表达式。#$(eval text)#text的内容将作为makefile的一部分而被make解析和执行##循环调用DOSUBDIR命令包#这一步会将libavcodec,libavformat等文件夹下的Makefile包含进来。$(foreach D,$(FFLIBS),$(eval $(call DOSUBDIR,lib$(D))))#ffplay需要SDLffplay.o: CFLAGS += $(SDL_CFLAGS)ffplay_g$(EXESUF): FF_EXTRALIBS += $(SDL_LIBS)ffserver_g$(EXESUF): LDFLAGS += $(FFSERVERLDFLAGS)#链接生成ffmpeg_g.exe等等#FF_DEP_LIBS= libavcodec/libavcodec.a libavutil/libavutil.a ....%$(PROGSSUF)_g$(EXESUF): %.o cmdutils.o $(FF_DEP_LIBS)$(LD) $(LDFLAGS) -o $@ $< cmdutils.o $(FF_EXTRALIBS)OBJDIRS += tools-include $(wildcard tools/*.d)VERSION_SH  = $(SRC_PATH)/version.shGIT_LOG     = $(SRC_PATH)/.git/logs/HEAD.version: $(wildcard $(GIT_LOG)) $(VERSION_SH) config.mak.version: M=@version.h .version:$(M)$(VERSION_SH) $(SRC_PATH) version.h $(EXTRA_VERSION)$(Q)touch .version# force version.sh to run whenever version might have changed-include .version#安装install#安装程序ifdef PROGSinstall: install-progs install-dataendif#安装类库和头文件install: install-libs install-headers#install-libs-yes位于library.makinstall-libs: install-libs-yesinstall-progs-yes:install-progs-$(CONFIG_SHARED): install-libs#config.mak中:#BINDIR=$(DESTDIR)${prefix}/bin#INSTALL=install#cp与install区别:#cp会先清空文件后往里写入新文件,而install则会先删除掉原先的文件然后写入新文件。install-progs: install-progs-yes $(PROGS)$(Q)mkdir -p "$(BINDIR)"$(INSTALL) -c -m 755 $(INSTPROGS) "$(BINDIR)"install-data: $(DATA_FILES)$(Q)mkdir -p "$(DATADIR)"$(INSTALL) -m 644 $(DATA_FILES) "$(DATADIR)"#卸载uninstall: uninstall-libs uninstall-headers uninstall-progs uninstall-data#addprefix()用于加前缀#在这里获取ffmpeg.exe等的完整路径(用于删除)uninstall-progs:$(RM) $(addprefix "$(BINDIR)/", $(ALLPROGS))uninstall-data:$(RM) -r "$(DATADIR)"#清空clean::$(RM) $(ALLPROGS) $(ALLPROGS_G)$(RM) $(CLEANSUFFIXES)$(RM) $(TOOLS)$(RM) $(CLEANSUFFIXES:%=tools/%)$(RM) coverage.info$(RM) -r coverage-htmldistclean::$(RM) $(DISTCLEANSUFFIXES)$(RM) config.* .version version.h libavutil/avconfig.hconfig:$(SRC_PATH)/configure $(value FFMPEG_CONFIGURATION)# Without the sed genthml thinks "libavutil" and "./libavutil" are two different thingscoverage.info: $(wildcard *.gcda *.gcno */*.gcda */*.gcno */*/*.gcda */*/*.gcno)$(Q)lcov -c -d . -b . | sed -e 's#/./#/#g' > $@coverage-html: coverage.info$(Q)mkdir -p $@$(Q)genhtml -o $@ $<$(Q)touch $@include $(SRC_PATH)/doc/Makefileinclude $(SRC_PATH)/tests/Makefile$(sort $(OBJDIRS)):$(Q)mkdir -p $@# Dummy rule to stop make trying to rebuild removed or renamed headers%.h:@:# Disable suffix rules.  Most of the builtin rules are suffix rules,# so this saves some time on slow systems..SUFFIXES:#显示地指明一个目标是“伪目标”.PHONY: all all-yes alltools *clean config examples install*.PHONY: testprogs uninstall*

根目录Makefile代码一开始的时候包含了config.mak文件。这个文件是运行./configure的后生成的配置文件,包含了所有的配置信息。

随后代码定义了ffplay.exe,ffmpeg.exe,ffprobe.exe与ffplay_g.exe,ffmpeg_g.exe,ffprobe_g.exe的依赖关系。然后定义了ffplay_g.exe,ffmpeg_g.exe,ffprobe_g.exe与libavformat,libavcodec等这些类库的依赖关系。

根目录Makefile中也定义了all,install,uninstall,clean等等一系列的伪目标,这样可以通过给Makefile指定不同的目标来完成不同的事。

此外根目录的Makefile中有一个很重要的命令包DOSUBDIR。在该命令包通过包含libavXXX/Makefile和library.mak等文件,定义了FFmpeg类库(例如libavformat,libavcodec,libavutil等)的依赖关系。

config.mak

config.mak文件是运行./configure的后生成的配置文件,包含了所有的配置信息。简单注释过的config.mak的代码如下所示。
# FFmpeg config.mak## 注释:雷霄骅# leixiaohua1020@126.com# http://blog.csdn.net/leixiaohua1020## Configure脚本生成的Makefile,包含了各种配置信息。## Automatically generated by configure - do not modify!#基本信息ifndef FFMPEG_CONFIG_MAKFFMPEG_CONFIG_MAK=1FFMPEG_CONFIGURATION=#各种路径========================================prefix=/usr/localLIBDIR=$(DESTDIR)${prefix}/libSHLIBDIR=$(DESTDIR)${prefix}/binINCDIR=$(DESTDIR)${prefix}/includeBINDIR=$(DESTDIR)${prefix}/binDATADIR=$(DESTDIR)${prefix}/share/ffmpegMANDIR=$(DESTDIR)${prefix}/share/man#是个相对路径SRC_PATH=.ifndef MAIN_MAKEFILESRC_PATH:=$(SRC_PATH:.%=..%)endif#工具集==========================================CC_IDENT=gcc 4.6.2 (GCC)#架构ARCH=x86#编译器CC=gccCXX=g++AS=gcc#链接器LD=gccDEPCC=gcc#汇编器YASM=yasmYASMDEP=yasm#生成静态库.a工具AR=arRANLIB=ranlibCP=cp -pLN_S=ln -sfSTRIP=strip#参数集==========================================#编译器的参数CPPFLAGS= -D_ISOC99_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -U__STRICT_ANSI__CFLAGS=   -std=c99 -fno-common -fomit-frame-pointer -I/include/SDL -D_GNU_SOURCE=1 -Dmain=SDL_main -g -Wdeclaration-after-statement -Wall -Wno-parentheses -Wno-switch -Wno-format-zero-length -Wdisabled-optimization -Wpointer-arith -Wredundant-decls -Wno-pointer-sign -Wcast-qual -Wwrite-strings -Wtype-limits -Wundef -Wmissing-prototypes -Wno-pointer-to-int-cast -Wstrict-prototypes -O3 -fno-math-errno -fno-signed-zeros -fno-tree-vectorize -Werror=implicit-function-declaration -Werror=missing-prototypesCXXFLAGS=  -D__STDC_CONSTANT_MACROSASFLAGS=   -g#目标文件有关的参数AS_O=-o $@CC_O=-o $@CXX_O=-o $@#链接器有关的参数LDFLAGS= -Wl,--as-needed -Wl,--warn-common -Wl,-rpath-link=libpostproc:libswresample:libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutilFFSERVERLDFLAGS=-Wl,-ESHFLAGS=-shared -Wl,--output-def,$$(@:$(SLIBSUF)=.def) -Wl,--out-implib,$(SUBDIR)lib$(SLIBNAME:$(SLIBSUF)=.dll.a) -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-auto-image-base -Wl,-Bsymbolic -Wl,--version-script,$(SUBDIR)lib$(NAME).verYASMFLAGS=-f win32  -DPREFIX#前缀后缀========================================BUILDSUF=PROGSSUF=#${NAME}位于每个liavXXX/Makefile中,例如avformatFULLNAME=$(NAME)$(BUILDSUF)LIBPREF=libLIBSUF=.a#例如libavformat.aLIBNAME=$(LIBPREF)$(FULLNAME)$(LIBSUF)SLIBPREF=SLIBSUF=.dllEXESUF=.exeEXTRA_VERSION=DEPFLAGS=$(CPPFLAGS) $(CFLAGS) -MMCCDEP=CXXDEP=$(DEPCC) $(DEPFLAGS) $< | sed -e "/^\#.*/d" -e "s,^[[:space:]]*$(*F)\\.o,$(@D)/$(*F).o," > $(@:.o=.d)ASDEP=CC_DEPFLAGS=-MMD -MF $(@:.o=.d) -MT $@AS_DEPFLAGS=-MMD -MF $(@:.o=.d) -MT $@HOSTCC=gccHOSTCFLAGS=-D_ISOC99_SOURCE -O3 -g -std=c99 -WallHOSTEXESUF=.exeHOSTLDFLAGS=HOSTLIBS=-lmTARGET_EXEC=TARGET_PATH=$(CURDIR)#SDLSDL_LIBS=-L/lib -lmingw32 -lSDLmain -lSDL -mwindowsSDL_CFLAGS=-I/include/SDL -D_GNU_SOURCE=1 -Dmain=SDL_mainLIB_INSTALL_EXTRA_CMD=$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"#链接EXTRALIBS=-lavicap32 -lws2_32 -L/lib -lmingw32 -lSDLmain -lSDL -mwindows -lm -lz -lpsapi INSTALL=installLIBTARGET=i386#例如libavformat.dllSLIBNAME=$(SLIBPREF)$(FULLNAME)$(SLIBSUF)#LIBVERSION变量位于library.mak#例如libavformat-53.dll#生成的Dll似乎就是这个版本的SLIBNAME_WITH_VERSION=$(SLIBPREF)$(FULLNAME)-$(LIBVERSION)$(SLIBSUF)#例如libavformat-53.31.100.dllSLIBNAME_WITH_MAJOR=$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)SLIB_CREATE_DEF_CMD=#生成导出库lib,会调用lib.exeSLIB_EXTRA_CMD=-lib.exe /machine:$(LIBTARGET) /def:$$(@:$(SLIBSUF)=.def) /out:$(SUBDIR)$(SLIBNAME:$(SLIBSUF)=.lib)SLIB_INSTALL_NAME=$(SLIBNAME_WITH_MAJOR)SLIB_INSTALL_LINKS=SLIB_INSTALL_EXTRA_LIB=lib$(SLIBNAME:$(SLIBSUF)=.dll.a) $(SLIBNAME_WITH_MAJOR:$(SLIBSUF)=.def)SLIB_INSTALL_EXTRA_SHLIB=$(SLIBNAME:$(SLIBSUF)=.lib)SAMPLES:=$(FATE_SAMPLES)NOREDZONE_FLAGS=-mno-red-zone#版本信息========================================libavcodec_VERSION=53.60.100libavcodec_VERSION_MAJOR=53libavdevice_VERSION=53.4.100libavdevice_VERSION_MAJOR=53libavfilter_VERSION=2.60.100libavfilter_VERSION_MAJOR=2libavformat_VERSION=53.31.100libavformat_VERSION_MAJOR=53libavutil_VERSION=51.34.101libavutil_VERSION_MAJOR=51libpostproc_VERSION=52.0.100libpostproc_VERSION_MAJOR=52libswresample_VERSION=0.6.100libswresample_VERSION_MAJOR=0libswscale_VERSION=2.1.100libswscale_VERSION_MAJOR=2#组件配置========================================#ARCH_!ARCH_ALPHA=yes!ARCH_ARM=yes!ARCH_AVR32=yes!ARCH_AVR32_AP=yes!ARCH_AVR32_UC=yes!ARCH_BFIN=yes!ARCH_IA64=yes!ARCH_M68K=yes!ARCH_MIPS=yes!ARCH_MIPS64=yes!ARCH_PARISC=yes!ARCH_PPC=yes!ARCH_PPC64=yes!ARCH_S390=yes!ARCH_SH4=yes!ARCH_SPARC=yes!ARCH_SPARC64=yes!ARCH_TOMI=yesARCH_X86=yesARCH_X86_32=yes!ARCH_X86_64=yes#HAVE_!HAVE_ALTIVEC=yesHAVE_AMD3DNOW=yesHAVE_AMD3DNOWEXT=yes!HAVE_ARMV5TE=yes!HAVE_ARMV6=yes!HAVE_ARMV6T2=yes!HAVE_ARMVFP=yesHAVE_AVX=yes!HAVE_IWMMXT=yes!HAVE_MMI=yesHAVE_MMX=yesHAVE_MMX2=yes!HAVE_NEON=yes!HAVE_PPC4XX=yesHAVE_SSE=yesHAVE_SSSE3=yes!HAVE_VFPV3=yes!HAVE_VIS=yes!HAVE_BIGENDIAN=yesHAVE_FAST_UNALIGNED=yes!HAVE_PTHREADS=yesHAVE_W32THREADS=yes!HAVE_OS2THREADS=yesHAVE_ALIGNED_STACK=yes!HAVE_ALSA_ASOUNDLIB_H=yes!HAVE_ALTIVEC_H=yes!HAVE_ARPA_INET_H=yes!HAVE_ASM_MOD_Y=yes!HAVE_ASM_TYPES_H=yesHAVE_ATTRIBUTE_MAY_ALIAS=yesHAVE_ATTRIBUTE_PACKED=yesHAVE_CBRTF=yesHAVE_CLOSESOCKET=yes!HAVE_CMOV=yes!HAVE_DCBZL=yes!HAVE_DEV_BKTR_IOCTL_BT848_H=yes!HAVE_DEV_BKTR_IOCTL_METEOR_H=yes!HAVE_DEV_IC_BT8XX_H=yes!HAVE_DEV_VIDEO_BKTR_IOCTL_BT848_H=yes!HAVE_DEV_VIDEO_METEOR_IOCTL_METEOR_H=yes!HAVE_DLFCN_H=yes!HAVE_DLOPEN=yesHAVE_DOS_PATHS=yesHAVE_EBP_AVAILABLE=yesHAVE_EBX_AVAILABLE=yesHAVE_EXP2=yesHAVE_EXP2F=yes!HAVE_FAST_64BIT=yesHAVE_FAST_CLZ=yes!HAVE_FAST_CMOV=yes!HAVE_FCNTL=yes!HAVE_FORK=yes!HAVE_GETADDRINFO=yes!HAVE_GETHRTIME=yesHAVE_GETPROCESSAFFINITYMASK=yesHAVE_GETPROCESSMEMORYINFO=yesHAVE_GETPROCESSTIMES=yes!HAVE_GETRUSAGE=yesHAVE_GNU_AS=yes!HAVE_IBM_ASM=yes!HAVE_INET_ATON=yesHAVE_INLINE_ASM=yesHAVE_ISATTY=yesHAVE_KBHIT=yes!HAVE_LDBRX=yesHAVE_LLRINT=yesHAVE_LLRINTF=yesHAVE_LOCAL_ALIGNED_16=yesHAVE_LOCAL_ALIGNED_8=yes!HAVE_LOCALTIME_R=yesHAVE_LOG2=yesHAVE_LOG2F=yes!HAVE_LOONGSON=yesHAVE_LRINT=yesHAVE_LRINTF=yes!HAVE_LZO1X_999_COMPRESS=yes!HAVE_MACHINE_IOCTL_BT848_H=yes!HAVE_MACHINE_IOCTL_METEOR_H=yesHAVE_MAKEINFO=yesHAVE_MALLOC_H=yesHAVE_MAPVIEWOFFILE=yes!HAVE_MEMALIGN=yes!HAVE_MKSTEMP=yes!HAVE_MMAP=yesHAVE_PEEKNAMEDPIPE=yes!HAVE_POLL_H=yes!HAVE_POSIX_MEMALIGN=yesHAVE_ROUND=yesHAVE_ROUNDF=yes!HAVE_SCHED_GETAFFINITY=yesHAVE_SDL=yesHAVE_SDL_VIDEO_SIZE=yesHAVE_SETMODE=yes!HAVE_SETRLIMIT=yes!HAVE_SNDIO_H=yesHAVE_SOCKLEN_T=yes!HAVE_SOUNDCARD_H=yes!HAVE_STRERROR_R=yes!HAVE_STRPTIME=yesHAVE_STRUCT_ADDRINFO=yesHAVE_STRUCT_IPV6_MREQ=yes!HAVE_STRUCT_RUSAGE_RU_MAXRSS=yesHAVE_STRUCT_SOCKADDR_IN6=yes!HAVE_STRUCT_SOCKADDR_SA_LEN=yesHAVE_STRUCT_SOCKADDR_STORAGE=yes!HAVE_STRUCT_V4L2_FRMIVALENUM_DISCRETE=yesHAVE_SYMVER=yesHAVE_SYMVER_ASM_LABEL=yes!HAVE_SYMVER_GNU_ASM=yes!HAVE_SYSCONF=yes!HAVE_SYSCTL=yes!HAVE_SYS_MMAN_H=yesHAVE_SYS_PARAM_H=yes!HAVE_SYS_RESOURCE_H=yes!HAVE_SYS_SELECT_H=yes!HAVE_SYS_SOUNDCARD_H=yes!HAVE_SYS_VIDEOIO_H=yes!HAVE_TERMIOS_H=yesHAVE_THREADS=yesHAVE_TRUNC=yesHAVE_TRUNCF=yes!HAVE_VFP_ARGS=yesHAVE_VIRTUALALLOC=yesHAVE_WINSOCK2_H=yes!HAVE_XFORM_ASM=yes!HAVE_XMM_CLOBBERS=yesHAVE_YASM=yes#CONFIG_CONFIG_BSFS=yesCONFIG_DECODERS=yesCONFIG_DEMUXERS=yesCONFIG_ENCODERS=yesCONFIG_FILTERS=yes!CONFIG_HWACCELS=yesCONFIG_INDEVS=yesCONFIG_MUXERS=yesCONFIG_OUTDEVS=yesCONFIG_PARSERS=yesCONFIG_PROTOCOLS=yesCONFIG_FFPLAY=yesCONFIG_FFPROBE=yes!CONFIG_FFSERVER=yesCONFIG_FFMPEG=yes!CONFIG_AVPLAY=yes!CONFIG_AVPROBE=yes!CONFIG_AVSERVER=yesCONFIG_AANDCT=yesCONFIG_AC3DSP=yesCONFIG_AVCODEC=yesCONFIG_AVDEVICE=yesCONFIG_AVFILTER=yesCONFIG_AVFORMAT=yes!CONFIG_AVISYNTH=yes!CONFIG_BZLIB=yes!CONFIG_CRYSTALHD=yesCONFIG_DCT=yes!CONFIG_DOC=yesCONFIG_DWT=yes!CONFIG_DXVA2=yesCONFIG_FASTDIV=yesCONFIG_FFT=yes!CONFIG_FREI0R=yes!CONFIG_GNUTLS=yesCONFIG_GOLOMB=yes!CONFIG_GPL=yes!CONFIG_GRAY=yesCONFIG_H264CHROMA=yesCONFIG_H264DSP=yesCONFIG_H264PRED=yes!CONFIG_HARDCODED_TABLES=yesCONFIG_HUFFMAN=yes!CONFIG_LIBAACPLUS=yes!CONFIG_LIBASS=yes!CONFIG_LIBCDIO=yes!CONFIG_LIBCELT=yes!CONFIG_LIBDC1394=yes!CONFIG_LIBDIRAC=yes!CONFIG_LIBFAAC=yes!CONFIG_LIBFREETYPE=yes!CONFIG_LIBGSM=yes!CONFIG_LIBMODPLUG=yes!CONFIG_LIBMP3LAME=yes!CONFIG_LIBNUT=yes!CONFIG_LIBOPENCORE_AMRNB=yes!CONFIG_LIBOPENCORE_AMRWB=yes!CONFIG_LIBOPENCV=yes!CONFIG_LIBOPENJPEG=yes!CONFIG_LIBPULSE=yes!CONFIG_LIBRTMP=yes!CONFIG_LIBSCHROEDINGER=yes!CONFIG_LIBSPEEX=yes!CONFIG_LIBSTAGEFRIGHT_H264=yes!CONFIG_LIBTHEORA=yes!CONFIG_LIBUTVIDEO=yes!CONFIG_LIBV4L2=yes!CONFIG_LIBVO_AACENC=yes!CONFIG_LIBVO_AMRWBENC=yes!CONFIG_LIBVORBIS=yes!CONFIG_LIBVPX=yes!CONFIG_LIBX264=yes!CONFIG_LIBXAVS=yes!CONFIG_LIBXVID=yesCONFIG_LPC=yesCONFIG_LSP=yesCONFIG_MDCT=yesCONFIG_MEMALIGN_HACK=yes!CONFIG_MLIB=yesCONFIG_MPEGAUDIODSP=yesCONFIG_NETWORK=yes!CONFIG_NONFREE=yes!CONFIG_OPENAL=yes!CONFIG_OPENSSL=yes!CONFIG_PIC=yes!CONFIG_POSTPROC=yesCONFIG_RDFT=yesCONFIG_RTPDEC=yes!CONFIG_RUNTIME_CPUDETECT=yesCONFIG_SAFE_BITSTREAM_READER=yes!CONFIG_SHARED=yesCONFIG_SINEWIN=yes!CONFIG_SMALL=yes!CONFIG_SRAM=yesCONFIG_STATIC=yesCONFIG_SWRESAMPLE=yesCONFIG_SWSCALE=yesCONFIG_SWSCALE_ALPHA=yes!CONFIG_THUMB=yes!CONFIG_VAAPI=yes!CONFIG_VDA=yes!CONFIG_VDPAU=yes!CONFIG_VERSION3=yes!CONFIG_X11GRAB=yesCONFIG_ZLIB=yesCONFIG_AVUTIL=yes!CONFIG_GPLV3=yes!CONFIG_LGPLV3=yesCONFIG_AAC_ADTSTOASC_BSF=yesCONFIG_CHOMP_BSF=yesCONFIG_DUMP_EXTRADATA_BSF=yesCONFIG_H264_MP4TOANNEXB_BSF=yesCONFIG_IMX_DUMP_HEADER_BSF=yesCONFIG_MJPEG2JPEG_BSF=yesCONFIG_MJPEGA_DUMP_HEADER_BSF=yesCONFIG_MP3_HEADER_COMPRESS_BSF=yesCONFIG_MP3_HEADER_DECOMPRESS_BSF=yesCONFIG_MOV2TEXTSUB_BSF=yesCONFIG_NOISE_BSF=yesCONFIG_REMOVE_EXTRADATA_BSF=yesCONFIG_TEXT2MOVSUB_BSF=yesCONFIG_AASC_DECODER=yesCONFIG_AMV_DECODER=yesCONFIG_ANM_DECODER=yesCONFIG_ANSI_DECODER=yesCONFIG_ASV1_DECODER=yesCONFIG_ASV2_DECODER=yesCONFIG_AURA_DECODER=yesCONFIG_AURA2_DECODER=yesCONFIG_AVRP_DECODER=yesCONFIG_AVS_DECODER=yesCONFIG_BETHSOFTVID_DECODER=yesCONFIG_BFI_DECODER=yesCONFIG_BINK_DECODER=yesCONFIG_BMP_DECODER=yesCONFIG_BMV_VIDEO_DECODER=yesCONFIG_C93_DECODER=yesCONFIG_CAVS_DECODER=yesCONFIG_CDGRAPHICS_DECODER=yesCONFIG_CINEPAK_DECODER=yesCONFIG_CLJR_DECODER=yesCONFIG_CSCD_DECODER=yesCONFIG_CYUV_DECODER=yesCONFIG_DFA_DECODER=yesCONFIG_DIRAC_DECODER=yesCONFIG_DNXHD_DECODER=yesCONFIG_DPX_DECODER=yesCONFIG_DSICINVIDEO_DECODER=yesCONFIG_DVVIDEO_DECODER=yesCONFIG_DXA_DECODER=yesCONFIG_DXTORY_DECODER=yesCONFIG_EACMV_DECODER=yesCONFIG_EAMAD_DECODER=yesCONFIG_EATGQ_DECODER=yesCONFIG_EATGV_DECODER=yesCONFIG_EATQI_DECODER=yesCONFIG_EIGHTBPS_DECODER=yesCONFIG_EIGHTSVX_EXP_DECODER=yesCONFIG_EIGHTSVX_FIB_DECODER=yesCONFIG_ESCAPE124_DECODER=yesCONFIG_ESCAPE130_DECODER=yesCONFIG_FFV1_DECODER=yesCONFIG_FFVHUFF_DECODER=yesCONFIG_FLASHSV_DECODER=yesCONFIG_FLASHSV2_DECODER=yesCONFIG_FLIC_DECODER=yesCONFIG_FLV_DECODER=yesCONFIG_FOURXM_DECODER=yesCONFIG_FRAPS_DECODER=yesCONFIG_FRWU_DECODER=yesCONFIG_GIF_DECODER=yesCONFIG_H261_DECODER=yesCONFIG_H263_DECODER=yesCONFIG_H263I_DECODER=yesCONFIG_H264_DECODER=yes#此处省略若干条…CONFIG_RTMP_PROTOCOL=yesCONFIG_RTMPT_PROTOCOL=yesCONFIG_RTMPE_PROTOCOL=yesCONFIG_RTMPTE_PROTOCOL=yesCONFIG_RTMPS_PROTOCOL=yesCONFIG_RTP_PROTOCOL=yesCONFIG_TCP_PROTOCOL=yes!CONFIG_TLS_PROTOCOL=yesCONFIG_UDP_PROTOCOL=yes#TestACODEC_TESTS=ac3_fixed adpcm_adx adpcm_ima_qt adpcm_ima_wav adpcm_ms adpcm_swf adpcm_yam alac aref flac g722 g723_1 g726 mp2 pcm_alaw pcm_f32be pcm_f32le pcm_f64be pcm_f64le pcm_mulaw pcm_s16be pcm_s16le pcm_s24be pcm_s24daud pcm_s24le pcm_s32be pcm_s32le pcm_s8 pcm_u8 wmav1 wmav2 VCODEC_TESTS=amv asv1 asv2 cljr dnxhd_1080i dnxhd_720p dnxhd_720p_10bit dnxhd_720p_rd dv dv50 dv_411 error ffv1 flashsv flashsv2 flv h261 h263 h263p huffyuv jpeg2000 jpegls ljpeg mjpeg mpeg mpeg1b mpeg2 mpeg2_422 mpeg2_idct_int mpeg2_ilace mpeg2_ivlc_qprd mpeg2thread mpeg2thread_ilace mpeg4 mpeg4_adap mpeg4_qpel mpeg4_qprd mpeg4adv mpeg4nr mpeg4thread mpng msmpeg4 msmpeg4v2 msvideo1 prores qtrle qtrlegray rc rgb roq rv10 rv20 snow snowll svq1 v210 vref wmv1 wmv2 yuv zlib zmbv LAVF_TESTS=aiff alaw asf au avi bmp caf dpx dv_fmt ffm flv_fmt gif gxf jpg mkv mmf mov mpg mulaw mxf mxf_d10 nut ogg pbmpipe pcx pgm pgmpipe pixfmt png ppm ppmpipe rm rso sgi sox swf tga tiff ts voc voc_s16 wav wtv yuv4mpeg LAVFI_TESTS=crop crop_scale crop_scale_vflip crop_vflip null pixdesc pixfmts_copy pixfmts_crop pixfmts_hflip pixfmts_null pixfmts_pad pixfmts_scale pixfmts_vflip scale200 scale500 vflip vflip_crop vflip_vflip SEEK_TESTS=seek_ac3_rm seek_adpcm_ima_wav seek_adpcm_ms_wav seek_adpcm_qt_aiff seek_adpcm_swf_flv seek_adpcm_yam_wav seek_alac_m4a seek_asv1_avi seek_asv2_avi seek_dnxhd_1080i_mov seek_dnxhd_720p_dnxhd seek_dnxhd_720p_rd_dnxhd seek_dv411_dv seek_dv50_dv seek_dv_dv seek_error_mpeg4_adv_avi seek_ffv1_avi seek_flac_flac seek_flashsv_flv seek_flv_flv seek_g726_wav seek_h261_avi seek_h263_avi seek_h263p_avi seek_huffyuv_avi seek_image_bmp seek_image_jpg seek_image_pcx seek_image_pgm seek_image_ppm seek_image_sgi seek_image_tga seek_image_tiff seek_jpegls_avi seek_lavf_aif seek_lavf_al seek_lavf_asf seek_lavf_au seek_lavf_avi seek_lavf_dv seek_lavf_ffm seek_lavf_flv seek_lavf_gif seek_lavf_gxf seek_lavf_mkv seek_lavf_mmf seek_lavf_mov seek_lavf_mpg seek_lavf_mxf seek_lavf_mxf_d10 seek_lavf_nut seek_lavf_ogg seek_lavf_rm seek_lavf_swf seek_lavf_ts seek_lavf_ul seek_lavf_voc seek_lavf_wav seek_lavf_wtv seek_lavf_y4m seek_ljpeg_avi seek_mjpeg_avi seek_mp2_mp2 seek_mpeg1_mpg seek_mpeg1b_mpg seek_mpeg2_422_mpg seek_mpeg2_idct_int_mpg seek_mpeg2i_mpg seek_mpeg2ivlc_qprd_mpg seek_mpeg2reuse_mpg seek_mpeg2thread_mpg seek_mpeg2threadivlc_mpg seek_mpeg4_adap_avi seek_mpeg4_adv_avi seek_mpeg4_nr_avi seek_mpeg4_qprd_avi seek_mpeg4_rc_avi seek_mpeg4_thread_avi seek_msmpeg4_avi seek_msmpeg4v2_avi seek_odivx_mp4 seek_pbmpipe_pbm seek_pcm_alaw_wav seek_pcm_f32be_au seek_pcm_f32le_wav seek_pcm_f64be_au seek_pcm_f64le_wav seek_pcm_mulaw_wav seek_pcm_s16be_mov seek_pcm_s16le_wav seek_pcm_s24be_mov seek_pcm_s24daud_302 seek_pcm_s24le_wav seek_pcm_s32be_mov seek_pcm_s32le_wav seek_pcm_s8_mov seek_pcm_u8_wav seek_pgmpipe_pgm seek_ppmpipe_ppm seek_rgb_avi seek_roqav_roq seek_rv10_rm seek_rv20_rm seek_snow53_avi seek_snow_avi seek_svq1_mov seek_wmav1_asf seek_wmav2_asf seek_wmv1_avi seek_wmv2_avi seek_yuv_avi endif # FFMPEG_CONFIG_MAK

config.mak代码大致可以分为以下几类信息:
(1)各种路径(prefix等)
(2)工具集(arch、cc、ld、yasm等)
(3)参数集(cppflag、cflag、ldflag等)
(4)前缀后缀(.a、.dll、.exe等)
(5)类库版本(libavXXX_version信息)
(6)组件配置。这一部分信息使用{组件名}=yes的方式进行书写。对于不支持的组件,则在该组件所在行的前面标记上“!”号(感叹号似乎在Makefile语法中并没有什么特殊的用意,此处可能仅仅是作为一种标记?)。这一部分可以分为3类信息:
a)ARCH_信息
b)HAVE_信息
c)CONFIG_信息。这一部分内容最多,将近有1000行。
(7)Test信息(测试组件的结果?还没研究)

libavXXXX/Makefile

libavXXXX/Makefile指的是FFmpeg类库(libavformat、libavcodec、libavutil等)所在的文件夹下的Makefile。例如libavformat文件夹下的Makefile代码如下所示。
# FFmpeg Libavformat Makefile## 注释:雷霄骅# leixiaohua1020@126.com# http://blog.csdn.net/leixiaohua1020## FFmpeg中libavformat的Makefile。# 注意该Makefile并没有定义类库的编译规则(这一部分统一在library.mak中完成)。# 该Makefile中只是赋值了几个重要的字符串:#       NAME,FFLIBS,HEADERS,OBJS,OBJS-yes#重要:包含了configure信息,位于上一级目录include $(SUBDIR)../config.mak#名称NAME = avformat#用到的库?FFLIBS = avcodec avutil#SDK中的头文件HEADERS = avformat.h avio.h version.h#OBJS存储的是必须的目标文件OBJS = allformats.o         \       cutils.o             \       id3v1.o              \       id3v2.o              \       metadata.o           \       options.o            \       os_support.o         \       sdp.o                \       seek.o               \       utils.o              \#OBJS-yes存储的是可选的目标文件OBJS-$(CONFIG_NETWORK)                   += network.o# muxers/demuxersOBJS-$(CONFIG_A64_MUXER)                 += a64.oOBJS-$(CONFIG_AAC_DEMUXER)               += aacdec.o rawdec.oOBJS-$(CONFIG_AC3_DEMUXER)               += ac3dec.o rawdec.oOBJS-$(CONFIG_AC3_MUXER)                 += rawenc.oOBJS-$(CONFIG_ACT_DEMUXER)               += act.oOBJS-$(CONFIG_ADF_DEMUXER)               += bintext.o sauce.oOBJS-$(CONFIG_ADX_DEMUXER)               += adxdec.oOBJS-$(CONFIG_ADX_MUXER)                 += rawenc.oOBJS-$(CONFIG_ADTS_MUXER)                += adtsenc.oOBJS-$(CONFIG_AEA_DEMUXER)               += aea.o pcm.oOBJS-$(CONFIG_AIFF_DEMUXER)              += aiffdec.o riff.o pcm.o isom.oOBJS-$(CONFIG_AIFF_MUXER)                += aiffenc.o riff.o isom.oOBJS-$(CONFIG_AMR_DEMUXER)               += amr.oOBJS-$(CONFIG_AMR_MUXER)                 += amr.oOBJS-$(CONFIG_ANM_DEMUXER)               += anm.oOBJS-$(CONFIG_APC_DEMUXER)               += apc.oOBJS-$(CONFIG_APE_DEMUXER)               += ape.o apetag.oOBJS-$(CONFIG_APPLEHTTP_DEMUXER)         += applehttp.oOBJS-$(CONFIG_ASF_DEMUXER)               += asfdec.o asf.o asfcrypt.o \                                            riff.o avlanguage.oOBJS-$(CONFIG_ASF_MUXER)                 += asfenc.o asf.o riff.oOBJS-$(CONFIG_ASS_DEMUXER)               += assdec.oOBJS-$(CONFIG_ASS_MUXER)                 += assenc.oOBJS-$(CONFIG_AU_DEMUXER)                += au.o pcm.oOBJS-$(CONFIG_AU_MUXER)                  += au.oOBJS-$(CONFIG_AVI_DEMUXER)               += avidec.o riff.oOBJS-$(CONFIG_AVI_MUXER)                 += avienc.o riff.oOBJS-$(CONFIG_AVISYNTH)                  += avisynth.oOBJS-$(CONFIG_AVM2_MUXER)                += swfenc.oOBJS-$(CONFIG_AVS_DEMUXER)               += avs.o vocdec.o voc.oOBJS-$(CONFIG_BETHSOFTVID_DEMUXER)       += bethsoftvid.oOBJS-$(CONFIG_BFI_DEMUXER)               += bfi.oOBJS-$(CONFIG_BINK_DEMUXER)              += bink.oOBJS-$(CONFIG_BINTEXT_DEMUXER)           += bintext.o sauce.oOBJS-$(CONFIG_BIT_DEMUXER)               += bit.oOBJS-$(CONFIG_BIT_MUXER)                 += bit.oOBJS-$(CONFIG_BMV_DEMUXER)               += bmv.oOBJS-$(CONFIG_C93_DEMUXER)               += c93.o vocdec.o voc.oOBJS-$(CONFIG_CAF_DEMUXER)               += cafdec.o caf.o mov.o mov_chan.o \                                            riff.o isom.oOBJS-$(CONFIG_CAF_MUXER)                 += cafenc.o caf.o riff.o isom.oOBJS-$(CONFIG_CAVSVIDEO_DEMUXER)         += cavsvideodec.o rawdec.oOBJS-$(CONFIG_CAVSVIDEO_MUXER)           += rawenc.oOBJS-$(CONFIG_CDG_DEMUXER)               += cdg.oOBJS-$(CONFIG_CRC_MUXER)                 += crcenc.oOBJS-$(CONFIG_DAUD_DEMUXER)              += daud.oOBJS-$(CONFIG_DAUD_MUXER)                += daud.oOBJS-$(CONFIG_DFA_DEMUXER)               += dfa.oOBJS-$(CONFIG_DIRAC_DEMUXER)             += diracdec.o rawdec.oOBJS-$(CONFIG_DIRAC_MUXER)               += rawenc.oOBJS-$(CONFIG_DNXHD_DEMUXER)             += dnxhddec.o rawdec.oOBJS-$(CONFIG_DNXHD_MUXER)               += rawenc.oOBJS-$(CONFIG_DSICIN_DEMUXER)            += dsicin.oOBJS-$(CONFIG_DTS_DEMUXER)               += dtsdec.o rawdec.oOBJS-$(CONFIG_DTS_MUXER)                 += rawenc.oOBJS-$(CONFIG_DV_DEMUXER)                += dv.oOBJS-$(CONFIG_DV_MUXER)                  += dvenc.oOBJS-$(CONFIG_DXA_DEMUXER)               += dxa.o riff.oOBJS-$(CONFIG_EA_CDATA_DEMUXER)          += eacdata.oOBJS-$(CONFIG_EA_DEMUXER)                += electronicarts.oOBJS-$(CONFIG_EAC3_DEMUXER)              += ac3dec.o rawdec.oOBJS-$(CONFIG_EAC3_MUXER)                += rawenc.oOBJS-$(CONFIG_FFM_DEMUXER)               += ffmdec.oOBJS-$(CONFIG_FFM_MUXER)                 += ffmenc.oOBJS-$(CONFIG_FFMETADATA_DEMUXER)        += ffmetadec.oOBJS-$(CONFIG_FFMETADATA_MUXER)          += ffmetaenc.oOBJS-$(CONFIG_FILMSTRIP_DEMUXER)         += filmstripdec.oOBJS-$(CONFIG_FILMSTRIP_MUXER)           += filmstripenc.oOBJS-$(CONFIG_FLAC_DEMUXER)              += flacdec.o rawdec.o \                                            oggparsevorbis.o \                                            vorbiscomment.oOBJS-$(CONFIG_FLAC_MUXER)                += flacenc.o flacenc_header.o \                                            vorbiscomment.oOBJS-$(CONFIG_FLIC_DEMUXER)              += flic.oOBJS-$(CONFIG_FLV_DEMUXER)               += flvdec.oOBJS-$(CONFIG_FLV_MUXER)                 += flvenc.o avc.oOBJS-$(CONFIG_FOURXM_DEMUXER)            += 4xm.oOBJS-$(CONFIG_FRAMECRC_MUXER)            += framecrcenc.oOBJS-$(CONFIG_FRAMEMD5_MUXER)            += md5enc.oOBJS-$(CONFIG_GIF_MUXER)                 += gif.oOBJS-$(CONFIG_GSM_DEMUXER)               += gsmdec.oOBJS-$(CONFIG_GXF_DEMUXER)               += gxf.oOBJS-$(CONFIG_GXF_MUXER)                 += gxfenc.o audiointerleave.oOBJS-$(CONFIG_G722_DEMUXER)              += rawdec.oOBJS-$(CONFIG_G722_MUXER)                += rawenc.oOBJS-$(CONFIG_G723_1_DEMUXER)            += g723_1.oOBJS-$(CONFIG_G723_1_MUXER)              += rawenc.oOBJS-$(CONFIG_G729_DEMUXER)              += g729dec.oOBJS-$(CONFIG_H261_DEMUXER)              += h261dec.o rawdec.oOBJS-$(CONFIG_H261_MUXER)                += rawenc.oOBJS-$(CONFIG_H263_DEMUXER)              += h263dec.o rawdec.oOBJS-$(CONFIG_H263_MUXER)                += rawenc.oOBJS-$(CONFIG_H264_DEMUXER)              += h264dec.o rawdec.oOBJS-$(CONFIG_H264_MUXER)                += rawenc.oOBJS-$(CONFIG_ICO_DEMUXER)               += icodec.oOBJS-$(CONFIG_IDCIN_DEMUXER)             += idcin.oOBJS-$(CONFIG_IDF_DEMUXER)               += bintext.oOBJS-$(CONFIG_IFF_DEMUXER)               += iff.oOBJS-$(CONFIG_IMAGE2_DEMUXER)            += img2.oOBJS-$(CONFIG_IMAGE2_MUXER)              += img2.oOBJS-$(CONFIG_IMAGE2PIPE_DEMUXER)        += img2.oOBJS-$(CONFIG_IMAGE2PIPE_MUXER)          += img2.oOBJS-$(CONFIG_INGENIENT_DEMUXER)         += ingenientdec.o rawdec.oOBJS-$(CONFIG_IPMOVIE_DEMUXER)           += ipmovie.oOBJS-$(CONFIG_ISS_DEMUXER)               += iss.oOBJS-$(CONFIG_IV8_DEMUXER)               += iv8.oOBJS-$(CONFIG_IVF_DEMUXER)               += ivfdec.o riff.oOBJS-$(CONFIG_IVF_MUXER)                 += ivfenc.oOBJS-$(CONFIG_JV_DEMUXER)                += jvdec.oOBJS-$(CONFIG_LATM_DEMUXER)              += rawdec.oOBJS-$(CONFIG_LATM_MUXER)                += latmenc.oOBJS-$(CONFIG_LMLM4_DEMUXER)             += lmlm4.oOBJS-$(CONFIG_LOAS_DEMUXER)              += loasdec.oOBJS-$(CONFIG_LXF_DEMUXER)               += lxfdec.oOBJS-$(CONFIG_M4V_DEMUXER)               += m4vdec.o rawdec.oOBJS-$(CONFIG_M4V_MUXER)                 += rawenc.oOBJS-$(CONFIG_MATROSKA_DEMUXER)          += matroskadec.o matroska.o \                                            riff.o isom.o rmdec.o rm.oOBJS-$(CONFIG_MATROSKA_MUXER)            += matroskaenc.o matroska.o \                                            riff.o isom.o avc.o \                                            flacenc_header.o avlanguage.oOBJS-$(CONFIG_MD5_MUXER)                 += md5enc.oOBJS-$(CONFIG_MICRODVD_DEMUXER)          += microdvddec.oOBJS-$(CONFIG_MICRODVD_MUXER)            += microdvdenc.o rawenc.oOBJS-$(CONFIG_MJPEG_DEMUXER)             += rawdec.oOBJS-$(CONFIG_MJPEG_MUXER)               += rawenc.oOBJS-$(CONFIG_MLP_DEMUXER)               += rawdec.oOBJS-$(CONFIG_MLP_MUXER)                 += rawenc.oOBJS-$(CONFIG_MM_DEMUXER)                += mm.oOBJS-$(CONFIG_MMF_DEMUXER)               += mmf.o pcm.oOBJS-$(CONFIG_MMF_MUXER)                 += mmf.o riff.oOBJS-$(CONFIG_MOV_DEMUXER)               += mov.o riff.o isom.o mov_chan.oOBJS-$(CONFIG_MOV_MUXER)                 += movenc.o riff.o isom.o avc.o \                                            movenchint.o rtpenc_chain.o \                                            mov_chan.oOBJS-$(CONFIG_MP2_MUXER)                 += mp3enc.o rawenc.oOBJS-$(CONFIG_MP3_DEMUXER)               += mp3dec.oOBJS-$(CONFIG_MP3_MUXER)                 += mp3enc.o rawenc.o id3v2enc.oOBJS-$(CONFIG_MPC_DEMUXER)               += mpc.o apetag.oOBJS-$(CONFIG_MPC8_DEMUXER)              += mpc8.oOBJS-$(CONFIG_MPEG1SYSTEM_MUXER)         += mpegenc.oOBJS-$(CONFIG_MPEG1VCD_MUXER)            += mpegenc.oOBJS-$(CONFIG_MPEG2DVD_MUXER)            += mpegenc.oOBJS-$(CONFIG_MPEG2VOB_MUXER)            += mpegenc.oOBJS-$(CONFIG_MPEG2SVCD_MUXER)           += mpegenc.oOBJS-$(CONFIG_MPEG1VIDEO_MUXER)          += rawenc.oOBJS-$(CONFIG_MPEG2VIDEO_MUXER)          += rawenc.oOBJS-$(CONFIG_MPEGPS_DEMUXER)            += mpeg.oOBJS-$(CONFIG_MPEGTS_DEMUXER)            += mpegts.o isom.oOBJS-$(CONFIG_MPEGTS_MUXER)              += mpegtsenc.o adtsenc.oOBJS-$(CONFIG_MPEGVIDEO_DEMUXER)         += mpegvideodec.o rawdec.oOBJS-$(CONFIG_MPJPEG_MUXER)              += mpjpeg.oOBJS-$(CONFIG_MSNWC_TCP_DEMUXER)         += msnwc_tcp.oOBJS-$(CONFIG_MTV_DEMUXER)               += mtv.oOBJS-$(CONFIG_MVI_DEMUXER)               += mvi.oOBJS-$(CONFIG_MXF_DEMUXER)               += mxfdec.o mxf.oOBJS-$(CONFIG_MXF_MUXER)                 += mxfenc.o mxf.o audiointerleave.oOBJS-$(CONFIG_MXG_DEMUXER)               += mxg.oOBJS-$(CONFIG_NC_DEMUXER)                += ncdec.oOBJS-$(CONFIG_NSV_DEMUXER)               += nsvdec.oOBJS-$(CONFIG_NULL_MUXER)                += nullenc.oOBJS-$(CONFIG_NUT_DEMUXER)               += nutdec.o nut.o riff.oOBJS-$(CONFIG_NUT_MUXER)                 += nutenc.o nut.o riff.oOBJS-$(CONFIG_NUV_DEMUXER)               += nuv.o riff.oOBJS-$(CONFIG_OGG_DEMUXER)               += oggdec.o         \                                            oggparsecelt.o   \                                            oggparsedirac.o  \                                            oggparseflac.o   \                                            oggparseogm.o    \                                            oggparseskeleton.o \                                            oggparsespeex.o  \                                            oggparsetheora.o \                                            oggparsevorbis.o \                                            riff.o \                                            vorbiscomment.oOBJS-$(CONFIG_OGG_MUXER)                 += oggenc.o \                                            vorbiscomment.oOBJS-$(CONFIG_OMA_DEMUXER)               += omadec.o pcm.o oma.oOBJS-$(CONFIG_OMA_MUXER)                 += omaenc.o rawenc.o oma.o id3v2enc.oOBJS-$(CONFIG_PCM_ALAW_DEMUXER)          += pcmdec.o pcm.o rawdec.oOBJS-$(CONFIG_PCM_ALAW_MUXER)            += pcmenc.o rawenc.oOBJS-$(CONFIG_PCM_F32BE_DEMUXER)         += pcmdec.o pcm.o rawdec.oOBJS-$(CONFIG_PCM_F32BE_MUXER)           += pcmenc.o rawenc.oOBJS-$(CONFIG_PCM_F32LE_DEMUXER)         += pcmdec.o pcm.o rawdec.oOBJS-$(CONFIG_PCM_F32LE_MUXER)           += pcmenc.o rawenc.oOBJS-$(CONFIG_PCM_F64BE_DEMUXER)         += pcmdec.o pcm.o rawdec.oOBJS-$(CONFIG_PCM_F64BE_MUXER)           += pcmenc.o rawenc.oOBJS-$(CONFIG_PCM_F64LE_DEMUXER)         += pcmdec.o pcm.o rawdec.oOBJS-$(CONFIG_PCM_F64LE_MUXER)           += pcmenc.o rawenc.oOBJS-$(CONFIG_PCM_MULAW_DEMUXER)         += pcmdec.o pcm.o rawdec.oOBJS-$(CONFIG_PCM_MULAW_MUXER)           += pcmenc.o rawenc.oOBJS-$(CONFIG_PCM_S16BE_DEMUXER)         += pcmdec.o pcm.o rawdec.oOBJS-$(CONFIG_PCM_S16BE_MUXER)           += pcmenc.o rawenc.oOBJS-$(CONFIG_PCM_S16LE_DEMUXER)         += pcmdec.o pcm.o rawdec.oOBJS-$(CONFIG_PCM_S16LE_MUXER)           += pcmenc.o rawenc.oOBJS-$(CONFIG_PCM_S24BE_DEMUXER)         += pcmdec.o pcm.o rawdec.oOBJS-$(CONFIG_PCM_S24BE_MUXER)           += pcmenc.o rawenc.oOBJS-$(CONFIG_PCM_S24LE_DEMUXER)         += pcmdec.o pcm.o rawdec.oOBJS-$(CONFIG_PCM_S24LE_MUXER)           += pcmenc.o rawenc.oOBJS-$(CONFIG_PCM_S32BE_DEMUXER)         += pcmdec.o pcm.o rawdec.oOBJS-$(CONFIG_PCM_S32BE_MUXER)           += pcmenc.o rawenc.oOBJS-$(CONFIG_PCM_S32LE_DEMUXER)         += pcmdec.o pcm.o rawdec.oOBJS-$(CONFIG_PCM_S32LE_MUXER)           += pcmenc.o rawenc.oOBJS-$(CONFIG_PCM_S8_DEMUXER)            += pcmdec.o pcm.o rawdec.oOBJS-$(CONFIG_PCM_S8_MUXER)              += pcmenc.o rawenc.oOBJS-$(CONFIG_PCM_U16BE_DEMUXER)         += pcmdec.o pcm.o rawdec.oOBJS-$(CONFIG_PCM_U16BE_MUXER)           += pcmenc.o rawenc.oOBJS-$(CONFIG_PCM_U16LE_DEMUXER)         += pcmdec.o pcm.o rawdec.oOBJS-$(CONFIG_PCM_U16LE_MUXER)           += pcmenc.o rawenc.oOBJS-$(CONFIG_PCM_U24BE_DEMUXER)         += pcmdec.o pcm.o rawdec.oOBJS-$(CONFIG_PCM_U24BE_MUXER)           += pcmenc.o rawenc.oOBJS-$(CONFIG_PCM_U24LE_DEMUXER)         += pcmdec.o pcm.o rawdec.oOBJS-$(CONFIG_PCM_U24LE_MUXER)           += pcmenc.o rawenc.oOBJS-$(CONFIG_PCM_U32BE_DEMUXER)         += pcmdec.o pcm.o rawdec.oOBJS-$(CONFIG_PCM_U32BE_MUXER)           += pcmenc.o rawenc.oOBJS-$(CONFIG_PCM_U32LE_DEMUXER)         += pcmdec.o pcm.o rawdec.oOBJS-$(CONFIG_PCM_U32LE_MUXER)           += pcmenc.o rawenc.oOBJS-$(CONFIG_PCM_U8_DEMUXER)            += pcmdec.o pcm.o rawdec.oOBJS-$(CONFIG_PCM_U8_MUXER)              += pcmenc.o rawenc.oOBJS-$(CONFIG_PMP_DEMUXER)               += pmpdec.oOBJS-$(CONFIG_PVA_DEMUXER)               += pva.oOBJS-$(CONFIG_QCP_DEMUXER)               += qcp.oOBJS-$(CONFIG_R3D_DEMUXER)               += r3d.oOBJS-$(CONFIG_RAWVIDEO_DEMUXER)          += rawvideodec.o rawdec.oOBJS-$(CONFIG_RAWVIDEO_MUXER)            += rawenc.oOBJS-$(CONFIG_RL2_DEMUXER)               += rl2.oOBJS-$(CONFIG_RM_DEMUXER)                += rmdec.o rm.oOBJS-$(CONFIG_RM_MUXER)                  += rmenc.o rm.oOBJS-$(CONFIG_ROQ_DEMUXER)               += idroqdec.oOBJS-$(CONFIG_ROQ_MUXER)                 += idroqenc.o rawenc.oOBJS-$(CONFIG_RSO_DEMUXER)               += rsodec.o rso.o pcm.oOBJS-$(CONFIG_RSO_MUXER)                 += rsoenc.o rso.oOBJS-$(CONFIG_RPL_DEMUXER)               += rpl.oOBJS-$(CONFIG_RTP_MUXER)                 += rtp.o         \                                            rtpenc_aac.o     \                                            rtpenc_latm.o    \                                            rtpenc_amr.o     \                                            rtpenc_h263.o    \                                            rtpenc_mpv.o     \                                            rtpenc.o      \                                            rtpenc_h264.o \                                            rtpenc_vp8.o  \                                            rtpenc_xiph.o \                                            avc.oOBJS-$(CONFIG_RTPDEC)                    += rdt.o         \                                            rtp.o         \                                            rtpdec.o      \                                            rtpdec_amr.o  \                                            rtpdec_asf.o  \                                            rtpdec_g726.o \                                            rtpdec_h263.o \                                            rtpdec_h264.o \                                            rtpdec_latm.o \                                            rtpdec_mpeg4.o \                                            rtpdec_qcelp.o \                                            rtpdec_qdm2.o \                                            rtpdec_qt.o   \                                            rtpdec_svq3.o \                                            rtpdec_vp8.o  \                                            rtpdec_xiph.oOBJS-$(CONFIG_RTSP_DEMUXER)              += rtsp.o rtspdec.o httpauth.oOBJS-$(CONFIG_RTSP_MUXER)                += rtsp.o rtspenc.o httpauth.o \                                            rtpenc_chain.oOBJS-$(CONFIG_SAP_DEMUXER)               += sapdec.oOBJS-$(CONFIG_SAP_MUXER)                 += sapenc.o rtpenc_chain.oOBJS-$(CONFIG_SBG_DEMUXER)               += sbgdec.oOBJS-$(CONFIG_SDP_DEMUXER)               += rtsp.oOBJS-$(CONFIG_SEGAFILM_DEMUXER)          += segafilm.oOBJS-$(CONFIG_SEGMENT_MUXER)             += segment.oOBJS-$(CONFIG_SHORTEN_DEMUXER)           += rawdec.oOBJS-$(CONFIG_SIFF_DEMUXER)              += siff.oOBJS-$(CONFIG_SMACKER_DEMUXER)           += smacker.oOBJS-$(CONFIG_SMJPEG_DEMUXER)            += smjpegdec.o smjpeg.oOBJS-$(CONFIG_SMJPEG_MUXER)              += smjpegenc.o smjpeg.oOBJS-$(CONFIG_SOL_DEMUXER)               += sol.o pcm.oOBJS-$(CONFIG_SOX_DEMUXER)               += soxdec.o pcm.oOBJS-$(CONFIG_SOX_MUXER)                 += soxenc.oOBJS-$(CONFIG_SPDIF_DEMUXER)             += spdif.o spdifdec.oOBJS-$(CONFIG_SPDIF_MUXER)               += spdif.o spdifenc.oOBJS-$(CONFIG_SRT_DEMUXER)               += srtdec.oOBJS-$(CONFIG_SRT_MUXER)                 += rawenc.oOBJS-$(CONFIG_STR_DEMUXER)               += psxstr.oOBJS-$(CONFIG_SWF_DEMUXER)               += swfdec.oOBJS-$(CONFIG_SWF_MUXER)                 += swfenc.oOBJS-$(CONFIG_THP_DEMUXER)               += thp.oOBJS-$(CONFIG_TIERTEXSEQ_DEMUXER)        += tiertexseq.oOBJS-$(CONFIG_MKVTIMESTAMP_V2_MUXER)     += mkvtimestamp_v2.oOBJS-$(CONFIG_TMV_DEMUXER)               += tmv.oOBJS-$(CONFIG_TRUEHD_DEMUXER)            += rawdec.oOBJS-$(CONFIG_TRUEHD_MUXER)              += rawenc.oOBJS-$(CONFIG_TTA_DEMUXER)               += tta.oOBJS-$(CONFIG_TTY_DEMUXER)               += tty.o sauce.oOBJS-$(CONFIG_TXD_DEMUXER)               += txd.oOBJS-$(CONFIG_VC1_DEMUXER)               += rawdec.oOBJS-$(CONFIG_VC1T_DEMUXER)              += vc1test.oOBJS-$(CONFIG_VC1T_MUXER)                += vc1testenc.oOBJS-$(CONFIG_VMD_DEMUXER)               += sierravmd.oOBJS-$(CONFIG_VOC_DEMUXER)               += vocdec.o voc.oOBJS-$(CONFIG_VOC_MUXER)                 += vocenc.o voc.oOBJS-$(CONFIG_VQF_DEMUXER)               += vqf.oOBJS-$(CONFIG_W64_DEMUXER)               += wav.o riff.o pcm.oOBJS-$(CONFIG_WAV_DEMUXER)               += wav.o riff.o pcm.oOBJS-$(CONFIG_WAV_MUXER)                 += wav.o riff.oOBJS-$(CONFIG_WC3_DEMUXER)               += wc3movie.oOBJS-$(CONFIG_WEBM_MUXER)                += matroskaenc.o matroska.o \                                            riff.o isom.o avc.o \                                            flacenc_header.o avlanguage.oOBJS-$(CONFIG_WSAUD_DEMUXER)             += westwood_aud.oOBJS-$(CONFIG_WSVQA_DEMUXER)             += westwood_vqa.oOBJS-$(CONFIG_WTV_DEMUXER)               += wtvdec.o wtv.o asfdec.o asf.o asfcrypt.o \                                            avlanguage.o mpegts.o isom.o riff.oOBJS-$(CONFIG_WTV_MUXER)                 += wtvenc.o wtv.o asf.o asfenc.o riff.oOBJS-$(CONFIG_WV_DEMUXER)                += wv.o apetag.oOBJS-$(CONFIG_XA_DEMUXER)                += xa.oOBJS-$(CONFIG_XBIN_DEMUXER)              += bintext.o sauce.oOBJS-$(CONFIG_XMV_DEMUXER)               += xmv.o riff.oOBJS-$(CONFIG_XWMA_DEMUXER)              += xwma.o riff.oOBJS-$(CONFIG_YOP_DEMUXER)               += yop.oOBJS-$(CONFIG_YUV4MPEGPIPE_MUXER)        += yuv4mpeg.oOBJS-$(CONFIG_YUV4MPEGPIPE_DEMUXER)      += yuv4mpeg.o# external librariesOBJS-$(CONFIG_LIBMODPLUG_DEMUXER)        += libmodplug.oOBJS-$(CONFIG_LIBNUT_DEMUXER)            += libnut.o riff.oOBJS-$(CONFIG_LIBNUT_MUXER)              += libnut.o riff.o# protocols I/OOBJS+= avio.o aviobuf.oOBJS-$(CONFIG_APPLEHTTP_PROTOCOL)        += applehttpproto.oOBJS-$(CONFIG_CACHE_PROTOCOL)            += cache.oOBJS-$(CONFIG_CONCAT_PROTOCOL)           += concat.oOBJS-$(CONFIG_CRYPTO_PROTOCOL)           += crypto.oOBJS-$(CONFIG_FILE_PROTOCOL)             += file.oOBJS-$(CONFIG_GOPHER_PROTOCOL)           += gopher.oOBJS-$(CONFIG_HTTP_PROTOCOL)             += http.o httpauth.oOBJS-$(CONFIG_HTTPPROXY_PROTOCOL)        += http.o httpauth.oOBJS-$(CONFIG_HTTPS_PROTOCOL)            += http.o httpauth.oOBJS-$(CONFIG_MMSH_PROTOCOL)             += mmsh.o mms.o asf.oOBJS-$(CONFIG_MMST_PROTOCOL)             += mmst.o mms.o asf.oOBJS-$(CONFIG_MD5_PROTOCOL)              += md5proto.oOBJS-$(CONFIG_PIPE_PROTOCOL)             += file.o# external or internal rtmpRTMP-OBJS-$(CONFIG_LIBRTMP)               = librtmp.oRTMP-OBJS-$(!CONFIG_LIBRTMP)              = rtmpproto.o rtmppkt.oOBJS-$(CONFIG_RTMP_PROTOCOL)             += $(RTMP-OBJS-yes)OBJS-$(CONFIG_RTP_PROTOCOL)              += rtpproto.oOBJS-$(CONFIG_TCP_PROTOCOL)              += tcp.oOBJS-$(CONFIG_TLS_PROTOCOL)              += tls.oOBJS-$(CONFIG_UDP_PROTOCOL)              += udp.oSKIPHEADERS-$(CONFIG_NETWORK)            += network.h rtsp.hTESTPROGS = seekTOOLS     = aviocat ismindex pktdumper probetest

从代码可以看出,libavformat文件夹下的Makefile的规则十分简单,并不包含文件之间的依赖关系(依赖关系位于library.mak中),仅仅是设置了几个变量的值:
NAME:类库名称。注意不包含类库前面的“lib”以及类库的后缀。在这里是“avformat”。
FFLIBS:该类库依赖的类库名称。在这里用到了“avcodec”和“avutil”。
HEADERS:该类库导出的头文件。在这里是“avformat.h”,“avio.h”,“version.h”。
OBJS:该类库依赖的目标文件(必须的)。在这里是“utils.o”等等。
OBJS-yes:该类库依赖的目标文件(可选的)。在这里是“flvdec.o”、“flvenc.o”等等。

library.mak

library.mak专门用于存储编译类库的规则,是和libavXXX/Makefile配合使用的。它的源代码如下所示。
# FFmpeg library.mak## 注释:雷霄骅# leixiaohua1020@126.com# http://blog.csdn.net/leixiaohua1020## 编译类库(libavformat等)专用的Makefile,其中包含了编译类库的规则。#【NAME位于每个类库的Makefile】,可以取avcodec,avformat等等SRC_DIR := $(SRC_PATH)/lib$(NAME)include $(SRC_PATH)/common.mak#这些信息都位于config.mak中#例如:# libavformat_VERSION=53.31.100# libavformat_VERSION_MAJOR=53LIBVERSION := $(lib$(NAME)_VERSION)LIBMAJOR   := $(lib$(NAME)_VERSION_MAJOR)INCINSTDIR := $(INCDIR)/lib$(NAME)THIS_LIB   := $(SUBDIR)$($(CONFIG_SHARED:yes=S)LIBNAME)all-$(CONFIG_STATIC): $(SUBDIR)$(LIBNAME)all-$(CONFIG_SHARED): $(SUBDIR)$(SLIBNAME)$(SUBDIR)%-test.o: $(SUBDIR)%-test.c$(COMPILE_C)$(SUBDIR)%-test.o: $(SUBDIR)%.c$(COMPILE_C)#汇编?$(SUBDIR)x86/%.o: $(SUBDIR)x86/%.asm$(YASMDEP) $(YASMFLAGS) -I $(<D)/ -M -o $@ $< > $(@:.o=.d)$(YASM) $(YASMFLAGS) -I $(<D)/ -o $@ $<$(OBJS) $(OBJS:.o=.s) $(SUBDIR)%.ho $(TESTOBJS): CPPFLAGS += -DHAVE_AV_CONFIG_H$(TESTOBJS): CPPFLAGS += -DTEST#【OBJS来自于每个类库的Makefile】#$@  表示规则中的目标文件集#$^  所有的依赖目标的集合。#生成静态库?$(SUBDIR)$(LIBNAME): $(OBJS)$(RM) $@$(AR) rc $@ $^ $(EXTRAOBJS)$(RANLIB) $@#安转头文件,根目录的Makefile调用install-headers: install-lib$(NAME)-headers install-lib$(NAME)-pkgconfig#install-libs-yes被install-libs(位于根目录Makefile)调用install-libs-$(CONFIG_STATIC): install-lib$(NAME)-staticinstall-libs-$(CONFIG_SHARED): install-lib$(NAME)-shareddefine RULES$(EXAMPLES) $(TESTPROGS) $(TOOLS): %$(EXESUF): %.o$$(LD) $(LDFLAGS) -o $$@ $$^ -l$(FULLNAME) $(FFEXTRALIBS) $$(ELIBS)$(SUBDIR)$(SLIBNAME): $(SUBDIR)$(SLIBNAME_WITH_MAJOR)$(Q)cd ./$(SUBDIR) && $(LN_S) $(SLIBNAME_WITH_MAJOR) $(SLIBNAME)$(SUBDIR)$(SLIBNAME_WITH_MAJOR): $(OBJS) $(SUBDIR)lib$(NAME).ver$(SLIB_CREATE_DEF_CMD)$$(LD) $(SHFLAGS) $(LDFLAGS) -o $$@ $$(filter %.o,$$^) $(FFEXTRALIBS) $(EXTRAOBJS)$(SLIB_EXTRA_CMD)#SLIBNAME_WITH_MAJOR包含了Major版本号。例如:libavformat-53.dllifdef SUBDIR$(SUBDIR)$(SLIBNAME_WITH_MAJOR): $(DEP_LIBS)endif#清空clean::$(RM) $(addprefix $(SUBDIR),*-example$(EXESUF) *-test$(EXESUF) $(CLEANFILES) $(CLEANSUFFIXES) $(LIBSUFFIXES)) \    $(foreach dir,$(DIRS),$(CLEANSUFFIXES:%=$(SUBDIR)$(dir)/%)) \    $(HOSTOBJS) $(HOSTPROGS)distclean:: clean$(RM) $(DISTCLEANSUFFIXES:%=$(SUBDIR)%) \    $(foreach dir,$(DIRS),$(DISTCLEANSUFFIXES:%=$(SUBDIR)$(dir)/%))#安装库文件=====================install-lib$(NAME)-shared: $(SUBDIR)$(SLIBNAME)$(Q)mkdir -p "$(SHLIBDIR)"$$(INSTALL) -m 755 $$< "$(SHLIBDIR)/$(SLIB_INSTALL_NAME)"$$(STRIP) "$(SHLIBDIR)/$(SLIB_INSTALL_NAME)"$(Q)$(foreach F,$(SLIB_INSTALL_LINKS),cd "$(SHLIBDIR)" && $(LN_S) $(SLIB_INSTALL_NAME) $(F);)$(if $(SLIB_INSTALL_EXTRA_SHLIB),$$(INSTALL) -m 644 $(SLIB_INSTALL_EXTRA_SHLIB:%=$(SUBDIR)%) "$(SHLIBDIR)")$(if $(SLIB_INSTALL_EXTRA_LIB),$(Q)mkdir -p "$(LIBDIR)")$(if $(SLIB_INSTALL_EXTRA_LIB),$$(INSTALL) -m 644 $(SLIB_INSTALL_EXTRA_LIB:%=$(SUBDIR)%) "$(LIBDIR)")install-lib$(NAME)-static: $(SUBDIR)$(LIBNAME)$(Q)mkdir -p "$(LIBDIR)"$$(INSTALL) -m 644 $$< "$(LIBDIR)"$(LIB_INSTALL_EXTRA_CMD)#安装头文件=====================#-m#权限:644,755,777#644 rw-r--r--#755 rwxr-xr-x#777 rwxrwxrwx#从左至右,1-3位数字代表文件所有者的权限,4-6位数字代表同组用户的权限,7-9数字代表其他用户的权限。#通过4、2、1的组合,得到以下几种权限:0(没有权限);4(读取权限);5(4+1 | 读取+执行);6(4+2 | 读取+写入);7(4+2+1 | 读取+写入+执行)#addprefix()#$(addprefix src/,foo bar)返回值是“src/foo src/bar”。#【HEADERS来自于每个类库的Makefile】#例如libavformat中HEADERS = avformat.h avio.h version.hinstall-lib$(NAME)-headers: $(addprefix $(SUBDIR),$(HEADERS) $(BUILT_HEADERS))$(Q)mkdir -p "$(INCINSTDIR)"$$(INSTALL) -m 644 $$^ "$(INCINSTDIR)"install-lib$(NAME)-pkgconfig: $(SUBDIR)lib$(NAME).pc$(Q)mkdir -p "$(LIBDIR)/pkgconfig"$$(INSTALL) -m 644 $$^ "$(LIBDIR)/pkgconfig"#卸载uninstall-libs::-$(RM) "$(SHLIBDIR)/$(SLIBNAME_WITH_MAJOR)" \       "$(SHLIBDIR)/$(SLIBNAME)"            \       "$(SHLIBDIR)/$(SLIBNAME_WITH_VERSION)"-$(RM) $(SLIB_INSTALL_EXTRA_SHLIB:%="$(SHLIBDIR)"%)-$(RM) $(SLIB_INSTALL_EXTRA_LIB:%="$(LIBDIR)"%)-$(RM) "$(LIBDIR)/$(LIBNAME)"uninstall-headers::$(RM) $(addprefix "$(INCINSTDIR)/",$(HEADERS)) $(addprefix "$(INCINSTDIR)/",$(BUILT_HEADERS))$(RM) "$(LIBDIR)/pkgconfig/lib$(NAME).pc"-rmdir "$(INCINSTDIR)"endef$(eval $(RULES))$(EXAMPLES) $(TESTPROGS) $(TOOLS): $(THIS_LIB) $(DEP_LIBS)$(TESTPROGS): $(SUBDIR)$(LIBNAME)examples: $(EXAMPLES)testprogs: $(TESTPROGS)

library.mak代码中首先包含了common.mak文件。这个文件定义了通用的一些编译规则。然后定义了类库的依赖关系。
此外library.mak中也定义了install-headers,install-lib$(NAME)-shared,install-lib$(NAME)-static,install-lib$(NAME)-headers,clean等等一系列的伪目标(NAME取值avformat、avcodec等)。这些目标主要配合根目录的Makefile使用。

common.mak

common.mak文件定义了通用的一些编译规则。代码如下所示。

# FFmpeg common.mak## 注释:雷霄骅# leixiaohua1020@126.com# http://blog.csdn.net/leixiaohua1020## 通用的Makefile,其中包含了通用的编译规则。## common bits used by all libraries## first so "all" becomes default targetall: all-yesifndef SUBDIR#在控制台打印信息ifndef VQ      = @#输出ECHO   = printf "$(1)\t%s\n" $(2)BRIEF  = CC CXX AS YASM AR LD HOSTCC STRIP CPSILENT = DEPCC YASMDEP RM RANLIBMSG    = $@M      = @$(call ECHO,$(TAG),$@);$(foreach VAR,$(BRIEF), \    $(eval override $(VAR) = @$$(call ECHO,$(VAR),$$(MSG)); $($(VAR))))$(foreach VAR,$(SILENT),$(eval override $(VAR) = @$($(VAR))))$(eval INSTALL = @$(call ECHO,INSTALL,$$(^:$(SRC_DIR)/%=%)); $(INSTALL))endif#所有的libALLFFLIBS = avcodec avdevice avfilter avformat avutil postproc swscale swresample# NASM requires -I path terminated with /#各种Flag#SRC_PATH=.IFLAGS     := -I. -I$(SRC_PATH)/CPPFLAGS   := $(IFLAGS) $(CPPFLAGS)CFLAGS     += $(ECFLAGS)CCFLAGS     = $(CFLAGS)CXXFLAGS   := $(CFLAGS) $(CXXFLAGS)YASMFLAGS  += $(IFLAGS) -I$(SRC_PATH)/libavutil/x86/ -Pconfig.asmHOSTCFLAGS += $(IFLAGS)#avcodec处理后成为-Llibavcodec#config.mak文件中:#LDFLAGS= -Wl,--as-needed -Wl,--warn-common -Wl,#-rpath-link=libpostproc:libswresample:libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutilLDFLAGS    := $(ALLFFLIBS:%=-Llib%) $(LDFLAGS)#命令包#具体编译命令##$(1)可以取CC、CXX等#例如取$(1)取CC#config.mak文件中:#SRC_PATH=.#CC=gcc##CCFLAGS=$(CFLAGS)#CFLAGS=   -std=c99 -fno-common -fomit-frame-pointer -I/include/SDL -D_GNU_SOURCE=1 -Dmain=SDL_main# -g -Wdeclaration-after-statement -Wall -Wno-parentheses -Wno-switch -Wno-format-zero-length# -Wdisabled-optimization -Wpointer-arith -Wredundant-decls -Wno-pointer-sign -Wcast-qual -Wwrite-strings# -Wtype-limits -Wundef -Wmissing-prototypes -Wno-pointer-to-int-cast -Wstrict-prototypes# -O3 -fno-math-errno -fno-signed-zeros -fno-tree-vectorize -Werror=implicit-function-declaration -Werror=missing-prototypes##CPPFLAGS= -D_ISOC99_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -U__STRICT_ANSI__#CC_O=-o $@#CC_DEPFLAGS=-MMD -MF $(@:.o=.d) -MT $@#举例:#gcc -I. -Itest/ -c -o $@ $<#再例如$(1)取CXX#CXXFLAGS=  -D__STDC_CONSTANT_MACROSdefine COMPILE       $($(1)DEP)       $($(1)) $(CPPFLAGS) $($(1)FLAGS) $($(1)_DEPFLAGS) -c $($(1)_O) $<endef#编译命令#$(call <expression>,<parm1>,<parm2>,<parm3>...)#当make执行这个函数时,<expression>参数中的变量,如$(1),$(2),$(3)等,会被参数#<parm1>,<parm2>,<parm3>依次取代。而<expression>的返回值就是call函数的返回值。COMPILE_C = $(call COMPILE,CC)COMPILE_CXX = $(call COMPILE,CXX)COMPILE_S = $(call COMPILE,AS)#COMPILE_C为:#$(CC DEP)#$($(CC) $(CPPFLAGS) $($(1)FLAGS) $($(1)_DEPFLAGS) -c $($(1)_O) $<#依赖关系#C语言%.o: %.c#编译$(COMPILE_C)#C++%.o: %.cpp$(COMPILE_CXX)%.s: %.c$(CC) $(CPPFLAGS) $(CFLAGS) -S -o $@ $<%.o: %.S$(COMPILE_S)%.ho: %.h$(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused -c -o $@ -x c $<%.ver: %.v$(Q)sed 's/$$MAJOR/$($(basename $(@F))_VERSION_MAJOR)/' $^ > $@%.c %.h: TAG = GEN# Dummy rule to stop make trying to rebuild removed or renamed headers%.h:@:# Disable suffix rules.  Most of the builtin rules are suffix rules,# so this saves some time on slow systems..SUFFIXES:# Do not delete intermediate files from chains of implicit rules$(OBJS):endifOBJS-$(HAVE_MMX) +=  $(MMX-OBJS-yes)#源自Makefile#OBJS:该类库必须的目标文件#OBJS-yes:该类库可配置的目标文件OBJS      += $(OBJS-yes)#FFLIBS:必须的类库#FFLIBS-yes:可选的类库#FFLIBS = avcodec avutil ....FFLIBS    := $(FFLIBS-yes) $(FFLIBS)TESTPROGS += $(TESTPROGS-yes)FFEXTRALIBS := $(FFLIBS:%=-l%$(BUILDSUF)) $(EXTRALIBS)EXAMPLES  := $(EXAMPLES:%=$(SUBDIR)%-example$(EXESUF))#排序?OBJS      := $(sort $(OBJS:%=$(SUBDIR)%))TESTOBJS  := $(TESTOBJS:%=$(SUBDIR)%) $(TESTPROGS:%=$(SUBDIR)%-test.o)TESTPROGS := $(TESTPROGS:%=$(SUBDIR)%-test$(EXESUF))HOSTOBJS  := $(HOSTPROGS:%=$(SUBDIR)%.o)HOSTPROGS := $(HOSTPROGS:%=$(SUBDIR)%$(HOSTEXESUF))TOOLS     += $(TOOLS-yes)TOOLOBJS  := $(TOOLS:%=tools/%.o)TOOLS     := $(TOOLS:%=tools/%$(EXESUF))#DEP_LIBS= libavcodec/libavcodec.a libavutil/libavutil.a ....DEP_LIBS := $(foreach NAME,$(FFLIBS),lib$(NAME)/$($(CONFIG_SHARED:yes=S)LIBNAME))ALLHEADERS := $(subst $(SRC_DIR)/,$(SUBDIR),$(wildcard $(SRC_DIR)/*.h $(SRC_DIR)/$(ARCH)/*.h))SKIPHEADERS += $(ARCH_HEADERS:%=$(ARCH)/%) $(SKIPHEADERS-)SKIPHEADERS := $(SKIPHEADERS:%=$(SUBDIR)%)checkheaders: $(filter-out $(SKIPHEADERS:.h=.ho),$(ALLHEADERS:.h=.ho))alltools: $(TOOLS)$(HOSTOBJS): %.o: %.c$(HOSTCC) $(HOSTCFLAGS) -c -o $@ $<$(HOSTPROGS): %$(HOSTEXESUF): %.o$(HOSTCC) $(HOSTLDFLAGS) -o $@ $< $(HOSTLIBS)$(OBJS):     | $(sort $(dir $(OBJS)))$(HOSTOBJS): | $(sort $(dir $(HOSTOBJS)))$(TESTOBJS): | $(sort $(dir $(TESTOBJS)))$(TOOLOBJS): | toolsOBJDIRS := $(OBJDIRS) $(dir $(OBJS) $(HOSTOBJS) $(TESTOBJS))CLEANSUFFIXES     = *.d *.o *~ *.ho *.map *.ver *.gcno *.gcdaDISTCLEANSUFFIXES = *.pcLIBSUFFIXES       = *.a *.lib *.so *.so.* *.dylib *.dll *.def *.dll.a *.exp#依赖文件.d(dependence)-include $(wildcard $(OBJS:.o=.d) $(TESTOBJS:.o=.d))

从代码中可以看出,common.mak定义了一些通用的编译规则,例如编译时候的控制台输出格式,编译命令COMPILE_C、COMPILE_CXX、COMPILE_S,以及.c、.o等文件之间的依赖关系等。




雷霄骅
leixiaohua1020@126.com
http://blog.csdn.net/leixiaohua1020




6 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 衣服硬的咯人怎么办 脖子上的勒痕怎么办 腿上容易出现勒痕怎么办 身上总有内裤印怎么办 内裤穿出了印怎么办 饮水机热水口不出水怎么办 饮水机热水口出水小怎么办 新饮水机热水口出水小怎么办 白钢水桶中间支撑怎么办 17岁想长高应该怎么办 身子瘦但脸胖怎么办 减肥只瘦了胸是怎么办 减肥把胸瘦了怎么办 脸又大又圆怎么办 想长高又想减肥怎么办 孩子做作业精力不集中怎么办 写作业老要睡觉怎么办 孩子写作业精神不集中怎么办 小孩精神不集中要怎么办 注意力不集中上课走神怎么办 注意力不集中总是走神怎么办 孩子注意力不集中走神怎么办 上课老走神注意力不集中怎么办 注意力不集中老走神怎么办 7岁儿童视力0.6怎么办 三岁宝宝注意力不集中怎么办 四岁宝宝注意力不集中怎么办 一直在想一件事怎么办 买的家具味道大怎么办 买的木床有味道怎么办 宝宝拍胸片衣服有扣子怎么办 前扣内衣扣子坏了怎么办 运动内衣穿上平胸怎么办 文胸的海绵变形了怎么办 文胸背部松紧变形了怎么办 黑色裤子被漂白水漂红了怎么办 黑色裤子晒红了怎么办 黑色裤子泛红了怎么办 黑色裤子洗红了怎么办 新内衣穿了痒怎么办 灰色针织运动裤洗完发黄怎么办