一次Makefile的编写过程

最近闲着没事,找了一个socket异步io的库写了一个服务端程序。好久没有写过C/C++程序,Makefile也不会写了。先在网上找了一个Makefile模板,修修改改也基本能用。

基本能用不行啊,我需要一些高级点的操作。

首先,我希望目标文件不要和源代码放在一起,所以创建了一个目标目录,编译生成到目标目录中

dest_dir = build

src_dir = src

obj_dir = $(dest_dir)/objects

bin_dir = $(dest_dir)/bin

$(bin_dir)/%:

@echo ">>> Linking" $@ "<<<"

@if [ ! -d $(bin_dir) ]; then mkdir -p $(bin_dir); fi;

$(CC) -o $@ $^ $(LLIB)

ln -sf $@ $(notdir $@)



$(obj_dir)/%.o: $(src_dir)/%.cpp

@echo ">>> Compiling" $< "<<<"

@if [ ! -d $(obj_dir) ]; then mkdir -p $(obj_dir); fi;

$(CC) $(CFLAGS) $(IINC) -c $< -o $@

其次,需要添加多目标,clean,debug之类的不能少。debug依赖clean和all,另外,debug的编译选项也不同

CFLAGS = -Wall -O3 -std=c++14

debug: CFLAGS = -c -g -Ddebug -std=c++14

debug: clean all

第三步,由于用到protobuf,使用protobuf生成的C++文件的后缀是cc,添加cc的编译设置,并且由于生成文件我希望是在另外自动创建的generate目录,所以增加cc编译选项,并修改原来的编译选项,使用VPATH变量指定源代码搜寻目录

VPATH = $(src_dir):$(src_dir)/generated

$(obj_dir)/%.o: %.cpp

@echo ">>> Compiling" $< "<<<"

@if [ ! -d $(obj_dir) ]; then mkdir -p $(obj_dir); fi;

$(C++) $(CCFLAGS) $(IINC) -c $< -o $@



$(obj_dir)/%.o: %.cc

@echo ">>> Compiling" $< "<<<"

@if [ ! -d $(obj_dir) ]; then mkdir -p $(obj_dir); fi;

$(C++) $(CCFLAGS) $(IINC) -c $< -o $@

另外,protobuf相关的代码是纯C,同样的方式增加C编译选项

最后,不想在Makefile中罗列源代码列表了,直接罗列obj文件,至于源码是什么后缀,由make自己去搜寻。由于obj文件我们希望还是生成在目标目录,通过addprefix命令,在目标文件列表中统一添加目标目录前缀

# C++FILES = main.cpp

# CCFILES = base.pb.cc calc.pb.cc login.pb.cc

# CFILES = protorpc.c

#ofiles = $(C++FILES:%.cpp=$(obj_dir)/%.o) $(CCFILES:%.cc=$(obj_dir)/%.o) $(CFILES:%.c=$(obj_dir)/%.o)

ofiles = $(addprefix $(obj_dir)/, main.o base.pb.o calc.pb.o login.pb.o protorpc.o)

至此,一个功能相对完备的Makefile文件完成,能够适应我这个相对复杂的需求。

# $@: 目标文件, $^: 所有依赖文件, $<: 第一个依赖文件

# 语法规则:

# targets: prerequisites

# command

dest_dir = build

src_dir = src

obj_dir = $(dest_dir)/objects

bin_dir = $(dest_dir)/bin

inc_dir = /usr/local/include

lib_dir = /usr/local/lib



CC = gcc

C++ = g++

RESULT = boyiserver

CFLAGS = -Wall -O3

# C++FILES = main.cpp

# CCFILES = base.pb.cc calc.pb.cc login.pb.cc

# CFILES = protorpc.c

IINC = -I$(inc_dir)

LLIB = -L $(lib_dir) -lhv -lhiredis -lprotobuf

VPATH = $(src_dir):$(src_dir)/generated

#vpath %.cc $(src_dir)/generated



#ofiles = $(C++FILES:%.cpp=$(obj_dir)/%.o) $(CCFILES:%.cc=$(obj_dir)/%.o) $(CFILES:%.c=$(obj_dir)/%.o)

ofiles = $(addprefix $(obj_dir)/, main.o base.pb.o calc.pb.o login.pb.o protorpc.o)

program = $(bin_dir)/$(RESULT)

all: $(program)



debug: CFLAGS = -c -g -Ddebug

debug: clean all



CCFLAGS = $(CFLAGS) -std=c++14

$(program): $(ofiles)



$(bin_dir)/%:

@echo ">>> Linking" $@ "<<<"

@if [ ! -d $(bin_dir) ]; then mkdir -p $(bin_dir); fi;

$(C++) -o $@ $^ $(LLIB)

ln -sf $@ $(notdir $@)



$(obj_dir)/%.o: %.cpp

@echo ">>> Compiling" $< "<<<"

@if [ ! -d $(obj_dir) ]; then mkdir -p $(obj_dir); fi;

$(C++) $(CCFLAGS) $(IINC) -c $< -o $@



$(obj_dir)/%.o: %.cc

@echo ">>> Compiling" $< "<<<"

@if [ ! -d $(obj_dir) ]; then mkdir -p $(obj_dir); fi;

$(C++) $(CCFLAGS) $(IINC) -c $< -o $@



$(obj_dir)/%.o: %.c

@echo ">>> Compiling" $< "<<<"

@if [ ! -d $(obj_dir) ]; then mkdir -p $(obj_dir); fi;

$(CC) $(CFLAGS) $(IINC) -c $< -o $@



.PHONY: clean

clean:

rm -rf $(dest_dir)

rm -f $(RESULT)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值