ifeq ($(TARGET),3DS) ifeq ($(strip $(DEVKITPRO)),) $(error "Please set DEVKITPRO in your environment. export DEVKITPRO=devkitPro") endif ifeq ($(strip $(DEVKITARM)),) $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") endif endif # TOOLS # BUILDTOOLS_DIR := $(dir $(lastword $(MAKEFILE_LIST))) define createdirrule $(1): | $(dir $(1)) ifndef $(dir $(1))_DIRECTORY_RULE_IS_DEFINED $(dir $(1)): @mkdir -p $$@ $(dir $(1))_DIRECTORY_RULE_IS_DEFINED := 1 endif endef rwildcard=$(wildcard $1/$2) $(foreach d,$(wildcard $1/*),$(call rwildcard,$d,$2)) # SETUP # OBJECT_FILES := $(foreach dir,$(SOURCE_DIRS), \ $(patsubst %.c,$(BUILD_DIR)/%.o,$(call rwildcard,$(dir),*.c)) \ $(patsubst %.cpp,$(BUILD_DIR)/%.o,$(call rwildcard,$(dir),*.cpp)) \ $(patsubst %.s,$(BUILD_DIR)/%.o,$(call rwildcard,$(dir),*.s)) \ $(patsubst %.bin,$(BUILD_DIR)/%.bin.o,$(call rwildcard,$(dir),*.bin)) \ $(patsubst %.v.pica,$(BUILD_DIR)/%.shbin.o,$(call rwildcard,$(dir),*.v.pica)) \ $(patsubst %.shlist,$(BUILD_DIR)/%.shbin.o,$(call rwildcard,$(dir),*.shlist)) \ ) OUTPUT_ZIP_FILE := $(OUTPUT_DIR)/$(NAME).zip ifeq ($(LIBRARY),1) OUTPUT_FILES := $(OUTPUT_DIR)/lib$(NAME).a $(OUTPUT_DIR)/lib$(NAME).so else ifeq ($(TARGET),3DS) OUTPUT_FILES := $(OUTPUT_DIR)/$(NAME).elf $(OUTPUT_DIR)/3ds/$(NAME)/$(NAME).smdh $(OUTPUT_DIR)/3ds/$(NAME)/$(NAME).3dsx $(OUTPUT_DIR)/$(NAME).3ds $(OUTPUT_DIR)/$(NAME).cia else OUTPUT_FILES := $(OUTPUT_DIR)/$(NAME) endif ifeq ($(TARGET),3DS) AR := $(DEVKITARM)/bin/arm-none-eabi-ar AS := $(DEVKITARM)/bin/arm-none-eabi-as CC := $(DEVKITARM)/bin/arm-none-eabi-gcc CXX := $(DEVKITARM)/bin/arm-none-eabi-g++ else AR := ar AS := as CC := gcc CXX := g++ endif LD_FLAGS := $(patsubst %,-L%/lib,$(LIBRARY_DIRS)) $(patsubst %,-l%,$(LIBRARIES)) COMMON_CC_FLAGS := $(patsubst %,-I%,$(INCLUDE_DIRS)) $(patsubst %,-I%/include,$(LIBRARY_DIRS)) -g -Wall -O2 $(BUILD_FLAGS) ifeq ($(LIBRARY),1) COMMON_CC_FLAGS += -fPIC endif ifeq ($(TARGET),3DS) COMMON_CC_FLAGS += -mword-relocations -fomit-frame-pointer -ffast-math -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft -DARM11 -D_3DS LD_FLAGS += -specs=3dsx.specs endif CC_FLAGS := $(COMMON_CC_FLAGS) -std=gnu99 CXX_FLAGS := $(COMMON_CC_FLAGS) -std=gnu++11 ifeq ($(TARGET),3DS) ifeq ($(suffix $(BANNER_IMAGE)),".cgfx") BANNER_IMAGE_ARG := -ci else BANNER_IMAGE_ARG := -i endif ifeq ($(suffix $(BANNER_AUDIO)),".cwav") BANNER_AUDIO_ARG := -ca else BANNER_AUDIO_ARG := -a endif RSF := $(BUILDTOOLS_DIR)/3ds/template.rsf ROMFS_PARAM := ifneq ("$(wildcard $(ROMFS_DIR))","") ROMFS_PARAM := -DAPP_ROMFS="RootPath: $(ROMFS_DIR)" endif COMMON_MAKEROM_PARAMS := -rsf $(RSF) -target t -exefslogo -icon $(BUILD_DIR)/icon.icn -banner $(BUILD_DIR)/banner.bnr -DAPP_TITLE="$(NAME)" -DAPP_PRODUCT_CODE="$(PRODUCT_CODE)" -DAPP_UNIQUE_ID="$(UNIQUE_ID)" $(ROMFS_PARAM) -DAPP_SYSTEM_MODE="$(SYSTEM_MODE)" -DAPP_SYSTEM_MODE_EXT="$(SYSTEM_MODE_EXT)" SMDHTOOL := $(DEVKITARM)/bin/smdhtool _3DSXTOOL := $(DEVKITARM)/bin/3dsxtool ifeq ($(OS),Windows_NT) MAKEROM := $(BUILDTOOLS_DIR)/3ds/makerom.exe BANNERTOOL := $(BUILDTOOLS_DIR)/3ds/bannertool.exe else UNAME_S := $(shell uname -s) ifeq ($(UNAME_S),Linux) MAKEROM := $(BUILDTOOLS_DIR)/3ds/makerom-linux BANNERTOOL := $(BUILDTOOLS_DIR)/3ds/bannertool-linux endif ifeq ($(UNAME_S),Darwin) MAKEROM := $(BUILDTOOLS_DIR)/3ds/makerom-mac BANNERTOOL := $(BUILDTOOLS_DIR)/3ds/bannertool-mac endif endif _3DSXFLAGS := ifneq ("$(wildcard $(ROMFS_DIR))","") _3DSXFLAGS += --romfs=$(ROMFS_DIR) endif endif # RULES # .PHONY: all run clean .PRECIOUS: %.bnr %.icn all: $(OUTPUT_ZIP_FILE) ifneq ($(LIBRARY),1) run: $(OUTPUT_FILES) ./$< $(RUN_FLAGS) endif clean: @rm -rf $(BUILD_DIR) $(OUTPUT_DIR) @echo "Cleaned." $(foreach file,$(OBJECT_FILES),$(eval $(call createdirrule,$(file)))) $(foreach file,$(OUTPUT_FILES),$(eval $(call createdirrule,$(file)))) $(OUTPUT_ZIP_FILE): $(OUTPUT_FILES) @echo $@ @cd $(OUTPUT_DIR); \ zip -r $(patsubst $(OUTPUT_DIR)/%,%,$@ $^) > /dev/null $(OUTPUT_DIR)/$(NAME): $(OBJECT_FILES) @echo $@ @$(CXX) $(CXX_FLAGS) $^ -o $@ $(LD_FLAGS) %.elf: $(OBJECT_FILES) @echo $@ @$(CXX) $(CXX_FLAGS) $^ -o $@ $(LD_FLAGS) %.a: $(OBJECT_FILES) @echo $@ @$(AR) -rc $@ $^ %.so: $(OBJECT_FILES) @echo $@ @$(CXX) $(CXX_FLAGS) -shared $^ -o $@ $(LD_FLAGS) $(BUILD_DIR)/%.o: %.c @echo $@ @$(CC) -c $(CC_FLAGS) -MMD -MP -MF $(BUILD_DIR)/$*.d $< -o $@ $(BUILD_DIR)/%.o: %.cpp @echo $@ @$(CXX) -c $(CXX_FLAGS) -MMD -MP -MF $(BUILD_DIR)/$*.d $< -o $@ $(BUILD_DIR)/%.o: %.s @echo $@ @$(CC) -c $(CC_FLAGS) -MMD -MP -MF -x assembler-with-cpp $(BUILD_DIR)/$*.d $< -o $@ $(BUILD_DIR)/%.o: %.S @echo $@ @$(CC) -c $(CC_FLAGS) -MMD -MP -MF -x assembler-with-cpp $(BUILD_DIR)/$*.d $< -o $@ ifeq ($(TARGET),3DS) define bin2o bin2s $< | $(AS) -o $(@) echo "extern const u8" `(echo $( `(echo $(> `(echo $(> `(echo $( `(echo $(CURBIN) | tr . _)`.h echo "extern const u8" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> `(echo $(CURBIN) | tr . _)`.h echo "extern const u32" `(echo $(CURBIN) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(CURBIN) | tr . _)`.h endef $(BUILD_DIR)/%.shbin.o : %.v.pica %.g.pica @echo $@ @$(call shader-as,$^) $(BUILD_DIR)/%.shbin.o : %.v.pica @echo $@ @$(call shader-as,$<) $(BUILD_DIR)/%.shbin.o : %.shlist @echo $@ @$(call shader-as,$(foreach file,$(shell cat $<),$(dir $<)/$(file))) %.bnr: $(BANNER_IMAGE) $(BANNER_AUDIO) @echo $@ @$(BANNERTOOL) makebanner $(BANNER_IMAGE_ARG) $(BANNER_IMAGE) $(BANNER_AUDIO_ARG) $(BANNER_AUDIO) -o $@ > /dev/null %.icn: $(ICON) @echo $@ @$(BANNERTOOL) makesmdh -s "$(NAME)" -l "$(DESCRIPTION)" -p "$(AUTHOR)" -i $(ICON) -o $@ > /dev/null %.smdh: $(ICON) @echo $@ @$(SMDHTOOL) --create "$(NAME)" "$(DESCRIPTION)" "$(AUTHOR)" $(ICON) $@ $(OUTPUT_DIR)/3ds/$(NAME)/%.3dsx: $(OUTPUT_DIR)/%.elf $(OUTPUT_DIR)/3ds/$(NAME)/%.smdh @echo $@ @$(_3DSXTOOL) $< $@ --smdh=$(word 2,$^) $(_3DSXFLAGS) %.3ds: %.elf $(BUILD_DIR)/banner.bnr $(BUILD_DIR)/icon.icn @echo $@ @$(MAKEROM) -f cci -o $@ -elf $< -DAPP_ENCRYPTED=true $(COMMON_MAKEROM_PARAMS) %.cia: %.elf $(BUILD_DIR)/banner.bnr $(BUILD_DIR)/icon.icn @echo $@ @$(MAKEROM) -f cia -o $@ -elf $< -DAPP_ENCRYPTED=false $(COMMON_MAKEROM_PARAMS) endif # DEPENDS # DEPENDS := $(OBJECT_FILES:.o=.d) -include $(DEPENDS)