非常好的makefile写法

要点

makefile的依赖规则,都是从前向后的。即当前依赖的向后找或写

  1. 在编写makefile时,一定要搞清楚依赖关系。
    如:
    .o 依赖的.cpp
    .so依赖的.o
  2. 链接时的依赖关系
    链接的动态库有依赖关系时,要注意顺序,被依赖的放后面,相互没依赖,随便放。
  3. 工程文件的组织形式
    好的文件组织形式,可以使我们的makefile文件更加清晰,写起来更顺心。
  4. .d文件很重要
    配置了.d文件,我们就会在它里面看到该文件依赖的所有文件,只要这些文件发生变化时,就会识别出来,并重新编译;如果没有.d文件有些头文件的修改时,不会去重新编译。

示例

在工程根目录创建demo、include、src三个文件夹和一个makefile文件

demo  include  Makefile  src

这里的demo中,可以有很多个包含main函数的demo文件,我们的makefile会一次全部编译出来。
这个makefile可以直接生成动态库、静态库和可执行文件

CXX=g++

CPPFLAGS := -std=c++11 
CPPFLAGS += -Werror=return-type -O3  -pthread
CPPFLAGS += -I./include
CPPFLAGS += -I/usr/local/include
CPPFLAGS += -L/usr/local/lib
LDFLAGS += -Wl,-rpath ./lib
LIB := -lopencv_core -lopencv_imgcodecs -lopencv_imgproc -lopencv_highgui -lopencv_calib3d -lopencv_video

BUILD_PATH := build
LIB_NAME ?= test
STATIC_NAME ?= lib$(LIB_NAME).a
SHARE_NAME  ?= lib$(LIB_NAME).so

SRC_MAIN_CPP := $(shell find demo -name "*.cpp")
SOURCE := $(shell find src -name "*.cpp")

$(info $(SOURCE))

TARGET_PATH := lib
STATIC_TARGET := $(TARGET_PATH)/$(STATIC_NAME)
SHARE_TARGET := $(TARGET_PATH)/$(SHARE_NAME)
TARGET_NULTI_EXE := $(SRC_MAIN_CPP:%.cpp=$(BUILD_PATH)/%.bin)

OBJS:=$(patsubst %.cpp, $(BUILD_PATH)/%.o, $(SRC_MAIN_CPP))
SOBJS:=$(patsubst %.cpp, $(BUILD_PATH)/%.o, $(SOURCE))  
OBJS+=$(patsubst %.cpp, $(BUILD_PATH)/%.o, $(SOURCE)) 

BUILD_DIR := $(sort $(BUILD_PATH) $(dir $(OBJS)))

DEPS  :=$(OBJS:%.o=%.d) #静态模式(变量值替换,OBJS中所有以o结尾的换成以d结尾的)

all:$(BUILD_DIR) $(TARGET_PATH) $(OBJS) $(STATIC_TARGET) $(SHARE_TARGET) $(TARGET_NULTI_EXE)
#   
.PHONY:all clean
#生成可执行文件
# #静态模式 (目标集合:目标模式:依赖模式)
$(TARGET_NULTI_EXE):%.bin:%.o $(SOBJS) | $(BUILD_DIR) 
	@echo $(CXX) $< $(SOBJS) $@
	$(CXX) -g $(CPPFLAGS) -o $@ $< $(SOBJS) $(LIB)

#依赖生成的so生成可执行文件
# $(TARGET_NULTI_EXE):%.bin:%.o | $(TARGET_PATH) $(BUILD_DIR) 
# 	@echo $(CXX) $< $@
# 	$(CXX) -g $(CPPFLAGS) -L./$(TARGET_PATH) -o $@ $< -ltest  $(LIB) $(LDFLAGS)

#生成静态库
#动态库的调用仍是动态调用,而不是把动态库的相关函数copy到自己身上
$(STATIC_TARGET):$(OBJS)  | $(TARGET_PATH) $(BUILD_DIR) 
	ar rcs $@ $<
	ranlib $@ 

#生成动态库 (.so添加链接库,生成库的依赖关系,若不加就没有依赖关系 ldd ./lib/libtest.so)
$(SHARE_TARGET):$(OBJS) | $(TARGET_PATH) $(BUILD_DIR) 
	@echo $(CXX) $< $@
	$(CXX) -shared -fPIC $(CPPFLAGS) -o $@ $< $(LIB) 

#生成二进制文件
$(BUILD_PATH)/%.o: %.cpp $(SRC_MAIN_CPP) | $(TARGET_PATH) $(BUILD_DIR) 
	@echo $(CXX) $< $@
	$(CXX) $(CPPFLAGS) -fPIC -MMD -MP -c $< -o $@

$(BUILD_DIR):
	@echo mkdir $@
	mkdir -p $(BUILD_DIR)
$(TARGET_PATH):
	@echo mkdir $@
	mkdir -p $(TARGET_PATH)

clean:
	rm -rf $(TARGET_PATH) $(BUILD_DIR)

-include $(DEPS)

github

git clone https://github.com/guoqingMeng/makefile.git
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值