mirror of
https://github.com/google/pebble.git
synced 2025-04-30 23:31:40 -04:00
674 lines
25 KiB
Python
674 lines
25 KiB
Python
from waflib import Build, Task
|
|
from waflib.Tools.ccroot import link_task
|
|
from waflib.TaskGen import before_method, feature
|
|
import waflib.Logs
|
|
|
|
import waftools.asm
|
|
import waftools.compress
|
|
import waftools.gitinfo
|
|
import waftools.ldscript
|
|
import waftools.objcopy
|
|
import waftools.generate_log_strings_json
|
|
import waftools.generate_timezone_data
|
|
import tools.mpu_calc
|
|
|
|
import collections
|
|
import json
|
|
import os
|
|
|
|
from waflib.Configure import conf
|
|
|
|
|
|
@feature("c")
|
|
@before_method('apply_link')
|
|
def use_group_link(self):
|
|
"""
|
|
Use a link group to resolve dependencies
|
|
"""
|
|
if 'cprogram' in self.features and getattr(self, 'link_group', False):
|
|
self.features.insert(0, "group_cprogram")
|
|
|
|
|
|
class group_cprogram(link_task):
|
|
run_str = '${LINK_CC} ${LINKFLAGS} ${CCLNK_SRC_F}${SRC} ${CCLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} -Wl,--start-group ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB} -Wl,--end-group'
|
|
ext_out=['.bin']
|
|
vars=['LINKDEPS']
|
|
inst_to='${BINDIR}'
|
|
|
|
|
|
@conf
|
|
def get_pbz_node(ctx, fw_type, board_type, version_string):
|
|
return ctx.path.get_bld().make_node('{}_{}_{}.pbz'.format(fw_type, board_type, version_string))
|
|
|
|
|
|
@conf
|
|
def get_pbpack_node(ctx):
|
|
return ctx.path.get_bld().make_node('system_resources.pbpack')
|
|
|
|
|
|
@conf
|
|
def get_tintin_fw_node(ctx, subdir=None):
|
|
subpath = 'src/fw/tintin_fw.bin'
|
|
if subdir:
|
|
subpath = os.path.join(subdir, subpath)
|
|
return ctx.path.get_bld().make_node(subpath)
|
|
|
|
|
|
@conf
|
|
def get_tintin_fw_node_prf(ctx):
|
|
return ctx.get_tintin_fw_node('prf')
|
|
|
|
|
|
@conf
|
|
def get_tintin_boot_node(ctx):
|
|
return ctx.path.get_bld().make_node('src/boot/tintin_boot.bin')
|
|
|
|
|
|
def options(opt):
|
|
pass
|
|
|
|
|
|
|
|
def configure(conf):
|
|
conf.load('binary_header')
|
|
conf.recurse('vendor')
|
|
conf.recurse('applib')
|
|
conf.recurse('services')
|
|
|
|
if conf.is_silk():
|
|
conf.env.append_value('DEFINES', ['MFG_INFO_RECORDS_TEST_RESULTS'])
|
|
|
|
if conf.options.sdkshell:
|
|
conf.env.NORMAL_SHELL = 'sdk'
|
|
conf.env.append_value('DEFINES', ['SHELL_SDK'])
|
|
else:
|
|
conf.env.NORMAL_SHELL = 'normal'
|
|
|
|
|
|
def _generate_memory_layout(bld):
|
|
|
|
if bld.is_cutts() or bld.is_robert():
|
|
ldscript_template = bld.path.find_node('stm32f7xx_flash_fw.ld.template')
|
|
elif bld.is_silk():
|
|
ldscript_template = bld.path.find_node('stm32f412_flash_fw.ld.template')
|
|
elif bld.is_snowy_compatible():
|
|
ldscript_template = bld.path.find_node('stm32f439_flash_fw.ld.template')
|
|
elif bld.is_tintin():
|
|
ldscript_template = bld.path.find_node('stm32f2xx_flash_fw.ld.template')
|
|
|
|
# Determine bootloader size so we can later calculate FLASH_LENGTH_*
|
|
if bld.env.MICRO_FAMILY == 'STM32F2':
|
|
flash_size = '512K'
|
|
bootloader_size = '16K'
|
|
|
|
elif bld.env.MICRO_FAMILY == 'STM32F4':
|
|
if bld.env.BOARD in ('snowy_evt', 'snowy_evt2', 'spalding_evt'):
|
|
bootloader_size = '64K'
|
|
else:
|
|
bootloader_size = '16K'
|
|
if bld.is_silk() and bld.variant == 'prf':
|
|
# silk PRF is limited to 512k to save on SPI flash space
|
|
flash_size = '512K'
|
|
else:
|
|
flash_size = '1024K'
|
|
|
|
elif bld.env.MICRO_FAMILY == 'STM32F7':
|
|
bootloader_size = '32K'
|
|
flash_size = '2048K'
|
|
|
|
if bld.env.QEMU:
|
|
flash_size = '4M'
|
|
|
|
if bld.env.FLASH_ITCM:
|
|
flash_origin = '0x00200000'
|
|
else:
|
|
flash_origin = '0x08000000'
|
|
|
|
# Determine FLASH_LENGTH_*
|
|
fw_flash_length = '%(flash_size)s - %(bootloader_size)s' % locals()
|
|
fw_flash_origin = '%(flash_origin)s + %(bootloader_size)s' % locals()
|
|
|
|
if bld.env.MICRO_FAMILY == 'STM32F2' and bld.variant == '':
|
|
# If we're building a tintin normal firmware make sure to plug in all the symbols that we
|
|
# want to use from the bootloader.
|
|
|
|
with open(bld.path.find_node('bootloader_symbols.json').abspath(), 'r') as f:
|
|
bootloader_symbols_json = json.load(f)
|
|
|
|
bootloader_symbols = bootloader_symbols_json['bootloader_symbols'].iteritems()
|
|
bootloader_symbol_strings = ("%s = %s;" % (n, v) for n, v in bootloader_symbols)
|
|
bootloader_symbol_definitions = "\n ".join(bootloader_symbol_strings)
|
|
else:
|
|
bootloader_symbol_definitions = ""
|
|
|
|
# Determine ram layout
|
|
|
|
# Each tuple defines the amount of RAM we give to apps (stack + text + data
|
|
# + bss + heap) and the amount of RAM reserved for the application runtime
|
|
# (AppState) for each SDK platform, respectively.
|
|
AppRamSize = collections.namedtuple('AppRamSize',
|
|
'app_segment runtime_reserved')
|
|
APP_RAM_SIZES = {
|
|
'aplite': AppRamSize(25952, 6820),
|
|
'basalt': AppRamSize(66 * 1024, 30 * 1024),
|
|
'chalk': AppRamSize(66 * 1024, 30 * 1024),
|
|
# FIXME: The runtime_reserved size could be reduced for diorite
|
|
'diorite': AppRamSize(66 * 1024, 30 * 1024),
|
|
'emery': AppRamSize(130 * 1024, 62 * 1024),
|
|
}
|
|
APP_UNSUPPORTED = AppRamSize(0, 0)
|
|
|
|
# The process loader enforces eight-byte alignment on all segments, so
|
|
# configuring a segment with a size that is not a multiple of eight will
|
|
# result in segments being smaller than expected. The runtime_reserved
|
|
# size is not checked as its value isn't currently used anywhere.
|
|
for platform, sizes in APP_RAM_SIZES.iteritems():
|
|
if sizes.app_segment % 8 != 0:
|
|
bld.fatal("The app_segment size for APP_RAM_SIZES[%r] is not a "
|
|
"multiple of eight bytes. You're gonna have a bad "
|
|
"time." % platform)
|
|
|
|
# In the FW, the app execution environment is based on the major FW version with which the SDK
|
|
# is associated. Each model supports a different set of SDK platforms, and determines the SDK
|
|
# platform of an app using these major FW version associations (and also by considering the
|
|
# hardware capabilities watch model itself - i.e. chalk vs basalt). We want to define
|
|
# APP_RAM_*X_SIZE macros for each app execution environment supported by the model so we
|
|
# don't need to hard-code these in the FW itself.
|
|
if bld.is_tintin():
|
|
app_ram_size_2x = APP_RAM_SIZES['aplite']
|
|
app_ram_size_3x = APP_RAM_SIZES['aplite']
|
|
app_ram_size_4x = APP_UNSUPPORTED
|
|
# We have a 128k continuous block of RAM.
|
|
total_ram = (0x20000000, 128 * 1024)
|
|
elif bld.is_snowy():
|
|
app_ram_size_2x = APP_RAM_SIZES['aplite']
|
|
app_ram_size_3x = APP_RAM_SIZES['basalt']
|
|
app_ram_size_4x = APP_RAM_SIZES['basalt']
|
|
# We have a 192k continuous block of RAM, plus a separate 64k of CCM which we don't care
|
|
# about here.
|
|
total_ram = (0x20000000, 192 * 1024)
|
|
elif bld.is_spalding():
|
|
app_ram_size_2x = APP_UNSUPPORTED
|
|
app_ram_size_3x = APP_RAM_SIZES['chalk']
|
|
app_ram_size_4x = APP_RAM_SIZES['chalk']
|
|
# We have a 192k continuous block of RAM, plus a separate 64k of CCM which we don't care
|
|
# about here.
|
|
total_ram = (0x20000000, 192 * 1024)
|
|
elif bld.is_silk():
|
|
app_ram_size_2x = APP_RAM_SIZES['aplite']
|
|
app_ram_size_3x = APP_RAM_SIZES['aplite']
|
|
app_ram_size_4x = APP_RAM_SIZES['diorite']
|
|
# We have a 256k continuous block of RAM.
|
|
total_ram = (0x20000000, 256 * 1024)
|
|
elif bld.is_cutts() or bld.is_robert():
|
|
app_ram_size_2x = APP_RAM_SIZES['aplite']
|
|
app_ram_size_3x = APP_RAM_SIZES['basalt']
|
|
app_ram_size_4x = APP_RAM_SIZES['emery']
|
|
# We block off the 128k of DTCM for variables marked as DTCM_BSS. We use the remaining 384k
|
|
# of SRAM as a continuous block of RAM.
|
|
total_ram = (0x20020000, 384 * 1024)
|
|
else:
|
|
bld.fatal("No set of supported SDK platforms defined for this board")
|
|
|
|
# Allocate RAM from the end to the start. Do the app first, then the worker, then give whatever
|
|
# is left to the kernel.
|
|
ram_end = sum(total_ram) # The end of RAM is the start address plus the size.
|
|
all_app_ram_sizes = [app_ram_size_2x, app_ram_size_3x, app_ram_size_4x]
|
|
app_ram_size = max(sum(x) for x in all_app_ram_sizes)
|
|
system_app_segment_size = max(x.app_segment for x in all_app_ram_sizes)
|
|
app_runtime_size = max(x.runtime_reserved for x in all_app_ram_sizes)
|
|
if app_ram_size <= 0 or app_runtime_size <= 0:
|
|
bld.fatal("App RAM is too small!")
|
|
app_ram = (ram_end - app_ram_size, app_ram_size)
|
|
worker_ram_size = 12 * 1024 # The worker always gets 12k of RAM.
|
|
worker_ram = (ram_end - app_ram_size - worker_ram_size, worker_ram_size)
|
|
kernel_ram_size = total_ram[1] - app_ram_size - worker_ram_size
|
|
kernel_ram = (total_ram[0], kernel_ram_size)
|
|
|
|
# As a basic sanity check, make sure we're giving the kernel at least 64k.
|
|
if kernel_ram_size < 64 * 1024:
|
|
bld.fatal("Kernel RAM is too small!")
|
|
|
|
ldscript_result = ldscript_template.get_bld().change_ext('.ld', ext_in='.ld.template')
|
|
|
|
bld(features='subst',
|
|
source=ldscript_template,
|
|
target=ldscript_result,
|
|
KERNEL_RAM_ADDR="0x{:x}".format(kernel_ram[0]),
|
|
KERNEL_RAM_SIZE=kernel_ram[1],
|
|
APP_RAM_ADDR="0x{:x}".format(app_ram[0]),
|
|
APP_RAM_SIZE=app_ram[1],
|
|
WORKER_RAM_ADDR="0x{:x}".format(worker_ram[0]),
|
|
WORKER_RAM_SIZE=worker_ram[1],
|
|
FLASH_ORIGIN=flash_origin,
|
|
FW_FLASH_ORIGIN=fw_flash_origin,
|
|
FW_FLASH_LENGTH=fw_flash_length,
|
|
FLASH_SIZE=flash_size,
|
|
BOOTLOADER_SYMBOLS=bootloader_symbol_definitions)
|
|
|
|
app_mpu_region = tools.mpu_calc.find_subregions_for_region(app_ram[0], app_ram[1])
|
|
worker_mpu_region = tools.mpu_calc.find_subregions_for_region(worker_ram[0], worker_ram[1])
|
|
|
|
bld(features='subst',
|
|
source=bld.path.find_node('kernel/mpu_regions.template.h'),
|
|
target=bld.path.get_bld().make_node('kernel/mpu_regions.auto.h'),
|
|
APP_BASE_ADDRESS="0x{:x}".format(app_mpu_region.address),
|
|
APP_SIZE="0x{:x}".format(app_mpu_region.size),
|
|
APP_DISABLED_SUBREGIONS="0b{:08b}".format(app_mpu_region.disabled_subregion),
|
|
WORKER_BASE_ADDRESS="0x{:x}".format(worker_mpu_region.address),
|
|
WORKER_SIZE="0x{:x}".format(worker_mpu_region.size),
|
|
WORKER_DISABLED_SUBREGIONS=" 0b{:08b}".format(worker_mpu_region.disabled_subregion))
|
|
|
|
bld(features='subst',
|
|
source=bld.path.find_node('process_management/sdk_memory_limits.template.h'),
|
|
target=bld.path.get_bld().make_node('process_management/sdk_memory_limits.auto.h'),
|
|
APP_RAM_2X_SIZE=str(app_ram_size_2x.app_segment),
|
|
APP_RAM_3X_SIZE=str(app_ram_size_3x.app_segment),
|
|
APP_RAM_4X_SIZE=str(app_ram_size_4x.app_segment),
|
|
APP_RAM_SYSTEM_SIZE=str(system_app_segment_size))
|
|
|
|
return ldscript_result
|
|
|
|
|
|
def _link_firmware(bld, sources):
|
|
if bld.is_spalding():
|
|
sources += ['board/displays/display_spalding.c']
|
|
|
|
fw_linkflags = ['-Wl,--cref',
|
|
'-Wl,-Map=tintin_fw.map',
|
|
'-Wl,--gc-sections',
|
|
'-Wl,--build-id=sha1',
|
|
'-Wl,--sort-section=alignment',
|
|
'-nostdlib']
|
|
|
|
fw_linkflags.extend(['-Wl,--wrap=malloc',
|
|
'-Wl,--undefined=__wrap_malloc',
|
|
'-Wl,--wrap=realloc',
|
|
'-Wl,--undefined=__wrap_realloc',
|
|
'-Wl,--wrap=calloc',
|
|
'-Wl,--undefined=__wrap_calloc',
|
|
'-Wl,--wrap=free',
|
|
'-Wl,--undefined=__wrap_free'])
|
|
|
|
uses = ['applib',
|
|
'board',
|
|
'bt_driver',
|
|
'drivers',
|
|
'freertos',
|
|
'fw_services',
|
|
'gcc',
|
|
'proto_schemas',
|
|
'jerry_core',
|
|
'jerry_libm',
|
|
'libbtutil',
|
|
'libos',
|
|
'libutil',
|
|
'nanopb',
|
|
'pblibc',
|
|
'root_includes',
|
|
'startup',
|
|
'tinymt32',
|
|
'upng']
|
|
|
|
ldscript = _generate_memory_layout(bld)
|
|
|
|
if bld.env.NO_LINK:
|
|
# Only build the object files
|
|
bld.objects(source=sources,
|
|
use=uses,
|
|
includes='fonts')
|
|
else:
|
|
# ..and actually build and link the firmware ELF
|
|
elf_node = bld.path.get_bld().make_node('tintin_fw.elf')
|
|
bld.program(source=sources,
|
|
use=uses,
|
|
link_group=True,
|
|
lib=['gcc'],
|
|
target=elf_node,
|
|
includes='fonts',
|
|
ldscript=[ldscript, 'fw_common.ld'],
|
|
linkflags=fw_linkflags)
|
|
|
|
if bld.env.FLASH_ITCM:
|
|
# 0x07E00000 is the difference between the flash memory address and the flash ITCM
|
|
# address. We need to add this because otherwise OpenOCD is unable to write the
|
|
# image into the flash chip.
|
|
extra_args = '--change-addresses 0x07E00000'
|
|
else:
|
|
extra_args = ''
|
|
|
|
hex_node = elf_node.change_ext('.hex')
|
|
bld(rule=waftools.objcopy.objcopy_hex, source=elf_node, target=hex_node, extra_args=extra_args)
|
|
bin_node = elf_node.change_ext('.bin')
|
|
bld(rule=waftools.objcopy.objcopy_bin, source=elf_node, target=bin_node)
|
|
|
|
# Create the log_strings .elf and check the format specifier rules
|
|
if 'PBL_LOGS_HASHED' in bld.env.DEFINES:
|
|
fw_loghash_node = bld.path.get_bld().make_node('tintin_fw_loghash_dict.json')
|
|
bld(rule=waftools.generate_log_strings_json.wafrule,
|
|
source=elf_node, target=fw_loghash_node)
|
|
bld.LOGHASH_DICTS.append(fw_loghash_node)
|
|
|
|
|
|
def _get_mfg_paths(bld):
|
|
"""Return a list of directories we want to build to support manufacturing on a platform"""
|
|
|
|
if bld.is_tintin():
|
|
return ('mfg/tintin',)
|
|
elif bld.is_snowy():
|
|
return ('mfg/snowy',)
|
|
elif bld.is_spalding():
|
|
return ('mfg/spalding',)
|
|
elif bld.is_silk():
|
|
return ('mfg/silk',)
|
|
elif bld.is_cutts():
|
|
# This probably should end up as 'mfg/cutts' if this comes back
|
|
return ('mfg/robert',)
|
|
elif bld.is_robert():
|
|
return ('mfg/robert',)
|
|
else:
|
|
bld.fatal('No MFG configuration for board %s' % bld.env.BOARD)
|
|
|
|
def _get_dbg_paths(bld):
|
|
"""Return a list of directories we want to build to support debug logging on a platform"""
|
|
|
|
if bld.is_tintin():
|
|
return ('debug/legacy',)
|
|
else:
|
|
return ('debug/default',)
|
|
|
|
def _gen_fpga_bitstream_header(bld):
|
|
if bld.is_snowy():
|
|
if bld.env.BOARD in ('snowy_bb', 'snowy_evt'):
|
|
source_bitstream = '../../platform/snowy/snowy_framebuffer_evt.fpga'
|
|
else:
|
|
source_bitstream = '../../platform/snowy/Snowy_LP1K_framebuffer.fpga'
|
|
elif bld.is_spalding():
|
|
if bld.env.BOARD in ('spalding_bb2',):
|
|
source_bitstream = '../../platform/snowy/Spalding_LP1K_framebuffer.fpga'
|
|
else:
|
|
source_bitstream = '../../platform/snowy/Spalding_UL1K_framebuffer.fpga'
|
|
elif bld.is_cutts():
|
|
source_bitstream = '../../platform/robert/Cutts_UL1K_framebuffer_144x168_bitmap.fpga'
|
|
elif bld.is_robert():
|
|
source_bitstream = '../../platform/robert/Robert_UL1K_framebuffer_bitmap.fpga'
|
|
else:
|
|
bld.fatal('No FPGA available for {}'.format(bld.env.BOARD))
|
|
|
|
bld(features='binary_header',
|
|
source=source_bitstream,
|
|
target='drivers/display/ice40lp/fpga_bitstream.auto.h',
|
|
array_name='s_fpga_bitstream',
|
|
compressed=True)
|
|
|
|
def _get_comm_sources(bld, is_recovery):
|
|
excl = []
|
|
if bld.env.QEMU:
|
|
excl.append('comm/internals/profiles/ispp.c')
|
|
|
|
if is_recovery:
|
|
excl.append('comm/ble/kernel_le_client/ancs/*.c')
|
|
excl.append('comm/ble/kernel_le_client/ams/*.c')
|
|
else:
|
|
excl.append('comm/prf_stubs/*')
|
|
|
|
return bld.path.ant_glob('comm/**/*.c', excl=excl)
|
|
|
|
|
|
def _build_recovery(bld):
|
|
source_dirs = ['apps/core_apps/**',
|
|
'apps/prf_apps/**',
|
|
'process_management',
|
|
'process_state/**',
|
|
'console',
|
|
'debug',
|
|
'flash_region',
|
|
'graphics',
|
|
'kernel/**',
|
|
'mfg',
|
|
'mfg/mfg_apps',
|
|
'mfg/mfg_mode',
|
|
'resource',
|
|
'syscall',
|
|
'system',
|
|
'shell',
|
|
'shell/prf/**',
|
|
'util/**']
|
|
|
|
source_dirs.extend(_get_mfg_paths(bld))
|
|
source_dirs.extend(_get_dbg_paths(bld))
|
|
|
|
excludes = ['process_management/app_custom_icon.c',
|
|
'process_management/app_menu_data_source.c',
|
|
'resource/resource_storage_file.c']
|
|
|
|
if 'MFG_INFO_RECORDS_TEST_RESULTS' not in bld.env.DEFINES:
|
|
excludes.extend('mfg/results_ui.c')
|
|
|
|
if bld.is_silk():
|
|
bld.env.append_value('DEFINES', ['QSPI_DMA_DISABLE=1'])
|
|
|
|
sources = sum([bld.path.ant_glob('%s/*.c' % d, excl=excludes) for d in source_dirs], [])
|
|
sources.extend(_get_comm_sources(bld, True))
|
|
sources.extend(bld.path.ant_glob('*.c'))
|
|
sources.extend(bld.path.ant_glob('*.[sS]'))
|
|
|
|
sources.append(bld.path.make_node('popups/bluetooth_pairing_ui.c'))
|
|
|
|
sources.append(bld.path.get_bld().make_node('builtin_resources.auto.c'))
|
|
|
|
if bld.is_snowy_compatible() or bld.is_cutts() or bld.is_robert():
|
|
_gen_fpga_bitstream_header(bld)
|
|
|
|
if bld.is_snowy():
|
|
bld(features='binary_header',
|
|
source='../../platform/snowy/snowy_boot.fpga',
|
|
target='mfg/snowy/snowy_boot.fpga.auto.h',
|
|
array_name='s_boot_fpga')
|
|
elif bld.is_spalding():
|
|
bld(features='binary_header',
|
|
source='../../platform/snowy/spalding_boot.fpga',
|
|
target='mfg/spalding/spalding_boot.fpga.auto.h',
|
|
array_name='s_boot_fpga')
|
|
|
|
if 'BOOTLOADER_TEST_STAGE1=1' in bld.env.DEFINES:
|
|
bld(features='binary_header',
|
|
source=bld.path.make_node('../../bootloader_test_stage2.bin'),
|
|
target='bootloader_test_bin.auto.h',
|
|
array_name='s_bootloader_test_stage2')
|
|
|
|
|
|
if bld.env.DISABLE_PROMPT:
|
|
sources = [ x for x in sources if not x.abspath().endswith('console/prompt.c') ]
|
|
sources = [ x for x in sources if not x.abspath().endswith('console/prompt_commands.c') ]
|
|
|
|
_link_firmware(bld, sources)
|
|
|
|
|
|
def _get_launcher_globs_to_exclude(bld):
|
|
system_launchers_root_path = 'apps/system_apps/launcher/'
|
|
legacy_launcher_glob = system_launchers_root_path + 'legacy/**'
|
|
default_launcher_glob = system_launchers_root_path + 'default/**'
|
|
launcher_globs_to_exclude = [legacy_launcher_glob, default_launcher_glob]
|
|
|
|
if bld.is_tintin():
|
|
launcher_glob_to_use = legacy_launcher_glob
|
|
else:
|
|
launcher_glob_to_use = default_launcher_glob
|
|
|
|
launcher_globs_to_exclude.remove(launcher_glob_to_use)
|
|
return launcher_globs_to_exclude
|
|
|
|
|
|
def _build_normal(bld):
|
|
# Generate timezone data
|
|
olson_txt = bld.srcnode.make_node('resources/normal/base/tzdata/timezones_olson.txt')
|
|
tzdata_bin = bld.bldnode.make_node('resources/normal/base/tzdata/tzdata.bin.reso')
|
|
bld(rule=waftools.generate_timezone_data.wafrule,
|
|
source=olson_txt,
|
|
target=tzdata_bin)
|
|
|
|
bld.DYNAMIC_RESOURCES.append(tzdata_bin)
|
|
|
|
source_dirs = ['process_management',
|
|
'process_state/**',
|
|
'bt_test',
|
|
'console',
|
|
'debug',
|
|
'flash_region',
|
|
'graphics',
|
|
'kernel/**',
|
|
'launcher/**',
|
|
'mfg',
|
|
'popups/**',
|
|
'resource',
|
|
'syscall',
|
|
'system',
|
|
'shell',
|
|
'shell/%s/**' % bld.env.NORMAL_SHELL,
|
|
'util/**']
|
|
|
|
source_files = []
|
|
excludes = []
|
|
|
|
source_dirs.append('apps/core_apps/**')
|
|
if bld.env.NORMAL_SHELL == 'sdk':
|
|
source_dirs.append('apps/sdk/**')
|
|
source_dirs.append('apps/system_apps/timeline')
|
|
if bld.capability('HAS_SDK_SHELL4'):
|
|
source_dirs.append('apps/system_apps/launcher/default/**')
|
|
else:
|
|
excludes.append('process_management/app_custom_icon.c')
|
|
excludes.append('process_management/app_menu_data_source.c')
|
|
else:
|
|
source_dirs.extend(('apps/%s/**' % d for d in ('system_apps', 'watch')))
|
|
if bld.is_spalding():
|
|
excludes.append('apps/watch/tictoc/default')
|
|
else:
|
|
excludes.append('apps/watch/tictoc/spalding')
|
|
|
|
if bld.is_cutts():
|
|
excludes.append('apps/watch/kickstart')
|
|
|
|
source_dirs.extend(_get_mfg_paths(bld))
|
|
source_dirs.extend(_get_dbg_paths(bld))
|
|
|
|
if bld.env.BUILD_TEST_APPS:
|
|
source_dirs.append('apps/demo_apps/**')
|
|
if bld.is_tintin() or bld.is_silk():
|
|
excludes.append('apps/demo_apps/vibe_score_demo.c')
|
|
elif bld.env.PERFORMANCE_TESTS:
|
|
source_dirs.append('apps/demo_apps/gfx_tests')
|
|
|
|
excludes.extend(_get_launcher_globs_to_exclude(bld))
|
|
|
|
if not bld.capability('HAS_BUILTIN_HRM'):
|
|
excludes.append('popups/ble_hrm/**')
|
|
|
|
if bld.is_tintin():
|
|
excludes.append('apps/system_apps/health/**')
|
|
excludes.append('apps/system_apps/settings/settings_vibe_patterns.c')
|
|
excludes.append('apps/system_apps/weather/**')
|
|
excludes.append('apps/system_apps/workout/**')
|
|
|
|
sources = sum([bld.path.ant_glob('%s/*.c' % d, excl=excludes) for d in source_dirs], [])
|
|
sources.extend(bld.path.make_node(x) for x in source_files)
|
|
sources.extend(_get_comm_sources(bld, False))
|
|
sources.extend(bld.path.ant_glob('*.c'))
|
|
sources.extend(bld.path.ant_glob('*.[sS]'))
|
|
|
|
if bld.env.NORMAL_SHELL == 'sdk':
|
|
sources.append('apps/system_apps/app_fetch_ui.c')
|
|
if bld.capability('HAS_SDK_SHELL4'):
|
|
sources.append('apps/system_apps/watchfaces.c')
|
|
|
|
gettexts = []
|
|
gettexts.extend(sources)
|
|
gettexts.extend(bld.path.ant_glob('**/*.h'))
|
|
gettexts.extend(bld.path.ant_glob('**/*.def'))
|
|
|
|
bld.gettext(source=gettexts, target='fw.pot')
|
|
bld.msgcat(
|
|
source='fw.pot services/services.pot applib/applib.pot',
|
|
target='tintin.pot')
|
|
|
|
if bld.is_snowy_compatible() or bld.is_cutts() or bld.is_robert():
|
|
_gen_fpga_bitstream_header(bld)
|
|
|
|
if bld.is_snowy():
|
|
bld(features='binary_header',
|
|
source='../../platform/snowy/snowy_boot.fpga',
|
|
target='mfg/snowy/snowy_boot.fpga.auto.h',
|
|
array_name='s_boot_fpga')
|
|
elif bld.is_spalding():
|
|
bld(features='binary_header',
|
|
source='../../platform/snowy/spalding_boot.fpga',
|
|
target='mfg/spalding/spalding_boot.fpga.auto.h',
|
|
array_name='s_boot_fpga')
|
|
|
|
sources.append(bld.path.get_bld().make_node('pebble.auto.c'))
|
|
sources.append(bld.path.get_bld().make_node('resource/pfs_resource_table.auto.c'))
|
|
sources.append(bld.path.get_bld().make_node('resource/timeline_resource_table.auto.c'))
|
|
sources.append(bld.path.get_bld().make_node('builtin_resources.auto.c'))
|
|
|
|
if bld.env.DISABLE_PROMPT:
|
|
sources = [ x for x in sources if not x.abspath().endswith('console/prompt.c') ]
|
|
sources = [ x for x in sources if not x.abspath().endswith('console/prompt_commands.c') ]
|
|
|
|
_link_firmware(bld, sources)
|
|
|
|
def build(bld):
|
|
# FIXME create applib_includes or something like that
|
|
bld(export_includes=['.',
|
|
'applib/vendor/uPNG',
|
|
'applib/vendor/tinflate'],
|
|
use=['stm32_stdlib',
|
|
'libbtutil_includes',
|
|
'libos_includes',
|
|
'libutil_includes',
|
|
'root_includes',
|
|
'idl_includes',
|
|
'nanopb_includes'],
|
|
name='fw_includes')
|
|
|
|
if bld.variant in ('applib', 'test_rocky_emx'):
|
|
bld.set_env(bld.all_envs['local'])
|
|
bld.env.DEFINES.extend(['UNITTEST', 'SCREEN_COLOR_DEPTH_BITS=8',
|
|
'DISP_COLS=144', 'DISP_ROWS=168',
|
|
'DISPLAY_FRAMEBUFFER_BYTES=%d' % (144 * 168),
|
|
'PBL_COLOR', 'PBL_RECT'])
|
|
bld.recurse('applib')
|
|
return
|
|
|
|
# Truncate the commit to fit in our versions struct. This may cause an ambiguous commit
|
|
# hash, but it's better than killing the build because the commit doesn't fit.
|
|
git_rev = waftools.gitinfo.get_git_revision(bld)
|
|
git_rev['COMMIT'] = git_rev['COMMIT'][:7]
|
|
git_rev['PATCH_VERBOSE_STRING']
|
|
if len(git_rev['TAG']) > 31:
|
|
waflib.Logs.warn('Git tag {} is too long, truncating'.format(git_rev['TAG']))
|
|
git_rev['TAG'] = git_rev['TAG'][:31]
|
|
|
|
bld(features='subst',
|
|
source='git_version.auto.h.in',
|
|
target='git_version.auto.h',
|
|
**git_rev)
|
|
|
|
bld.recurse('startup')
|
|
bld.recurse('drivers')
|
|
bld.recurse('board')
|
|
bld.recurse('shell')
|
|
bld.recurse('vendor')
|
|
bld.recurse('services')
|
|
bld.recurse('applib')
|
|
|
|
# We can't use DMA until we root cause PBL-37278
|
|
if bld.is_silk():
|
|
bld.env.append_value('DEFINES', ['QSPI_DMA_DISABLE=1'])
|
|
|
|
if bld.variant == 'prf':
|
|
_build_recovery(bld)
|
|
else:
|
|
_build_normal(bld)
|
|
|
|
# vim:filetype=python
|