diff --git a/build/Makefile b/build/Makefile index ce4f996..f0c9dc9 100644 --- a/build/Makefile +++ b/build/Makefile @@ -6,26 +6,24 @@ TOP=$(shell pwd) DIRS=src all: pre - @if [ ! -f src/Makefile ]; then \ - (./RUNME;) \ - fi - $(foreach var,$(DIRS), (cd $(var); $(MAKE) $@) ;) + $(foreach var,$(DIRS), $(MAKE) -C $(var) $@; ) format: $(foreach var,$(DIRS), (cd $(var); cp $(TOP)/.clang-format .) ;) $(foreach var,$(DIRS), (cd $(var); sh $(TOP)/build/tidy_source.sh do) ;) $(foreach var,$(DIRS), (cd $(var); sh $(TOP)/build/format.sh do) ;) -clean: - $(foreach var,$(DIRS), (cd $(var); $(MAKE) $@) ;) - /bin/rm -rf data/sounds - /bin/rm -rf data/gfx - /bin/rm -rf build.log - /bin/rm -rf appdata +clean_files: + /bin/rm -rf data/sounds/ + /bin/rm -rf data/gfx/ + /bin/rm -f build.log -clobber: clean - $(foreach var,$(DIRS), (cd $(var); $(MAKE) $@) ;) +clean: clean_files + $(foreach var,$(DIRS), $(MAKE) -C $(var) $@; ) -.PHONY: all clean clobber format pre +clobber: clean_files + $(foreach var,$(DIRS), $(MAKE) -C $(var) $@; ) + +.PHONY: all clean_files clean clobber format pre .DEFAULT_GOAL := all diff --git a/src/Makefile b/src/Makefile index cda6162..6eca270 100644 --- a/src/Makefile +++ b/src/Makefile @@ -3,7 +3,7 @@ include ../build/Makefile.template NAME=yelindor BUILD_DIR=../.o -TARGET_GAME=$(NAME)$(EXE) +TARGET_GAME=../$(NAME)$(EXE) SRC_DIR=. # @@ -13,34 +13,37 @@ SRC_DIR=. all: $(TARGET_GAME) -SOURCES := $(wildcard *.cpp) $(wildcard */*.cpp) $(wildcard */*/*.cpp) $(wildcard *.S) -OBJECTS :=\ - $(addprefix $(BUILD_DIR)/,$(addsuffix .o,$(basename $(SOURCES)))) +# function to make object names from source files +# (changes suffix to .o, encodes directory names so subdirectories in build dir aren't necessary) +obj_name = $(addsuffix .o,$(subst /,__,$(subst ../,,$(basename $1)))) -DEP_FILES := $(OBJECTS:.o=.d) -DEP_FLAGS = -MMD -MP - -$(BUILD_DIR)/things/world: ; mkdir -p $(BUILD_DIR)/things/world -$(OBJECTS): | $(BUILD_DIR)/things/world +# recursively search all src/ subdirectories for cpp source files +CPP_SOURCES := $(subst ./,,$(shell find $(SRC_DIR) -name \*.cpp)) +ASM_SOURCES := $(wildcard *.S) +SOURCES := $(CPP_SOURCES) $(ASM_SOURCES) -$(BUILD_DIR)/things/player: ; mkdir -p $(BUILD_DIR)/things/player -$(OBJECTS): | $(BUILD_DIR)/things/player +OBJECTS := $(call obj_name,$(SOURCES)) +OBJ_FILES := $(addprefix $(BUILD_DIR)/,$(OBJECTS)) -$(BUILD_DIR)/things/dungeon: ; mkdir -p $(BUILD_DIR)/things/dungeon -$(OBJECTS): | $(BUILD_DIR)/things/dungeon +DEP_FILES := $(OBJ_FILES:.o=.d) +DEP_FLAGS = -MMD -MP $(BUILD_DIR): ; mkdir -p $(BUILD_DIR) -$(OBJECTS): | $(BUILD_DIR) +$(OBJ_FILES): | $(BUILD_DIR) + +# custom compile command for each source file needed because object file +# base names don't match source files that were in src/ subdirectories +$(foreach x,$(CPP_SOURCES),\ +$(eval $(BUILD_DIR)/$(call obj_name,$x): $x ; $(CC) $(CFLAGS) $(DEP_FLAGS) -c -o $$@ $$<)) -$(BUILD_DIR)/%.o: %.cpp - $(CC) $(CFLAGS) $(DEP_FLAGS) -c -o $@ $< +$(foreach x,$(ASM_SOURCES),\ +$(eval $(BUILD_DIR)/$(call obj_name,$x): $x ; $(CC) $(DEP_FLAGS) -c -o $$@ $$<)) -$(BUILD_DIR)/%.o: %.S - $(CC) $(DEP_FLAGS) -c -o $@ $< -$(TARGET_GAME): $(OBJECTS) - cd $(BUILD_DIR); $(CC) $(LDFLAGS) *.o */*/*.o $(LDLIBS) -o $(TARGET_GAME) - cp -f $(BUILD_DIR)/$(NAME)* .. +# use file list instead of wildcard for link command so we don't accidentally +# link with old object files for removed source files +$(TARGET_GAME): $(OBJ_FILES) + cd $(BUILD_DIR); $(CC) $(LDFLAGS) $(OBJECTS) $(LDLIBS) -o $(TARGET_GAME) tidy: for src in $(SOURCES) ; do \ @@ -52,9 +55,10 @@ tidy: .PHONY: style check-style tidy clean: - rm -f ../$(TARGET_GAME) ../stdout.txt ../stderr.txt - rm -f $(TARGET_GAME) stdout.txt stderr.txt - rm -rf $(BUILD_DIR) + rm -f $(TARGET_GAME) ../stdout.txt ../stderr.txt + @# safer delete of build dir instead of just 'rm -rf $(BUILD_DIR)' + rm -f $(BUILD_DIR)/*.[od] + @([ -d "$(BUILD_DIR)" ] && rmdir $(BUILD_DIR)) || true clobber: clean rm -f ramdisk_data.cpp $(wildcard ramdisk_data*.S)