#---------------------------------------------------------------------------- # Project: Horizon # File: commondefs.funcs.om # # Copyright (C)2009-2011 Nintendo Co., Ltd. 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. # # $Rev: 41092 $ #---------------------------------------------------------------------------- # This file is only function definitions # Do not add anything other than function definitions #---------------------------------------------------------------------------- # Function definitions #---------------------------------------------------------------------------- #------------------------------------ # #------------------------------------ # Find the relative path from the project root. # When the path is in "sources" just below the root, "sources" is also removed GetSubPath(path) = private.apath = $(absname $(path)) private.subpath = $(removeprefix $(AROOT)$(DIRSEP), $(apath)) private.subpath = $(removeprefix sources$(DIRSEP), $(subpath)) if $(and \ $(or $(equal $(apath), $(subpath)), \ $(and $(defined FORCE_REFERENCE_ROOT), \ $(FORCE_REFERENCE_ROOT))), \ $(defined SOURCES_REFERENCE_ROOT)) private.subpath_refer = $(removeprefix $(absname $(SOURCES_REFERENCE_ROOT)), $(apath)) 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) = private.parent_path = $(absname $(parent_path)) private.child_path = $(absname $(child_path)) if $(equal $(removeprefix $(parent_path), $(child_path)), $(child_path)) return false else return true completeLibrarySuffix(config, libfiles) = private.result = foreach(libfile, $(libfiles)) if $(findstring $(libfile), $'\.(small)|(fast)(\.|$)') value $(libfile) else value $(libfile).$(config.effort) return $(result) private.Bin2ObjDefaultSymbolFunction(filename) = private.prefix = $(uppercase $(removesuffix $(basename $(filename)))) return $(prefix)_BEGIN $(prefix)_END private.CreateCmdFile(path, files) = private.f = $(fopen $(path),w) foreach(line, $(absname $(files))) fprint($(f),$'"') fprint($(f),$(line)) if $(and $(defined TARGET_MODULE),$(equal $(suffix $(line)),.a)) fprintln($(f),$'"(*)') else fprintln($(f),$'"') close($(f)) #------------------------------------ # Root definition #------------------------------------ #------------------------------------------------------- # AddRuleToMakeObjectFromC # # Overview # Add a rule to create .o from .c # Return the .o path # # Referenced global variables # None. #------------------------------------------------------- AddRuleToMakeObjectFromC(path, src, includes, flags, flags_build, flags_scan) = private.scanner_name = $(SCANNER_PREFIX)-c-$(fullname $(rootname $(path))) .SCANNER: $(scanner_name): $(src) .PHONY/$(ROOT)/build-setup :value: $(digest-in-path-optional_ $(includes), $&) $(CC) $(flags) $(flags_scan) $(CCOUT)$(absname $(path)) $(absname $<) $(path): $(src) :scanner: $(scanner_name) :value: $(getMtimeIfLarge $(src)) $(CC) $(flags) $(flags_build) -c $(CCOUT)$(absname $@) $(absname $<) $(path): $(nth 0, $(CC)) $(makeDirectory $(dirname $(path))) return $(path) #------------------------------------------------------- # AddRuleToMakeObjectFromCpp # # Description # Add a rule to create .o from .cpp # Return the .o path # # Referenced global variables # None. #------------------------------------------------------- AddRuleToMakeObjectFromCpp(path, src, includes, flags, flags_build, flags_scan) = private.scanner_name = $(SCANNER_PREFIX)-cxx-$(fullname $(rootname $(path))) .SCANNER: $(scanner_name): $(src) .PHONY/$(ROOT)/build-setup :value: $(digest-in-path-optional_ $(includes), $&) $(CXX) $(flags) $(flags_scan) $(CCOUT)$(absname $(path)) $(absname $<) $(path): $(src) :scanner: $(scanner_name) :value: $(getMtimeIfLarge $(src)) $(CXX) $(flags) $(flags_build) -c $(CCOUT)$(absname $@) $(absname $<) $(path): $(nth 0, $(CXX)) $(makeDirectory $(dirname $(path))) return $(path) #------------------------------------------------------- # AddRuleToMakeObjectFromAsm # # Description # Add a rule to create .o from .s # Return the .o path # # Referenced global variables # None. #------------------------------------------------------- AddRuleToMakeObjectFromAsm(path, src, flags, flags_build) = $(path): $(src) :effects: asmlock :value: $(getMtimeIfLarge $(src)) $(AS) $(flags) $(flags_build) $(ASOUT)$(absname $@) $(absname $<) $(path): $(nth 0, $(AS)) $(makeDirectory $(dirname $(path))) return $(path) #------------------------------------------------------- # AddRuleToInstall # # Description # Add rule to copy a file # Return the .o path # # Referenced global variables # None. #------------------------------------------------------- AddRuleToInstall(dst, src) = $(dst): $(makeDirectory $(dirname $(dst))) $(dst): $(src) cp $< $@ return $(dst) #------------------------------------------------------- # AddRuleToMakeStaticLibrary # # Description # Add a rule to create .a from .o list # Return the .a path # # Referenced global variables # None. #------------------------------------------------------- AddRuleToMakeStaticLibrary(lib, srcs) = $(lib): $(nth 0, $(AR)) $(lib): $(makeDirectory $(dirname $(lib))) $(lib): $(srcs) :value: $(getMtimeIfLarge $(srcs)) CreateCmdFile($@.res,$^) rm -f $(absname $@) $(AR) $(ARFLAGS) $(absname $@) --via $(absname $@.res) rm -f $@.res return $(lib) #------------------------------------------------------- # AddRuleToMakeObjectFromBinary # # Description # Add a rule to create .o from any file # Return the .o path # # Referenced global variables # None. #------------------------------------------------------- AddRuleToMakeObjectFromBinary(obj, bin, sympair, flags) = private.begin = $(nth 0, $(sympair)) private.end = $(nth 1, $(sympair)) $(obj): $(bin) $(BIN2OBJ) :value: $(getMtimeIfLarge $(bin)) $(BIN2OBJ) $(flags) -b $(begin) -e $(end) $< $@ return $(obj) #------------------------------------------------------- # AddRuleToPreProcess # # Description # Add a rule to apply a C preprocess process. # Return the result file path # # Referenced global variables # None. #------------------------------------------------------- AddRuleToPreProcess(outfile, infile, includes, flags, flags_scan) = private.scanner_name = $(SCANNER_PREFIX)-cpp-$(fullname $(rootname $(outfile))) private.outdir = $(makeDirectory $(dirname $(outfile))) .SCANNER: $(scanner_name): $(infile) .PHONY/$(ROOT)/build-setup :value: $(digest-in-path-optional_ $(includes), $&) $(CPP) $(flags) $(flags_scan) $(CCOUT)$(absname $(outfile)) $(absname $<) $(outfile): $(infile) $(outdir) :scanner: $(scanner_name) $(CPP) $(flags) $(CCOUT)$(absname $@) $(absname $<) return $(outfile) #------------------------------------------------------- # AddRuleToMakeElf # # Description # Add rule to create the ELF file # Return the ELF file path # # Referenced global variables # None. #------------------------------------------------------- AddRuleToMakeElf(elf, flags, files, depends) = private.dasm = $(file $(removesuffix $(elf))$(EXT_DASM)) $(elf): $(nth 0, $(LD)) $(elf): $(depends) :effects: $(dasm) :value: $(getMtimeIfLarge $(depends)) $(LD) $(LDOUT)$(absname $@) $(flags) $(set $(files)) $(if $(DISAS), $(DISAS) -o$(absname $(dasm)) $(absname $@)) return $(elf) #------------------------------------------------------- # AddRuleToMakeElfUsingCmdFile # # Description # Add a rule to create an ELF file via the option file # Return the ELF file path # # Referenced global variables # None. #------------------------------------------------------- AddRuleToMakeElfUsingCmdFile(elf, flags, files, depends) = private.dasm = $(file $(removesuffix $(elf))$(EXT_DASM)) $(elf): $(nth 0, $(LD)) $(makeDirectory $(dirname $(elf))) $(elf): $(depends) :effects: $(dasm) :value: $(getMtimeIfLarge $(depends)) CreateCmdFile($@.res,$(set $(files))) $(LD) $(LDOUT)$(absname $@) $(flags) $(LDRESP) $(absname $@.res) $(if $(DISAS), $(DISAS) -o$(absname $(dasm)) $(absname $@)) return $(elf) makeObjectPath(src) = private.oname = if $(not $(is_under $(CWD), $(src))) value $(rootname $(GetSubPath $(src)))$(EXT_OBJ) else value $(rootname $(src))$(EXT_OBJ) return $(file $(makePath $(obj_dir) $(oname))) # INCLUDES, CFLAGS, PREFIXED_INCLUDES, CSCANFLAGS, CCFLAGS_BUILD MakeObjectFromC(src) = private.dst = $(makeObjectPath $(src)) return $(AddRuleToMakeObjectFromC $(dst),$(src),$(INCLUDES),$(CFLAGS) $(PREFIXED_INCLUDES),$(CCFLAGS_BUILD),$(CSCANFLAGS)) # INCLUDES, CXXFLAGS, PREFIXED_INCLUDS, CSCANFLAGS, CCFLAGS_BUILD MakeObjectFromCpp(src) = private.dst = $(makeObjectPath $(src)) return $(AddRuleToMakeObjectFromCpp $(dst),$(src),$(INCLUDES),$(CXXFLAGS) $(PREFIXED_INCLUDES),$(CCFLAGS_BUILD),$(CSCANFLAGS)) # ASFLAGS, CCFLAGS_BUILD, PREFIXED_INCLUDES MakeObjectFromAsm(src) = private.dst = $(makeObjectPath $(src)) return $(AddRuleToMakeObjectFromAsm $(dst),$(src),$(ASFLAGS) $(PREFIXED_INCLUDES),$(CCFLAGS_BUILD)) #------------------------------------ # Build control #------------------------------------ #------------------------------------------------------- # ObjectOne # # Description # Perform an appropriate process according to the extension of the input file # Convert to the object file # Return the path to the generated object file # # Referenced global variables # COMPILER INCLUDES #------------------------------------------------------- ObjectOne(config, src, obj_dir) = CCFLAGS += $(COMPILER.getCCFlags $(config)) $(config.getSystemCCFlags) CCFLAGS_MACRO += $(COMPILER.getMacroFlags $(config)) ASFLAGS += $(COMPILER.getASFlags $(config)) INCLUDES = $(dir $(INCLUDES)) private.ofile = match $(src) case $"\($(EXT_C)\)$$" value $(MakeObjectFromC $(src)) case $"\(\.cpp\)$$" value $(MakeObjectFromCpp $(src)) case $"\($(EXT_ASM)\)$$" value $(MakeObjectFromAsm $(src)) default eprintln($"Unsupported source file: " '$(src)') exit(1) return $(ofile) #------------------------------------------------------- # Object # # Description # Apply ObjectOne to multiple input files # Return the ObjectOne result list # # Referenced global variables # None. #------------------------------------------------------- Object(config, srcs) = if $(not $(srcs)) return $(EMPTY) private.obj_dir_parent = $(config.getObjectDirectory) # Explicitly define rules for each file private.ofiles = foreach(filename, $(srcs)) if $(not $(equal $(filename),$(EMPTY))) value $(ObjectOne $(config), $(string $(filename)), $(obj_dir_parent)) clean: rm -rf $(obj_dir_parent) $(SUBDIR_OBJECTS) return $(stripEmpty $(ofiles)) #------------------------------------------------------- # StaticObject # # Description # Apply the Object, and copy the generated file to the specified location # Return the list of file paths after copying # # Referenced global variables # None. #------------------------------------------------------- StaticObject(config, srcs) = private.libdir = $(config.getLibraryDirectory true) private.ofiles = foreach(filename, $(srcs)) private.obj = $(ObjectOne $(config),$(filename),$(config.getObjectDirectory)) private.libpath = $(file $(libdir)/$(config.getStaticObjectName $(rootname $(filename)))) value $(AddRuleToInstall $(libpath),$(obj)) clean: rm -f $(ofiles) return $(ofiles) #------------------------------------------------------- # StaticLibrary # # Description # Appropriately process multiple input files according to their extensions # After converting to an object file, consolidate in an .a file # # Return the .a file path # # Referenced global variables # None. #------------------------------------------------------- StaticLibrary(config, name, files, libfiles) = private.libdir = $(config.getLibraryDirectory true) private.objs = $(filter %$(EXT_OBJ),$(files)) private.srcs = $(filter-out %$(EXT_OBJ),$(files)) private.ofiles = $(objs) $(Object $(config), $(srcs)) LIBDIR = $(config.getLibraryDirectory false) private.lfiles = foreach(lfile,$(libfiles)) match $(lfile) case $"/|\\" value $(file \ $(addsuffix $(EXT_LIB), \ $(completeLibrarySuffix $(config), \ $(replacesuffixes $(EXT_LIB), $"$(EMPTY)", $(lfile))))) default value $(file \ $(addprefix $(LIBDIR)$(DIRSEP), \ $(addsuffix $(EXT_LIB), \ $(completeLibrarySuffix $(config), $(lfile))))) private.libpath = $(file $(libdir)$(DIRSEP)$(config.getLibraryName $(name))) return $(AddRuleToMakeStaticLibrary $(libpath), $(ofiles) $(lfiles)) #------------------------------------------------------- # ObjectFromBinaryWithSymbol # # Description # Convert a file to an object file # Return the path to the generated object file # # Referenced global variables # BIN2OBJ_FLAGS #------------------------------------------------------- public.ObjectFromBinaryWithSymbol(config, files, symbol_function) = private.obj_dir_parent = $(config.getObjectDirectory) private.ofiles = foreach(filename, $(files)) private.ofile = $(file $(obj_dir_parent)/$(basename $(filename))$(EXT_OBJ)) private.symbol_pair = $(symbol_function $(filename)) $(ofile): $(obj_dir_parent) value $(AddRuleToMakeObjectFromBinary $(ofile),$(filename),$(symbol_pair),$(BIN2OBJ_FLAGS)) return $(ofiles) #------------------------------------------------------- # ObjectFromBinary # # Description # Convert a file to an object file # Use the default format in the generated symbol # Return the path to the generated object file # # Referenced global variables # None. #------------------------------------------------------- public.ObjectFromBinary(config, files) = return $(ObjectFromBinaryWithSymbol $(config), $(files), $(Bin2ObjDefaultSymbolFunction)) #------------------------------------------------------- # PreProcess # # Description # Create a file that has a C preprocess process applied # Return the file path after application # # Referenced global variables # CCFLAGS_MACRO COMPILER # INCLUDES CCFLAGS PREFIXED_INCLUDES CSCANFLAGS #------------------------------------------------------- public.PreProcess(config, infile, outfile) = CCFLAGS_MACRO += $(COMPILER.getMacroFlags $(config)) return $(AddRuleToPreProcess $(outfile),$(infile),$(INCLUDES),$(CCFLAGS) $(PREFIXED_INCLUDES),$(CSCANFLAGS)) #------------------------------------------------------- # InstallFiles # # Description # Copy multiple files # # Referenced global variables # None. #------------------------------------------------------- public.InstallFiles(source_root, sources, destination) = private.destination = $(absname $(destination)) private.source_root = $(absname $(source_root)) private.sources = $(removeprefix $(source_root)$(DIRSEP), $(sources)) private.dfiles = $(addprefix $(destination)$(DIRSEP), $(sources)) .SUBDIRS: $(source_root) foreach(source, $(sources)) private.dfile = $(addprefix $(destination)$(DIRSEP), $(source)) AddRuleToInstall($(dfile),$(source)) return $(dfiles) Elf(elf, flags, files, depends) = if $(equal $(LDRESP),$(EMPTY)) return $(AddRuleToMakeElf $(elf), $(flags), $(files), $(depends)) else return $(AddRuleToMakeElfUsingCmdFile $(elf), $(flags), $(files), $(depends)) #------------------------------------------------------- # ExecutableElf # # Description # Create an EXECUTABLE format ELF # # Referenced global variables # LIBDIR, LDFLAGS, COMPILER, MINIMUM_LIBS, DEFAULT_LIBS, # LIBS, TOOL, LIBFILES, CRT_0_O, MAPFILE, LDSCRIPT_TEMPLATE, # LDSCRIPT #------------------------------------------------------- ExecutableElf(config, name, files) = private.image_dir = $(config.getImageDirectory false) private.elf = $(config.getBinaryPath $(name), $(EXT_ELF)) LIBDIR = $(config.getLibraryDirectory false) LDFLAGS += $(COMPILER.getLDFlags $(config)) MINIMUM_LIBS += $(config.getMinimumLibraries) DEFAULT_LIBS += $(config.getDefaultLibraries) if $(config.isHostIoEnable) DEFAULT_LIBS += $(config.getHostIoLibraries) export private.ext_elfs = $(addprefix %, $(EXT_OBJ) $(EXT_ELF) $(EXT_PLF)) private.ofiles = $(Object $(config), $(filter-out $(ext_elfs),$(files))) $(filter $(ext_elfs),$(files)) private.lfiles = $(EMPTY) if $(not $(defined LDSCRIPT)) LDSCRIPT = export LDSCRIPT 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))) private.filtered_lfiles = $(filter-out $"$(EMPTY)",$(LIBS)) export lfiles export LDSCRIPT lfiles = $(file $(addprefix $(LIBDIR)$(DIRSEP), $(addsuffix $(EXT_LIB), $(completeLibrarySuffix $(config), $(filtered_lfiles))))) 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)))))) MAPFILE = $(config.getMapfilePath $(name)) export MAPFILE if $(defined LDSCRIPT_TEMPLATE) LDSCRIPT = $(PreProcess $(config), $(LDSCRIPT_TEMPLATE), $(absname $(config.getLdscriptPath $(name)))) $(LDSCRIPT): $(image_dir) if $(defined LDSCRIPT) $(elf): $(LDSCRIPT) clean: rm -rf $(image_dir) $(SUBDIR_IMAGES) return $(Elf $(elf), $(LDFLAGS), $(ofiles) $(lfiles), $(ofiles) $(lfiles)) #Program(config, name, files) = #------------------------------------ # Other #------------------------------------ # 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($" ") public.CGeneratedFiles(files) = CGeneratedFilesTarget: $(files) public.LocalCGeneratedFiles(files) = .SCANNER: scan-c-%: $(files) .SCANNER: scan-cxx-%: $(files) .SCANNER: %$(EXT_OBJ): $(files) export makePlatformDefsPath(name) = return $(ROOT_OMAKE)/platforms/$(TARGET_PLATFORM.Name)/$(TARGET_PLATFORM.Name).$(name).om IsTestBuild() = return $(filter dotests% tests, $(TARGETS)) IsDocumentBuild() = return $(filter documents clean-documents, $(TARGETS))