1#!/usr/bin/env omake
2#----------------------------------------------------------------------------
3# Project: Horizon
4# File:    commondefs.om
5#
6# Copyright 2007-2009 Nintendo. All rights reserved.
7#
8# These coded instructions, statements, and computer programs contain
9# proprietary information of Nintendo of America Inc. and/or Nintendo
10# Company Ltd., and are protected by Federal copyright law. They may
11# not be disclosed to third parties or copied or duplicated in any form,
12# in whole or in part, without the prior written consent of Nintendo.
13#
14# $Date:: 2011-02-10#$
15# $Rev: 34316 $
16# $Author: takiguchi_shinichi $
17#----------------------------------------------------------------------------
18
19# Load the OMake default library once only
20open build/Common
21
22SCANNER_MODE=disabled
23
24# Get directory root/environmental variable (can build even if not defined)
25public.HORIZON_ROOT =
26if $(defined-env HORIZON_ROOT)
27    HORIZON_ROOT = $(absname $"$(getenv HORIZON_ROOT)")
28    export
29
30if $(defined-env CTRSDK_ROOT)
31    CTRSDK_ROOT = $(absname $"$(getenv CTRSDK_ROOT)")
32    if $(and $(defined-env HORIZON_ROOT), $(not $(equal $(HORIZON_ROOT), $(CTRSDK_ROOT))))
33        eprintln(HORIZON_ROOT �� CTRSDK_ROOT ����v���܂���B�����pX��ݒ肷�邩�A�ǂ��炩����������`���ĉ������B)
34        exit(1)
35    HORIZON_ROOT = $(CTRSDK_ROOT)
36    export
37
38if $(defined-env CTRSDK_TARGETS)
39    CTRSDK_TARGETS = $(absname $"$(getenv CTRSDK_TARGETS)")
40    if $(defined-env HORIZON_TARGETS)
41        eprintln(HORIZON_TARGETS �� CTRSDK_TARGETS �͓����Ɏgp�ł��܂���̂ŁA�ǂ��炩����������`���ĉ������B)
42        exit(1)
43    HORIZON_TARGETS = $(CTRSDK_TARGETS)
44    export
45
46if $(not $(HORIZON_ROOT))
47    eprintln($"$$CTRSDK_ROOT is not defined")
48    HORIZON_ROOT = $(absname $(ROOT))
49    export
50
51public.HORIZON_ADDINS_ROOT =
52if $(defined-env HORIZON_ADDINS_ROOT)
53    HORIZON_ADDINS_ROOT = $(absname $"$(getenv HORIZON_ADDINS_ROOT)")
54    export
55else
56    HORIZON_ADDINS_ROOT = $(absname $(HORIZON_ROOT)/../CTR/Addins)
57    export
58    if $(not $(file-exists $(HORIZON_ADDINS_ROOT)))
59        HORIZON_ADDINS_ROOT =
60        export
61
62# Define directory
63public.SUBDIR_IMAGES    = images
64public.SUBDIR_SD_IMAGES = sdimages
65public.SUBDIR_OBJECTS   = objects
66public.SUBDIR_LIBRARIES = libraries
67public.SUBDIR_INCLUDE   = include
68public.DIRSUFFIX_FEEDBACK = .__feedback__
69public.SCANNER_PREFIX   = scan
70
71public.AROOT            = $(absname $(ROOT))
72
73public.ROOT_IMAGES      = $(absname $(ROOT)$(DIRSEP)$(SUBDIR_IMAGES))
74public.ROOT_OBJECTS     = $(absname $(ROOT)$(DIRSEP)$(SUBDIR_OBJECTS))
75public.ROOT_LIBRARIES   = $(absname $(HORIZON_ROOT)$(DIRSEP)$(SUBDIR_LIBRARIES))
76public.ROOT_BUILD       = $(absname $(HORIZON_ROOT)$(DIRSEP)build)
77public.ROOT_OMAKE       = $(absname $(ROOT_BUILD)$(DIRSEP)omake)
78public.ROOT_INCLUDE     = $(absname $(ROOT)$(DIRSEP)$(SUBDIR_INCLUDE))
79public.ROOT_SOURCES     = $(absname $(ROOT)$(DIRSEP)sources)
80public.ROOT_TOOLS       = $(absname $(HORIZON_ROOT)$(DIRSEP)tools)
81public.ROOT_TARGETTOOLS = $(absname $(HORIZON_ROOT)$(DIRSEP)tools$(DIRSEP)TargetTools)
82public.ROOT_COMMANDS    = $(absname $(ROOT_TOOLS)$(DIRSEP)CommandLineTools)
83public.ROOT_RESOURCES   = $(absname $(HORIZON_ROOT)$(DIRSEP)resources)
84
85public.HORIZON_ROOT_INCLUDE     = $(HORIZON_ROOT)$(DIRSEP)$(SUBDIR_INCLUDE)
86public.HORIZON_ROOT_IMAGES      = $(HORIZON_ROOT)$(DIRSEP)$(SUBDIR_IMAGES)
87public.HORIZON_ROOT_LIBRARIES   = $(HORIZON_ROOT)$(DIRSEP)$(SUBDIR_LIBRARIES)
88
89# Installation destination settings (prioritized as follows)
90# 1. Environmental variable HORIZON_INSTALL_ROOT
91# 2. Variable INSTALL_ROOT
92# 3. Variable HORIZON_ROOT
93if $(defined-env HORIZON_INSTALL_ROOT)
94    HORIZON_INSTALL_ROOT = $(dir $"$(getenv HORIZON_INSTALL_ROOT)")
95
96declare public.INSTALL_ROOT
97if $(defined HORIZON_INSTALL_ROOT)
98    INSTALL_ROOT    = $(dir $(HORIZON_INSTALL_ROOT))
99    export
100else
101    if $(defined INSTALL_ROOT)
102        INSTALL_ROOT    = $(dir $(INSTALL_ROOT))
103        export
104    elseif $(equal $(AROOT), $(HORIZON_ROOT))
105        INSTALL_ROOT    = $(ROOT)
106        export
107    export
108
109if $(not $(defined INSTALL_IMAGES_DIR))
110    INSTALL_IMAGES_DIR = $(SUBDIR_IMAGES)
111    export
112
113if $(defined INSTALL_ROOT)
114    INSTALL_ROOT_IMAGES     = $(dir $(INSTALL_ROOT)$(DIRSEP)$(INSTALL_IMAGES_DIR))
115    INSTALL_ROOT_LIBRARIES  = $(dir $(INSTALL_ROOT)$(DIRSEP)$(SUBDIR_LIBRARIES))
116    export
117
118public.HORIZON_PRIVATE_RULES = $(EMPTY)
119
120# Library for Horizon
121include $(ROOT_OMAKE)/utildefs
122include $(ROOT_OMAKE)/commondefs.cctype
123include $(ROOT_OMAKE)/commondefs.gl
124include $(ROOT_OMAKE)/targetdefs
125include $(ROOT_OMAKE)/packagedefs
126include $(ROOT_OMAKE)/debuggerdefs.partner
127
128# Incorporate individual settings
129if $(test -f $(ROOT_OMAKE)/localdefs.om)
130    include $(ROOT_OMAKE)/localdefs
131    export
132
133# Select compiler (TODO: create a switch interface)
134
135COMPILER = $(CompilerRVCT.new)
136
137# Extension settings
138
139EXT_OBJ = .o
140EXT_LIB = .a
141EXT_ASM = .s
142EXT_C   = .c
143
144EXT_EXE     = $(EXE)
145EXT_ELF     = .axf
146EXT_PLF     = .plf
147EXT_CCI     = .cci      # CTR Card Image
148EXT_CIP     = .cip      # CTR Initial Process
149EXT_CSU     = .csu      # CTR System Updater
150EXT_CXI     = .cxi      # CTR eXecutable Image
151EXT_CIA     = .cia      # CTR Importable Archive
152EXT_CDI     = .cdi      # CTR Development Image
153EXT_OLS     = .ols.cia
154EXT_CFA     = .cfa      # CTR File Archive
155EXT_BANNER  = .bnr
156EXT_ICON    = .icn
157
158EXT_PUB = .pubbin
159EXT_PRI = .pribin
160
161# Application type setting
162
163APPTYPE_CARD = CARD
164APPTYPE_NAND = NAND
165APPTYPE_BOTH = BOTH
166
167# Settings for rules for Horizon
168
169public.MAKEROM      = $(ROOT_COMMANDS)$(DIRSEP)ctr_makerom32.exe
170public.MAKECIA      = $(ROOT_COMMANDS)$(DIRSEP)ctr_makecia32.exe
171public.MAKEOLS      = $(ROOT_COMMANDS)$(DIRSEP)ctr_makeols32.exe
172public.MAKEBANNER   = $(ROOT_COMMANDS)$(DIRSEP)ctr_makebanner32.exe
173
174public.MAKEROMFLAGS =
175public.MAKECIAFLAGS =
176
177public.BIN2OBJ      = $(file $(ROOT_COMMANDS)/ctr_bin2obj32$(EXE))
178public.BIN2OBJ_FLAGS=
179public.RUNNER       = $(file $(ROOT_BUILD)/runner/run.sh)
180public.RUNNER_LOCK  = $(file $(ROOT_BUILD)/runner/.lock)
181
182# Parameter variables
183
184if $(not $(defined SKIP_BUILD))
185    public.SKIP_BUILD = false
186    export
187
188if $(not $(defined DEBUG_PRINT))
189    public.DEBUG_PRINT      = $`(DEBUG_PRINT_DEFAULT)
190    export
191
192if $(not $(defined DEBUG_PRINT_SDK))
193    public.DEBUG_PRINT_SDK  = $`(DEBUG_PRINT_SDK_DEFAULT)
194    export
195
196if $(not $(defined ASSERT_WARNING))
197    public.ASSERT_WARNING   = $`(ASSERT_WARNING_DEFAULT)
198    export
199
200if $(not $(defined ASSERT_WARNING_SDK))
201    public.ASSERT_WARNING_SDK = $`(ASSERT_WARNING_SDK_DEFAULT)
202    export
203
204if $(not $(defined HOST_IO))
205    public.HOST_IO          = $`(HOST_IO_DEFAULT)
206    export
207
208public.SOURCES =
209public.OBJECTS =
210
211public.BUILD_APPLICATION = false
212public.BUILD_KERNEL      = false
213
214public.FEEDBACK_1ST_STAGE = false
215public.FEEDBACK_2ND_STAGE = false
216
217public.EXCLUSION_SCATTER = false
218
219if $(not $(defined TRACE_PRODUCTCODE))
220    public.TRACE_PRODUCTCODE =
221    export
222
223# Variable to have the user specify a directory matching the build target and build type
224public.BUILD_TARGET_DIR      =   $`(TARGET.getFullnameWithSystem Process)
225public.BUILD_TYPE_DIR        =   $`(TARGET.buildtype)
226
227# Utility functions
228
229# Find the relative path from the project root.
230# When the path is in "sources" just below the root, "sources" is also removed
231GetSubPath(path) =
232    apath = $(absname $(path))
233    #println(target: $(apath))
234
235    subpath = $(removeprefix  $(AROOT)$(DIRSEP), $(apath))
236    subpath = $(removeprefix sources$(DIRSEP), $(subpath))
237
238    if $(and                                            \
239         $(or $(equal $(apath), $(subpath)),            \
240              $(and $(defined FORCE_REFERENCE_ROOT),    \
241                    $(FORCE_REFERENCE_ROOT))),           \
242         $(defined SOURCES_REFERENCE_ROOT))
243        subpath_refer = $(removeprefix $(absname $(SOURCES_REFERENCE_ROOT)), $(apath))
244        #println(subpath_refer: $(subpath_refer))
245        return $(subpath_refer)
246    else
247        if $(equal $(subpath), $(apath))
248            eprintln($"Trying to build a file outside the tree.: $(apath)")
249            eprintln($"Specify a base directory manually with SOURCES_REFERENCE_ROOT.")
250            return $(basename $(apath))
251    return $(subpath)
252
253# Check the parent-child relationship of the directories
254is_under(parent_path, child_path) =
255    parent_path = $(absname $(parent_path))
256    child_path  = $(absname $(child_path))
257    if $(equal $(removeprefix $(parent_path), $(child_path)), $(child_path))
258        return false
259    else
260        return true
261
262
263GetBuildGroup() =
264    return group$(mod $(random), 10)
265
266IsTestBuild() =
267    return $(filter test tests dotest dotests dotests-%, $(TARGETS))
268
269IsDocumentBuild() =
270    return $(filter documents clean-documents, $(TARGETS))
271
272# Create an object file
273public.Object(config, files) =
274    if $(and $(FEEDBACK_1ST_STAGE), $(FEEDBACK_2ND_STAGE))
275        eprintln(FEEDBACK error)
276        exit(1)
277
278    CCFLAGS        += $(COMPILER.getCCFlags $(config)) $(config.getSystemCCFlags)
279    CCFLAGS_MACRO  += $(COMPILER.getMacroFlags $(config)) -DNN_USE_MAKECCI
280    ASFLAGS        += $(COMPILER.getASFlags $(config))
281
282    INCLUDES        = $(dir $(INCLUDES))
283
284    DEPEND_FEEDBACK = false
285    if $(FEEDBACK_2ND_STAGE)
286        # 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).
287        FEEDBACK = $(config.getFeedBackPath)
288        CCFLAGS_BUILD += --feedback=$(absname $(FEEDBACK))
289        if $(test ! -e $(FEEDBACK))
290            #
291            #
292            #
293            DEPEND_FEEDBACK = true
294            export
295        export
296
297    OFILES =
298    export OFILES
299
300    obj_dir_parent = $(config.getObjectDirectory)
301
302    CC              = $,(CC)
303    CXX             = $,(CXX)
304    CFLAGS          = $,(CFLAGS)
305    CCFLAGS         = $,(CCFLAGS)
306    CXXFLAGS        = $,(CXXFLAGS)
307
308    .PHONY: build-random group1 group2 group3 group4 group5 group6 group7 group8 group9 group0
309    build-random: group1 group2 group3 group4 group5 group6 group7 group8 group9 group0
310
311    # Explicitly defines rules for each file
312    foreach(filename, $(files))
313        if $(not $(equal $(filename), $(EMPTY)))
314            if $(not $(is_under $(CWD), $(filename)))
315                ONAME = $(rootname $(GetSubPath $(filename)))$(EXT_OBJ)
316                export
317            else
318                ONAME = $(rootname $(filename))$(EXT_OBJ)
319                export
320
321            OFILE = $(file $(obj_dir_parent)/$(ONAME))
322            ODIR  = $(makeDirectory $(dirname $(OFILE)))
323
324            $(OFILE): $(ODIR)
325
326            match $(filename)
327            case $"\($(EXT_C)\)$$"
328                scanner_name = $(SCANNER_PREFIX)-c-$(fullname $(rootname $(OFILE)))
329                .SCANNER: $(scanner_name): $(filename) .PHONY/$(ROOT)/build-setup :value: $(digest-in-path-optional $(INCLUDES), $&)
330                    $(CC) $(CFLAGS) $(PREFIXED_INCLUDES) $(CSCANFLAGS) $(CCOUT)$(absname $(OFILE)) $(absname $<)
331
332                $(OFILE): $(filename) :scanner: $(scanner_name)
333                    $(CC) $(CFLAGS) $(CCFLAGS_BUILD) $(PREFIXED_INCLUDES) -c $(CCOUT)$(absname $@) $(absname $<)
334
335                $(OFILE): $(nth 0, $(CC))
336
337                $(GetBuildGroup): $(OFILE)
338
339            case $"\(\.cpp\)$$"
340                EXT = $1
341                scanner_name = $(SCANNER_PREFIX)-cxx-$(fullname $(rootname $(OFILE)))
342                .SCANNER: $(scanner_name): $(filename) .PHONY/$(ROOT)/build-setup :value: $(digest-in-path-optional $(INCLUDES), $&)
343                    $(CXX) $(CXXFLAGS) $(PREFIXED_INCLUDES) $(CSCANFLAGS) $(CCOUT)$(absname $(OFILE)) $(absname $<)
344
345                $(OFILE): $(filename) :scanner: $(scanner_name)
346                    $(CXX) $(CXXFLAGS) $(CCFLAGS_BUILD) $(PREFIXED_INCLUDES) -c $(CCOUT)$(absname $@) $(absname $<)
347
348                $(OFILE): $(nth 0, $(CXX))
349
350                $(GetBuildGroup): $(OFILE)
351
352            case $"\($(EXT_ASM)\)$$"
353                 $(OFILE): $(filename) :effects: asmlock
354                    $(AS) $(ASFLAGS) $(CCFLAGS_BUILD) $(PREFIXED_INCLUDES) $(ASOUT)$(absname $@) $(absname $<)
355
356                 $(OFILE): $(nth 0, $(AS))
357
358            default
359                eprintln($"Unsupported source file: " '$(filename)')
360                exit(1)
361
362            # When compiling using feedback, depends on the feedback file
363            # When rules are defined individually, the dependency relationship must also be specified individually
364            if $(DEPEND_FEEDBACK)
365                $(OFILE): $(config.getFeedBackPath)
366
367            OFILES += $(OFILE)
368
369    clean:
370        rm -rf $(obj_dir_parent) $(SUBDIR_OBJECTS)
371
372    return $(OFILES)
373
374public.Bin2ObjDefaultSymbolFunction(filename) =
375    SYMBOL_PREFIX = $(uppercase $(removesuffix $(basename $(filename))))
376    return $(SYMBOL_PREFIX)_BEGIN $(SYMBOL_PREFIX)_END
377
378public.Bin2ObjHashSymbolFunction(filename) =
379    SYMBOL_PREFIX = $(uppercase $(removesuffix $(basename $(filename))))
380    return $(SYMBOL_PREFIX)_HASH_BEGIN $(SYMBOL_PREFIX)_HASH_END
381
382
383public.ObjectFromBinaryWithSymbol(config, files, symbol_function) =
384    OFILES =
385
386    obj_dir_parent = $(config.getObjectDirectory)
387
388    foreach(filename, $(files))
389        OFILE = $(file $(obj_dir_parent)/$(basename $(filename))$(EXT_OBJ))
390        OFILES += $(OFILE)
391
392        SYMBOL_PAIR = $(symbol_function $(filename))
393        $(OFILE): $(filename) $(BIN2OBJ) :value: $(getMtimeIfLarge $(filename))
394            $(BIN2OBJ) $(BIN2OBJ_FLAGS) -b $(nth 0, $(SYMBOL_PAIR)) -e $(nth 1, $(SYMBOL_PAIR)) $< $@
395
396        $(OFILE): $(obj_dir_parent)
397
398        export OFILES
399    return $(OFILES)
400
401
402public.ObjectFromBinary(config, files) =
403    return $(ObjectFromBinaryWithSymbol $(config), $(files), $(Bin2ObjDefaultSymbolFunction))
404
405public.HashFromBinary(config, files) =
406    EXT_HASH = .hash
407    HFILES =
408
409    obj_dir_parent = $(config.getObjectDirectory)
410    foreach(filename, $(files))
411        HFILE = $(file $(obj_dir_parent)/$(basename $(filename))$(EXT_HASH)$(EXT_OBJ))
412        HFILES += $(HFILE)
413
414        SYMBOL_PAIR = $(Bin2ObjHashSymbolFunction $(filename))
415        $(HFILE): $(filename) $(BIN2OBJ)
416            $(RUBY) -e "require 'Digest/md5'; STDOUT.binmode; print [Digest::SHA1.hexdigest(File.open('$(filename)', 'rb').read)].pack('H*');" > $@
417            $(BIN2OBJ) $(BIN2OBJ_FLAGS) -b $(nth 0, $(SYMBOL_PAIR)) -e $(nth 1, $(SYMBOL_PAIR)) $@ $@
418
419        $(HFILE): $(obj_dir_parent)
420
421        export HFILES
422    return $(HFILES)
423
424%.c: %.y
425    $(YACC) $<
426
427%.c: %.l
428    $(LEX) $<
429
430public.PreProcess(config, infile, outfile) =
431    CCFLAGS_MACRO  += $(COMPILER.getMacroFlags $(config)) -DNN_USE_MAKECCI
432
433    scanner_name = $(SCANNER_PREFIX)-cpp-$(fullname $(rootname $(outfile)))
434
435    .SCANNER: $(scanner_name): $(infile) .PHONY/$(ROOT)/build-setup :value: $(digest-in-path-optional $(INCLUDES), $&)
436        $(CPP) $(CCFLAGS) $(PREFIXED_INCLUDES) $(CSCANFLAGS) $(CCOUT)$(absname $(outfile)) $(absname $<)
437
438    outdir = $(makeDirectory $(dirname $(outfile)))
439
440    $(outfile): $(infile) $(outdir) :scanner: $(scanner_name)
441        $(CPP) $(CCFLAGS) $(PREFIXED_INCLUDES) $(CCOUT)$(absname $@) $(absname $<)
442    return $(outfile)
443
444#
445# Default C scanner
446#
447
448.PHONY: CGeneratedFilesTarget
449
450public.CGeneratedFiles(files) =
451    CGeneratedFilesTarget: $(files)
452
453public.LocalCGeneratedFiles(files) =
454    .SCANNER: scan-c-%: $(files)
455    .SCANNER: scan-cxx-%: $(files)
456    .SCANNER: %$(EXT_OBJ): $(files)
457    export
458
459
460.PHONY: build-romfs
461
462public.StaticLibrary(config, name, files) =
463    private.LIBDIR = $(config.getLibraryDirectory true)
464    private.OFILES = $(Object $(config), $(filter-out %$(EXT_OBJ),$(files))) $(filter %$(EXT_OBJ),$(files))
465    private.NORMALLIB = $(file $(LIBDIR)$(DIRSEP)$(config.getLibraryName $(name)))
466
467    $(NORMALLIB): $(LIBDIR) $(nth 0, $(AR))
468    $(NORMALLIB): $(OFILES)
469        echo $(absname $^) > $@.res
470        rm -f $(absname $@)
471        $(AR) $(ARFLAGS) $(absname $@) --via $(absname $@.res)
472        rm -f $@.res
473
474    clean:
475        rm -f $(NORMALLIB)
476
477    .PHONY: build-random group1 group2 group3 group4 group5 group6 group7 group8 group9 group0
478    build-random: group1 group2 group3 group4 group5 group6 group7 group8 group9 group0
479    $(GetBuildGroup): $(NORMALLIB)
480
481    return $(NORMALLIB)
482
483
484public.StaticObject(config, files) =
485    private.LIBDIR = $(config.getLibraryDirectory true)
486
487    SOFILES =
488    foreach(filename, $(files))
489        private.OFILE = $(Object $(config), $(filename))
490
491        private.NORMALLIB = $(file $(LIBDIR)/$(config.getStaticObjectName $(rootname $(filename))))
492
493        $(NORMALLIB): $(LIBDIR)
494        $(NORMALLIB): $(OFILE)
495            cp $< $@
496
497        SOFILES += $(NORMALLIB)
498        export SOFILES
499
500    clean:
501        rm -f $(SOFILES)
502
503    return $(SOFILES)
504
505
506completeLibrarySuffix(config, libfiles) =
507    result =
508    foreach(libfile, $(libfiles))
509        if $(findstring $(libfile), $'\.(small)|(fast)(\.|$)')
510            result += $(libfile)
511            export
512        else
513            result += $(libfile).$(config.effort)
514            export
515        export
516    return $(result)
517
518public.Program(config, name, files) =
519    FEEDBACK_FILE       = $(config.getFeedBackPath)
520    private.IMAGE_DIR   = $(config.getImageDirectory false)
521    LIBDIR              = $(config.getLibraryDirectory false)
522    NAME                = $(config.getBinaryPath $(name), $(EXT_EXE))
523    LDFLAGS            += $(COMPILER.getLDFlags $(config))
524
525    MINIMUM_LIBS       += $(config.getMinimumLibraries)
526    DEFAULT_LIBS       += $(config.getDefaultLibraries)
527    if $(config.isHostIoEnable)
528        DEFAULT_LIBS   += $(config.getHostIoLibraries)
529        export
530
531    EXT_DIRECT          = $(addprefix %, $(EXT_OBJ) $(EXT_ELF) $(EXT_PLF))
532    OFILES              = $(Object $(config), $(filter-out $(EXT_DIRECT),$(files))) $(filter $(EXT_DIRECT),$(files))
533    DASM                = $(file $(removesuffix $(NAME)).dasm)
534
535    if $(filter %$(EXT_LIB), $(LIBS))
536        eprintln($""!!! WARNING: the LIBS variable should contain libraries _without_ extensions."")
537        LIBS = $(replacesuffixes $(EXT_LIB), $"$(EMPTY)", $(LIBS))
538        export
539
540    if $(not $(and $(defined TOOL), $(TOOL)))
541        FILTERED_LFILES = $(filter-out $"$(EMPTY)",$(LIBS))
542        LFILES          = $(file $(addprefix $(LIBDIR)$(DIRSEP), $(addsuffix $(EXT_LIB), $(completeLibrarySuffix $(config), $(FILTERED_LFILES)))))
543        LFILES         += $(file $(addsuffix $(EXT_LIB), $(completeLibrarySuffix $(config), $(replacesuffixes $(EXT_LIB), $"$(EMPTY)", $(LIBFILES)))))
544        LFILES         += $(file $(addsuffix $(EXT_LIB), $(completeLibrarySuffix $(config), $(replacesuffixes $(EXT_LIB), $"$(EMPTY)", $(LIBFILES)))))
545        LFILES         += $(file $(addsuffix $(EXT_LIB), $(completeLibrarySuffix $(config), $(replacesuffixes $(EXT_LIB), $"$(EMPTY)", $(LIBFILES)))))
546
547        if $(and $(defined CRT_0_O),$(not $(equal $(LDRESP),$(EMPTY))))
548            LFILES += $(file $(addprefix $(LIBDIR)$(DIRSEP), $(addsuffix $(EXT_OBJ), $(completeLibrarySuffix $(config), $(removesuffix $(CRT_0_O))))))
549            export
550
551        MAPFILE         = $(config.getMapfilePath $(name))
552        export MAPFILE
553
554        if $(defined LDSCRIPT_TEMPLATE)
555            LDSCRIPT        = $(PreProcess $(config), $(LDSCRIPT_TEMPLATE), $(absname $(config.getLdscriptPath $(name))))
556            export
557
558            $(LDSCRIPT): $(IMAGE_DIR)
559
560            if $(FEEDBACK_1ST_STAGE)
561                $(FEEDBACK_FILE): $(LDSCRIPT)
562            else
563                $(NAME): $(LDSCRIPT) :effects: $(MAPFILE)
564        export
565
566    else
567        LFILES          =
568
569        $(NAME): $(IMAGE_DIR)
570        export
571
572    if $(equal $(LDRESP),$(EMPTY))
573        $(NAME): $(OFILES) $(LFILES) :effects: $(DASM)
574            $(LD) $(LDOUT)$(absname $@) $(LDFLAGS) $^
575            $(if $(DISAS), $(DISAS) -o$(absname $(DASM)) $(absname $@))
576
577        if $(FEEDBACK_1ST_STAGE)
578            eprintln(feed back is not supported.)
579    else
580        if $(FEEDBACK_1ST_STAGE)
581            $(FEEDBACK_FILE): $(OFILES) $(LFILES)
582                echo $(absname $^) > $@.res
583                $(LD) $(LDOUT)$(absname $(NAME)) $(LDFLAGS) $(LDRESP) $(absname $@.res)
584                grep -v $"^;.+Last Updated:" $@.tmp > $@
585        else
586            # Rule not used with FEEDBACK_1ST_STAGE.
587            $(NAME): $(OFILES) $(LFILES) :effects: $(DASM)
588                echo $(absname $^) > $@.res
589                $(LD) $(LDOUT)$(absname $@) $(LDFLAGS) $(LDRESP) $(absname $@.res)
590                $(if $(DISAS), $(DISAS) -o$(absname $(DASM)) $(absname $@))
591
592    $(NAME): $(nth 0, $(LD))
593
594    clean:
595        rm -rf $(IMAGE_DIR) $(SUBDIR_IMAGES)
596
597    if $(FEEDBACK_1ST_STAGE)
598        return $(FEEDBACK_FILE)
599    else
600        return $(NAME)
601
602public.ProgramELF(config, name, files) =
603    EXT_EXE     = $(EXT_ELF)
604    return $(Program $(config), $(name), $(files))
605
606public.Tool(config, name, files) =
607    TOOL        = true
608    return $(Program $(config), $(name), $(files))
609
610public.InstallTool(files) =
611    install_files =
612    export install_files
613    foreach(filename, $(files))
614        install_file = $(file $(ROOT_COMMANDS)$(DIRSEP)$(basename $(filename)))
615        $(install_file): $(filename)
616            cp -f $< $@
617        install_files += $(install_file)
618    return $(install_files)
619
620public.GetMakeromUserVariables()=
621    if $(not $(defined ROMFS_ROOT))
622        ROMFS_ROOT =
623        export
624
625    if $(not $(defined TITLE))
626        TITLE = CtrApp
627        export
628
629    FLAGS =
630
631    FLAGS += -DROMFS_ROOT=$(ROMFS_ROOT)
632    FLAGS += -DTITLE=$(TITLE)
633    return $(FLAGS)
634
635public.GetBannerFile(config) =
636    BannerFile = $(config.getDefaultBannerFile)
637    if $(defined CTR_BANNER_SPEC)
638        base    = $(removesuffix $(CTR_BANNER_SPEC))
639        BannerFile = $(addprefix $(config.getObjectDirectory)$(DIRSEP), $(addsuffixes $(EXT_BANNER), $(base)))
640        export
641    else
642        if $(defined CTR_BANNER)
643            BannerFile = $(CTR_BANNER)
644            export
645        elseif $(or $(and $(defined CTR_NO_BANNER_ICON), $(equal $(CTR_NO_BANNER_ICON), true)), \
646                    $(and $(defined CTR_NO_BANNER), $(equal $(CTR_NO_BANNER), true))            )
647            BannerFile =
648            export
649        export
650    return $(BannerFile)
651
652public.GetIconFile(config) =
653    IconFile = $(config.getDefaultIconFile)
654    if $(defined CTR_BANNER_SPEC)
655        base     = $(removesuffix $(CTR_BANNER_SPEC))
656        IconFile = $(addprefix $(config.getObjectDirectory)$(DIRSEP), $(addsuffixes $(EXT_ICON), $(base)))
657        export
658    else
659        if $(defined CTR_ICON)
660            IconFile = $(CTR_ICON)
661            export
662        elseif $(and $(defined CTR_NO_BANNER_ICON), $(equal $(CTR_NO_BANNER_ICON), true))
663            IconFile =
664            export
665        export
666    return $(IconFile)
667
668public.GetMakeromBannerOptions(config) =
669    if $(defined CTR_BANNER_SPEC)
670        if $(or $(defined CTR_BANNER), $(defined CTR_ICON))
671            eprintln($"CTR_BANNER CTR_ICON and CTR_BANNER_SPEC cannot be used simultaneously")
672            exit(1)
673
674    options =
675    BannerFile = $(GetBannerFile $(config))
676    IconFile = $(GetIconFile $(config))
677    if $(not $(equal $(BannerFile.length), 0))
678        options += -banner $(BannerFile)
679        export
680
681    if $(not $(equal $(IconFile.length), 0))
682        options += -icon $(IconFile)
683        export
684
685    return $(options)
686
687public.UserProcess(config, name, files) =
688    BUILD_APPLICATION = true
689
690    if $(not $(defined LDSCRIPT_TEMPLATE))
691        LDSCRIPT_TEMPLATE = $(config.getLdscriptTemplatePath)
692        export
693
694    if $(not $(defined CRT_0_O))
695        CRT_0_O   = crt0.o
696        export
697
698    ELFFile = $(ProgramELF $(config), $(name), $(files))
699    CCIFile = $(replacesuffixes $(EXT_ELF), $(EXT_CCI), $(ELFFile))
700    CIPFile = $(replacesuffixes $(EXT_ELF), $(EXT_CIP), $(ELFFile))
701    CSUFile = $(replacesuffixes $(EXT_ELF), $(EXT_CSU), $(ELFFile))
702    CXIFile = $(replacesuffixes $(EXT_ELF), $(EXT_CXI), $(ELFFile))
703    CIAFile = $(replacesuffixes $(EXT_ELF), $(EXT_CIA), $(ELFFile))
704    CDIFile = $(replacesuffixes $(EXT_ELF), $(EXT_CDI), $(ELFFile))
705    OLSFile = $(replacesuffixes $(EXT_ELF), $(EXT_OLS), $(ELFFile))
706
707    MAKEROM_INPUTS[] = $(EMPTY)
708    MAKECIA_INPUTS[] = $(EMPTY)
709
710    if $(not $(defined DESCRIPTOR))
711        DESCRIPTOR = $(config.getDefaultDescriptorPath)
712        export
713
714    if $(not $(defined ROMFS_DEPENDENCIES))
715        if $(defined ROMFS_ROOT)
716            ROMFS_DEPENDENCIES = $(ls -R, $(dir $(ROMFS_ROOT)))
717            export
718        else
719            ROMFS_DEPENDENCIES =
720            export
721        export
722
723
724    if $(not $(defined ROM_SPEC_FILE))
725        ROM_SPEC_FILE = $(config.getDefaultRomSpecFile)
726        export
727
728    if $(not $(defined CTR_APPTYPE))
729        CTR_APPTYPE = $(APPTYPE_CARD)
730        export
731
732    if $(and $(defined CTR_NANDAPP),$(equal $(CTR_NANDAPP),true))
733        CTR_APPTYPE = $(APPTYPE_NAND)
734        export
735
736    if $(or  \
737       $(and $(defined CTR_REMOVE_AMCORE), $(CTR_REMOVE_AMCORE)), \
738       $(and $(defined CTR_MAKESIMPLECIA), $(CTR_MAKESIMPLECIA))  \
739    )
740        MAKECIA = $(ROOT_COMMANDS)$(DIRSEP)ctr_makesimplecia32.exe
741        export
742
743    DEFAULT_ROM_SPEC_FILE = $(config.getDefaultRomSpecFile)
744
745    # For manual
746    if $(defined MANUAL_DIR)
747        MANUAL_CFA = $(nth 0,$(FileArchive $(MANUAL_DIR), $(ROOT_RESOURCES)/specfiles/Manual.rsf))
748
749        MAKEROMFLAGS += -content $(MANUAL_CFA):1
750        MAKEROM_INPUTS += $(MANUAL_CFA)
751
752        MAKECIAFLAGS += -i $(MANUAL_CFA):1
753        MAKECIA_INPUTS += $(MANUAL_CFA)
754        export
755
756    # For child
757    if $(defined CHILD_APPS)
758        MAKE_CIA_ARCHIVE    =   $(ROOT_COMMANDS)$(DIRSEP)ctr_makeciaarchive32.exe
759        cia_archive_root    =   $(TARGET.getObjectDirectory)/cia_archive_root
760        child_cfa           =   $(TARGET.getObjectDirectory)/childroot.cfa
761        $(child_cfa): $(CHILD_APPS) $(makeDirectory $(cia_archive_root)) $(MAKE_CIA_ARCHIVE) :effects: $(cia_archive_root)
762            $(MAKE_CIA_ARCHIVE) -cia $(CHILD_APPS) -rsf $(ROOT_RESOURCES)/specfiles/Child.rsf -o $@ --romfs-root $(cia_archive_root)
763
764        MAKEROMFLAGS += -content $(child_cfa):2
765        MAKEROM_INPUTS += $(child_cfa)
766
767        MAKECIAFLAGS += -i $(child_cfa):2
768        MAKECIA_INPUTS += $(child_cfa)
769
770        export
771
772    # For update partition
773    if $(defined CTR_UPDATE_ARCHIVE)
774        MAKEROMFLAGS   += -content $(CTR_UPDATE_ARCHIVE):3
775        MAKEROM_INPUTS += $(CTR_UPDATE_ARCHIVE)
776
777        MAKECIAFLAGS   += -i $(CTR_UPDATE_ARCHIVE):3
778        MAKECIA_INPUTS += $(CTR_UPDATE_ARCHIVE)
779        export
780
781    # Dependent process variation forced specification
782    if $(defined CTR_DEPENDENCY_VARIATION)
783        MAKEROMFLAGS    +=  -dv $(CTR_DEPENDENCY_VARIATION)
784        export
785
786    # For 1st stage updater
787    if $(and $(defined CTR_BUILD_1ST_STAGE_UPDATER), $(CTR_BUILD_1ST_STAGE_UPDATER))
788        MAKEROMFLAGS    +=  -temp
789        export
790
791    MAKEROMFLAGS += -desc $(DESCRIPTOR) -rsf $(ROM_SPEC_FILE)
792    MAKEROMFLAGS += $(GetMakeromUserVariables)
793    MAKEROMFLAGS += $(GetMakeromBannerOptions $(config))
794    MAKEROM_INPUTS += $(DESCRIPTOR) $(ROM_SPEC_FILE) $(DEFAULT_ROM_SPEC_FILE) $(ROMFS_DEPENDENCIES) $(GetBannerFile $(config)) $(GetIconFile $(config))
795
796    $(CCIFile): $(ELFFile) $(MAKEROM) $(MAKEROM_INPUTS) build-romfs :value: $(getMtimeIfLarge $(ELFFile))
797        $(MAKEROM) -o $@ $< $(MAKEROMFLAGS) -f card
798
799    $(CIPFile): $(ELFFile) $(MAKEROM) $(MAKEROM_INPUTS) build-romfs :value: $(getMtimeIfLarge $(ELFFile))
800        $(MAKEROM) -o $@ $< $(MAKEROMFLAGS) -align 4 -cip
801
802    $(CSUFile): $(ELFFile) $(MAKEROM) $(MAKEROM_INPUTS) build-romfs :value: $(getMtimeIfLarge $(ELFFile))
803        $(MAKEROM) -o $@ $< $(MAKEROMFLAGS) -f card
804
805    $(CXIFile): $(ELFFile) $(MAKEROM) $(MAKEROM_INPUTS) build-romfs :value: $(getMtimeIfLarge $(ELFFile))
806        $(MAKEROM) -o $@ $< $(MAKEROMFLAGS)
807
808    $(CDIFile): $(ELFFile) $(MAKEROM) $(MAKEROM_INPUTS) build-romfs :value: $(getMtimeIfLarge $(ELFFile))
809        $(MAKEROM) -o $@ $< $(MAKEROMFLAGS) -cdi
810
811    $(CIAFile): $(CXIFile) $(MAKECIA) $(MAKECIA_INPUTS) :value: $(getMtimeIfLarge $(CXIFile))
812        $(MAKECIA) -i $< -o $@ $(MAKECIAFLAGS)
813        if $(and $(defined CTR_MAKEOLSZIP), $(CTR_MAKEOLSZIP))
814            $(MAKEOLS) -i $< -o $@ $(MAKECIAFLAGS)
815
816    # Determine file that will be the target
817    CARD_IMAGE_FILE = $(CCIFile)
818    if $(defined IS_CIP)
819        CARD_IMAGE_FILE = $(CIPFile)
820        export CARD_IMAGE_FILE
821
822    if $(defined MAKECSU)
823        CARD_IMAGE_FILE = $(CSUFile)
824        export CARD_IMAGE_FILE
825
826    # For NAND applications, generate CIA
827    NAND_IMAGE_FILE = $(CIAFile)
828
829    # Determine target according to the application type
830    switch $(CTR_APPTYPE)
831    case $(APPTYPE_CARD)
832        TARGET_FILES = $(CARD_IMAGE_FILE)
833        if $(and $(defined CTR_MAKE_DEVELOPMENT_IMAGE), $(CTR_MAKE_DEVELOPMENT_IMAGE))
834            TARGET_FILES += $(CDIFile)
835            export
836        export
837    case $(APPTYPE_NAND)
838        TARGET_FILES = $(NAND_IMAGE_FILE)
839        export
840    case $(APPTYPE_BOTH)
841        TARGET_FILES = $(CARD_IMAGE_FILE) $(NAND_IMAGE_FILE)
842        export
843
844    # Create CDI only when CTR_MAKE_DEVELOPMENT_IMAGE is defined
845    if $(and $(defined CTR_MAKE_DEVELOPMENT_IMAGE), $(CTR_MAKE_DEVELOPMENT_IMAGE))
846        TARGET_FILES += $(CDIFile)
847        export
848
849    # For testing
850    export LIST_PREFIX
851    if $(and $(defined BUILD_TESTS),$(equal $(BUILD_TESTS),true))
852        LIST_PREFIX = $(removesuffix $(basename $(CCIFile)))_
853    else
854        LIST_PREFIX = $(EMPTY)
855
856    # If the tree is referenced externally, determine whether to install
857    INSTALL_TARGET_IMAGEDIR = $(config.getImageDirectory true)
858    INSTALL_TARGETS =
859    if $(or $(and $(config.isSdkTool),\
860                  $(equal $(filter full,$(BUILDTYPES)),full)),\
861            $(and $(not $(config.isSdkTool)),\
862                  $(not $(equal $(INSTALL_TARGET_IMAGEDIR), $(dirname $(CARD_IMAGE_FILE))))))
863
864        foreach(TARGET, $(TARGET_FILES))
865            INSTALL_TARGET = $(INSTALL_TARGET_IMAGEDIR)/$(basename $(TARGET))
866            $(INSTALL_TARGET): $(INSTALL_TARGET_IMAGEDIR)
867            $(INSTALL_TARGET): $(TARGET)
868                cp -f $< $@
869            INSTALL_TARGETS += $(INSTALL_TARGET)
870            export INSTALL_TARGETS
871        export INSTALL_TARGETS
872
873    return $(TARGET_FILES) $(INSTALL_TARGETS)
874
875public.UserProcessTest(config, files) =
876    name = $(removesuffix $(basename $(nth 0,$(files))))
877
878    BUILD_TESTS = true
879    EXEFile = $(UserProcess $(config), $(name), $(files))
880
881    return $(EXEFile)
882
883public.Title(config, name, contents) =
884    ELFFile = $(config.getBinaryPath $(name), $(EXT_ELF))
885    CCIFile = $(replacesuffixes $(EXT_ELF), $(EXT_CCI), $(ELFFile))
886    CXIFile = $(replacesuffixes $(EXT_ELF), $(EXT_CXI), $(ELFFile))
887    CIAFile = $(replacesuffixes $(EXT_ELF), $(EXT_CIA), $(ELFFile))
888    CDIFile = $(replacesuffixes $(EXT_ELF), $(EXT_CDI), $(ELFFile))
889
890    CARD_IMAGE_FILE = $(CCIFile)
891    NAND_IMAGE_FILE = $(CIAFile)
892
893    depends[] =
894
895    if $(and $(defined CTR_NANDAPP),$(equal $(CTR_NANDAPP),true))
896        CTR_APPTYPE = $(APPTYPE_NAND)
897        export
898
899    switch $(CTR_APPTYPE)
900    case $(APPTYPE_CARD)
901        TARGET_FILES = $(CARD_IMAGE_FILE)
902        export
903    case $(APPTYPE_NAND)
904        TARGET_FILES = $(NAND_IMAGE_FILE)
905        export
906    case $(APPTYPE_BOTH)
907        TARGET_FILES = $(CARD_IMAGE_FILE) $(NAND_IMAGE_FILE)
908        export
909
910    MAKEROMFLAGS += -rsf $(ROM_SPEC_FILE)
911    depends += $(ROM_SPEC_FILE)
912
913    contentfiles[] =
914
915    foreach(CONTENTSTR, $(contents))
916        contentseq = $(split >,$(CONTENTSTR))
917
918        index = $(nth 0,$(contentseq))
919        contentfile = $(nth 1,$(contentseq))
920
921        contentfiles += $(contentfile)
922
923        MAKEROMFLAGS += -content $(contentfile):$(index)
924        MAKECIAFLAGS += -i $(contentfile):$(index)
925        $(CCIFile): :value: $(getMtimeIfLarge $(contentfile))
926        $(CIAFile): :value: $(getMtimeIfLarge $(contentfile))
927        export
928
929    depends += $(contentfiles)
930
931    # If the shared data title is only for CFA, will make so that major version will be separately set
932    if $(not $(defined SHAREDDATATITLE_MAJOR_VERSION))
933        SHAREDDATATITLE_MAJOR_VERSION = 0
934        export
935
936    if $(not $(equal $(suffix $(nth 0,$(contentfiles))), $(EXT_CXI)))
937        MAKECIAFLAGS += -major $(SHAREDDATATITLE_MAJOR_VERSION)
938        export
939
940    $(CCIFile): $(makeDirectory $(dirname $(CCIFile)))
941    $(CCIFile): $(MAKEROM) build-romfs  $(depends)
942        $(MAKEROM) -o $@ $(MAKEROMFLAGS) -f card
943
944    $(CIAFile): $(makeDirectory $(dirname $(CIAFile)))
945    $(CIAFile): $(MAKECIA) $(depends)
946        $(MAKECIA) -o $@ $(MAKECIAFLAGS)
947
948    return $(TARGET_FILES)
949
950public.FileArchive(srcdir, rsf) =
951    name = $(basename $(srcdir))
952    SOURCES_BASE_ROOT = $(dirname $(srcdir))
953    CFAFile = $(makeDirectory $(getOutputBaseDirectory)$(DIRSEP)$(SUBDIR_OBJECTS)$(DIRSEP)$(getModuleSubDirectory))$(DIRSEP)$(name)$(EXT_CFA)
954
955    if $(not $(defined ARCHIVE_DEPENDENCIES))
956        ARCHIVE_DEPENDENCIES = $(ls -R, $(dir $(srcdir)))
957        export
958    ARCHIVE_DEPENDENCIES += $(rsf)
959
960    $(CFAFile): $(srcdir)
961    $(CFAFile): $(makeDirectory $(dirname $(CFAFile)))
962    $(CFAFile): $(srcdir) $(MAKEROM) $(rsf) $(ARCHIVE_DEPENDENCIES)
963        $(MAKEROM) -o $@ -DROMFS_ROOT=$(srcdir) $(MAKEROMFLAGS) -f data -rsf $(rsf)
964
965    return $(CFAFile)
966
967public.Banner(config, spec) =
968    BannerFile  = $(GetBannerFile $(config))
969    IconFile    = $(GetIconFile $(config))
970    $(BannerFile) $(IconFile): $(spec) $(MAKEBANNER)
971        mkdir -p $(dirname $(BannerFile))
972        $(MAKEBANNER) $< $(BannerFile) $(IconFile)
973
974    return $(BannerFile)
975
976public.MakeDataCia(source, titleid) =
977    name = $(rootname $(basename $(source)))
978    CIAFile = $(getOutputBaseDirectory)$(DIRSEP)$(SUBDIR_IMAGES)$(DIRSEP)$(getModuleSubDirectory)$(DIRSEP)$(name)$(EXT_CIA)
979
980    TARGET_FILES = $(CIAFile)
981
982    $(CIAFile): $(makeDirectory $(dirname $(CIAFile)))
983    $(CIAFile): $(source) $(MAKECIA)
984        $(MAKECIA) -a $(source) -o $(CIAFile) -p $(titleid) -padding
985
986    return $(TARGET_FILES)
987
988public.MakeSrlCia(srlfile) =
989    name = $(rootname $(basename $(srlfile)))
990    CIAFile = $(getOutputBaseDirectory)$(DIRSEP)$(SUBDIR_IMAGES)$(DIRSEP)$(getModuleSubDirectory)$(DIRSEP)$(name)$(EXT_CIA)
991
992    TARGET_FILES = $(CIAFile)
993
994    $(CIAFile): $(makeDirectory $(dirname $(CIAFile)))
995    $(CIAFile): $(srlfile) $(MAKECIA)
996        $(MAKECIA) -s $< -o $@ -padding
997
998    return $(TARGET_FILES)
999
1000public.InstallFiles(source_root, sources, destination) =
1001    destination = $(absname $(destination))
1002    source_root = $(absname $(source_root))
1003    sources     = $(removeprefix $(source_root)$(DIRSEP), $(sources))
1004
1005    dfiles = $(addprefix $(destination)$(DIRSEP), $(sources))
1006
1007    .SUBDIRS: $(source_root)
1008        foreach(source, $(sources))
1009            dfile = $(addprefix $(destination)$(DIRSEP), $(source))
1010            $(dfile): $(source)
1011                mkdir -p $(dirname $(dfile))
1012                ln-or-cp $(source) $(dfile)
1013
1014    return $(dfiles)
1015
1016public.Filelist(destfile, filelist) =
1017    $(destfile): $(dirname $(destfile)) :value: $(filelist)
1018        section
1019            f = $(fopen $(@), w)
1020            foreach(filename, $(filelist))
1021                fprintln($(f), $(filename))
1022            close($(f))
1023    return $(destfile)
1024
1025public.ParseDependProcess(config, process, depends) =
1026    RESULT_PROCESSES =
1027    export RESULT_PROCESSES
1028    foreach(DEPEND, $(depends))
1029        if $(findstring $(DEPEND), $">")
1030            DEPEND_PAIR = $(split >, $(DEPEND))
1031            PROCESS_KEY = $(nth 0, $(DEPEND_PAIR))
1032            if $(equal $(process), $(PROCESS_KEY))
1033                RESULT_PROCESSES += $(split $",", $(nth 1, $(DEPEND_PAIR)))
1034        else
1035            RESULT_PROCESSES += $(DEPEND)
1036
1037    return $(RESULT_PROCESSES)
1038
1039# Target to execute before compiling all source files
1040public.RequireSetup(targets) =
1041    .PHONY/$(ROOT)/build-setup: $(targets)
1042
1043public.DefineDefaultRules() =
1044
1045    .DEFAULT: build
1046
1047    all: build tests
1048
1049    run: run-scripts
1050
1051    %.log: run-scripts
1052
1053    dotests run: $(RUNNER) :effects: $(RUNNER_LOCK)
1054        $(RunDependMCR $@)
1055
1056public.ShowConfig() =
1057    NOT_FOUND = $"Not found"
1058    println($"Environmental Variables/Automatic Settings--------------------------------------")
1059    println($"  HORIZON_ROOT:           " $(absname $(HORIZON_ROOT)))
1060    println($"  HORIZON_ADDINS_ROOT:    " $(HORIZON_ADDINS_ROOT))
1061    println($"  HORIZON_TARGETS:        " $(if $(defined-env HORIZON_TARGETS),                   $`(getenv HORIZON_TARGETS)))
1062    println($"  ARMLMD_LICENSE_FILE:    " $(if $(defined-env ARMLMD_LICENSE_FILE),               $`(getenv ARMLMD_LICENSE_FILE)))
1063    println($"  $(RVCT_ENV_PREFIX)BIN:              " $(if $(defined-env $(RVCT_ENV_PREFIX)BIN), $`(getenv $(RVCT_ENV_PREFIX)BIN)))
1064    if $(defined-env $(RVCT_ENV_PREFIX)BIN)
1065        ARMCC_VERSION   = $(gsub $(string $(shell $"$(RVCT_BINDIR)armcc.exe" --help)),   $" Usage:.*", $(EMPTY))
1066        ARMASM_VERSION  = $(gsub $(string $(shell $"$(RVCT_BINDIR)armasm.exe" --help)),  $" Usage:.*", $(EMPTY))
1067        ARMLINK_VERSION = $(gsub $(string $(shell $"$(RVCT_BINDIR)armlink.exe" --help)), $" Usage:.*", $(EMPTY))
1068        ARMAR_VERSION   = $(gsub $(string $(shell $"$(RVCT_BINDIR)armar.exe" --help)),   $" - archive.*", $(EMPTY))
1069        FROMELF_VERSION = $(gsub $(string $(shell $"$(RVCT_BINDIR)fromelf.exe" --help)), $"ARM image.*", $(EMPTY))
1070
1071        println($"                           - $(ARMCC_VERSION)")
1072        println($"                           - $(ARMASM_VERSION)")
1073        println($"                           - $(ARMLINK_VERSION)")
1074        println($"                           - $(ARMAR_VERSION)")
1075        println($"                           - $(FROMELF_VERSION)")
1076    println($"  $(RVCT_ENV_PREFIX)INC:              " $(if $(defined-env $(RVCT_ENV_PREFIX)INC),           $`(getenv $(RVCT_ENV_PREFIX)INC)))
1077    println($"  $(RVCT_ENV_PREFIX)LIB:              " $(if $(defined-env $(RVCT_ENV_PREFIX)LIB),           $`(getenv $(RVCT_ENV_PREFIX)LIB)))
1078
1079    println($" ")
1080    println($"Project Settings ---------------------------------------")
1081    println($"  ROOT:                   " $(absname $(ROOT)))
1082    println($"  INSTALL_ROOT:           " $(absname $(INSTALL_ROOT)))
1083    println($"  INSTALL_ROOT_IMAGES:    " $(absname $(INSTALL_ROOT_IMAGES)))
1084    println($"  INSTALL_ROOT_LIBRARIES: " $(absname $(INSTALL_ROOT_LIBRARIES)))
1085    println($" ")
1086    println($"Programs ---------------------------------------------")
1087
1088    GCC_VERSION =
1089    if $(GCC)
1090        GCC_VERSION = $`(gsub $(string $(shell $(GCC) --version)), $" Copyright.*", $(EMPTY))
1091        export
1092
1093    #OMAKE_VERSION_ = $`(gsub $(string $(shell omake --version)), $":.*", $(EMPTY))
1094    println($"  GCC:                    " $(if $(equal $(GCC),   $(EMPTY)), $(NOT_FOUND), $`(GCC) [$`(GCC_VERSION)]))
1095    println($"  RUBY:                   " $(if $(equal $(RUBY),  $(EMPTY)), $(NOT_FOUND), $`(RUBY) [$`(RUBY_VERSION)]))
1096    println($"  7ZIP:                   " $(if $(equal $(7ZIP),  $(EMPTY)), $(NOT_FOUND), $`(7ZIP)))
1097    println($"  UNZIP:                  " $(if $(equal $(UNZIP), $(EMPTY)), $(NOT_FOUND), $`(UNZIP)))
1098    println($" ")
1099
1100.PHONY: show-config
1101show-config:
1102    $(ShowConfig)
1103
1104