• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# coding=utf-8
3
4'''
5* Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
6* Licensed under the Apache License, Version 2.0 (the "License");
7* you may not use this file except in compliance with the License.
8* You may obtain a copy of the License at
9*
10*     http://www.apache.org/licenses/LICENSE-2.0
11*
12* Unless required by applicable law or agreed to in writing, software
13* distributed under the License is distributed on an "AS IS" BASIS,
14* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15* See the License for the specific language governing permissions and
16* limitations under the License.
17*
18* Description: SCons build system entry.
19'''
20
21EnsureSConsVersion(3, 0, 1)
22EnsurePythonVersion(3, 7)
23
24import os
25import sys
26import datetime
27import atexit
28from distutils import dir_util
29sys.path.append(os.path.join(os.getcwd(), 'build'))
30from scripts import common_env
31from scripts import scons_utils
32from scripts import scons_app
33from scripts import scons_env_cfg
34from scripts import pkt_builder
35from scripts.packet_create import packet_bin
36from tools.nvtool.build_nv import make_nv_bin
37import shutil
38
39#Init compile parameters
40env_cfg = scons_env_cfg.SconsEnvCfg()
41
42#Accept APP parameter
43app_name = ARGUMENTS.get('app', 'demo')
44factory_mode = ARGUMENTS.get('factory_mode', 'no')
45app_builder = scons_app.AppTarget(app_name, factory_mode)
46env_cfg.set_app_builder(app_builder)
47
48#Compile message output control
49if common_env.log_output_flag == False:
50    current = datetime.datetime.now()
51    if not os.path.exists(os.path.dirname(env_cfg.log_path)) or not os.path.exists(env_cfg.log_path):
52        os.makedirs(env_cfg.log_path)
53    log_file = os.path.join(env_cfg.log_path,'scons_trace.log')
54    old_stdout = sys.stdout
55    file = open(log_file, 'w+')
56    file.write("Building at %s %s\n" % (current.strftime('%Y/%m/%d'), current.strftime('%H:%M:%S')))
57    sys.stdout = file
58
59#Init environment
60env = Environment(ENV={'PATH':os.environ['PATH']},
61                  TARGET_PREFIX = env_cfg.target_name, tools=['mingw'])
62
63env_cfg.set_tools(env)
64env_cfg.set_environs(env)
65
66print('----------------------------top-----------------')
67#libraries to be built
68libs = [env.SConscript(os.path.join(env_cfg.get_module_dir(module), 'SConscript'), {'env':env, 'env_cfg':env_cfg, 'module':module},
69    variant_dir=os.path.join(env_cfg.lib_path, env_cfg.get_module_dir(module)), duplicate=0) for module in env_cfg.get_build_modules()]
70#Get settings
71env['LIBPATH'] = env_cfg.get_lib_path()
72
73if scons_utils.scons_usr_bool_option('CONFIG_TARGET_CHIP_HI3861') == 'y':
74    if scons_utils.scons_usr_bool_option('CONFIG_DIAG_SUPPORT') == 'y':
75        if factory_mode == 'yes':
76            env.Append(LIBPATH=os.path.join('-Lbuild', 'libs', 'hi3861', 'debug', 'factory'))
77        elif scons_utils.scons_usr_bool_option('CONFIG_QUICK_SEND_MODE') == 'y':
78            env.Append(LIBPATH=os.path.join('-Lbuild', 'libs', 'hi3861', 'debug', 'no_mesh_quick_start'))
79        elif scons_utils.scons_usr_bool_option('CONFIG_MESH_SUPPORT') == 'y':
80            env.Append(LIBPATH=os.path.join('-Lbuild', 'libs', 'hi3861', 'debug', 'mesh'))
81        else:
82            env.Append(LIBPATH=os.path.join('-Lbuild', 'libs', 'hi3861', 'debug', 'no_mesh'))
83    else:
84        if factory_mode == 'yes':
85            env.Append(LIBPATH=os.path.join('-Lbuild', 'libs', 'hi3861', 'release', 'factory'))
86        elif scons_utils.scons_usr_bool_option('CONFIG_QUICK_SEND_MODE') == 'y':
87            env.Append(LIBPATH=os.path.join('-Lbuild', 'libs', 'hi3861', 'release', 'no_mesh_quick_start'))
88        elif scons_utils.scons_usr_bool_option('CONFIG_MESH_SUPPORT') == 'y':
89            env.Append(LIBPATH=os.path.join('-Lbuild', 'libs', 'hi3861', 'release', 'mesh'))
90        else:
91            env.Append(LIBPATH=os.path.join('-Lbuild', 'libs', 'hi3861', 'release', 'no_mesh'))
92else:
93    if scons_utils.scons_usr_bool_option('CONFIG_DIAG_SUPPORT') == 'y':
94        if factory_mode == 'yes':
95            env.Append(LIBPATH=os.path.join('-Lbuild', 'libs', 'hi3861l', 'debug', 'factory'))
96        elif scons_utils.scons_get_cfg_val('CONFIG_CHIP_PKT_48K') == 'y':
97            env.Append(LIBPATH=os.path.join('-Lbuild', 'libs', 'hi3861l', 'debug', 'no_mesh_pkt_48k'))
98        elif scons_utils.scons_usr_bool_option('CONFIG_MESH_SUPPORT') == 'y':
99            env.Append(LIBPATH=os.path.join('-Lbuild', 'libs', 'hi3861l', 'debug', 'mesh'))
100        else:
101            env.Append(LIBPATH=os.path.join('-Lbuild', 'libs', 'hi3861l', 'debug', 'no_mesh'))
102    else:
103        if factory_mode == 'yes':
104            env.Append(LIBPATH=os.path.join('-Lbuild', 'libs', 'hi3861l', 'release', 'factory'))
105        elif scons_utils.scons_get_cfg_val('CONFIG_CHIP_PKT_48K') == 'y':
106            env.Append(LIBPATH=os.path.join('-Lbuild', 'libs', 'hi3861l', 'release', 'no_mesh_pkt_48k'))
107        elif scons_utils.scons_usr_bool_option('CONFIG_MESH_SUPPORT') == 'y':
108            env.Append(LIBPATH=os.path.join('-Lbuild', 'libs', 'hi3861l', 'release', 'mesh'))
109        else:
110            env.Append(LIBPATH=os.path.join('-Lbuild', 'libs', 'hi3861l', 'release', 'no_mesh'))
111
112env.Append(LIBPATH=app_builder.get_app_lib_path())
113## wifiiot_app is the only one app for ohos
114if app_name != "wifiiot_app":
115    env['LIBS'] = list(map(lambda x:'-l%s'%x, env_cfg.get_libs()))
116else:
117    env['LIBS'] = list(map(lambda x:'-l%s'%x, env_cfg.get_libs())) + ['--whole-archive'] + list(map(lambda x:'-l%s'%x, env_cfg.get_ohos_libs())) + ['--no-whole-archive']
118env.Append(LIBS = app_builder.get_app_libs())
119env.Append(LIBS = '-lwifi_flash')
120env.Append(LIBS = '-lwifi')
121env.Append(LIBS = '-llitekernel_flash')
122env.Append(LIBS = '-lsystem')
123if scons_utils.scons_usr_bool_option('CONFIG_MESH_SUPPORT') == 'y':
124    if factory_mode != 'yes':
125        env.Append(LIBS = '-lmeshautolink')
126env['LIBS'] = sorted(env["LIBS"])
127env['LIBPATH'] = sorted(env["LIBPATH"])
128env['LINKFILE'] = env_cfg.link_file
129env['MAPFILE'] = env_cfg.map_file
130print('~~~~~~~~~~~~~~~~~~~~~~~~~~~~libpath:',env['LIBPATH'])
131print('~~~~~~~~~~~~~~~~~~~~~~~~~~~~libs:',env['LIBS'])
132
133#######################################################  LINK by Command  #######################################################
134
135# config by menuconfig
136signature = {
137    'RSA':{
138        0:0x0054d3c0, # factory startup addr:0x1E3000(HILINK_ADDR - 600K) = 0x14D000
139        'A':0x0040d3c0,
140        'B':0x004f13c0,
141    },
142    'ECC':{
143        0:0x0054d3c0, # factory startup addr:0x1E3000(HILINK_ADDR - 600K) = 0x14D000
144        'A':0x0040d3c0,
145        'B':0x004f13c0,
146    }
147}
148
149link_env = env.Clone()
150
151"""Build link script
152"""
153linker_builder = Builder(
154    action='$CC $LINK_SCRIPTS_FLAG -E $SOURCE -o $TARGET -P',
155    src_suffix='.ld.S'
156)
157
158"""Build elf file
159"""
160elf_builder = Builder(
161    action='$LINK $LINKFLAGS $LIBPATH -T$LINKFILE -Map=$MAPFILE -o $TARGET --start-group $LIBS --end-group',#--verbose
162    suffix='.out'
163)
164
165"""Build binary from .out file
166"""
167binary_builder = Builder(
168    action='$OBJCOPY -O binary $SOURCE $TARGET',
169    suffix='.bin',
170    src_suffix='.out'
171)
172
173"""Build asm file from binary
174"""
175asm_builder = Builder(
176    action='$OBJDUMP -d $SOURCE >$TARGET',
177    suffix='.asm',
178    src_suffix='.out'
179)
180
181"""Base image builder
182"""
183def baseimg_builder(target, source, env):
184    base_bin_target = str(target[0])
185    scons_utils.scons_bin_dd(str(source[0]), base_bin_target, seek=0, count=278)
186    env_cfg.base_bin_check(base_bin_target)
187    no_base_bin_target = str(target[1])
188    scons_utils.scons_bin_dd(str(source[0]), no_base_bin_target, skip=278)
189
190"""NV image builder
191"""
192def nvimg_builder(target, source, env):
193    if os.path.exists(env_cfg.nv_path) is False:
194        os.makedirs(env_cfg.nv_path)
195    make_nv_bin(env_cfg.nv_path, env_cfg.target_name, env_cfg.nv_cfg_name) #genrate nv first
196
197"""Combine NV image and kernel
198"""
199def nvkernel_builder(target, source, env):
200    factory_nv = str(source[0])
201    normal_nv = str(source[1])
202    no_base_bin_target = str(source[2])
203    nv_kernel_bin = str(target[0])
204    scons_utils.scons_bin_dd(factory_nv, nv_kernel_bin, seek=0, bs=4096, count=1)
205    scons_utils.scons_bin_dd(normal_nv, nv_kernel_bin, seek=2, bs=4096, count=1)
206    scons_utils.scons_bin_dd(no_base_bin_target, nv_kernel_bin, seek=4, bs=4096)
207
208factory_nv = os.path.join(env_cfg.nv_path, env_cfg.nv_factory_name)
209normal_nv = os.path.join(env_cfg.nv_path, env_cfg.nv_normal_name)
210#Build flashboot
211flash_boot_bin = env.SConscript(os.path.join('boot', 'flashboot', 'SConscript'), {'env':env, 'env_cfg':env_cfg, 'module':'boot'}, duplicate=0)
212#Build loaderboot
213loader_boot_bin = env.SConscript(os.path.join('boot', 'loaderboot', 'SConscript'), {'env':env, 'env_cfg':env_cfg, 'module':'loaderboot'}, duplicate=0)
214#ota object
215ota_flag = 1 if scons_utils.scons_usr_bool_option('CONFIG_COMPRESSION_OTA_SUPPORT') != 'y' else 0
216ota_build_object = pkt_builder.ImageBuild(env_cfg.target_name, ota_mode=ota_flag)
217def init_ota_build_object(ota_build_object):
218    ota_build_object.set_pkt_path(env_cfg.bin_path)
219    ota_build_object.set_src_path(boot_bin_path=str(flash_boot_bin[0]), normal_nv_path=normal_nv, factory_nv_path=factory_nv)
220    ota_build_object.set_chip_product_name(env.get("CHIP_TYPE"))
221
222def get_ota_object():
223    return ota_build_object
224
225def get_secure_boot():
226    if (scons_utils.scons_usr_bool_option('CONFIG_TARGET_SIG_SHA256') == 'y'):
227        return False
228    else:
229        return True;
230
231def get_hilink_enable():
232    if (scons_utils.scons_usr_bool_option('CONFIG_HILINK') == 'y'):
233        return True
234    else:
235        return False;
236
237def get_sign_dict():
238    sig = ''
239    if scons_utils.scons_usr_bool_option('CONFIG_TARGET_SIG_RSA_V15') == 'y':
240        sig = 'RSA'
241        get_ota_object().set_sign_alg(0x0)
242    elif scons_utils.scons_usr_bool_option('CONFIG_TARGET_SIG_RSA_PSS') == 'y':
243        sig = 'RSA'
244        get_ota_object().set_sign_alg(0x1)
245    elif scons_utils.scons_usr_bool_option('CONFIG_TARGET_SIG_ECC') == 'y':
246        sig = 'ECC'
247        get_ota_object().set_sign_alg(0x10)
248    elif scons_utils.scons_usr_bool_option('CONFIG_TARGET_SIG_SHA256') == 'y':
249        sig = 'ECC'
250        get_ota_object().set_sign_alg(0x3F)
251    if sig not in signature:
252        raise scons_utils.SconsBuildError("%s============== <%s> SIGNATURE SETTING NULL =============%s"%(scons_utils.colors['red'], sig, scons_utils.colors['end']))
253    return signature[sig]
254
255init_ota_build_object(ota_build_object)
256sign_dict = get_sign_dict()    #signature mode configuration
257
258def ota_builder(target, source, env):
259    """Build upg binary
260    """
261    get_ota_object().set_encrypt_flag(0x42)
262    if scons_utils.scons_usr_bool_option('CONFIG_FLASH_ENCRYPT_SUPPORT') == 'y':
263        get_ota_object().set_file_attr_encrypt(0x2)
264    else:
265        get_ota_object().set_file_attr_encrypt(0x1)
266    if scons_utils.scons_usr_bool_option('CONFIG_COMPRESSION_OTA_SUPPORT') == 'y':
267        get_ota_object().set_kernel_file_attr_ota(0x4)
268        get_ota_object().set_kernel_max_size(0) #(912+972)KB
269    else:
270        get_ota_object().set_kernel_file_attr_ota(env['SIGN'])
271        get_ota_object().set_kernel_max_size(env['SIGN']) #912 or 972KB
272        if scons_utils.scons_usr_bool_option('CONFIG_FLASH_ENCRYPT_SUPPORT') == 'y':
273            get_ota_object().set_encrypt_flag(0xFF)
274    get_ota_object().set_src_path(kernel_bin_path=str(source[1]))
275    get_ota_object().BuildUpgBin(str(target[0]))
276
277    return 0
278
279def factory_builder(target, source, env):
280    """Build factory binary
281    """
282    get_ota_object().set_encrypt_flag(0x42)
283    if scons_utils.scons_usr_bool_option('CONFIG_FLASH_ENCRYPT_SUPPORT') == 'y':
284        get_ota_object().set_file_attr_encrypt(0x2)
285    else:
286        get_ota_object().set_file_attr_encrypt(0x1)
287    get_ota_object().set_kernel_file_attr_ota('A') # same as kernel A.
288    get_ota_object().set_kernel_max_size(0x4) #0x4 means __factory_bin_max_size:600K
289    get_ota_object().set_src_path(kernel_bin_path=str(source[1]))
290    get_ota_object().BuildUpgBurnBin(str(target[0]))
291
292    factory_bin_path = os.path.join('build', 'libs', 'factory_bin')
293    if not os.path.exists(factory_bin_path):
294        os.makedirs(factory_bin_path)
295    shutil.rmtree(factory_bin_path)
296    shutil.copytree(env_cfg.bin_path, factory_bin_path, False) #copy factory bin output to build/libs temply.
297
298    return 0
299
300def burn_bin_builder(target, source, env):
301    """Build binary
302    """
303    get_ota_object().set_build_temp_path(build_temp_path = env_cfg.cache_path)
304    burn_bin = get_ota_object().BuildHiburnBin(str(target[0]), str(source[0]))
305    loader_bin = str(source[1])
306    efuse_bin = str(source[2]) if len(source) == 3 else None
307    boot_b = os.path.join('output', 'bin', '%s_boot_signed_B.bin'%(env.get('CHIP_TYPE')))
308    boot_b_size = os.path.getsize(boot_b)
309    factory_bin_path = os.path.join('build', 'libs', 'factory_bin')
310    factory_bin = os.path.join(factory_bin_path, '%s_factory.bin'%env_cfg.target_name)
311    burn_for_erase_bin = os.path.join('build', 'basebin', 'burn_for_erase_4k.bin')
312    #证书安全存储示例
313    tee_cert1_file = os.path.join('build', 'basebin', 'tee_cert1.bin');
314    tee_cert2_file = os.path.join('build', 'basebin', 'tee_cert2.bin');
315    tee_key_file = os.path.join('build', 'basebin', 'tee_key.bin');
316    tee_cert_key_bin_max = 12*1024; #必须为4KB证书倍,需匹配分区表确定烧写地址和大小
317    tee_total_file_cnt = 3; #3个文件:2个证书,1个key。
318    burn_tee_cert = False
319    if ((os.path.exists(tee_cert1_file)) and (os.path.exists(tee_cert2_file)) and (os.path.exists(tee_key_file))):
320        burn_tee_cert = True
321
322    version_bin = bytearray(8)
323    boot_ver = get_ota_object().get_flashboot_file_ver()
324    kernel_ver = get_ota_object().get_kernel_file_ver()
325    boot_ver_bytes = boot_ver.to_bytes(4, byteorder = 'little', signed = True)
326    kernel_ver_bytes = kernel_ver.to_bytes(4, byteorder = 'little', signed = True)
327    version_bin[0:4] = boot_ver_bytes
328    version_bin[4:8] = kernel_ver_bytes
329    version_file = os.path.join("output", "bin", '%s_vercfg.bin'%env_cfg.target_name)
330    with open(version_file, 'wb+') as fp:
331        fp.write(version_bin)
332
333    burn_bin_ease_size = 0x200000;
334    #根据分区表适配烧写地址和大小
335    if (get_hilink_enable() == True):
336        burn_bin_ease_size = 0x200000 - 0x8000 - 0x1000 - 0x2000
337    if (burn_tee_cert == True):
338        burn_bin_ease_size = 0x200000 - 0x8000 - 0x1000 - 0x2000 - 0x5000
339
340    if os.path.exists(factory_bin):
341        cmd_list = ['%s|0|0|0'%loader_bin, '%s|0|0|3'%efuse_bin, '%s|0|%d|1'%(burn_bin, burn_bin_ease_size), '%s|%d|%d|6'%(factory_bin, 0x14D000, 0x96000)] if efuse_bin!=None else ['%s|0|0|0'%loader_bin, '%s|0|%d|1'%(burn_bin, burn_bin_ease_size), '%s|%d|%d|6'%(factory_bin, 0x14D000, 0x96000),]
342        shutil.copytree(factory_bin_path, os.path.join(env_cfg.bin_path, 'factory_bin'))
343    else:
344        cmd_list = ['%s|0|0|0'%loader_bin, '%s|0|0|3'%efuse_bin, '%s|0|%d|1'%(burn_bin, burn_bin_ease_size)] if efuse_bin!=None else ['%s|0|0|0'%loader_bin, '%s|0|%d|1'%(burn_bin, burn_bin_ease_size)]
345
346    if ((get_hilink_enable() == True) or (burn_tee_cert == True)):
347        cmd_list.append('%s|%d|%d|1'%(burn_for_erase_bin, 0x200000 - 0x8000 - 0x1000, 0x1000))
348
349    #cmd_list.append('%s|%d|%d|1'%(boot_b, 0x200000 - boot_b_size, boot_b_size));
350
351    if (burn_tee_cert == True):
352        cert_key_bin = bytearray(tee_cert_key_bin_max)
353        tee_cert1_size = os.path.getsize(tee_cert1_file)
354        tee_cert2_size = os.path.getsize(tee_cert2_file)
355        tee_key_size = os.path.getsize(tee_key_file)
356        total_cert_key_size = tee_cert1_size + tee_cert2_size + tee_key_size
357        if (total_cert_key_size > tee_cert_key_bin_max - 4 - 4 - 4*tee_total_file_cnt):
358            print ("%s============== cert total len bigger than %d=============%s"%(scons_utils.colors['red'], total_cert_key_size,scons_utils.colors['end']))
359            return -1
360        else:
361            with open(tee_cert1_file, 'rb') as fp:
362                tee_cert1_bin = fp.read()
363            with open(tee_cert2_file, 'rb') as fp:
364                tee_cert2_bin = fp.read()
365            with open(tee_key_file, 'rb') as fp:
366                tee_key_bin = fp.read()
367
368            #填充头部结构
369            start_flag = 0xDEADBEEF
370            start_flag_bytes = start_flag.to_bytes(4, byteorder = 'little', signed = False)
371            cert_key_bin[0:4] = start_flag_bytes #填充魔术字
372            tee_total_file_cnt_bytes = tee_total_file_cnt.to_bytes(4, byteorder = 'little', signed = True)
373            cert_key_bin[4:8] = tee_total_file_cnt_bytes #填充总的文件数
374            #填充各文件的大小
375            cert_key_bin[8:12] = tee_cert1_size.to_bytes(4, byteorder = 'little', signed = True)
376            cert_key_bin[12:16] = tee_cert2_size.to_bytes(4, byteorder = 'little', signed = True)
377            cert_key_bin[16:20] = tee_key_size.to_bytes(4, byteorder = 'little', signed = True)
378            #填充各文件
379            cert_key_bin[20:20 + tee_cert1_size] = tee_cert1_bin
380            cert_key_bin[20 + tee_cert1_size:20 + tee_cert1_size + tee_cert2_size] = tee_cert2_bin
381            cert_key_bin[20 + tee_cert1_size + tee_cert2_size:20 + tee_cert1_size + tee_cert2_size + tee_key_size] = tee_key_bin
382            #写文件
383            cert_bin_file = os.path.join("output", "bin", '%s_tee_cert_key.bin'%env_cfg.target_name)
384            with open(cert_bin_file, 'wb+') as fp:
385                fp.write(cert_key_bin)
386            cmd_list.append('%s|%d|%d|1'%(cert_bin_file, 0x200000 - 0x8000 - 0x1000 - 0x2000 - 0x5000, tee_cert_key_bin_max))
387
388    if (get_secure_boot() == True): #only need write ver file in secure boot mode.
389        cmd_list.append('%s|0|0|7'%version_file)
390
391    packet_bin(str(target[1]), cmd_list)
392    if os.path.exists(factory_bin_path):
393        shutil.rmtree(factory_bin_path)
394    return 0
395
396def compress_ota_builder(target, source, env):
397    """Build compressed upgrade file
398    """
399    get_ota_object().set_encrypt_flag(0x42)
400    if scons_utils.scons_usr_bool_option('CONFIG_FLASH_ENCRYPT_SUPPORT') == 'y':
401        get_ota_object().set_file_attr_encrypt(0x2)
402        get_ota_object().set_encrypt_flag(0xFF)
403    else:
404        get_ota_object().set_file_attr_encrypt(0x1)
405    get_ota_object().set_kernel_file_attr_ota(0x4)
406    get_ota_object().set_build_temp_path(build_temp_path = env_cfg.cache_path)
407    compress_ota = get_ota_object().BuildCompressUpgBin(str(target[0]), str(source[0]))
408    return 0
409
410def boot_ota_builder(target, source, env):
411    """Build boot ota
412    """
413    if scons_utils.scons_usr_bool_option('CONFIG_FLASH_ENCRYPT_SUPPORT') == 'y':
414        get_ota_object().set_file_attr_encrypt(0x2)
415    else:
416        get_ota_object().set_file_attr_encrypt(0x1)
417    if scons_utils.scons_usr_bool_option('CONFIG_COMPRESSION_OTA_SUPPORT') == 'y':
418        get_ota_object().set_flashboot_file_attr_ota(0x4)
419    else:
420        get_ota_object().set_flashboot_file_attr_ota(0x3)
421    get_ota_object().set_encrypt_flag(0x42)
422    boot_ota = get_ota_object().BuildUpgBoot(str(target[0]))
423    return 0
424
425#Builders
426link_env.Append(BUILDERS={'LinkFile':linker_builder,
427    'Elf':elf_builder,
428    'Binary':binary_builder,
429    'Asm':asm_builder,
430    'BaseImg':Builder(action=baseimg_builder),
431    'NVKernel':Builder(action=nvkernel_builder),
432    'BootOta':Builder(action=boot_ota_builder),
433    'OtaImg':Builder(action=ota_builder),
434    'FactoryImg':Builder(action=factory_builder),
435    'BurnImg':Builder(action=burn_bin_builder),
436    'CompressOtaImg':Builder(action = compress_ota_builder),
437})
438
439def build_all(build_env, link_sys, flash_boot_bin, loader_boot_bin):
440    """Processing build
441    """
442
443    #kernel_ver
444    kernel_ver = scons_utils.scons_usr_int_option('CONFIG_TARGET_KERNEL_VER')
445    if (kernel_ver < 0 or kernel_ver > 48):
446        raise scons_utils.SconsBuildError("%s============== kernel_ver invalied, should be 0-48 =============%s"%(scons_utils.colors['red'], scons_utils.colors['end']))
447    else:
448        get_ota_object().set_kernel_file_ver(kernel_ver)
449
450    #boot_ver
451    boot_ver = scons_utils.scons_usr_int_option('CONFIG_TARGET_BOOT_VER')
452    if (boot_ver < 0 or boot_ver > 16):
453        raise scons_utils.SconsBuildError("%s============== boot_ver invalied, should be 0-16 =============%s"%(scons_utils.colors['red'], scons_utils.colors['end']))
454    else:
455        get_ota_object().set_flashboot_file_ver(boot_ver)
456
457    #images container, insert boot ota at first
458    imgs = [build_env.BootOta(target=os.path.join(env_cfg.bin_path, '%s_flash_boot_ota.bin'%env_cfg.target_name), source=flash_boot_bin)]
459    for sig_key in sign_dict:
460        if sig_key == 0 and factory_mode != 'yes':
461            continue
462        sign_build = build_env.Clone()
463        sign_build['SIGN'] = sig_key
464        name_suffix = '_%s'%sig_key
465        if sig_key == 0:
466            name_suffix = '_factory'
467            ota_file = os.path.join(env_cfg.bin_path, '%s%s.bin'%(env_cfg.target_name, name_suffix))
468        elif scons_utils.scons_usr_bool_option('CONFIG_COMPRESSION_OTA_SUPPORT') == 'y':
469            name_suffix = ''
470            ota_file = os.path.join(env_cfg.cache_path, '%s_ota_%s.bin'%(env_cfg.target_name, 'temp')) #tmp file
471        else:
472            ota_file = os.path.join(env_cfg.bin_path, '%s_ota%s.bin'%(env_cfg.target_name, name_suffix))
473
474        sign_build['LINKFILE'] = os.path.join(env_cfg.link_path, 'link%s.lds'%name_suffix)
475        sign_build['MAPFILE'] = '%s%s.map'%(sign_build['MAPFILE'][:-len('.map')], name_suffix)
476        sign_build.Append(LINK_SCRIPTS_FLAG = '-DFLASH_FIRM_START=%s'%sign_dict[sig_key])
477
478        link_risc = sign_build.LinkFile(source=os.path.join('build', 'link', 'link'),
479                                        target='$LINKFILE')
480        sign_build.Depends(link_risc, link_sys)
481        #start
482        target_out = sign_build.Elf(source = libs, target = os.path.join(env_cfg.bin_path, '%s%s.out'%(env_cfg.target_name, name_suffix)))
483        sign_build.Depends(target_out, [link_risc, libs])
484        target_out_bin = sign_build.Binary(source = target_out, target = os.path.join(env_cfg.cache_path, '%s%s'%(env_cfg.target_name, name_suffix)))
485        target_asm = sign_build.Asm(source = target_out, target=os.path.join(env_cfg.bin_path, '%s%s.asm'%(env_cfg.target_name, name_suffix)))
486
487        base_bin_target = os.path.join(env_cfg.cache_path, '%s_base%s.bin'%(env_cfg.target_name, name_suffix))
488        kernel_bin_target = os.path.join(env_cfg.cache_path, '%s_kernel%s.bin'%(env_cfg.target_name, name_suffix))
489
490        #Build kernel and ota
491        kernel = sign_build.BaseImg(source=target_out_bin, target=[base_bin_target, kernel_bin_target])
492        if factory_mode == 'yes':
493            ota_bin = sign_build.FactoryImg(source=kernel, target=ota_file)
494        else:
495            ota_bin = sign_build.OtaImg(source=kernel, target=ota_file)
496        imgs.append(ota_bin)
497        sign_build.AddPostAction(kernel, scons_utils.cleanup) #hook clean
498        if sig_key == 'A': #need signature
499            loader_bin = os.path.join('#', env_cfg.bin_path, '%s_loader_signed.bin'%(env.get('CHIP_TYPE')))
500            efuse_bin = os.path.join('build', 'basebin', 'efuse_cfg.bin')
501            burn_bin = os.path.join(env_cfg.bin_path, '%s_burn.bin'%env_cfg.target_name)
502            allinone_bin = os.path.join(env_cfg.bin_path, '%s_allinone.bin'%env_cfg.target_name)
503            burn_bins = sign_build.BurnImg(source=[ota_bin, loader_bin, efuse_bin] if os.path.exists(efuse_bin) else [ota_bin, loader_bin],
504                                           target=[burn_bin, allinone_bin])
505            imgs.append(burn_bins)
506        #mark binaries to be built everytime
507        if sig_key in ['A', 'B']:
508            sign_build.AlwaysBuild([link_risc, target_out, target_out_bin, target_asm, kernel, ota_bin, burn_bins])
509        if scons_utils.scons_usr_bool_option('CONFIG_COMPRESSION_OTA_SUPPORT') == 'y' and sig_key == 'A':
510            compress_ota_bin = os.path.join(env_cfg.bin_path, '%s_ota.bin'%env_cfg.target_name)
511            compress_ota_file = sign_build.CompressOtaImg(source = ota_bin, target = compress_ota_bin)
512            break
513        if sig_key == 0:
514            break
515    return imgs
516
517link_env.AddMethod(build_all, 'BUILD')
518#prepare link script
519link_sys = link_env.LinkFile(source=os.path.join('build', 'link', 'system_config'),
520                             target=os.path.join(env_cfg.link_path, 'system_config.ld'))
521link_env.Depends(link_sys, [flash_boot_bin, loader_boot_bin])
522link_env.AddPostAction(link_sys, nvimg_builder) #prepare nv image
523
524# START LINK
525target_img = link_env.BUILD(link_sys, flash_boot_bin, loader_boot_bin)
526link_env.AlwaysBuild([target_img, link_sys])
527Clean(target_img, env_cfg.clean_list)
528#######################################################  LINK  #######################################################
529
530#######################################################  BUILD CHECK  #######################################################
531
532def build_status():
533    bf = GetBuildFailures()
534    status = 0
535    failures_message = ''
536    if bf:
537        status = -1
538        failures_message = "\n".join(["Failed building %s" % scons_utils.bf_to_str(x) for x in bf if x is not None])
539    return (status, failures_message)
540
541def display_build_status():
542    if env.GetOption("clean"):
543        return
544    status, failures_message = build_status()
545    if status == 0:
546        scons_utils.show_burn_tips()
547    else:
548        scons_utils.show_alert("BUILD FAILED!!!!")
549        scons_utils.show_alert(failures_message)
550
551atexit.register(display_build_status)
552
553if common_env.log_output_flag == False:
554    file.close() #close log file handler
555    sys.stdout = old_stdout
556
557