forked from lightful/syscpp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathposix.mk
137 lines (105 loc) · 5.11 KB
/
posix.mk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# "Universal C++ POSIX Makefile" v2.1 for GNU make
# Copyright Ciriaco Garcia de Celis 2011-2016.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
# With automatic dependencies generation (gcc/clang) and recursive source directory tree support
#
# In your project(s) Makefile it is only required to define a few settings and include this file AT THE END:
#
# Settings which can be defined in any project (all optional unless otherwise stated):
# BUILD_DIR := debug # mandatory setting
# SRC_DIR := src # mandatory setting
# INCLUDES :=
# CXX := g++ # a default value is provided in your system
# CXXFLAGS := -O0 -g3 -DDEBUG # see also ARCHFLAGS and WARNFLAGS bellow
#
# Settings to be defined only for library subprojects
# OUT_LIB := LibName.a # mandatory setting (file will always be placed in BUILD_DIR)
#
# Settings to be defined only for executable projects:
# PATH_BIN := $(BUILD_DIR)/executable # mandatory setting
# SUBPRJS := ../Lib1 ../Lib2 # each require its own Makefile
# LIBS := ../../ExternLib/SomeLib.a # Note: omit subprojects (implicitly linked and included)
# LDLIBS := -lboost_system -lpthread
# LDFLAGS :=
# NOTES:
# * The includes exported by library subprojects must be placed in a directory called 'include'
# * When used on a top project, its library subprojects makefiles are automatically invoked in the proper order:
# - Any target will be passed to them (not only 'all' or 'clean')
# - To make only the top project run "DONTLOOP=1 make"
# - If ARCHFLAGS/WARNFLAGS are setup they need to be exported when aiming to override implicit defaults in subprojects
# * To hook 'all' or 'clean' targets in your Makefile use '::' (instead of ':')
# * Other targets than 'all' or 'clean' should be placed after including this file (to keep 'all' as the default target)
ARCHFLAGS ?= -std=c++11 -march=native # set these variables in your Makefile to override these implicit defaults
WARNFLAGS ?= -Wall -Wextra -pedantic -Wconversion -Wsign-conversion -Wsign-promo -Wcast-qual -Wfloat-equal \
-Wpointer-arith -Wnon-virtual-dtor -Woverloaded-virtual -Wshadow -Wundef -Wmissing-include-dirs
CXXFLAGS += $(ARCHFLAGS) $(WARNFLAGS)
CXXFLAGS := $(filter-out $(SKIPFLAGS), $(CXXFLAGS)) # allow skipping particular warnings
INCLUDES := $(foreach dir,$(SUBPRJS),-I$(dir)/include) $(INCLUDES)
LIBS := $(foreach dir,$(SUBPRJS),$(wildcard $(dir)/$(BUILD_DIR)/*.a)) $(LIBS)
ifdef OUT_LIB
INCLUDES := -Iinclude $(INCLUDES)
endif
ifndef MK_NOHL
HL_DONE := \e[30;42mDONE
HL_ERROR := \e[30;101mERROR
HL_CMD := \e[35m
HL_OFF := \e[0m
else
HL_DONE := [DONE]
HL_ERROR := [ERROR]
endif
ifndef SUBPRJS
MAKEACTIVE := 1
else
ifdef DONTLOOP
MAKEACTIVE := 1
else
export DONTLOOP := 1
reverse_list = $(if $(1),$(call reverse_list,$(wordlist 2,$(words $(1)),$(1)))) $(firstword $(1))
ALL_MK_PROJECTS := $(call reverse_list,$(SUBPRJS)) .
all:: whichever
whichever::
@for prj in $(ALL_MK_PROJECTS); do if ! \
$(MAKE) -C $$prj --no-print-directory $(MAKECMDGOALS) \
; then echo -e "$(HL_ERROR) $$prj$(HL_OFF)" && exit 1; fi; done
.PHONY: whichever all $(MAKECMDGOALS)
$(foreach target, $(MAKECMDGOALS), $(eval $(target):: whichever))
endif # DONTLOOP
endif # SUBPRJS
ifdef MAKEACTIVE
ifdef MK_FULLPATH # useful for IDE diagnostic parsing without requiring to setup the build directory
SRC_DIR := $(shell pwd)/$(SRC_DIR)
endif
SRC_SUBDIRS := $(shell [ -d $(SRC_DIR) ] && find -L $(SRC_DIR) -type d \
-not \( -path $(SRC_DIR)/$(BUILD_DIR) -prune \) -not \( -name .git -prune \))
BUILD_SUBDIRS := $(patsubst $(SRC_DIR)%,$(BUILD_DIR)%,$(SRC_SUBDIRS))
MKDIR_SUBDIRS := $(sort $(patsubst %/,,$(BUILD_SUBDIRS) $(dir $(PATH_BIN)) $(dir $(PATH_LIB))))
PATH_LIB ?= $(if $(OUT_LIB),$(BUILD_DIR)/$(OUT_LIB))
SRC_FILES := $(sort $(foreach sdir,$(SRC_SUBDIRS),$(wildcard $(sdir)/*.cpp)) $(AUTOGEN))
OBJ_FILES := $(patsubst $(SRC_DIR)/%.cpp,$(BUILD_DIR)/%.o,$(SRC_FILES))
DEPENDENCIES := $(OBJ_FILES:.o=.d)
vpath %.cpp $(SRC_SUBDIRS) $(BUILD_SUBDIRS)
.PHONY: all clean checkdirs
all:: checkdirs $(PATH_BIN) $(PATH_LIB)
@echo -e "$(HL_DONE)$(HL_OFF) $(lastword $(subst /, ,$(CURDIR)))"
clean::
@rm -rf $(BUILD_SUBDIRS)
checkdirs: $(MKDIR_SUBDIRS)
$(MKDIR_SUBDIRS):
@mkdir -p $@
-include $(DEPENDENCIES)
$(PATH_LIB): $(OBJ_FILES)
@echo -e "$(HL_CMD)$(AR)$(HL_OFF)" -r "$(HL_CMD)$@$(HL_OFF)" $(OBJ_FILES)
@$(AR) -r $@ $(OBJ_FILES)
$(PATH_BIN): $(OBJ_FILES) $(LIBS)
@echo -e "$(HL_CMD)$(CXX)$(HL_OFF)" $(LDFLAGS) $(OBJ_FILES) $(CXXFLAGS) -MMD "$(HL_CMD)-o $@$(HL_OFF)" $(LIBS) $(LDLIBS)
@$(CXX) $(LDFLAGS) $(OBJ_FILES) $(CXXFLAGS) -MMD -o $@ $(LIBS) $(LDLIBS)
define build-subdir-goal
$1/%.o: %.cpp
@echo -e "$(HL_CMD)$(CXX)$(HL_OFF)" $(CXXFLAGS) $(INCLUDES) -MMD "$(HL_CMD)-c $$<$(HL_OFF)" -o $$@
@$(CXX) $(CXXFLAGS) $(INCLUDES) -MMD -c $$< -o $$@
endef
$(foreach bdir,$(BUILD_SUBDIRS),$(eval $(call build-subdir-goal,$(bdir))))
endif # MAKEACTIVE