1#!/usr/bin/env omake
2#----------------------------------------------------------------------------
3# Project: Horizon
4# File:    targetdefs.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-01-18#$
15# $Rev: 33556 $
16# $Author: hatamoto_minoru $
17#----------------------------------------------------------------------------
18
19public.DEFAULT_FILTER = CTR-TS*MPCore*
20
21# Function to get directory not dependent on the target
22getOutputBaseDirectory() =
23    abs_cwd = $(absname $(CWD))
24    #println(abs_cwd: $(abs_cwd))
25    # Is the project root HORIZON_ROOT? (SDK build?)
26    if $(equal $(AROOT), $(HORIZON_ROOT))
27        return $(dir $(HORIZON_ROOT))
28
29    # Is the current directory in HORIZON_ROOT?
30    subdir = $(removeprefix $(HORIZON_ROOT), $(abs_cwd))
31    if $(not $(equal $(subdir), $(abs_cwd)))
32        #println("UNDER HORIZON: "$(abs_cwd))
33        return $(dir $(HORIZON_ROOT))
34
35    # Is there a sources directory in the project root?
36    subdir = $(removeprefix $(AROOT)\\sources\\, $(abs_cwd))
37    if $(not $(equal $(subdir), $(abs_cwd)))
38        #println("SOURCES EXIST: "$(abs_cwd))
39        return $(ROOT)
40
41    #println(subdir: $(subdir))
42    # Output to current directory
43    return $(dir .)
44
45getModuleOutputSubDirectoryOf(module_dir, sub_dir) =
46    if $(defined SOURCES_BASE_ROOT)
47        module_dir = $(SOURCES_BASE_ROOT)
48        export
49
50    abs_dir = $(absname $(module_dir))
51    subpath = $(removeprefix  $(AROOT)$(DIRSEP), $(abs_dir))
52    subpath = $(removeprefix sources$(DIRSEP), $(subpath))
53
54    # Is the project root HORIZON_ROOT? (SDK build?)
55    if $(equal $(AROOT), $(HORIZON_ROOT))
56        return $(dir $(HORIZON_ROOT)/$(sub_dir)/$(subpath))
57
58    # Is the current directory in HORIZON_ROOT?
59    subdir = $(removeprefix $(HORIZON_ROOT), $(abs_dir))
60    if $(not $(equal $(subdir), $(abs_dir)))
61        return $(dir $(HORIZON_ROOT)/$(sub_dir)/$(subpath))
62
63    # Is there a sources directory in the project root?
64    subdir = $(removeprefix $(AROOT)\\sources\\, $(abs_dir))
65    if $(not $(equal $(subdir), $(abs_dir)))
66        return $(dir $(ROOT)/$(sub_dir)/$(subpath))
67
68    # Output to target directory
69    return $(dir $(module_dir)$(DIRSEP)$(sub_dir))
70
71getModuleImageSubDirectoryOf(module_dir) =
72    return $(getModuleOutputSubDirectoryOf $(module_dir), $(SUBDIR_IMAGES))
73
74getModuleObjectsSubDirectoryOf(module_dir) =
75    return $(getModuleOutputSubDirectoryOf $(module_dir), $(SUBDIR_OBJECTS))
76
77# Get the subdirectory name where generated items are stored from the source path name
78getModuleSubDirectory() =
79    if $(defined SOURCES_BASE_ROOT)
80        basedir = $(SOURCES_BASE_ROOT)
81        export
82    else
83        basedir = $(CWD)
84        export
85    #println(basedir: $(basedir))
86    if $(equal $(ROOT), $(basedir))
87        return .
88
89    basedir = $(absname $(basedir))
90    subpath = $(removeprefix  $(AROOT)$(DIRSEP), $(basedir))
91    subpath = $(removeprefix sources$(DIRSEP), $(subpath))
92    return $(subpath)
93
94getObjectBaseDirectory() =
95    base_dir = $(getOutputBaseDirectory)
96    if $(equal ., $(base_dir))
97        module_dir =
98        export
99    else
100        module_dir = $(getModuleSubDirectory)$(DIRSEP)
101        export
102    return $(base_dir)$(DIRSEP)$(SUBDIR_OBJECTS)$(DIRSEP)$(module_dir)
103
104TargetSpec. =
105    class TargetSpec
106
107    processor   =
108    platform    =
109    hardware    =
110
111    new(name) =
112        this.name = $(name)
113        return $(this)
114
115    dump() =
116        println($"name: "$(name))
117        println($"  platform:   "$(platform))
118        println($"  hardware:   "$(hardware))
119        println($"  processors: "$(processors))
120        println($' ')
121
122    getMacroFlags(systemname, processor) =
123        return $(EMPTY)
124
125TargetConfig. =
126    class TargetConfig
127
128    hardware    =
129    systemname  =
130    processor   =
131    effort      =
132    buildtype   =
133    matched     = true
134
135    new() =
136        return $(this)
137
138    dump() =
139        println($"hardware: "$(hardware))
140        println($"  processor: "$(processor))
141        println($' ')
142
143    getFullname() =
144        return $(hardware).$(systemname).$(processor).$(effort)
145
146    getFullnameWithSystem(altsystemname) =
147        return $(hardware).$(altsystemname).$(processor).$(effort)
148
149    getFullnameWithSystemAndEffort(altsystemname, alteffort) =
150        return $(hardware).$(altsystemname).$(processor).$(alteffort)
151
152    getScannerName() =
153        return $(getFullname)-$(buildtype)$(if $(FEEDBACK_1ST_STAGE),.f)
154
155    getObjectDirectory() =
156        dir_suffix =
157        if $(FEEDBACK_1ST_STAGE)
158            dir_suffix = $(DIRSUFFIX_FEEDBACK)
159            export
160
161        return $(makeDirectory $(getObjectBaseDirectory)$(DIRSEP)$(getTargetSubDirectory false)$(dir_suffix))
162
163    getObjectDirectory() =
164        if $(FEEDBACK_1ST_STAGE)
165            return $(getObjectDirectoryFeedback true)
166
167        return $(getObjectDirectoryFeedback false)
168
169    getObjectDirectoryFeedback(isFeedback) =
170        dir_suffix =
171        if $(isFeedback)
172            dir_suffix = $(DIRSUFFIX_FEEDBACK)
173            export
174
175        return $(makeDirectory $(getModuleObjectsSubDirectoryOf $(CWD))$(DIRSEP)$(getTargetSubDirectory false)$(dir_suffix))
176
177    getLibraryDirectory(isInstall) =
178        if $(and $(isInstall), $(defined INSTALL_ROOT))
179            return $(makeDirectory $(INSTALL_ROOT_LIBRARIES)$(DIRSEP)$(getTargetSubDirectory true))
180        else
181            return $(makeDirectory $(HORIZON_ROOT_LIBRARIES)$(DIRSEP)$(getTargetSubDirectory true))
182
183    isTestBuild() =
184        if $(not $(defined BUILD_TESTS))
185            return false
186        else
187            return $(BUILD_TESTS)
188
189    getOutputBaseDirectory() =
190        return $(getOutputBaseDirectory)
191
192    getImageDirectory(isInstall) =
193        module_dir = $(getModuleSubDirectory)$(DIRSEP)
194
195        if $(and $(isInstall), $(isSdkTool))
196            images_dir = $(ROOT_TARGETTOOLS)
197            return $(makeDirectory $(images_dir)$(DIRSEP)$(hardware)$(DIRSEP)$(buildtype))
198            export
199        elseif $(and $(isInstall), $(defined INSTALL_ROOT))
200            # Installation directory
201            images_dir = $(INSTALL_ROOT_IMAGES)
202            export
203        else
204            base_dir = $(getOutputBaseDirectory)
205            if $(equal ., $(base_dir))
206                module_dir =
207                export
208            images_dir = $(base_dir)$(DIRSEP)$(SUBDIR_IMAGES)
209            export
210
211        # When building a test, the path rules change
212        if $(isTestBuild)
213            module_dir = tests$(DIRSEP)$(gsub $(module_dir), $"\$(DIRSEP)tests?(\$(DIRSEP)|$$)", $(DIRSEP))
214            export
215
216        return $(makeDirectory $(images_dir)$(DIRSEP)$(module_dir)$(getTargetSubDirectory false))
217
218    getImageDirectoryOf(target_dir) =
219        images_dir = $(getModuleImageSubDirectoryOf $(target_dir))
220        return $(dir $(images_dir)$(DIRSEP)$(getTargetSubDirectory false))
221
222    isSdkTool() =
223        if $(and $(defined INSTALL_SDK_TOOL), $(INSTALL_SDK_TOOL), \
224             $(equal $(systemname), Process), \
225             $(equal $(processor), MPCore), \
226             $(equal $(effort), fast))
227            return true
228        else
229            return false
230
231
232    getOptimizeType() =
233        opttype =
234            switch($(buildtype))
235            case Debug
236                value noopt
237            case Development
238                value verbose
239            case Release
240                value release
241            default
242                value etc
243        return $(opttype)
244
245    getTargetSubDirectory(isLibrary) =
246        subdir = $(hardware).$(systemname).$(processor)
247        if $(isLibrary)
248            return $(subdir)$(DIRSEP)$(getOptimizeType)
249        else
250            return $(subdir).$(effort)$(DIRSEP)$(buildtype)
251
252    getLibraryName(name) =
253        return $(name).$(effort)$(EXT_LIB)
254
255    getStaticObjectName(name) =
256        return $(basename $(name)).$(effort)$(EXT_OBJ)
257
258    getLdscriptPath(name) =
259        return $(getBinaryPath $(name), $".autogen.ldscript")
260
261    getMapfilePath(name) =
262        return $(getBinaryPath $(name), $".map")
263
264    getLdscriptTemplatePath() =
265        base = $(ROOT_BUILD)$(DIRSEP)linker$(DIRSEP)$(platform).$(systemname).$(processor)
266        if $(and $(equal $(processor), ARM946ES) $(equal $(hardware), CTR-CTTS))
267            return $(file $(base).Legacy.ldscript.template)
268        else
269            return $(file $(base).ldscript.template)
270
271    getFeedBackPath() =
272        return $(file $(getImageDirectory false)$(DIRSEP)$(getOutputFilename feedback, .dat))
273
274    getBinaryPath(name, suffix) =
275        return $(file $(getImageDirectory false)$(DIRSEP)$(getOutputFilename $(name), $(suffix)))
276
277    getBinaryPathOf(target_dir, name, suffix) =
278        sub_dir = $(getModuleImageSubDirectoryOf $(target_dir))
279        img_dir = $(dir $(sub_dir)$(DIRSEP)$(getTargetSubDirectory false))
280        return $(file $(img_dir)$(DIRSEP)$(getOutputFilename $(name), $(suffix)))
281
282    getDefaultDescriptorPath() =
283        return $(file $(ROOT_RESOURCES)$(DIRSEP)specfiles$(DIRSEP)Application.desc)
284
285    getDefaultRomSpecFile() =
286        spec = $(TARGET_MANAGER.getSpecByHardware $(hardware))
287        if $(defined spec.getDefaultRomSpecFile)
288            return $(file $(ROOT_RESOURCES)$(DIRSEP)specfiles$(DIRSEP)$(spec.getDefaultRomSpecFile $(hardware)))
289        else
290            return $(file $(ROOT_RESOURCES)$(DIRSEP)specfiles$(DIRSEP)Application.rsf)
291
292    getDefaultBannerFile() =
293        return $(ROOT_RESOURCES)$(DIRSEP)banner$(DIRSEP)Default.bnr
294
295    getDefaultIconFile() =
296        return $(ROOT_RESOURCES)$(DIRSEP)banner$(DIRSEP)Default.icn
297
298    getOutputFilename(name, suffix) =
299        return $(name)$(suffix)
300
301    getSuitableKernelFilename() =
302        return $(HORIZON_ROOT_IMAGES)$(DIRSEP)kernel$(DIRSEP)$(getFullnameWithSystem Kernel)$(DIRSEP)$(buildtype)$(DIRSEP)kernel.axf
303
304    getSystemCCFlags() =
305        spec = $(TARGET_MANAGER.getSpecByHardware $(hardware))
306        if $(defined spec.getSystemFlags)
307            return $(spec.getSystemFlags $(systemname))
308        else
309            return $(EMPTY)
310
311    getMinimumLibraries() =
312        spec = $(TARGET_MANAGER.getSpecByHardware $(hardware))
313        if $(defined spec.getMinimumLibraries)
314            return $(spec.getMinimumLibraries $(systemname), $(processor))
315        else
316            return $(EMPTY)
317
318    getDefaultLibraries() =
319        spec = $(TARGET_MANAGER.getSpecByHardware $(hardware))
320        if $(defined spec.getDefaultLibraries)
321            return $(spec.getDefaultLibraries $(systemname), $(processor))
322        else
323            return $(EMPTY)
324
325    getHostIoLibraries() =
326        spec = $(TARGET_MANAGER.getSpecByHardware $(hardware))
327        if $(defined spec.getHostIoLibraries)
328            return $(spec.getHostIoLibraries $(systemname), $(processor))
329        else
330            return $(EMPTY)
331
332    getMacroFlags() =
333        spec = $(TARGET_MANAGER.getSpecByHardware $(hardware))
334        if $(defined spec.getMacroFlags)
335            return $(spec.getMacroFlags $(systemname), $(processor))
336        else
337            return $(EMPTY)
338
339    matches(varvalue, pattern) =
340        regex = compileToRegex($(pattern))
341        match($(varvalue))
342        case $(pattern)
343            return true
344        default
345            return false
346
347    isHostIoEnable() =
348        if $(equal $(buildtype),Release)
349            HOST_IO_DEFAULT         = false
350            export
351        else
352            HOST_IO_DEFAULT         = true
353            export
354
355        if $,(HOST_IO)
356            return true
357        else
358            return false
359
360    isFilterMatched() =
361        return $(matched)
362
363HardwareTargetConfig. =
364    extends $(TargetConfig)
365    class HardwareTargetConfig
366
367    new() =
368        return $(this)
369
370    getFullname() =
371        return $(hardware).$(effort)
372
373    getFullnameDetailed(altsystemname, altprocessor) =
374        return $(hardware).$(altsystemname).$(altprocessor).$(effort)
375
376    getTargetSubDirectory(isLibrary) =
377        if $(isLibrary)
378            return $(hardware)$(DIRSEP)$(getOptimizeType)
379        else
380            return $(hardware).$(effort)$(DIRSEP)$(buildtype)
381
382TargetManager. =
383    class TargetManager
384
385    new() =
386        this.tmap = $(Map)
387        return $(this)
388
389    register(target) =
390        #println($"register: "$(target.name))
391        tmap = $(tmap.add $(target.name), $(target))
392        export
393
394    dump() =
395        tmap.foreach(k, v)
396            v.dump()
397        return
398
399    getProcessors(hardware) =
400        spec = $(getSpecByHardware $(hardware))
401        return $(spec.processors)
402
403    getHardwares() =
404        return $(collectTargetValues $(fun v, $(v.hardware)))
405
406    getPlatform(hardware) =
407        spec = $(getSpecByHardware $(hardware))
408        return $(spec.platform)
409
410    getSpecByHardware(hardware) =
411        return $(tmap.find $(hardware))
412
413    collectTargetValues(getter) =
414        values =
415        tmap.foreach(k, v)
416            values += $(apply $(getter), $(v))
417            export
418        return $(set $(values))
419
420    enumerateTargets(filterstrings, ignoreFastSmall) =
421        #println(filter: $(filterstrings))
422        regex = $(compileToRegex $(filterstrings))
423        regex_global = $(compileToRegex $(TARGET_FILTER))
424        hardwares = $(getHardwares)
425        targets_list =
426        export targets_list
427        foreach(buildtype, $(TARGET_BUILDTYPES))
428            foreach(hardware, $(hardwares))
429                foreach(systemname, $(SYSTEM_LIST))
430                    foreach(processor, $(getProcessors $(hardware)))
431                        matched_fast  = false
432                        export matched_fast
433                        foreach(effort, fast small)
434                            fullname = $"$(hardware).$(systemname).$(processor).$(effort)"
435                            #println($(fullname))
436                            if $(and $(isFilterMatch $(regex), $(fullname)), $(isFilterMatch $(regex_global), $(fullname)))
437                                #eprintln($"name: " $(fullname)-$(buildtype))
438
439                                target = $(TargetConfig.new)
440                                target.platform    = $(getPlatform $(hardware))
441                                target.hardware    = $(hardware)
442                                target.systemname  = $(systemname)
443                                target.processor   = $(processor)
444                                target.effort      = $(effort)
445                                target.buildtype   = $(buildtype)
446
447                                targets_list += $(target)
448
449                                if $(equal $(effort), fast)
450                                    matched_fast   = true
451                                elseif $(and $(not $(matched_fast)), $(ignoreFastSmall))
452                                    target.effort  = fast
453                                    target.matched = false
454
455                                    targets_list += $(target)
456
457                            elseif $(and $(matched_fast), $(ignoreFastSmall))
458                                target = $(TargetConfig.new)
459                                target.platform    = $(getPlatform $(hardware))
460                                target.hardware    = $(hardware)
461                                target.systemname  = $(systemname)
462                                target.processor   = $(processor)
463                                target.effort      = small
464                                target.buildtype   = $(buildtype)
465                                target.matched     = false
466
467                                targets_list += $(target)
468
469
470        return $(targets_list)
471
472    enumerateHardwareTargets(filterstrings) =
473        regex = $(compileToRegex $(filterstrings))
474        regex_global = $(compileToRegex $(TARGET_FILTER))
475        hardwares = $(getHardwares)
476        targets_list =
477        foreach(buildtype, $(TARGET_BUILDTYPES))
478            foreach(hardware, $(hardwares))
479                foreach(effort, fast small)
480                    fullname = $"$(hardware).$(effort)"
481                    if $(and $(isFilterMatch $(regex), $(fullname)), $(isFilterMatch $(regex_global), $(fullname)))
482                        target = $(HardwareTargetConfig.new)
483                        target.platform    = $(getPlatform $(hardware))
484                        target.hardware    = $(hardware)
485                        target.effort      = $(effort)
486                        target.buildtype   = $(buildtype)
487
488                        targets_list += $(target)
489                        export
490                    export
491                export
492            export
493        return $(targets_list)
494
495    isFilterMatch(regex, fullname) =
496        match $(fullname)
497        case $(regex)
498            return true
499        default
500            return false
501
502Builder. =
503    class Builder
504
505    new(manager) =
506        this.manager = $(manager)
507        return $(this)
508
509    getTargets(targetfilters) =
510        SYSTEM_LIST = Kernel Process
511        configs = $(manager.enumerateTargets $(targetfilters), false)
512        return $(configs)
513
514    getLibraryTargets(targetfilters) =
515        SYSTEM_LIST = Kernel Process
516        configs = $(manager.enumerateTargets $(targetfilters), true)
517        return $(configs)
518
519    getHardwareTargets(targetfilters) =
520        configs = $(manager.enumerateHardwareTargets $(targetfilters))
521        return $(configs)
522
523    getToolTargets(targetfilters) =
524        TARGET_FILTER = WIN-IA32.*
525        SYSTEM_LIST   = Tool
526        configs = $(manager.enumerateTargets *)
527        return $(configs)
528
529    go(targetfilters, verb) =
530        result =
531        configs = $(getTargets $(targetfilters))
532        foreach(TARGET, $(configs))
533            result += $,(verb))
534            export
535        return $(result)
536
537    dumpConfigList(configs) =
538        foreach(config, $(configs))
539            config.dump()
540
541declare public.TARGET_FILTER
542if $(defined FILTER)
543    TARGET_FILTER = $(FILTER)
544    export
545elseif $(defined targets)
546    eprintln($"Warning: Use 'FILTER' instead of 'targets.'")
547    TARGET_FILTER = $(targets)
548    export
549else
550    if $(defined-env HORIZON_TARGETS)
551        TARGET_FILTER = $(getenv HORIZON_TARGETS)
552        export
553    elseif $(defined-env CTRSDK_TARGETS)
554        TARGET_FILTER = $(getenv CTRSDK_TARGETS)
555        export
556    else
557        TARGET_FILTER = $`(DEFAULT_FILTER)
558        export
559    export
560
561if $(grep q, $",", $(open-in-string $(TARGET_FILTER)))
562    TARGET_FILTER=$(split $",", $(TARGET_FILTER))
563    export
564
565
566if $(defined BUILD)
567    BUILDTYPES = $(BUILD)
568    export
569else
570    BUILDTYPES = Development
571    export
572
573section
574    RS=$'[ \t,]+'
575    TARGET_BUILDTYPES =
576    export TARGET_BUILDTYPES
577    awk($(open-in-string $(lowercase $(BUILDTYPES))))
578    case $'(debug)|(dbg)'
579        TARGET_BUILDTYPES += Debug
580    case $'dev(elop)?'
581        TARGET_BUILDTYPES += Development
582    case $'rel(ease)?'
583        TARGET_BUILDTYPES += Release
584    case $'full'
585        TARGET_BUILDTYPES += Debug Development Release
586
587    TARGET_BUILDTYPES = $(set $(TARGET_BUILDTYPES))
588
589declare public.TARGET_BUILDTYPES
590#eprintln($"TARGET:"$(string $(TARGET_BUILDTYPES)))
591
592declare public.TARGET_MANAGER
593TARGET_MANAGER = $(TargetManager.new)
594
595declare public.BUILDER
596BUILDER = $(Builder.new $(TARGET_MANAGER))
597
598include $(ROOT_OMAKE)/targetdefs.CTR
599include $(ROOT_OMAKE)/targetdefs.WIN
600
601