@@ -105,6 +105,21 @@ endif
105105ifneq (${NO_DEBUG},)
106106 CPP_FLAGS += -DNDEBUG
107107endif
108+
109+ # Variant builds: 'make debug|release|optimized' recurse with VARIANT set and
110+ # OBJ_DIR redirected to build/<variant>, so the three configurations get their
111+ # own object/binary directories and never share (and corrupt) each other's
112+ # objects.
113+ ifeq (debug,${VARIANT})
114+ OPTS_INTERNAL += -g -fno-omit-frame-pointer -O0 -fno-optimize-sibling-calls
115+ endif
116+ ifeq (release,${VARIANT})
117+ CPP_FLAGS += -DNDEBUG
118+ endif
119+ ifeq (optimized,${VARIANT})
120+ CPP_FLAGS += -DNDEBUG
121+ OPTS_INTERNAL += -fomit-frame-pointer
122+ endif
108123ifneq (${C++20},)
109124 CPP_FLAGS += --std=c++20
110125endif
@@ -201,29 +216,29 @@ endif
201216
202217SRC_H := $(filter % .h, $(SRC ) ) $(filter % .hh, $(SRC ) ) $(filter % .hpp, $(SRC ) ) $(filter % .inc, $(SRC ) )
203218SRC_CPP := $(filter % .cpp, $(SRC ) )
219+ # Variant builds land under build/<variant>; the default build still goes
220+ # in-tree (OBJ_DIR = .). The binary follows OBJ_DIR via TARGET_BIN.
221+ BUILD_DIR = build
204222OBJ_DIR = .
205223OBJ_EXT = o
206224DEP_EXT = d
207225SRC_OBJ := $(SRC_CPP:%.cpp=$(OBJ_DIR )$(PATHSEP ) %.$(OBJ_EXT ) )
208226SRC_DEPS := $(SRC_CPP:%.cpp=$(OBJ_DIR )$(PATHSEP ) %.$(DEP_EXT ) )
227+ TARGET_BIN = $(OBJ_DIR )$(PATHSEP )$(MODULE )
209228
210229.PHONY : .FORCE all mostlyclean clean
211230.FORCE :
212231
213- all : $(MODULE )
232+ all : $(TARGET_BIN )
214233
215234-include $(SRC_DEPS )
216235
217- debug:OPTS_INTERNAL += -g -fno-omit-frame-pointer -O0 -fno-optimize-sibling-calls
218- debug : $(MODULE )
219-
220- release:CPP_FLAGS += -DNDEBUG
221- release : $(MODULE )
222-
223- optimized:CPP_FLAGS += -DNDEBUG
224- optimized:OPTS_INTERNAL += -fomit-frame-pointer
225-
226- optimized : $(MODULE )
236+ # Build each variant in its own directory by recursing with OBJ_DIR redirected;
237+ # VARIANT (read in the flags section above) selects the extra compile flags.
238+ # 'make debug && make release' leaves both binaries side by side under build/.
239+ .PHONY : debug release optimized
240+ debug release optimized :
241+ @$(MAKE ) all OBJ_DIR=$(BUILD_DIR )$(PATHSEP ) $@ VARIANT=$@
227242
228243install : all
229244ifneq (${PREFIX},..)
@@ -235,12 +250,14 @@ ifneq (${PREFIX},..)
235250 $(COPY) -r $(wildcard ../profiles/*) $(SHARE_INSTALL_PATH)
236251endif
237252
238- $(MODULE ) : $(SRC_OBJ )
253+ $(TARGET_BIN ) : $(SRC_OBJ )
239254 -@echo [$( MODULE) ] Linking $@
255+ @$(MKDIR ) -p $(dir $@ )
240256 @$(CXX ) $(OPTS_INTERNAL ) $(OPTS ) $(LINK_FLAGS ) $^ -o $@ $(LINK_LIBS )
241257
242258$(OBJ_DIR )$(PATHSEP ) % .$(OBJ_EXT ) : % .cpp $(SRC_H )
243259 -@echo [$( MODULE) ] Compiling $<
260+ @$(MKDIR ) -p $(dir $@ )
244261 @$(CXX ) $(CPP_FLAGS ) $(OPTS_INTERNAL ) $(OPTS ) -c $< -o $@
245262
246263% .s : % .cpp $(SRC_H )
@@ -249,7 +266,7 @@ $(OBJ_DIR)$(PATHSEP)%.$(OBJ_EXT): %.cpp $(SRC_H)
249266
250267# Force regeneration of git_info.o on every recompilation to potntially get the
251268# changed GIT shorthash into the binary
252- util/git_info.o : .FORCE
269+ $( OBJ_DIR )$( PATHSEP ) util/git_info.$( OBJ_EXT ) : .FORCE
253270
254271# cleanup targets
255272mostlyclean :
@@ -259,6 +276,7 @@ mostlyclean:
259276clean : mostlyclean
260277 -@echo [$( MODULE) ] Cleaning target files
261278 @$(REMOVE ) $(MODULE ) sc_http$(MODULE_EXT )
279+ -@$(REMOVE ) -r $(BUILD_DIR )
262280
263281# Unit Tests
264282sc_http$(MODULE_EXT ) : interfaces$(PATHSEP ) sc_http.cpp util$(PATHSEP ) sc_io.cpp sc_thread.cpp sc_util.cpp
0 commit comments