make 编写技巧
@echo $(wildcard *.cpp) 只能打印出当前目录的cpp文件,不会遍历子目录
patsubst:替换
objects := $(patsubst %.c,%.o,$(wildcard *.c))//替换.c 字符为.o字符
foo : $(objects)
cc -o foo $(objects)
由于make命令由xx.o文件的推导出xx.cpp xx.h等文件只能在当前目录自动找,所以如果把头文件放在一个统一的路径,一般是推导不出来的
OBJ = main.o foo.o bar.o
prog:$(OBJ)
$(CC) -o $@ $(OBJ)
(如果头文件和源文件分离到不同目录,不能正常执行)
# Makefile
CC = gcc
OBJ = main.o foo.o bar.o
CPPFLAGS= -Iinclude //编译的时候的路径
#VPATH = src:include
vpath %.h include //相当于包该目录下的所有头文件放入make的备选文件列表中,不过只是文件名,没有路径
vpath %.c src
prog:$(OBJ)
$(CC) -o $@ $(OBJ)
%.o:%.c
$(CC) $(CPPFLAGS) -c $<
bigoutput littleoutput : text.g
generate text.g -$(subst output,,$@) > $@
上述规则等价于:
bigoutput : text.g
generate text.g -big > bigoutput
littleoutput : text.g
generate text.g -little > littleoutput
其中,
-$(subst output,,$@)中的“$”表示执行一个Makefile的函数,函数名为subst,后面的为参数。
这个函数是替换字符串的意思,
“$@”表示目标的集合,就像一个数组,“$@”依次取出目标,并执于命令。
“$<”表示依赖的第一个文件
“$@”表示目标集(也就是“foo.o bar.o”)
“$^”表示所有的依赖文件(也就是 “foo.c bar.c”),
写make的时候最好用“$<”
两个范例
cc=g++ flag= -m64 -std=c++11 -fPIC libflag= -shared target=libvap2.image_capturer.gb.gpu.so #export.cpp gb.cpp creator.cpp obj=gb.o NvDecoder.o export.o cuobj=ColorSpace.o build_dir= build/ headfile= Logger.h \ dhplayEx.h \ dhplay.h \ gb.h \ jyzbyj.lnp.GbClientSdk.h \ NvCodecUtils.h \ NvDecoder.h \ nvcuvid.h lib=-lopencv_imgproc \ -lPlayCtrl \ -lgbclientsdk \ -lopencv_core \ -lpthread \ -leXosip2 \ -ljrtp \ -losipparser2 \ -losip2 \ -ldl \ -lnvcuvid \ -lcuda \ -lboost_filesystem \ -lboost_system \ -lboost_thread #-lX11 \ -lXdmcp \ -lXau \ -lGL \ -lSuperRender \ -lAudioRender \ -lcrypto \ -lxcb \ #-lva #-drm #-x11 #-lGLdispatch -ltbb cuda_path = /usr/local/cuda-8.0 include_dir= -I /usr/include -I usr/include/c++/4.8 -I /home/user/liurui/video/common/include -I$(cuda_path)/include link_dir=-L /usr/local/lib -L /usr/lib/x86_64-linux-gnu -L/usr/local/cuda/lib64 -L/usr/lib/nvidia-384/ nvcc = $(cuda_path)/bin/nvcc #@mkdir $(build_dir) #$(build_dir)$(target):$(obj) $(cuobj) $(build_dir)$(target): ColorSpace.o NvDecoder.o gb.o export.o #(build_dir)$(target):$(patsubst $(build_dir)%,%,$(obj)) $(cuobj) $(cc) $(flag) $(libflag) -o $@ $^ $(include_dir) $(link_dir) $(lib) mv *.o $(build_dir) $(cuobj): ColorSpace.cu $(nvcc) -m64 -std=c++11 --compiler-options "-fPIC" $(include_dir) -o $@ -c $< #$(obj):$(patsubst %.o,%.cpp,$(obj)) #$(obj):$(wildcard *.cpp) #$(patsubst $(build_dir)%,%,$(obj)):$(patsubst %o,%cpp,$(obj)) gb.o :gb.cpp gb.h Logger.h NvDecoderImageProvider.h jyzbyj.lnp.GbClientSdk.h mkdir -p $(build_dir) # $(cc) $(flag) $(include_dir) -o $@ $(link_dir) $(lib) -c $^ $(cc) $(flag) $(include_dir) -o $@ -c $< export.o :export.cpp $(headfile) mkdir -p $(build_dir) # $(cc) $(flag) $(include_dir) -o $@ $(link_dir) $(lib) -c $^ $(cc) $(flag) $(include_dir) -o $@ -c $< #creator.o :creator.cpp creator.h Logger.h # mkdir -p $(build_dir) #$(cc) $(flag) $(include_dir) -o $@ $(link_dir) $(lib) -c $^ # $(cc) $(flag) $(include_dir) -o $@ -c $^ NvDecoder.o : NvDecoder.cpp NvDecoder.h Logger.h NvCodecUtils.h nvcuvid.h mkdir -p $(build_dir) $(cc) $(flag) $(include_dir) -o $@ -c $< #$(cc) $(flag) $(include_dir) -o $@ $(link_dir) $(lib) -c $^ #Logger.h NvDecoder.cpp NvDecoder.h NvCodecUtils.h clean: rm $(build_dir)*.o $(build_dir)*.so
INCLUDES = -I FFmpeg -I /usr/include -L /usr/lib/x86_64-linux-gnu LDFLAGS = -lnvcuvid -lavcodec -lavformat -lavutil -lswresample -lboost_filesystem -lboost_system -lboost_thread -lva-drm -lva-x11 BIN = libvap2.image_capturer.ffmpeg_gpu.so OBJ = ffmpeg_stream_chr.o ColorSpace.o NvDecoder.o export.o CUDA_PATH = /usr/local/cuda GCC = g++ NVCC = $(CUDA_PATH)/bin/nvcc CCFLAGS = -m64 -std=c++11 INCLUDES += -I /home/user/mjl/ffmpeg/include -I /usr/include -I$(CUDA_PATH)/include -I /home/user/chenyong/video_application_platform2/common/include LDFLAGS := -L /home/user/mjl/ffmpeg/lib \ -L /usr/lib/nvidia-375 \ -L/usr/local/lib \ -I /usr/lib/x86_64-linux-gnu \ -L/usr/local/cuda/lib64 $(LDFLAGS) LDFLAGS += -lopencv_core -lopencv_gpu -lopencv_highgui -lopencv_imgproc -lopencv_contrib -ldl -lcuda BUILDDIR = ./Build all: $(BUILDDIR)/$(BIN) $(addprefix $(BUILDDIR)/, $(OBJ)): | $(BUILDDIR) $(BUILDDIR): mkdir -p $(BUILDDIR) clean: rm -rf $(addprefix $(BUILDDIR)/, $(BIN) $(OBJ)) $(BUILDDIR)/$(BIN): $(addprefix $(BUILDDIR)/, $(OBJ)) $(GCC) $(CCFLAGS) -fPIC -shared -o $@ $+ $(LDFLAGS) #$(BUILDDIR)/NvEncoderBase.o: ../../NvCodec/NvEncoder/NvEncoderBase.cpp ../../NvCodec/NvEncoder/NvEncoderBase.h ../../NvCodec/NvEncoder/NvEncoderParam.h ../../NvCodec/Common/NvCodecUtils.h ../../NvCodec/Common/Logger.h # $(GCC) $(CCFLAGS) $(INCLUDES) -o $@ -c $< #$(BUILDDIR)/NvEncoderDevice.o: ../../NvCodec/NvEncoder/NvEncoderDevice.cpp ../../NvCodec/NvEncoder/NvEncoderDevice.h ../../NvCodec/NvEncoder/NvEncoderBase.h ../../NvCodec/NvEncoder/NvEncoderParam.h #../../NvCodec/Common/NvCodecUtils.h ../../NvCodec/Common/Logger.h # $(GCC) $(CCFLAGS) $(INCLUDES) -o $@ -c $< #$(BUILDDIR)/NvEncoderHost.o: ../../NvCodec/NvEncoder/NvEncoderHost.cpp ../../NvCodec/NvEncoder/NvEncoderHost.h ../../NvCodec/NvEncoder/NvEncoderBase.h ../../NvCodec/NvEncoder/NvEncoderParam.h ../../NvCodec/Common/NvCodecUtils.h #../../NvCodec/Common/Logger.h # $(GCC) $(CCFLAGS) $(INCLUDES) -o $@ -c $< #$(BUILDDIR)/NvEncoderME.o: ../../NvCodec/NvEncoder/NvEncoderME.cpp ../../NvCodec/NvEncoder/NvEncoderME.h ../../NvCodec/NvEncoder/NvEncoderBase.h ../../NvCodec/NvEncoder/NvEncoderParam.h ../../NvCodec/Common/NvCodecUtils.h #../../NvCodec/Common/Logger.h # $(GCC) $(CCFLAGS) $(INCLUDES) -o $@ -c $< #$(BUILDDIR)/NvEncoderMEDevice.o: ../../NvCodec/NvEncoder/NvEncoderMEDevice.cpp ../../NvCodec/NvEncoder/NvEncoderMEDevice.h ../../NvCodec/NvEncoder/NvEncoderDevice.h ../../NvCodec/NvEncoder/NvEncoderME.h #../../NvCodec/NvEncoder/NvEncoderBase.h ../../NvCodec/NvEncoder/NvEncoderParam.h ../../NvCodec/Common/NvCodecUtils.h ../../NvCodec/Common/Logger.h # $(GCC) $(CCFLAGS) $(INCLUDES) -o $@ -c $< #$(BUILDDIR)/NvEncoderMEHost.o: ../../NvCodec/NvEncoder/NvEncoderMEHost.cpp ../../NvCodec/NvEncoder/NvEncoderMEHost.h ../../NvCodec/NvEncoder/NvEncoderHost.h ../../NvCodec/NvEncoder/NvEncoderME.h #../../NvCodec/NvEncoder/NvEncoderBase.h ../../NvCodec/NvEncoder/NvEncoderParam.h ../../NvCodec/Common/NvCodecUtils.h ../../NvCodec/Common/Logger.h # $(GCC) $(CCFLAGS) $(INCLUDES) -o $@ -c $< $(BUILDDIR)/export.o: export.cpp ffmpeg_stream_chr.h $(GCC) $(CCFLAGS) -fPIC $(INCLUDES) -o $@ -c $< $(BUILDDIR)/ColorSpace.o: ColorSpace.cu $(NVCC) $(CCFLAGS) --compiler-options "-fPIC" $(INCLUDES) -o $@ -c $< $(BUILDDIR)/NvDecoder.o: NvDecoder.cpp NvDecoder.h NvCodecUtils.h Logger.h $(GCC) $(CCFLAGS) -fPIC $(INCLUDES) -o $@ -c $< $(BUILDDIR)/ffmpeg_stream_chr.o: ffmpeg_stream_chr.cpp ffmpeg_stream_chr.h NvDecoderImageProvider.h FFmpegDemuxer.h NvDecoder.h NvCodecUtils.h Logger.h $(GCC) $(CCFLAGS) -fPIC $(INCLUDES) -o $@ -c $< #$(BUILDDIR)/test.o: ffmpeg_stream_chr.h NvDecoderImageProvider.h FFmpegDemuxer.h NvDecoder.h NvCodecUtils.h Logger.h # $(GCC) $(CCFLAGS) $(INCLUDES) -o $@ -c $<
为所有的obj文件加路径前缀 $(addprefix $(BUILDDIR)/, $(OBJ))
“=” make会将整个makefile展开后,再决定变量的值。也就是说,变量的值将会是整个makefile中最后被指定的值。
看例子:
x = foo
y = $(x) bar
x = xyz
在上例中,y的值将会是 xyz bar ,而不是 foo bar 。
2、“:=”表示变量的值决定于它在makefile中的位置,
而不是整个makefile展开后的最终值。
x := foo
y := $(x) bar
x := xyz
在上例中,y的值将会是 foo bar ,而不是 xyz bar 了。