1import os
2
3c, link, asm, utils = emk.module("c", "link", "asm", "utils")
4
5default_compile_flags = ["-fvisibility=hidden", "-Wall", "-Wextra", "-Wshadow", "-Werror", "-Wno-missing-field-initializers", "-Wno-unused-parameter", \
6    "-Wno-comment", "-Wno-unused", "-Wno-unknown-pragmas"]
7default_link_flags = []
8opt_flags = {"dbg":["-g"], "std":["-O2"], "max":["-O3"], "small":["-Os"]}
9opt_link_flags = {"dbg":[], "std":[], "max":[], "small":[]}
10c_flags = ["-std=c99"]
11cxx_flags = ["-std=c++11", "-Wno-reorder", "-fno-rtti", "-fno-exceptions"]
12c_link_flags = []
13cxx_link_flags = ["-fno-rtti", "-fno-exceptions"]
14
15def setup_build_dir():
16    build_arch = None
17    if "arch" in emk.options:
18        build_arch = emk.options["arch"]
19    elif not emk.cleaning:
20        build_arch = "osx"
21    emk.options["arch"] = build_arch
22
23    opt_level = None
24    if "opt" in emk.options:
25        level = emk.options["opt"]
26        if level in opt_flags:
27            opt_level = level
28        else:
29            emk.log.warning("Unknown optimization level '%s'" % (level))
30    elif not emk.cleaning:
31        opt_level = "dbg"
32    emk.options["opt"] = opt_level
33
34    dirs = ["__build__"]
35    if build_arch:
36        dirs.append(build_arch)
37    if opt_level:
38        dirs.append(opt_level)
39    emk.build_dir = os.path.join(*dirs)
40
41def setup_osx():
42    global c
43    global link
44
45    flags = [("-arch", "x86_64"), "-fno-common", "-Wnewline-eof"]
46    c.flags.extend(flags)
47    c.cxx.flags += ["-stdlib=libc++"]
48    link.cxx.flags += ["-stdlib=libc++"]
49
50    link_flags = [("-arch", "x86_64")]
51    link.local_flags.extend(link_flags)
52
53def setup_avr():
54    global c
55    global link
56
57    c.compiler = c.GccCompiler("/Projects/avr-tools/bin/avr-")
58    c.flags += ["-mmcu=atmega256rfr2", "-ffunction-sections", "-fdata-sections"]
59    link.linker = link.GccLinker("/Projects/avr-tools/bin/avr-")
60    link.flags += ["-mmcu=atmega256rfr2", "-mrelax", "-Wl,--gc-sections"]
61    link.strip = True
62
63def setup_arm_thumb():
64    global c
65    global link
66    global asm
67    global utils
68
69    asm.assembler = asm.GccAssembler("/cross/arm_cortex/bin/arm-none-eabi-")
70    c.compiler = c.GccCompiler("/cross/arm_cortex/bin/arm-none-eabi-")
71    link.linker = link.GccLinker("/cross/arm_cortex/bin/arm-none-eabi-")
72
73    c.flags.extend(["-mcpu=cortex-m0", "-mthumb", "-ffunction-sections", "-fdata-sections", "-fno-builtin-fprintf", "-fno-builtin-printf"])
74    c.defines["LPC11XX"] = 1
75
76    link.local_flags.extend(["-mcpu=cortex-m0", "-mthumb", "-nostartfiles", "-nostdlib", "-Wl,--gc-sections"])
77    link.local_flags.extend(["-Tflash.lds", "-L/Projects/lpc11xx/core", "/Projects/lpc11xx/core/" + emk.build_dir + "/board_cstartup.o"])
78    link.local_syslibs += ["gcc"]
79    link.depdirs += ["/Projects/lpc11xx/stdlib"]
80
81    def do_objcopy(produces, requires):
82        utils.call("/cross/arm_cortex/bin/arm-none-eabi-objcopy", "-O", "binary", requires[0], produces[0])
83
84    def handle_exe(path):
85        emk.depend(path, "/Projects/lpc11xx/core/" + emk.build_dir + "/board_cstartup.o")
86        emk.rule(do_objcopy, path + ".bin", path, cwd_safe=True, ex_safe=True)
87        emk.autobuild(path + ".bin")
88
89    link.exe_funcs.append(handle_exe)
90    link.strip = True
91
92    emk.recurse("/Projects/lpc11xx/core")
93
94def setup_linux_rpi():
95    global c
96    global link
97
98    c.compiler = c.GccCompiler("/Volumes/xtools/arm-none-linux-gnueabi/bin/arm-none-linux-gnueabi-")
99    link.linker = link.GccLinker("/Volumes/xtools/arm-none-linux-gnueabi/bin/arm-none-linux-gnueabi-")
100
101    c.flags.extend(["-fomit-frame-pointer"])
102
103setup_build_dir()
104
105setup_funcs = {"osx":setup_osx, "avr":setup_avr, "arm_thumb":setup_arm_thumb, "rpi": setup_linux_rpi}
106
107if not emk.cleaning:
108    build_arch = emk.options["arch"]
109    opt_level = emk.options["opt"]
110
111    c.flags.extend(default_compile_flags)
112    c.flags.extend(opt_flags[opt_level])
113    c.c.flags.extend(c_flags)
114    c.cxx.flags.extend(cxx_flags)
115    link.local_flags.extend(default_link_flags)
116    link.local_flags.extend(opt_link_flags[opt_level])
117    link.c.local_flags.extend(c_link_flags)
118    link.cxx.local_flags.extend(cxx_link_flags)
119
120    c.include_dirs.append("$:proj:$")
121
122    if build_arch in setup_funcs:
123        setup_funcs[build_arch]()
124    else:
125        raise emk.BuildError("Unknown target arch '%s'" % (build_arch))
126
127    c.defines["TARGET_ARCH_" + build_arch.upper()] = 1
128