陈力就列 不能者止
基本的shell 命令
学习Makefile 《跟我一起写Makefile》,有余力者参考GNU make 参考书。电子版本
下载live555源码
1.保证编译通过
./genMakefiles linux
make -j8
上面配置 linux ,使用的参数在 config.linux 文件中是生成静态库的文件
2. Makefile 编译静态库过程
路径:live555/Makefile
Makefile 的规则:
target ... : prerequisites ...
command
...
...
多个生成的目标target 对应 于 多个依赖prerequisites
第二行开始就是执行编译操作,或者其他命令,command 前必须是table,make才能识别是命令
只有prerequisites文件比target 新,才会去执行编译
查看live555 总Makefile
每次执是一个原理行make,找到第一个target ,live555中是all,然后根据依赖链编译
all:
cd $(LIVEMEDIA_DIR) ; $(MAKE)
cd $(GROUPSOCK_DIR) ; $(MAKE)
cd $(USAGE_ENVIRONMENT_DIR) ; $(MAKE)
cd $(BASIC_USAGE_ENVIRONMENT_DIR) ; $(MAKE)
cd $(TESTPROGS_DIR) ; $(MAKE)
cd $(MEDIA_SERVER_DIR) ; $(MAKE)
cd $(PROXY_SERVER_DIR) ; $(MAKE)
Makefile规定 后面可以没有依赖,表示依赖文件一直比traget 新,后面会执行命令
如果想让前一个命令的输出,给后一个命令产生作用,command ; command 这种形式放在一行用分号间隔
进入 liveMedia 、groupsock、UsageEnvironment、BasicUsageEnvironment 、testProgs、 mediaServer 、proxyServer 分别执行子目录的Makefile
其中liveMedia、groupsock、UsageEnvironment、BasicUsageEnvironment是库文件
而 testProgs mediaServer是 rtspclient 和 mediaserver 测试代码在这里
举例 :
先编译 liveMedia 库 路径:live555/liveMedia/Makefile
从上面的依赖链就知道 最终会生成 libliveMedia.a,因为all 依赖 libliveMedia.a ,
而 libliveMedia.a 依赖LIVEMEDIA_LIB_OBJS 、PLATFORM_SPECIFIC_LIB_OBJS(没定义,不用看)
LIVEMEDIA_LIB_OBJS 依赖 Media.o 等一系列.o 的文件
LIVEMEDIA_LIB_OBJS = Media.$(OBJ) $(MISC_SOURCE_OBJS) \
$(MISC_SINK_OBJS) $(MISC_FILTER_OBJS) \
$(RTP_OBJS) $(RTCP_OBJS) \
$(GENERIC_MEDIA_SERVER_OBJS) \
$(RTSP_OBJS) $(SIP_OBJS) $(SESSION_OBJS) $(QUICKTIME_OBJS)\
$(AVI_OBJS) $(TRANSPORT_STREAM_TRICK_PLAY_OBJS)\
$(MATROSKA_OBJS) $(OGG_OBJS) $(MISC_OBJS)
根据makefile 的使用隐含规则的,make会根据 a.o 自动在当前目录 寻找的 a.cpp 这是makefile 的推导过程并且生成命令,但是a.cpp依赖的头文件需要手动添加依赖关系,比如Media.cpp
Media.$(CPP): include/Media.hh
$(LIVEMEDIA_LIB): $(LIVEMEDIA_LIB_OBJS) \
$(PLATFORM_SPECIFIC_LIB_OBJS)
$(LIBRARY_LINK)$@ $(LIBRARY_LINK_OPTS) \
$(LIVEMEDIA_LIB_OBJS)
.$(CPP).$(OBJ):
$(CPLUSPLUS_COMPILER) -c $(CPLUSPLUS_FLAGS) $<
最后执行的命令是 链接 .o 文件打包成静态库 libliveMedia.a
LIBRARY_LINK = ar cr 就是打包静态库的命令 使用 ar cr libXXX.a xxx.o xxx.o
$@ 是自动化变量 表示所有的目标集 就是所有的target ,LIBRARY_LINK_OPTS 表示 参数,但是我使用的文件中是空不用考虑,最后的LIVEMEDIA_LIB_OBJS 是所有的.o文件,这样一个静态库生成的关系链 就完成了
而所有 的.o 文件 都是通过 .$(CPP).$(OBJ):中的命令 生成 。$< 表示所有依赖的目标集合
.cpp.o是老式的“后缀规则”,编译器将会自动将.cpp识别为源文件后缀,而.o识别为输出文件后缀。特别需要注意的是,后缀规则不允许任何依赖文件,但也不能没有命令。
最后展开的编译命令 :
c++ -c \
-Iinclude -I../UsageEnvironment/include -I../groupsock/include \
-I. -O2 -DSOCKLEN_T=socklen_t -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 -DALLOW_RTSP_SERVER_PORT_REUSE=1 \
-Wall -DBSD=1 \
xxx.o ...
剩余的groupsock、UsageEnvironment、BasicUsageEnvironment 是一个原理
3.Makefile 编译测试用例过程
路径:live555/testProgs 文件Makefile
总Makefile文件 中
cd $(TESTPROGS_DIR) ; $(MAKE)
让make 进入了 live555/testProgs 执行make
ALL = $(MULTICAST_APPS) $(UNICAST_APPS) $(MISC_APPS)
all: $(ALL)
编译的应用分为 多播app \单播 app \混合app
testRTSPClient 在UNICAST_APPS 中
UNICAST_STREAMER_APPS = testOnDemandRTSPServer$(EXE)
UNICAST_RECEIVER_APPS = testRTSPClient$(EXE) openRTSP$(EXE) playSIP$(EXE)
UNICAST_APPS = $(UNICAST_STREAMER_APPS) $(UNICAST_RECEIVER_APPS)
testRTSPclient$(EXE) 是执行文件 最后生成 testRTSPclient
TEST_RTSP_CLIENT_OBJS = testRTSPClient.$(OBJ)
testRTSPClient$(EXE): $(TEST_RTSP_CLIENT_OBJS) $(LOCAL_LIBS)
$(LINK)$@ $(CONSOLE_LINK_OPTS) $(TEST_RTSP_CLIENT_OBJS) $(LIBS)
.$(CPP).$(OBJ):
$(CPLUSPLUS_COMPILER) -c $(CPLUSPLUS_FLAGS) $<
上面的 依赖关系链如下:
testRTSPclient 依赖 testRTSPClient.$(OBJ) $(LOCAL_LIBS) 表示 生成的liveMedia 、groupsock、UsageEnvironment、BasicUsageEnvironment 四个库 .a
当然这里存在Makefile 的推导 testRTSPClient.o 默认推导 testRTSPClient.cpp
通过 $(CPLUSPLUS_COMPILER) -c $(CPLUSPLUS_FLAGS) $< 生成可执行文件