对于文件较多的C++项目,目录结构的组织清晰能方便开发,多个文件夹存放了多个源文件和头文件,一般下方式在编译之后都会生成与源文件同目录下的目标文件,个人觉得这种方式不太好,各个目标文件分散不太集中,希望所有目标文件和可执行文件都放在bin目录下,具体目录结构如下:
--bin
|--a.o
|--b.o
|--...
|--module1
| |--ma1.o
| |--ma2.o
| |--...
|--test
| |--test1.o
| |--...
|--third
| |--third1.o
| |--...
|--exec1
|--exec2
|--...
--src
|--a.cpp/a.h
|--b.cpp/b.h
|--...
|--module1
|--ma1.cpp/ma1.h
|--ma2.cpp/ma2.h
...
--third
|--third1.cpp/third2.h
|--...
--test
|--test1.cpp/test1.h
|--...
--Makefile
--README.md
...
为了实现上述要求,自行编写的Makefile如下。
INCLUDE_PATH=-I$(CURDIR)/src
LIB_PATH=-L$(CURDIR)/third
LIB=-lpthread -lcurl
#-ljsoncpp
CXXFLAGS=-Wall -pipe
#-std=c++11
CC=g++
BIN_PATH=$(CURDIR)/bin
SRC_PATH=$(CURDIR)/src \
$(CURDIR)/src/module1 \
$(CURDIR)/src/module2
...
TEST_PATH=$(CURDIR)/test
SOURCES:=$(foreach SRC,$(SRC_PATH),\
$(wildcard $(SRC)/*.cpp)\
)
OBJECTS:=$(foreach S,$(SOURCES),\
$(addprefix $(BIN_PATH)/,\
$(patsubst %.cpp,%.o,\
$(subst $(CURDIR)/src/,,$(S))\
)\
)\
)
TEST_SOURCES=$(wildcard $(TEST_PATH)/*.cpp)
TEST_OBJECTS=$(addprefix $(BIN_PATH)/,\
$(addsuffix .o,\
$(basename $(notdir $(TEST_SOURCES))))\
)
exec1=$(BIN_PATH)/exec1
exec2=$(BIN_PATH)/exec2
EXEC=$(exec1) $(exec2)
.PHONY: all
all: $(EXEC)
$(exec1): $(BIN_PATH)/a.o $(BIN_PATH)/third/third1.o
@echo "Building $@ ..."
$(CC) $(LIB) -o $@ $^
@echo "Building $@ successfully!"
$(exec2): $(BIN_PATH)/b.o $(BIN_PATH)/third/third1.o
@echo "Building $@ ..."
$(CC) $(LIB) -o $@ $^
@echo "Building $@ successfully!"
$(filter %.o,$(OBJECTS)) : $(BIN_PATH)/%.o:$(CURDIR)/src/%.cpp
@echo "Compiling $@ from $<..."
@$(shell mkdir -p $(dir $@))
$(CC) $(INCLUDE_PATH) $(LIB_PATH) $(LIB) $(CXXFLAGS) -c $< -o $@
$(filter %.o,$(TEST_OBJECTS)) : $(BIN_PATH)/%.o:$(TEST_PATH)/%.cpp
@echo "Compiling $@ ..."
$(CC) $(INCLUDE_PATH) $(LIB_PATH) $(LIB) $(CXXFLAGS) -c $< -o $@
.PHONY : clean
clean:
@$(RM) $(OBJECTS) $(TEST_OBJECTS) $(EXEC)
@rm -rf $(BIN_PATH)/*
个人感觉比较好用,有需要者自行取用。