#!/usr/bin/env omake #---------------------------------------------------------------------------- # Project: Horizon # File: commondefs.om # # Copyright 2007-2009 Nintendo. All rights reserved. # # These coded instructions, statements, and computer programs contain # proprietary information of Nintendo of America Inc. and/or Nintendo # Company Ltd., and are protected by Federal copyright law. They may # not be disclosed to third parties or copied or duplicated in any form, # in whole or in part, without the prior written consent of Nintendo. # # $Date:: 2011-02-10#$ # $Rev: 34316 $ # $Author: takiguchi_shinichi $ #---------------------------------------------------------------------------- # Load the OMake default library once only open build/Common SCANNER_MODE=disabled # Get directory root/environmental variable (can build even if not defined) public.HORIZON_ROOT = if $(defined-env HORIZON_ROOT) HORIZON_ROOT = $(absname $"$(getenv HORIZON_ROOT)") export if $(defined-env CTRSDK_ROOT) CTRSDK_ROOT = $(absname $"$(getenv CTRSDK_ROOT)") if $(and $(defined-env HORIZON_ROOT), $(not $(equal $(HORIZON_ROOT), $(CTRSDK_ROOT)))) eprintln(HORIZON_ROOT と CTRSDK_ROOT が一致しません。同じパスを設定するか、どちらか一方だけを定義して下さい。) exit(1) HORIZON_ROOT = $(CTRSDK_ROOT) export if $(defined-env CTRSDK_TARGETS) CTRSDK_TARGETS = $(absname $"$(getenv CTRSDK_TARGETS)") if $(defined-env HORIZON_TARGETS) eprintln(HORIZON_TARGETS と CTRSDK_TARGETS は同時に使用できませんので、どちらか一方だけを定義して下さい。) exit(1) HORIZON_TARGETS = $(CTRSDK_TARGETS) export if $(not $(HORIZON_ROOT)) eprintln($"$$CTRSDK_ROOT is not defined") HORIZON_ROOT = $(absname $(ROOT)) export public.HORIZON_ADDINS_ROOT = if $(defined-env HORIZON_ADDINS_ROOT) HORIZON_ADDINS_ROOT = $(absname $"$(getenv HORIZON_ADDINS_ROOT)") export else HORIZON_ADDINS_ROOT = $(absname $(HORIZON_ROOT)/../CTR/Addins) export if $(not $(file-exists $(HORIZON_ADDINS_ROOT))) HORIZON_ADDINS_ROOT = export # Define directory public.SUBDIR_IMAGES = images public.SUBDIR_SD_IMAGES = sdimages public.SUBDIR_OBJECTS = objects public.SUBDIR_LIBRARIES = libraries public.SUBDIR_INCLUDE = include public.DIRSUFFIX_FEEDBACK = .__feedback__ public.SCANNER_PREFIX = scan public.AROOT = $(absname $(ROOT)) public.ROOT_IMAGES = $(absname $(ROOT)$(DIRSEP)$(SUBDIR_IMAGES)) public.ROOT_OBJECTS = $(absname $(ROOT)$(DIRSEP)$(SUBDIR_OBJECTS)) public.ROOT_LIBRARIES = $(absname $(HORIZON_ROOT)$(DIRSEP)$(SUBDIR_LIBRARIES)) public.ROOT_BUILD = $(absname $(HORIZON_ROOT)$(DIRSEP)build) public.ROOT_OMAKE = $(absname $(ROOT_BUILD)$(DIRSEP)omake) public.ROOT_INCLUDE = $(absname $(ROOT)$(DIRSEP)$(SUBDIR_INCLUDE)) public.ROOT_SOURCES = $(absname $(ROOT)$(DIRSEP)sources) public.ROOT_TOOLS = $(absname $(HORIZON_ROOT)$(DIRSEP)tools) public.ROOT_TARGETTOOLS = $(absname $(HORIZON_ROOT)$(DIRSEP)tools$(DIRSEP)TargetTools) public.ROOT_COMMANDS = $(absname $(ROOT_TOOLS)$(DIRSEP)CommandLineTools) public.ROOT_RESOURCES = $(absname $(HORIZON_ROOT)$(DIRSEP)resources) public.HORIZON_ROOT_INCLUDE = $(HORIZON_ROOT)$(DIRSEP)$(SUBDIR_INCLUDE) public.HORIZON_ROOT_IMAGES = $(HORIZON_ROOT)$(DIRSEP)$(SUBDIR_IMAGES) public.HORIZON_ROOT_LIBRARIES = $(HORIZON_ROOT)$(DIRSEP)$(SUBDIR_LIBRARIES) # Installation destination settings (prioritized as follows) # 1. Environmental variable HORIZON_INSTALL_ROOT # 2. Variable INSTALL_ROOT # 3. Variable HORIZON_ROOT if $(defined-env HORIZON_INSTALL_ROOT) HORIZON_INSTALL_ROOT = $(dir $"$(getenv HORIZON_INSTALL_ROOT)") declare public.INSTALL_ROOT if $(defined HORIZON_INSTALL_ROOT) INSTALL_ROOT = $(dir $(HORIZON_INSTALL_ROOT)) export else if $(defined INSTALL_ROOT) INSTALL_ROOT = $(dir $(INSTALL_ROOT)) export elseif $(equal $(AROOT), $(HORIZON_ROOT)) INSTALL_ROOT = $(ROOT) export export if $(not $(defined INSTALL_IMAGES_DIR)) INSTALL_IMAGES_DIR = $(SUBDIR_IMAGES) export if $(defined INSTALL_ROOT) INSTALL_ROOT_IMAGES = $(dir $(INSTALL_ROOT)$(DIRSEP)$(INSTALL_IMAGES_DIR)) INSTALL_ROOT_LIBRARIES = $(dir $(INSTALL_ROOT)$(DIRSEP)$(SUBDIR_LIBRARIES)) export public.HORIZON_PRIVATE_RULES = $(EMPTY) # Library for Horizon include $(ROOT_OMAKE)/utildefs include $(ROOT_OMAKE)/commondefs.cctype include $(ROOT_OMAKE)/commondefs.gl include $(ROOT_OMAKE)/targetdefs include $(ROOT_OMAKE)/packagedefs include $(ROOT_OMAKE)/debuggerdefs.partner # Incorporate individual settings if $(test -f $(ROOT_OMAKE)/localdefs.om) include $(ROOT_OMAKE)/localdefs export # Select compiler (TODO: create a switch interface) COMPILER = $(CompilerRVCT.new) # Extension settings EXT_OBJ = .o EXT_LIB = .a EXT_ASM = .s EXT_C = .c EXT_EXE = $(EXE) EXT_ELF = .axf EXT_PLF = .plf EXT_CCI = .cci # CTR Card Image EXT_CIP = .cip # CTR Initial Process EXT_CSU = .csu # CTR System Updater EXT_CXI = .cxi # CTR eXecutable Image EXT_CIA = .cia # CTR Importable Archive EXT_CDI = .cdi # CTR Development Image EXT_OLS = .ols.cia EXT_CFA = .cfa # CTR File Archive EXT_BANNER = .bnr EXT_ICON = .icn EXT_PUB = .pubbin EXT_PRI = .pribin # Application type setting APPTYPE_CARD = CARD APPTYPE_NAND = NAND APPTYPE_BOTH = BOTH # Settings for rules for Horizon public.MAKEROM = $(ROOT_COMMANDS)$(DIRSEP)ctr_makerom32.exe public.MAKECIA = $(ROOT_COMMANDS)$(DIRSEP)ctr_makecia32.exe public.MAKEOLS = $(ROOT_COMMANDS)$(DIRSEP)ctr_makeols32.exe public.MAKEBANNER = $(ROOT_COMMANDS)$(DIRSEP)ctr_makebanner32.exe public.MAKEROMFLAGS = public.MAKECIAFLAGS = public.BIN2OBJ = $(file $(ROOT_COMMANDS)/ctr_bin2obj32$(EXE)) public.BIN2OBJ_FLAGS= public.RUNNER = $(file $(ROOT_BUILD)/runner/run.sh) public.RUNNER_LOCK = $(file $(ROOT_BUILD)/runner/.lock) # Parameter variables if $(not $(defined SKIP_BUILD)) public.SKIP_BUILD = false export if $(not $(defined DEBUG_PRINT)) public.DEBUG_PRINT = $`(DEBUG_PRINT_DEFAULT) export if $(not $(defined DEBUG_PRINT_SDK)) public.DEBUG_PRINT_SDK = $`(DEBUG_PRINT_SDK_DEFAULT) export if $(not $(defined ASSERT_WARNING)) public.ASSERT_WARNING = $`(ASSERT_WARNING_DEFAULT) export if $(not $(defined ASSERT_WARNING_SDK)) public.ASSERT_WARNING_SDK = $`(ASSERT_WARNING_SDK_DEFAULT) export if $(not $(defined HOST_IO)) public.HOST_IO = $`(HOST_IO_DEFAULT) export public.SOURCES = public.OBJECTS = public.BUILD_APPLICATION = false public.BUILD_KERNEL = false public.FEEDBACK_1ST_STAGE = false public.FEEDBACK_2ND_STAGE = false public.EXCLUSION_SCATTER = false if $(not $(defined TRACE_PRODUCTCODE)) public.TRACE_PRODUCTCODE = export # Variable to have the user specify a directory matching the build target and build type public.BUILD_TARGET_DIR = $`(TARGET.getFullnameWithSystem Process) public.BUILD_TYPE_DIR = $`(TARGET.buildtype) # Utility functions # Find the relative path from the project root. # When the path is in "sources" just below the root, "sources" is also removed GetSubPath(path) = apath = $(absname $(path)) #println(target: $(apath)) subpath = $(removeprefix $(AROOT)$(DIRSEP), $(apath)) subpath = $(removeprefix sources$(DIRSEP), $(subpath)) if $(and \ $(or $(equal $(apath), $(subpath)), \ $(and $(defined FORCE_REFERENCE_ROOT), \ $(FORCE_REFERENCE_ROOT))), \ $(defined SOURCES_REFERENCE_ROOT)) subpath_refer = $(removeprefix $(absname $(SOURCES_REFERENCE_ROOT)), $(apath)) #println(subpath_refer: $(subpath_refer)) return $(subpath_refer) else if $(equal $(subpath), $(apath)) eprintln($"Trying to build a file outside the tree.: $(apath)") eprintln($"Specify a base directory manually with SOURCES_REFERENCE_ROOT.") return $(basename $(apath)) return $(subpath) # Check the parent-child relationship of the directories is_under(parent_path, child_path) = parent_path = $(absname $(parent_path)) child_path = $(absname $(child_path)) if $(equal $(removeprefix $(parent_path), $(child_path)), $(child_path)) return false else return true GetBuildGroup() = return group$(mod $(random), 10) IsTestBuild() = return $(filter test tests dotest dotests dotests-%, $(TARGETS)) IsDocumentBuild() = return $(filter documents clean-documents, $(TARGETS)) # Create an object file public.Object(config, files) = if $(and $(FEEDBACK_1ST_STAGE), $(FEEDBACK_2ND_STAGE)) eprintln(FEEDBACK error) exit(1) CCFLAGS += $(COMPILER.getCCFlags $(config)) $(config.getSystemCCFlags) CCFLAGS_MACRO += $(COMPILER.getMacroFlags $(config)) -DNN_USE_MAKECCI ASFLAGS += $(COMPILER.getASFlags $(config)) INCLUDES = $(dir $(INCLUDES)) DEPEND_FEEDBACK = false if $(FEEDBACK_2ND_STAGE) # If a dependency relationship is always generated when building using a feedback file, the build stops at the point when the feedback file is generated for a changed .h file. Accordingly, generate the dependency relationship only for the first build (when no previously generated feedback file exists). FEEDBACK = $(config.getFeedBackPath) CCFLAGS_BUILD += --feedback=$(absname $(FEEDBACK)) if $(test ! -e $(FEEDBACK)) # # # DEPEND_FEEDBACK = true export export OFILES = export OFILES obj_dir_parent = $(config.getObjectDirectory) CC = $,(CC) CXX = $,(CXX) CFLAGS = $,(CFLAGS) CCFLAGS = $,(CCFLAGS) CXXFLAGS = $,(CXXFLAGS) .PHONY: build-random group1 group2 group3 group4 group5 group6 group7 group8 group9 group0 build-random: group1 group2 group3 group4 group5 group6 group7 group8 group9 group0 # Explicitly defines rules for each file foreach(filename, $(files)) if $(not $(equal $(filename), $(EMPTY))) if $(not $(is_under $(CWD), $(filename))) ONAME = $(rootname $(GetSubPath $(filename)))$(EXT_OBJ) export else ONAME = $(rootname $(filename))$(EXT_OBJ) export OFILE = $(file $(obj_dir_parent)/$(ONAME)) ODIR = $(makeDirectory $(dirname $(OFILE))) $(OFILE): $(ODIR) match $(filename) case $"\($(EXT_C)\)$$" scanner_name = $(SCANNER_PREFIX)-c-$(fullname $(rootname $(OFILE))) .SCANNER: $(scanner_name): $(filename) .PHONY/$(ROOT)/build-setup :value: $(digest-in-path-optional $(INCLUDES), $&) $(CC) $(CFLAGS) $(PREFIXED_INCLUDES) $(CSCANFLAGS) $(CCOUT)$(absname $(OFILE)) $(absname $<) $(OFILE): $(filename) :scanner: $(scanner_name) $(CC) $(CFLAGS) $(CCFLAGS_BUILD) $(PREFIXED_INCLUDES) -c $(CCOUT)$(absname $@) $(absname $<) $(OFILE): $(nth 0, $(CC)) $(GetBuildGroup): $(OFILE) case $"\(\.cpp\)$$" EXT = $1 scanner_name = $(SCANNER_PREFIX)-cxx-$(fullname $(rootname $(OFILE))) .SCANNER: $(scanner_name): $(filename) .PHONY/$(ROOT)/build-setup :value: $(digest-in-path-optional $(INCLUDES), $&) $(CXX) $(CXXFLAGS) $(PREFIXED_INCLUDES) $(CSCANFLAGS) $(CCOUT)$(absname $(OFILE)) $(absname $<) $(OFILE): $(filename) :scanner: $(scanner_name) $(CXX) $(CXXFLAGS) $(CCFLAGS_BUILD) $(PREFIXED_INCLUDES) -c $(CCOUT)$(absname $@) $(absname $<) $(OFILE): $(nth 0, $(CXX)) $(GetBuildGroup): $(OFILE) case $"\($(EXT_ASM)\)$$" $(OFILE): $(filename) :effects: asmlock $(AS) $(ASFLAGS) $(CCFLAGS_BUILD) $(PREFIXED_INCLUDES) $(ASOUT)$(absname $@) $(absname $<) $(OFILE): $(nth 0, $(AS)) default eprintln($"Unsupported source file: " '$(filename)') exit(1) # When compiling using feedback, depends on the feedback file # When rules are defined individually, the dependency relationship must also be specified individually if $(DEPEND_FEEDBACK) $(OFILE): $(config.getFeedBackPath) OFILES += $(OFILE) clean: rm -rf $(obj_dir_parent) $(SUBDIR_OBJECTS) return $(OFILES) public.Bin2ObjDefaultSymbolFunction(filename) = SYMBOL_PREFIX = $(uppercase $(removesuffix $(basename $(filename)))) return $(SYMBOL_PREFIX)_BEGIN $(SYMBOL_PREFIX)_END public.Bin2ObjHashSymbolFunction(filename) = SYMBOL_PREFIX = $(uppercase $(removesuffix $(basename $(filename)))) return $(SYMBOL_PREFIX)_HASH_BEGIN $(SYMBOL_PREFIX)_HASH_END public.ObjectFromBinaryWithSymbol(config, files, symbol_function) = OFILES = obj_dir_parent = $(config.getObjectDirectory) foreach(filename, $(files)) OFILE = $(file $(obj_dir_parent)/$(basename $(filename))$(EXT_OBJ)) OFILES += $(OFILE) SYMBOL_PAIR = $(symbol_function $(filename)) $(OFILE): $(filename) $(BIN2OBJ) :value: $(getMtimeIfLarge $(filename)) $(BIN2OBJ) $(BIN2OBJ_FLAGS) -b $(nth 0, $(SYMBOL_PAIR)) -e $(nth 1, $(SYMBOL_PAIR)) $< $@ $(OFILE): $(obj_dir_parent) export OFILES return $(OFILES) public.ObjectFromBinary(config, files) = return $(ObjectFromBinaryWithSymbol $(config), $(files), $(Bin2ObjDefaultSymbolFunction)) public.HashFromBinary(config, files) = EXT_HASH = .hash HFILES = obj_dir_parent = $(config.getObjectDirectory) foreach(filename, $(files)) HFILE = $(file $(obj_dir_parent)/$(basename $(filename))$(EXT_HASH)$(EXT_OBJ)) HFILES += $(HFILE) SYMBOL_PAIR = $(Bin2ObjHashSymbolFunction $(filename)) $(HFILE): $(filename) $(BIN2OBJ) $(RUBY) -e "require 'Digest/md5'; STDOUT.binmode; print [Digest::SHA1.hexdigest(File.open('$(filename)', 'rb').read)].pack('H*');" > $@ $(BIN2OBJ) $(BIN2OBJ_FLAGS) -b $(nth 0, $(SYMBOL_PAIR)) -e $(nth 1, $(SYMBOL_PAIR)) $@ $@ $(HFILE): $(obj_dir_parent) export HFILES return $(HFILES) %.c: %.y $(YACC) $< %.c: %.l $(LEX) $< public.PreProcess(config, infile, outfile) = CCFLAGS_MACRO += $(COMPILER.getMacroFlags $(config)) -DNN_USE_MAKECCI scanner_name = $(SCANNER_PREFIX)-cpp-$(fullname $(rootname $(outfile))) .SCANNER: $(scanner_name): $(infile) .PHONY/$(ROOT)/build-setup :value: $(digest-in-path-optional $(INCLUDES), $&) $(CPP) $(CCFLAGS) $(PREFIXED_INCLUDES) $(CSCANFLAGS) $(CCOUT)$(absname $(outfile)) $(absname $<) outdir = $(makeDirectory $(dirname $(outfile))) $(outfile): $(infile) $(outdir) :scanner: $(scanner_name) $(CPP) $(CCFLAGS) $(PREFIXED_INCLUDES) $(CCOUT)$(absname $@) $(absname $<) return $(outfile) # # Default C scanner # .PHONY: CGeneratedFilesTarget public.CGeneratedFiles(files) = CGeneratedFilesTarget: $(files) public.LocalCGeneratedFiles(files) = .SCANNER: scan-c-%: $(files) .SCANNER: scan-cxx-%: $(files) .SCANNER: %$(EXT_OBJ): $(files) export .PHONY: build-romfs public.StaticLibrary(config, name, files) = private.LIBDIR = $(config.getLibraryDirectory true) private.OFILES = $(Object $(config), $(filter-out %$(EXT_OBJ),$(files))) $(filter %$(EXT_OBJ),$(files)) private.NORMALLIB = $(file $(LIBDIR)$(DIRSEP)$(config.getLibraryName $(name))) $(NORMALLIB): $(LIBDIR) $(nth 0, $(AR)) $(NORMALLIB): $(OFILES) echo $(absname $^) > $@.res rm -f $(absname $@) $(AR) $(ARFLAGS) $(absname $@) --via $(absname $@.res) rm -f $@.res clean: rm -f $(NORMALLIB) .PHONY: build-random group1 group2 group3 group4 group5 group6 group7 group8 group9 group0 build-random: group1 group2 group3 group4 group5 group6 group7 group8 group9 group0 $(GetBuildGroup): $(NORMALLIB) return $(NORMALLIB) public.StaticObject(config, files) = private.LIBDIR = $(config.getLibraryDirectory true) SOFILES = foreach(filename, $(files)) private.OFILE = $(Object $(config), $(filename)) private.NORMALLIB = $(file $(LIBDIR)/$(config.getStaticObjectName $(rootname $(filename)))) $(NORMALLIB): $(LIBDIR) $(NORMALLIB): $(OFILE) cp $< $@ SOFILES += $(NORMALLIB) export SOFILES clean: rm -f $(SOFILES) return $(SOFILES) completeLibrarySuffix(config, libfiles) = result = foreach(libfile, $(libfiles)) if $(findstring $(libfile), $'\.(small)|(fast)(\.|$)') result += $(libfile) export else result += $(libfile).$(config.effort) export export return $(result) public.Program(config, name, files) = FEEDBACK_FILE = $(config.getFeedBackPath) private.IMAGE_DIR = $(config.getImageDirectory false) LIBDIR = $(config.getLibraryDirectory false) NAME = $(config.getBinaryPath $(name), $(EXT_EXE)) LDFLAGS += $(COMPILER.getLDFlags $(config)) MINIMUM_LIBS += $(config.getMinimumLibraries) DEFAULT_LIBS += $(config.getDefaultLibraries) if $(config.isHostIoEnable) DEFAULT_LIBS += $(config.getHostIoLibraries) export EXT_DIRECT = $(addprefix %, $(EXT_OBJ) $(EXT_ELF) $(EXT_PLF)) OFILES = $(Object $(config), $(filter-out $(EXT_DIRECT),$(files))) $(filter $(EXT_DIRECT),$(files)) DASM = $(file $(removesuffix $(NAME)).dasm) if $(filter %$(EXT_LIB), $(LIBS)) eprintln($""!!! WARNING: the LIBS variable should contain libraries _without_ extensions."") LIBS = $(replacesuffixes $(EXT_LIB), $"$(EMPTY)", $(LIBS)) export if $(not $(and $(defined TOOL), $(TOOL))) FILTERED_LFILES = $(filter-out $"$(EMPTY)",$(LIBS)) LFILES = $(file $(addprefix $(LIBDIR)$(DIRSEP), $(addsuffix $(EXT_LIB), $(completeLibrarySuffix $(config), $(FILTERED_LFILES))))) LFILES += $(file $(addsuffix $(EXT_LIB), $(completeLibrarySuffix $(config), $(replacesuffixes $(EXT_LIB), $"$(EMPTY)", $(LIBFILES))))) LFILES += $(file $(addsuffix $(EXT_LIB), $(completeLibrarySuffix $(config), $(replacesuffixes $(EXT_LIB), $"$(EMPTY)", $(LIBFILES))))) LFILES += $(file $(addsuffix $(EXT_LIB), $(completeLibrarySuffix $(config), $(replacesuffixes $(EXT_LIB), $"$(EMPTY)", $(LIBFILES))))) if $(and $(defined CRT_0_O),$(not $(equal $(LDRESP),$(EMPTY)))) LFILES += $(file $(addprefix $(LIBDIR)$(DIRSEP), $(addsuffix $(EXT_OBJ), $(completeLibrarySuffix $(config), $(removesuffix $(CRT_0_O)))))) export MAPFILE = $(config.getMapfilePath $(name)) export MAPFILE if $(defined LDSCRIPT_TEMPLATE) LDSCRIPT = $(PreProcess $(config), $(LDSCRIPT_TEMPLATE), $(absname $(config.getLdscriptPath $(name)))) export $(LDSCRIPT): $(IMAGE_DIR) if $(FEEDBACK_1ST_STAGE) $(FEEDBACK_FILE): $(LDSCRIPT) else $(NAME): $(LDSCRIPT) :effects: $(MAPFILE) export else LFILES = $(NAME): $(IMAGE_DIR) export if $(equal $(LDRESP),$(EMPTY)) $(NAME): $(OFILES) $(LFILES) :effects: $(DASM) $(LD) $(LDOUT)$(absname $@) $(LDFLAGS) $^ $(if $(DISAS), $(DISAS) -o$(absname $(DASM)) $(absname $@)) if $(FEEDBACK_1ST_STAGE) eprintln(feed back is not supported.) else if $(FEEDBACK_1ST_STAGE) $(FEEDBACK_FILE): $(OFILES) $(LFILES) echo $(absname $^) > $@.res $(LD) $(LDOUT)$(absname $(NAME)) $(LDFLAGS) $(LDRESP) $(absname $@.res) grep -v $"^;.+Last Updated:" $@.tmp > $@ else # Rule not used with FEEDBACK_1ST_STAGE. $(NAME): $(OFILES) $(LFILES) :effects: $(DASM) echo $(absname $^) > $@.res $(LD) $(LDOUT)$(absname $@) $(LDFLAGS) $(LDRESP) $(absname $@.res) $(if $(DISAS), $(DISAS) -o$(absname $(DASM)) $(absname $@)) $(NAME): $(nth 0, $(LD)) clean: rm -rf $(IMAGE_DIR) $(SUBDIR_IMAGES) if $(FEEDBACK_1ST_STAGE) return $(FEEDBACK_FILE) else return $(NAME) public.ProgramELF(config, name, files) = EXT_EXE = $(EXT_ELF) return $(Program $(config), $(name), $(files)) public.Tool(config, name, files) = TOOL = true return $(Program $(config), $(name), $(files)) public.InstallTool(files) = install_files = export install_files foreach(filename, $(files)) install_file = $(file $(ROOT_COMMANDS)$(DIRSEP)$(basename $(filename))) $(install_file): $(filename) cp -f $< $@ install_files += $(install_file) return $(install_files) public.GetMakeromUserVariables()= if $(not $(defined ROMFS_ROOT)) ROMFS_ROOT = export if $(not $(defined TITLE)) TITLE = CtrApp export FLAGS = FLAGS += -DROMFS_ROOT=$(ROMFS_ROOT) FLAGS += -DTITLE=$(TITLE) return $(FLAGS) public.GetBannerFile(config) = BannerFile = $(config.getDefaultBannerFile) if $(defined CTR_BANNER_SPEC) base = $(removesuffix $(CTR_BANNER_SPEC)) BannerFile = $(addprefix $(config.getObjectDirectory)$(DIRSEP), $(addsuffixes $(EXT_BANNER), $(base))) export else if $(defined CTR_BANNER) BannerFile = $(CTR_BANNER) export elseif $(or $(and $(defined CTR_NO_BANNER_ICON), $(equal $(CTR_NO_BANNER_ICON), true)), \ $(and $(defined CTR_NO_BANNER), $(equal $(CTR_NO_BANNER), true)) ) BannerFile = export export return $(BannerFile) public.GetIconFile(config) = IconFile = $(config.getDefaultIconFile) if $(defined CTR_BANNER_SPEC) base = $(removesuffix $(CTR_BANNER_SPEC)) IconFile = $(addprefix $(config.getObjectDirectory)$(DIRSEP), $(addsuffixes $(EXT_ICON), $(base))) export else if $(defined CTR_ICON) IconFile = $(CTR_ICON) export elseif $(and $(defined CTR_NO_BANNER_ICON), $(equal $(CTR_NO_BANNER_ICON), true)) IconFile = export export return $(IconFile) public.GetMakeromBannerOptions(config) = if $(defined CTR_BANNER_SPEC) if $(or $(defined CTR_BANNER), $(defined CTR_ICON)) eprintln($"CTR_BANNER CTR_ICON and CTR_BANNER_SPEC cannot be used simultaneously") exit(1) options = BannerFile = $(GetBannerFile $(config)) IconFile = $(GetIconFile $(config)) if $(not $(equal $(BannerFile.length), 0)) options += -banner $(BannerFile) export if $(not $(equal $(IconFile.length), 0)) options += -icon $(IconFile) export return $(options) public.UserProcess(config, name, files) = BUILD_APPLICATION = true if $(not $(defined LDSCRIPT_TEMPLATE)) LDSCRIPT_TEMPLATE = $(config.getLdscriptTemplatePath) export if $(not $(defined CRT_0_O)) CRT_0_O = crt0.o export ELFFile = $(ProgramELF $(config), $(name), $(files)) CCIFile = $(replacesuffixes $(EXT_ELF), $(EXT_CCI), $(ELFFile)) CIPFile = $(replacesuffixes $(EXT_ELF), $(EXT_CIP), $(ELFFile)) CSUFile = $(replacesuffixes $(EXT_ELF), $(EXT_CSU), $(ELFFile)) CXIFile = $(replacesuffixes $(EXT_ELF), $(EXT_CXI), $(ELFFile)) CIAFile = $(replacesuffixes $(EXT_ELF), $(EXT_CIA), $(ELFFile)) CDIFile = $(replacesuffixes $(EXT_ELF), $(EXT_CDI), $(ELFFile)) OLSFile = $(replacesuffixes $(EXT_ELF), $(EXT_OLS), $(ELFFile)) MAKEROM_INPUTS[] = $(EMPTY) MAKECIA_INPUTS[] = $(EMPTY) if $(not $(defined DESCRIPTOR)) DESCRIPTOR = $(config.getDefaultDescriptorPath) export if $(not $(defined ROMFS_DEPENDENCIES)) if $(defined ROMFS_ROOT) ROMFS_DEPENDENCIES = $(ls -R, $(dir $(ROMFS_ROOT))) export else ROMFS_DEPENDENCIES = export export if $(not $(defined ROM_SPEC_FILE)) ROM_SPEC_FILE = $(config.getDefaultRomSpecFile) export if $(not $(defined CTR_APPTYPE)) CTR_APPTYPE = $(APPTYPE_CARD) export if $(and $(defined CTR_NANDAPP),$(equal $(CTR_NANDAPP),true)) CTR_APPTYPE = $(APPTYPE_NAND) export if $(or \ $(and $(defined CTR_REMOVE_AMCORE), $(CTR_REMOVE_AMCORE)), \ $(and $(defined CTR_MAKESIMPLECIA), $(CTR_MAKESIMPLECIA)) \ ) MAKECIA = $(ROOT_COMMANDS)$(DIRSEP)ctr_makesimplecia32.exe export DEFAULT_ROM_SPEC_FILE = $(config.getDefaultRomSpecFile) # For manual if $(defined MANUAL_DIR) MANUAL_CFA = $(nth 0,$(FileArchive $(MANUAL_DIR), $(ROOT_RESOURCES)/specfiles/Manual.rsf)) MAKEROMFLAGS += -content $(MANUAL_CFA):1 MAKEROM_INPUTS += $(MANUAL_CFA) MAKECIAFLAGS += -i $(MANUAL_CFA):1 MAKECIA_INPUTS += $(MANUAL_CFA) export # For child if $(defined CHILD_APPS) MAKE_CIA_ARCHIVE = $(ROOT_COMMANDS)$(DIRSEP)ctr_makeciaarchive32.exe cia_archive_root = $(TARGET.getObjectDirectory)/cia_archive_root child_cfa = $(TARGET.getObjectDirectory)/childroot.cfa $(child_cfa): $(CHILD_APPS) $(makeDirectory $(cia_archive_root)) $(MAKE_CIA_ARCHIVE) :effects: $(cia_archive_root) $(MAKE_CIA_ARCHIVE) -cia $(CHILD_APPS) -rsf $(ROOT_RESOURCES)/specfiles/Child.rsf -o $@ --romfs-root $(cia_archive_root) MAKEROMFLAGS += -content $(child_cfa):2 MAKEROM_INPUTS += $(child_cfa) MAKECIAFLAGS += -i $(child_cfa):2 MAKECIA_INPUTS += $(child_cfa) export # For update partition if $(defined CTR_UPDATE_ARCHIVE) MAKEROMFLAGS += -content $(CTR_UPDATE_ARCHIVE):3 MAKEROM_INPUTS += $(CTR_UPDATE_ARCHIVE) MAKECIAFLAGS += -i $(CTR_UPDATE_ARCHIVE):3 MAKECIA_INPUTS += $(CTR_UPDATE_ARCHIVE) export # Dependent process variation forced specification if $(defined CTR_DEPENDENCY_VARIATION) MAKEROMFLAGS += -dv $(CTR_DEPENDENCY_VARIATION) export # For 1st stage updater if $(and $(defined CTR_BUILD_1ST_STAGE_UPDATER), $(CTR_BUILD_1ST_STAGE_UPDATER)) MAKEROMFLAGS += -temp export MAKEROMFLAGS += -desc $(DESCRIPTOR) -rsf $(ROM_SPEC_FILE) MAKEROMFLAGS += $(GetMakeromUserVariables) MAKEROMFLAGS += $(GetMakeromBannerOptions $(config)) MAKEROM_INPUTS += $(DESCRIPTOR) $(ROM_SPEC_FILE) $(DEFAULT_ROM_SPEC_FILE) $(ROMFS_DEPENDENCIES) $(GetBannerFile $(config)) $(GetIconFile $(config)) $(CCIFile): $(ELFFile) $(MAKEROM) $(MAKEROM_INPUTS) build-romfs :value: $(getMtimeIfLarge $(ELFFile)) $(MAKEROM) -o $@ $< $(MAKEROMFLAGS) -f card $(CIPFile): $(ELFFile) $(MAKEROM) $(MAKEROM_INPUTS) build-romfs :value: $(getMtimeIfLarge $(ELFFile)) $(MAKEROM) -o $@ $< $(MAKEROMFLAGS) -align 4 -cip $(CSUFile): $(ELFFile) $(MAKEROM) $(MAKEROM_INPUTS) build-romfs :value: $(getMtimeIfLarge $(ELFFile)) $(MAKEROM) -o $@ $< $(MAKEROMFLAGS) -f card $(CXIFile): $(ELFFile) $(MAKEROM) $(MAKEROM_INPUTS) build-romfs :value: $(getMtimeIfLarge $(ELFFile)) $(MAKEROM) -o $@ $< $(MAKEROMFLAGS) $(CDIFile): $(ELFFile) $(MAKEROM) $(MAKEROM_INPUTS) build-romfs :value: $(getMtimeIfLarge $(ELFFile)) $(MAKEROM) -o $@ $< $(MAKEROMFLAGS) -cdi $(CIAFile): $(CXIFile) $(MAKECIA) $(MAKECIA_INPUTS) :value: $(getMtimeIfLarge $(CXIFile)) $(MAKECIA) -i $< -o $@ $(MAKECIAFLAGS) if $(and $(defined CTR_MAKEOLSZIP), $(CTR_MAKEOLSZIP)) $(MAKEOLS) -i $< -o $@ $(MAKECIAFLAGS) # Determine file that will be the target CARD_IMAGE_FILE = $(CCIFile) if $(defined IS_CIP) CARD_IMAGE_FILE = $(CIPFile) export CARD_IMAGE_FILE if $(defined MAKECSU) CARD_IMAGE_FILE = $(CSUFile) export CARD_IMAGE_FILE # For NAND applications, generate CIA NAND_IMAGE_FILE = $(CIAFile) # Determine target according to the application type switch $(CTR_APPTYPE) case $(APPTYPE_CARD) TARGET_FILES = $(CARD_IMAGE_FILE) if $(and $(defined CTR_MAKE_DEVELOPMENT_IMAGE), $(CTR_MAKE_DEVELOPMENT_IMAGE)) TARGET_FILES += $(CDIFile) export export case $(APPTYPE_NAND) TARGET_FILES = $(NAND_IMAGE_FILE) export case $(APPTYPE_BOTH) TARGET_FILES = $(CARD_IMAGE_FILE) $(NAND_IMAGE_FILE) export # Create CDI only when CTR_MAKE_DEVELOPMENT_IMAGE is defined if $(and $(defined CTR_MAKE_DEVELOPMENT_IMAGE), $(CTR_MAKE_DEVELOPMENT_IMAGE)) TARGET_FILES += $(CDIFile) export # For testing export LIST_PREFIX if $(and $(defined BUILD_TESTS),$(equal $(BUILD_TESTS),true)) LIST_PREFIX = $(removesuffix $(basename $(CCIFile)))_ else LIST_PREFIX = $(EMPTY) # If the tree is referenced externally, determine whether to install INSTALL_TARGET_IMAGEDIR = $(config.getImageDirectory true) INSTALL_TARGETS = if $(or $(and $(config.isSdkTool),\ $(equal $(filter full,$(BUILDTYPES)),full)),\ $(and $(not $(config.isSdkTool)),\ $(not $(equal $(INSTALL_TARGET_IMAGEDIR), $(dirname $(CARD_IMAGE_FILE)))))) foreach(TARGET, $(TARGET_FILES)) INSTALL_TARGET = $(INSTALL_TARGET_IMAGEDIR)/$(basename $(TARGET)) $(INSTALL_TARGET): $(INSTALL_TARGET_IMAGEDIR) $(INSTALL_TARGET): $(TARGET) cp -f $< $@ INSTALL_TARGETS += $(INSTALL_TARGET) export INSTALL_TARGETS export INSTALL_TARGETS return $(TARGET_FILES) $(INSTALL_TARGETS) public.UserProcessTest(config, files) = name = $(removesuffix $(basename $(nth 0,$(files)))) BUILD_TESTS = true EXEFile = $(UserProcess $(config), $(name), $(files)) return $(EXEFile) public.Title(config, name, contents) = ELFFile = $(config.getBinaryPath $(name), $(EXT_ELF)) CCIFile = $(replacesuffixes $(EXT_ELF), $(EXT_CCI), $(ELFFile)) CXIFile = $(replacesuffixes $(EXT_ELF), $(EXT_CXI), $(ELFFile)) CIAFile = $(replacesuffixes $(EXT_ELF), $(EXT_CIA), $(ELFFile)) CDIFile = $(replacesuffixes $(EXT_ELF), $(EXT_CDI), $(ELFFile)) CARD_IMAGE_FILE = $(CCIFile) NAND_IMAGE_FILE = $(CIAFile) depends[] = if $(and $(defined CTR_NANDAPP),$(equal $(CTR_NANDAPP),true)) CTR_APPTYPE = $(APPTYPE_NAND) export switch $(CTR_APPTYPE) case $(APPTYPE_CARD) TARGET_FILES = $(CARD_IMAGE_FILE) export case $(APPTYPE_NAND) TARGET_FILES = $(NAND_IMAGE_FILE) export case $(APPTYPE_BOTH) TARGET_FILES = $(CARD_IMAGE_FILE) $(NAND_IMAGE_FILE) export MAKEROMFLAGS += -rsf $(ROM_SPEC_FILE) depends += $(ROM_SPEC_FILE) contentfiles[] = foreach(CONTENTSTR, $(contents)) contentseq = $(split >,$(CONTENTSTR)) index = $(nth 0,$(contentseq)) contentfile = $(nth 1,$(contentseq)) contentfiles += $(contentfile) MAKEROMFLAGS += -content $(contentfile):$(index) MAKECIAFLAGS += -i $(contentfile):$(index) $(CCIFile): :value: $(getMtimeIfLarge $(contentfile)) $(CIAFile): :value: $(getMtimeIfLarge $(contentfile)) export depends += $(contentfiles) # If the shared data title is only for CFA, will make so that major version will be separately set if $(not $(defined SHAREDDATATITLE_MAJOR_VERSION)) SHAREDDATATITLE_MAJOR_VERSION = 0 export if $(not $(equal $(suffix $(nth 0,$(contentfiles))), $(EXT_CXI))) MAKECIAFLAGS += -major $(SHAREDDATATITLE_MAJOR_VERSION) export $(CCIFile): $(makeDirectory $(dirname $(CCIFile))) $(CCIFile): $(MAKEROM) build-romfs $(depends) $(MAKEROM) -o $@ $(MAKEROMFLAGS) -f card $(CIAFile): $(makeDirectory $(dirname $(CIAFile))) $(CIAFile): $(MAKECIA) $(depends) $(MAKECIA) -o $@ $(MAKECIAFLAGS) return $(TARGET_FILES) public.FileArchive(srcdir, rsf) = name = $(basename $(srcdir)) SOURCES_BASE_ROOT = $(dirname $(srcdir)) CFAFile = $(makeDirectory $(getOutputBaseDirectory)$(DIRSEP)$(SUBDIR_OBJECTS)$(DIRSEP)$(getModuleSubDirectory))$(DIRSEP)$(name)$(EXT_CFA) if $(not $(defined ARCHIVE_DEPENDENCIES)) ARCHIVE_DEPENDENCIES = $(ls -R, $(dir $(srcdir))) export ARCHIVE_DEPENDENCIES += $(rsf) $(CFAFile): $(srcdir) $(CFAFile): $(makeDirectory $(dirname $(CFAFile))) $(CFAFile): $(srcdir) $(MAKEROM) $(rsf) $(ARCHIVE_DEPENDENCIES) $(MAKEROM) -o $@ -DROMFS_ROOT=$(srcdir) $(MAKEROMFLAGS) -f data -rsf $(rsf) return $(CFAFile) public.Banner(config, spec) = BannerFile = $(GetBannerFile $(config)) IconFile = $(GetIconFile $(config)) $(BannerFile) $(IconFile): $(spec) $(MAKEBANNER) mkdir -p $(dirname $(BannerFile)) $(MAKEBANNER) $< $(BannerFile) $(IconFile) return $(BannerFile) public.MakeDataCia(source, titleid) = name = $(rootname $(basename $(source))) CIAFile = $(getOutputBaseDirectory)$(DIRSEP)$(SUBDIR_IMAGES)$(DIRSEP)$(getModuleSubDirectory)$(DIRSEP)$(name)$(EXT_CIA) TARGET_FILES = $(CIAFile) $(CIAFile): $(makeDirectory $(dirname $(CIAFile))) $(CIAFile): $(source) $(MAKECIA) $(MAKECIA) -a $(source) -o $(CIAFile) -p $(titleid) -padding return $(TARGET_FILES) public.MakeSrlCia(srlfile) = name = $(rootname $(basename $(srlfile))) CIAFile = $(getOutputBaseDirectory)$(DIRSEP)$(SUBDIR_IMAGES)$(DIRSEP)$(getModuleSubDirectory)$(DIRSEP)$(name)$(EXT_CIA) TARGET_FILES = $(CIAFile) $(CIAFile): $(makeDirectory $(dirname $(CIAFile))) $(CIAFile): $(srlfile) $(MAKECIA) $(MAKECIA) -s $< -o $@ -padding return $(TARGET_FILES) public.InstallFiles(source_root, sources, destination) = destination = $(absname $(destination)) source_root = $(absname $(source_root)) sources = $(removeprefix $(source_root)$(DIRSEP), $(sources)) dfiles = $(addprefix $(destination)$(DIRSEP), $(sources)) .SUBDIRS: $(source_root) foreach(source, $(sources)) dfile = $(addprefix $(destination)$(DIRSEP), $(source)) $(dfile): $(source) mkdir -p $(dirname $(dfile)) ln-or-cp $(source) $(dfile) return $(dfiles) public.Filelist(destfile, filelist) = $(destfile): $(dirname $(destfile)) :value: $(filelist) section f = $(fopen $(@), w) foreach(filename, $(filelist)) fprintln($(f), $(filename)) close($(f)) return $(destfile) public.ParseDependProcess(config, process, depends) = RESULT_PROCESSES = export RESULT_PROCESSES foreach(DEPEND, $(depends)) if $(findstring $(DEPEND), $">") DEPEND_PAIR = $(split >, $(DEPEND)) PROCESS_KEY = $(nth 0, $(DEPEND_PAIR)) if $(equal $(process), $(PROCESS_KEY)) RESULT_PROCESSES += $(split $",", $(nth 1, $(DEPEND_PAIR))) else RESULT_PROCESSES += $(DEPEND) return $(RESULT_PROCESSES) # Target to execute before compiling all source files public.RequireSetup(targets) = .PHONY/$(ROOT)/build-setup: $(targets) public.DefineDefaultRules() = .DEFAULT: build all: build tests run: run-scripts %.log: run-scripts dotests run: $(RUNNER) :effects: $(RUNNER_LOCK) $(RunDependMCR $@) public.ShowConfig() = NOT_FOUND = $"Not found" println($"Environmental Variables/Automatic Settings--------------------------------------") println($" HORIZON_ROOT: " $(absname $(HORIZON_ROOT))) println($" HORIZON_ADDINS_ROOT: " $(HORIZON_ADDINS_ROOT)) println($" HORIZON_TARGETS: " $(if $(defined-env HORIZON_TARGETS), $`(getenv HORIZON_TARGETS))) println($" ARMLMD_LICENSE_FILE: " $(if $(defined-env ARMLMD_LICENSE_FILE), $`(getenv ARMLMD_LICENSE_FILE))) println($" $(RVCT_ENV_PREFIX)BIN: " $(if $(defined-env $(RVCT_ENV_PREFIX)BIN), $`(getenv $(RVCT_ENV_PREFIX)BIN))) if $(defined-env $(RVCT_ENV_PREFIX)BIN) ARMCC_VERSION = $(gsub $(string $(shell $"$(RVCT_BINDIR)armcc.exe" --help)), $" Usage:.*", $(EMPTY)) ARMASM_VERSION = $(gsub $(string $(shell $"$(RVCT_BINDIR)armasm.exe" --help)), $" Usage:.*", $(EMPTY)) ARMLINK_VERSION = $(gsub $(string $(shell $"$(RVCT_BINDIR)armlink.exe" --help)), $" Usage:.*", $(EMPTY)) ARMAR_VERSION = $(gsub $(string $(shell $"$(RVCT_BINDIR)armar.exe" --help)), $" - archive.*", $(EMPTY)) FROMELF_VERSION = $(gsub $(string $(shell $"$(RVCT_BINDIR)fromelf.exe" --help)), $"ARM image.*", $(EMPTY)) println($" - $(ARMCC_VERSION)") println($" - $(ARMASM_VERSION)") println($" - $(ARMLINK_VERSION)") println($" - $(ARMAR_VERSION)") println($" - $(FROMELF_VERSION)") println($" $(RVCT_ENV_PREFIX)INC: " $(if $(defined-env $(RVCT_ENV_PREFIX)INC), $`(getenv $(RVCT_ENV_PREFIX)INC))) println($" $(RVCT_ENV_PREFIX)LIB: " $(if $(defined-env $(RVCT_ENV_PREFIX)LIB), $`(getenv $(RVCT_ENV_PREFIX)LIB))) println($" ") println($"Project Settings ---------------------------------------") println($" ROOT: " $(absname $(ROOT))) println($" INSTALL_ROOT: " $(absname $(INSTALL_ROOT))) println($" INSTALL_ROOT_IMAGES: " $(absname $(INSTALL_ROOT_IMAGES))) println($" INSTALL_ROOT_LIBRARIES: " $(absname $(INSTALL_ROOT_LIBRARIES))) println($" ") println($"Programs ---------------------------------------------") GCC_VERSION = if $(GCC) GCC_VERSION = $`(gsub $(string $(shell $(GCC) --version)), $" Copyright.*", $(EMPTY)) export #OMAKE_VERSION_ = $`(gsub $(string $(shell omake --version)), $":.*", $(EMPTY)) println($" GCC: " $(if $(equal $(GCC), $(EMPTY)), $(NOT_FOUND), $`(GCC) [$`(GCC_VERSION)])) println($" RUBY: " $(if $(equal $(RUBY), $(EMPTY)), $(NOT_FOUND), $`(RUBY) [$`(RUBY_VERSION)])) println($" 7ZIP: " $(if $(equal $(7ZIP), $(EMPTY)), $(NOT_FOUND), $`(7ZIP))) println($" UNZIP: " $(if $(equal $(UNZIP), $(EMPTY)), $(NOT_FOUND), $`(UNZIP))) println($" ") .PHONY: show-config show-config: $(ShowConfig)