xref: /nrf52832-nimble/rt-thread/tools/building.py (revision 104654410c56c573564690304ae786df310c91fc)
1*10465441SEvalZero#
2*10465441SEvalZero# File      : building.py
3*10465441SEvalZero# This file is part of RT-Thread RTOS
4*10465441SEvalZero# COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team
5*10465441SEvalZero#
6*10465441SEvalZero#  This program is free software; you can redistribute it and/or modify
7*10465441SEvalZero#  it under the terms of the GNU General Public License as published by
8*10465441SEvalZero#  the Free Software Foundation; either version 2 of the License, or
9*10465441SEvalZero#  (at your option) any later version.
10*10465441SEvalZero#
11*10465441SEvalZero#  This program is distributed in the hope that it will be useful,
12*10465441SEvalZero#  but WITHOUT ANY WARRANTY; without even the implied warranty of
13*10465441SEvalZero#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*10465441SEvalZero#  GNU General Public License for more details.
15*10465441SEvalZero#
16*10465441SEvalZero#  You should have received a copy of the GNU General Public License along
17*10465441SEvalZero#  with this program; if not, write to the Free Software Foundation, Inc.,
18*10465441SEvalZero#  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*10465441SEvalZero#
20*10465441SEvalZero# Change Logs:
21*10465441SEvalZero# Date           Author       Notes
22*10465441SEvalZero# 2015-01-20     Bernard      Add copyright information
23*10465441SEvalZero# 2015-07-25     Bernard      Add LOCAL_CCFLAGS/LOCAL_CPPPATH/LOCAL_CPPDEFINES for
24*10465441SEvalZero#                             group definition.
25*10465441SEvalZero#
26*10465441SEvalZero
27*10465441SEvalZeroimport os
28*10465441SEvalZeroimport sys
29*10465441SEvalZeroimport string
30*10465441SEvalZeroimport utils
31*10465441SEvalZero
32*10465441SEvalZerofrom SCons.Script import *
33*10465441SEvalZerofrom utils import _make_path_relative
34*10465441SEvalZerofrom mkdist import do_copy_file
35*10465441SEvalZero
36*10465441SEvalZeroBuildOptions = {}
37*10465441SEvalZeroProjects = []
38*10465441SEvalZeroRtt_Root = ''
39*10465441SEvalZeroEnv = None
40*10465441SEvalZero
41*10465441SEvalZero# SCons PreProcessor patch
42*10465441SEvalZerodef start_handling_includes(self, t=None):
43*10465441SEvalZero    """
44*10465441SEvalZero    Causes the PreProcessor object to start processing #import,
45*10465441SEvalZero    #include and #include_next lines.
46*10465441SEvalZero
47*10465441SEvalZero    This method will be called when a #if, #ifdef, #ifndef or #elif
48*10465441SEvalZero    evaluates True, or when we reach the #else in a #if, #ifdef,
49*10465441SEvalZero    #ifndef or #elif block where a condition already evaluated
50*10465441SEvalZero    False.
51*10465441SEvalZero
52*10465441SEvalZero    """
53*10465441SEvalZero    d = self.dispatch_table
54*10465441SEvalZero    p = self.stack[-1] if self.stack else self.default_table
55*10465441SEvalZero
56*10465441SEvalZero    for k in ('import', 'include', 'include_next', 'define'):
57*10465441SEvalZero        d[k] = p[k]
58*10465441SEvalZero
59*10465441SEvalZerodef stop_handling_includes(self, t=None):
60*10465441SEvalZero    """
61*10465441SEvalZero    Causes the PreProcessor object to stop processing #import,
62*10465441SEvalZero    #include and #include_next lines.
63*10465441SEvalZero
64*10465441SEvalZero    This method will be called when a #if, #ifdef, #ifndef or #elif
65*10465441SEvalZero    evaluates False, or when we reach the #else in a #if, #ifdef,
66*10465441SEvalZero    #ifndef or #elif block where a condition already evaluated True.
67*10465441SEvalZero    """
68*10465441SEvalZero    d = self.dispatch_table
69*10465441SEvalZero    d['import'] = self.do_nothing
70*10465441SEvalZero    d['include'] =  self.do_nothing
71*10465441SEvalZero    d['include_next'] =  self.do_nothing
72*10465441SEvalZero    d['define'] =  self.do_nothing
73*10465441SEvalZero
74*10465441SEvalZeroPatchedPreProcessor = SCons.cpp.PreProcessor
75*10465441SEvalZeroPatchedPreProcessor.start_handling_includes = start_handling_includes
76*10465441SEvalZeroPatchedPreProcessor.stop_handling_includes = stop_handling_includes
77*10465441SEvalZero
78*10465441SEvalZeroclass Win32Spawn:
79*10465441SEvalZero    def spawn(self, sh, escape, cmd, args, env):
80*10465441SEvalZero        # deal with the cmd build-in commands which cannot be used in
81*10465441SEvalZero        # subprocess.Popen
82*10465441SEvalZero        if cmd == 'del':
83*10465441SEvalZero            for f in args[1:]:
84*10465441SEvalZero                try:
85*10465441SEvalZero                    os.remove(f)
86*10465441SEvalZero                except Exception as e:
87*10465441SEvalZero                    print ('Error removing file: ' + e)
88*10465441SEvalZero                    return -1
89*10465441SEvalZero            return 0
90*10465441SEvalZero
91*10465441SEvalZero        import subprocess
92*10465441SEvalZero
93*10465441SEvalZero        newargs = ' '.join(args[1:])
94*10465441SEvalZero        cmdline = cmd + " " + newargs
95*10465441SEvalZero
96*10465441SEvalZero        # Make sure the env is constructed by strings
97*10465441SEvalZero        _e = dict([(k, str(v)) for k, v in env.items()])
98*10465441SEvalZero
99*10465441SEvalZero        # Windows(tm) CreateProcess does not use the env passed to it to find
100*10465441SEvalZero        # the executables. So we have to modify our own PATH to make Popen
101*10465441SEvalZero        # work.
102*10465441SEvalZero        old_path = os.environ['PATH']
103*10465441SEvalZero        os.environ['PATH'] = _e['PATH']
104*10465441SEvalZero
105*10465441SEvalZero        try:
106*10465441SEvalZero            proc = subprocess.Popen(cmdline, env=_e, shell=False)
107*10465441SEvalZero        except Exception as e:
108*10465441SEvalZero            print ('Error in calling command:' + cmdline.split(' ')[0])
109*10465441SEvalZero            print ('Exception: ' + os.strerror(e.errno))
110*10465441SEvalZero            if (os.strerror(e.errno) == "No such file or directory"):
111*10465441SEvalZero                print ("\nPlease check Toolchains PATH setting.\n")
112*10465441SEvalZero
113*10465441SEvalZero            return e.errno
114*10465441SEvalZero        finally:
115*10465441SEvalZero            os.environ['PATH'] = old_path
116*10465441SEvalZero
117*10465441SEvalZero        return proc.wait()
118*10465441SEvalZero
119*10465441SEvalZero# generate cconfig.h file
120*10465441SEvalZerodef GenCconfigFile(env, BuildOptions):
121*10465441SEvalZero    import rtconfig
122*10465441SEvalZero
123*10465441SEvalZero    if rtconfig.PLATFORM == 'gcc':
124*10465441SEvalZero        contents = ''
125*10465441SEvalZero        if not os.path.isfile('cconfig.h'):
126*10465441SEvalZero            import gcc
127*10465441SEvalZero            gcc.GenerateGCCConfig(rtconfig)
128*10465441SEvalZero
129*10465441SEvalZero        # try again
130*10465441SEvalZero        if os.path.isfile('cconfig.h'):
131*10465441SEvalZero            f = open('cconfig.h', 'r')
132*10465441SEvalZero            if f:
133*10465441SEvalZero                contents = f.read()
134*10465441SEvalZero                f.close()
135*10465441SEvalZero
136*10465441SEvalZero                prep = PatchedPreProcessor()
137*10465441SEvalZero                prep.process_contents(contents)
138*10465441SEvalZero                options = prep.cpp_namespace
139*10465441SEvalZero
140*10465441SEvalZero                BuildOptions.update(options)
141*10465441SEvalZero
142*10465441SEvalZero                # add HAVE_CCONFIG_H definition
143*10465441SEvalZero                env.AppendUnique(CPPDEFINES = ['HAVE_CCONFIG_H'])
144*10465441SEvalZero
145*10465441SEvalZerodef PrepareBuilding(env, root_directory, has_libcpu=False, remove_components = []):
146*10465441SEvalZero    import rtconfig
147*10465441SEvalZero
148*10465441SEvalZero    global BuildOptions
149*10465441SEvalZero    global Projects
150*10465441SEvalZero    global Env
151*10465441SEvalZero    global Rtt_Root
152*10465441SEvalZero
153*10465441SEvalZero    # ===== Add option to SCons =====
154*10465441SEvalZero    AddOption('--dist',
155*10465441SEvalZero                      dest = 'make-dist',
156*10465441SEvalZero                      action = 'store_true',
157*10465441SEvalZero                      default = False,
158*10465441SEvalZero                      help = 'make distribution')
159*10465441SEvalZero    AddOption('--dist-strip',
160*10465441SEvalZero                      dest = 'make-dist-strip',
161*10465441SEvalZero                      action = 'store_true',
162*10465441SEvalZero                      default = False,
163*10465441SEvalZero                      help = 'make distribution and strip useless files')
164*10465441SEvalZero    AddOption('--cscope',
165*10465441SEvalZero                      dest = 'cscope',
166*10465441SEvalZero                      action = 'store_true',
167*10465441SEvalZero                      default = False,
168*10465441SEvalZero                      help = 'Build Cscope cross reference database. Requires cscope installed.')
169*10465441SEvalZero    AddOption('--clang-analyzer',
170*10465441SEvalZero                      dest = 'clang-analyzer',
171*10465441SEvalZero                      action = 'store_true',
172*10465441SEvalZero                      default = False,
173*10465441SEvalZero                      help = 'Perform static analyze with Clang-analyzer. ' + \
174*10465441SEvalZero                           'Requires Clang installed.\n' + \
175*10465441SEvalZero                           'It is recommended to use with scan-build like this:\n' + \
176*10465441SEvalZero                           '`scan-build scons --clang-analyzer`\n' + \
177*10465441SEvalZero                           'If things goes well, scan-build will instruct you to invoke scan-view.')
178*10465441SEvalZero    AddOption('--buildlib',
179*10465441SEvalZero                      dest = 'buildlib',
180*10465441SEvalZero                      type = 'string',
181*10465441SEvalZero                      help = 'building library of a component')
182*10465441SEvalZero    AddOption('--cleanlib',
183*10465441SEvalZero                      dest = 'cleanlib',
184*10465441SEvalZero                      action = 'store_true',
185*10465441SEvalZero                      default = False,
186*10465441SEvalZero                      help = 'clean up the library by --buildlib')
187*10465441SEvalZero    AddOption('--target',
188*10465441SEvalZero                      dest = 'target',
189*10465441SEvalZero                      type = 'string',
190*10465441SEvalZero                      help = 'set target project: mdk/mdk4/mdk5/iar/vs/vsc/ua/cdk/ses')
191*10465441SEvalZero    AddOption('--genconfig',
192*10465441SEvalZero                dest = 'genconfig',
193*10465441SEvalZero                action = 'store_true',
194*10465441SEvalZero                default = False,
195*10465441SEvalZero                help = 'Generate .config from rtconfig.h')
196*10465441SEvalZero    AddOption('--useconfig',
197*10465441SEvalZero                dest = 'useconfig',
198*10465441SEvalZero                type = 'string',
199*10465441SEvalZero                help = 'make rtconfig.h from config file.')
200*10465441SEvalZero    AddOption('--verbose',
201*10465441SEvalZero                dest = 'verbose',
202*10465441SEvalZero                action = 'store_true',
203*10465441SEvalZero                default = False,
204*10465441SEvalZero                help = 'print verbose information during build')
205*10465441SEvalZero
206*10465441SEvalZero    Env = env
207*10465441SEvalZero    Rtt_Root = os.path.abspath(root_directory)
208*10465441SEvalZero
209*10465441SEvalZero    # make an absolute root directory
210*10465441SEvalZero    RTT_ROOT = Rtt_Root
211*10465441SEvalZero    Export('RTT_ROOT')
212*10465441SEvalZero
213*10465441SEvalZero    # set RTT_ROOT in ENV
214*10465441SEvalZero    Env['RTT_ROOT'] = Rtt_Root
215*10465441SEvalZero    # set BSP_ROOT in ENV
216*10465441SEvalZero    Env['BSP_ROOT'] = Dir('#').abspath
217*10465441SEvalZero
218*10465441SEvalZero    sys.path = sys.path + [os.path.join(Rtt_Root, 'tools')]
219*10465441SEvalZero
220*10465441SEvalZero    # {target_name:(CROSS_TOOL, PLATFORM)}
221*10465441SEvalZero    tgt_dict = {'mdk':('keil', 'armcc'),
222*10465441SEvalZero                'mdk4':('keil', 'armcc'),
223*10465441SEvalZero                'mdk5':('keil', 'armcc'),
224*10465441SEvalZero                'iar':('iar', 'iar'),
225*10465441SEvalZero                'vs':('msvc', 'cl'),
226*10465441SEvalZero                'vs2012':('msvc', 'cl'),
227*10465441SEvalZero                'vsc' : ('gcc', 'gcc'),
228*10465441SEvalZero                'cb':('keil', 'armcc'),
229*10465441SEvalZero                'ua':('gcc', 'gcc'),
230*10465441SEvalZero                'cdk':('gcc', 'gcc'),
231*10465441SEvalZero                'ses' : ('gcc', 'gcc')}
232*10465441SEvalZero    tgt_name = GetOption('target')
233*10465441SEvalZero
234*10465441SEvalZero    if tgt_name:
235*10465441SEvalZero        # --target will change the toolchain settings which clang-analyzer is
236*10465441SEvalZero        # depend on
237*10465441SEvalZero        if GetOption('clang-analyzer'):
238*10465441SEvalZero            print ('--clang-analyzer cannot be used with --target')
239*10465441SEvalZero            sys.exit(1)
240*10465441SEvalZero
241*10465441SEvalZero        SetOption('no_exec', 1)
242*10465441SEvalZero        try:
243*10465441SEvalZero            rtconfig.CROSS_TOOL, rtconfig.PLATFORM = tgt_dict[tgt_name]
244*10465441SEvalZero            # replace the 'RTT_CC' to 'CROSS_TOOL'
245*10465441SEvalZero            os.environ['RTT_CC'] = rtconfig.CROSS_TOOL
246*10465441SEvalZero            utils.ReloadModule(rtconfig)
247*10465441SEvalZero        except KeyError:
248*10465441SEvalZero            print ('Unknow target: '+ tgt_name+'. Avaible targets: ' +', '.join(tgt_dict.keys()))
249*10465441SEvalZero            sys.exit(1)
250*10465441SEvalZero    elif (GetDepend('RT_USING_NEWLIB') == False and GetDepend('RT_USING_NOLIBC') == False) \
251*10465441SEvalZero        and rtconfig.PLATFORM == 'gcc':
252*10465441SEvalZero        AddDepend('RT_USING_MINILIBC')
253*10465441SEvalZero
254*10465441SEvalZero    # auto change the 'RTT_EXEC_PATH' when 'rtconfig.EXEC_PATH' get failed
255*10465441SEvalZero    if not os.path.exists(rtconfig.EXEC_PATH):
256*10465441SEvalZero        if 'RTT_EXEC_PATH' in os.environ:
257*10465441SEvalZero            # del the 'RTT_EXEC_PATH' and using the 'EXEC_PATH' setting on rtconfig.py
258*10465441SEvalZero            del os.environ['RTT_EXEC_PATH']
259*10465441SEvalZero            utils.ReloadModule(rtconfig)
260*10465441SEvalZero
261*10465441SEvalZero    # add compability with Keil MDK 4.6 which changes the directory of armcc.exe
262*10465441SEvalZero    if rtconfig.PLATFORM == 'armcc':
263*10465441SEvalZero        if not os.path.isfile(os.path.join(rtconfig.EXEC_PATH, 'armcc.exe')):
264*10465441SEvalZero            if rtconfig.EXEC_PATH.find('bin40') > 0:
265*10465441SEvalZero                rtconfig.EXEC_PATH = rtconfig.EXEC_PATH.replace('bin40', 'armcc/bin')
266*10465441SEvalZero                Env['LINKFLAGS'] = Env['LINKFLAGS'].replace('RV31', 'armcc')
267*10465441SEvalZero
268*10465441SEvalZero        # reset AR command flags
269*10465441SEvalZero        env['ARCOM'] = '$AR --create $TARGET $SOURCES'
270*10465441SEvalZero        env['LIBPREFIX'] = ''
271*10465441SEvalZero        env['LIBSUFFIX'] = '.lib'
272*10465441SEvalZero        env['LIBLINKPREFIX'] = ''
273*10465441SEvalZero        env['LIBLINKSUFFIX'] = '.lib'
274*10465441SEvalZero        env['LIBDIRPREFIX'] = '--userlibpath '
275*10465441SEvalZero
276*10465441SEvalZero    elif rtconfig.PLATFORM == 'iar':
277*10465441SEvalZero        env['LIBPREFIX'] = ''
278*10465441SEvalZero        env['LIBSUFFIX'] = '.a'
279*10465441SEvalZero        env['LIBLINKPREFIX'] = ''
280*10465441SEvalZero        env['LIBLINKSUFFIX'] = '.a'
281*10465441SEvalZero        env['LIBDIRPREFIX'] = '--search '
282*10465441SEvalZero
283*10465441SEvalZero    # patch for win32 spawn
284*10465441SEvalZero    if env['PLATFORM'] == 'win32':
285*10465441SEvalZero        win32_spawn = Win32Spawn()
286*10465441SEvalZero        win32_spawn.env = env
287*10465441SEvalZero        env['SPAWN'] = win32_spawn.spawn
288*10465441SEvalZero
289*10465441SEvalZero    if env['PLATFORM'] == 'win32':
290*10465441SEvalZero        os.environ['PATH'] = rtconfig.EXEC_PATH + ";" + os.environ['PATH']
291*10465441SEvalZero    else:
292*10465441SEvalZero        os.environ['PATH'] = rtconfig.EXEC_PATH + ":" + os.environ['PATH']
293*10465441SEvalZero
294*10465441SEvalZero    # add program path
295*10465441SEvalZero    env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
296*10465441SEvalZero    # add rtconfig.h/BSP path into Kernel group
297*10465441SEvalZero    DefineGroup("Kernel", [], [], CPPPATH=[str(Dir('#').abspath)])
298*10465441SEvalZero
299*10465441SEvalZero    # add library build action
300*10465441SEvalZero    act = SCons.Action.Action(BuildLibInstallAction, 'Install compiled library... $TARGET')
301*10465441SEvalZero    bld = Builder(action = act)
302*10465441SEvalZero    Env.Append(BUILDERS = {'BuildLib': bld})
303*10465441SEvalZero
304*10465441SEvalZero    # parse rtconfig.h to get used component
305*10465441SEvalZero    PreProcessor = PatchedPreProcessor()
306*10465441SEvalZero    f = open('rtconfig.h', 'r')
307*10465441SEvalZero    contents = f.read()
308*10465441SEvalZero    f.close()
309*10465441SEvalZero    PreProcessor.process_contents(contents)
310*10465441SEvalZero    BuildOptions = PreProcessor.cpp_namespace
311*10465441SEvalZero
312*10465441SEvalZero    if GetOption('clang-analyzer'):
313*10465441SEvalZero        # perform what scan-build does
314*10465441SEvalZero        env.Replace(
315*10465441SEvalZero                CC   = 'ccc-analyzer',
316*10465441SEvalZero                CXX  = 'c++-analyzer',
317*10465441SEvalZero                # skip as and link
318*10465441SEvalZero                LINK = 'true',
319*10465441SEvalZero                AS   = 'true',)
320*10465441SEvalZero        env["ENV"].update(x for x in os.environ.items() if x[0].startswith("CCC_"))
321*10465441SEvalZero        # only check, don't compile. ccc-analyzer use CCC_CC as the CC.
322*10465441SEvalZero        # fsyntax-only will give us some additional warning messages
323*10465441SEvalZero        env['ENV']['CCC_CC']  = 'clang'
324*10465441SEvalZero        env.Append(CFLAGS=['-fsyntax-only', '-Wall', '-Wno-invalid-source-encoding'])
325*10465441SEvalZero        env['ENV']['CCC_CXX'] = 'clang++'
326*10465441SEvalZero        env.Append(CXXFLAGS=['-fsyntax-only', '-Wall', '-Wno-invalid-source-encoding'])
327*10465441SEvalZero        # remove the POST_ACTION as it will cause meaningless errors(file not
328*10465441SEvalZero        # found or something like that).
329*10465441SEvalZero        rtconfig.POST_ACTION = ''
330*10465441SEvalZero
331*10465441SEvalZero    # generate cconfig.h file
332*10465441SEvalZero    GenCconfigFile(env, BuildOptions)
333*10465441SEvalZero
334*10465441SEvalZero    # auto append '_REENT_SMALL' when using newlib 'nano.specs' option
335*10465441SEvalZero    if rtconfig.PLATFORM == 'gcc' and str(env['LINKFLAGS']).find('nano.specs') != -1:
336*10465441SEvalZero        env.AppendUnique(CPPDEFINES = ['_REENT_SMALL'])
337*10465441SEvalZero
338*10465441SEvalZero    if GetOption('genconfig'):
339*10465441SEvalZero        from genconf import genconfig
340*10465441SEvalZero        genconfig()
341*10465441SEvalZero        exit(0)
342*10465441SEvalZero
343*10465441SEvalZero    if env['PLATFORM'] != 'win32':
344*10465441SEvalZero        AddOption('--menuconfig',
345*10465441SEvalZero                    dest = 'menuconfig',
346*10465441SEvalZero                    action = 'store_true',
347*10465441SEvalZero                    default = False,
348*10465441SEvalZero                    help = 'make menuconfig for RT-Thread BSP')
349*10465441SEvalZero        if GetOption('menuconfig'):
350*10465441SEvalZero            from menuconfig import menuconfig
351*10465441SEvalZero            menuconfig(Rtt_Root)
352*10465441SEvalZero            exit(0)
353*10465441SEvalZero
354*10465441SEvalZero    AddOption('--pyconfig',
355*10465441SEvalZero                dest = 'pyconfig',
356*10465441SEvalZero                action = 'store_true',
357*10465441SEvalZero                default = False,
358*10465441SEvalZero                help = 'make menuconfig for RT-Thread BSP')
359*10465441SEvalZero    AddOption('--pyconfig-silent',
360*10465441SEvalZero                dest = 'pyconfig_silent',
361*10465441SEvalZero                action = 'store_true',
362*10465441SEvalZero                default = False,
363*10465441SEvalZero                help = 'Don`t show pyconfig window')
364*10465441SEvalZero
365*10465441SEvalZero    if GetOption('pyconfig_silent'):
366*10465441SEvalZero        from menuconfig import pyconfig_silent
367*10465441SEvalZero
368*10465441SEvalZero        pyconfig_silent(Rtt_Root)
369*10465441SEvalZero        exit(0)
370*10465441SEvalZero    elif GetOption('pyconfig'):
371*10465441SEvalZero        from menuconfig import pyconfig
372*10465441SEvalZero
373*10465441SEvalZero        pyconfig(Rtt_Root)
374*10465441SEvalZero        exit(0)
375*10465441SEvalZero
376*10465441SEvalZero    configfn = GetOption('useconfig')
377*10465441SEvalZero    if configfn:
378*10465441SEvalZero        from menuconfig import mk_rtconfig
379*10465441SEvalZero        mk_rtconfig(configfn)
380*10465441SEvalZero        exit(0)
381*10465441SEvalZero
382*10465441SEvalZero
383*10465441SEvalZero    if not GetOption('verbose'):
384*10465441SEvalZero        # override the default verbose command string
385*10465441SEvalZero        env.Replace(
386*10465441SEvalZero            ARCOMSTR = 'AR $TARGET',
387*10465441SEvalZero            ASCOMSTR = 'AS $TARGET',
388*10465441SEvalZero            ASPPCOMSTR = 'AS $TARGET',
389*10465441SEvalZero            CCCOMSTR = 'CC $TARGET',
390*10465441SEvalZero            CXXCOMSTR = 'CXX $TARGET',
391*10465441SEvalZero            LINKCOMSTR = 'LINK $TARGET'
392*10465441SEvalZero        )
393*10465441SEvalZero
394*10465441SEvalZero    # fix the linker for C++
395*10465441SEvalZero    if GetDepend('RT_USING_CPLUSPLUS'):
396*10465441SEvalZero        if env['LINK'].find('gcc') != -1:
397*10465441SEvalZero            env['LINK'] = env['LINK'].replace('gcc', 'g++')
398*10465441SEvalZero
399*10465441SEvalZero    # we need to seperate the variant_dir for BSPs and the kernels. BSPs could
400*10465441SEvalZero    # have their own components etc. If they point to the same folder, SCons
401*10465441SEvalZero    # would find the wrong source code to compile.
402*10465441SEvalZero    bsp_vdir = 'build'
403*10465441SEvalZero    kernel_vdir = 'build/kernel'
404*10465441SEvalZero    # board build script
405*10465441SEvalZero    objs = SConscript('SConscript', variant_dir=bsp_vdir, duplicate=0)
406*10465441SEvalZero    # include kernel
407*10465441SEvalZero    objs.extend(SConscript(Rtt_Root + '/src/SConscript', variant_dir=kernel_vdir + '/src', duplicate=0))
408*10465441SEvalZero    # include libcpu
409*10465441SEvalZero    if not has_libcpu:
410*10465441SEvalZero        objs.extend(SConscript(Rtt_Root + '/libcpu/SConscript',
411*10465441SEvalZero                    variant_dir=kernel_vdir + '/libcpu', duplicate=0))
412*10465441SEvalZero
413*10465441SEvalZero    # include components
414*10465441SEvalZero    objs.extend(SConscript(Rtt_Root + '/components/SConscript',
415*10465441SEvalZero                           variant_dir=kernel_vdir + '/components',
416*10465441SEvalZero                           duplicate=0,
417*10465441SEvalZero                           exports='remove_components'))
418*10465441SEvalZero
419*10465441SEvalZero    return objs
420*10465441SEvalZero
421*10465441SEvalZerodef PrepareModuleBuilding(env, root_directory, bsp_directory):
422*10465441SEvalZero    import rtconfig
423*10465441SEvalZero
424*10465441SEvalZero    global BuildOptions
425*10465441SEvalZero    global Env
426*10465441SEvalZero    global Rtt_Root
427*10465441SEvalZero
428*10465441SEvalZero    # patch for win32 spawn
429*10465441SEvalZero    if env['PLATFORM'] == 'win32':
430*10465441SEvalZero        win32_spawn = Win32Spawn()
431*10465441SEvalZero        win32_spawn.env = env
432*10465441SEvalZero        env['SPAWN'] = win32_spawn.spawn
433*10465441SEvalZero
434*10465441SEvalZero    Env = env
435*10465441SEvalZero    Rtt_Root = root_directory
436*10465441SEvalZero
437*10465441SEvalZero    # parse bsp rtconfig.h to get used component
438*10465441SEvalZero    PreProcessor = PatchedPreProcessor()
439*10465441SEvalZero    f = open(bsp_directory + '/rtconfig.h', 'r')
440*10465441SEvalZero    contents = f.read()
441*10465441SEvalZero    f.close()
442*10465441SEvalZero    PreProcessor.process_contents(contents)
443*10465441SEvalZero    BuildOptions = PreProcessor.cpp_namespace
444*10465441SEvalZero
445*10465441SEvalZero    # add build/clean library option for library checking
446*10465441SEvalZero    AddOption('--buildlib',
447*10465441SEvalZero              dest='buildlib',
448*10465441SEvalZero              type='string',
449*10465441SEvalZero              help='building library of a component')
450*10465441SEvalZero    AddOption('--cleanlib',
451*10465441SEvalZero              dest='cleanlib',
452*10465441SEvalZero              action='store_true',
453*10465441SEvalZero              default=False,
454*10465441SEvalZero              help='clean up the library by --buildlib')
455*10465441SEvalZero
456*10465441SEvalZero    # add program path
457*10465441SEvalZero    env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
458*10465441SEvalZero
459*10465441SEvalZerodef GetConfigValue(name):
460*10465441SEvalZero    assert type(name) == str, 'GetConfigValue: only string parameter is valid'
461*10465441SEvalZero    try:
462*10465441SEvalZero        return BuildOptions[name]
463*10465441SEvalZero    except:
464*10465441SEvalZero        return ''
465*10465441SEvalZero
466*10465441SEvalZerodef GetDepend(depend):
467*10465441SEvalZero    building = True
468*10465441SEvalZero    if type(depend) == type('str'):
469*10465441SEvalZero        if not depend in BuildOptions or BuildOptions[depend] == 0:
470*10465441SEvalZero            building = False
471*10465441SEvalZero        elif BuildOptions[depend] != '':
472*10465441SEvalZero            return BuildOptions[depend]
473*10465441SEvalZero
474*10465441SEvalZero        return building
475*10465441SEvalZero
476*10465441SEvalZero    # for list type depend
477*10465441SEvalZero    for item in depend:
478*10465441SEvalZero        if item != '':
479*10465441SEvalZero            if not item in BuildOptions or BuildOptions[item] == 0:
480*10465441SEvalZero                building = False
481*10465441SEvalZero
482*10465441SEvalZero    return building
483*10465441SEvalZero
484*10465441SEvalZerodef LocalOptions(config_filename):
485*10465441SEvalZero    from SCons.Script import SCons
486*10465441SEvalZero
487*10465441SEvalZero    # parse wiced_config.h to get used component
488*10465441SEvalZero    PreProcessor = SCons.cpp.PreProcessor()
489*10465441SEvalZero
490*10465441SEvalZero    f = open(config_filename, 'r')
491*10465441SEvalZero    contents = f.read()
492*10465441SEvalZero    f.close()
493*10465441SEvalZero
494*10465441SEvalZero    PreProcessor.process_contents(contents)
495*10465441SEvalZero    local_options = PreProcessor.cpp_namespace
496*10465441SEvalZero
497*10465441SEvalZero    return local_options
498*10465441SEvalZero
499*10465441SEvalZerodef GetLocalDepend(options, depend):
500*10465441SEvalZero    building = True
501*10465441SEvalZero    if type(depend) == type('str'):
502*10465441SEvalZero        if not depend in options or options[depend] == 0:
503*10465441SEvalZero            building = False
504*10465441SEvalZero        elif options[depend] != '':
505*10465441SEvalZero            return options[depend]
506*10465441SEvalZero
507*10465441SEvalZero        return building
508*10465441SEvalZero
509*10465441SEvalZero    # for list type depend
510*10465441SEvalZero    for item in depend:
511*10465441SEvalZero        if item != '':
512*10465441SEvalZero            if not item in options or options[item] == 0:
513*10465441SEvalZero                building = False
514*10465441SEvalZero
515*10465441SEvalZero    return building
516*10465441SEvalZero
517*10465441SEvalZerodef AddDepend(option):
518*10465441SEvalZero    BuildOptions[option] = 1
519*10465441SEvalZero
520*10465441SEvalZerodef MergeGroup(src_group, group):
521*10465441SEvalZero    src_group['src'] = src_group['src'] + group['src']
522*10465441SEvalZero    if 'CCFLAGS' in group:
523*10465441SEvalZero        if 'CCFLAGS' in src_group:
524*10465441SEvalZero            src_group['CCFLAGS'] = src_group['CCFLAGS'] + group['CCFLAGS']
525*10465441SEvalZero        else:
526*10465441SEvalZero            src_group['CCFLAGS'] = group['CCFLAGS']
527*10465441SEvalZero    if 'CPPPATH' in group:
528*10465441SEvalZero        if 'CPPPATH' in src_group:
529*10465441SEvalZero            src_group['CPPPATH'] = src_group['CPPPATH'] + group['CPPPATH']
530*10465441SEvalZero        else:
531*10465441SEvalZero            src_group['CPPPATH'] = group['CPPPATH']
532*10465441SEvalZero    if 'CPPDEFINES' in group:
533*10465441SEvalZero        if 'CPPDEFINES' in src_group:
534*10465441SEvalZero            src_group['CPPDEFINES'] = src_group['CPPDEFINES'] + group['CPPDEFINES']
535*10465441SEvalZero        else:
536*10465441SEvalZero            src_group['CPPDEFINES'] = group['CPPDEFINES']
537*10465441SEvalZero    if 'ASFLAGS' in group:
538*10465441SEvalZero        if 'ASFLAGS' in src_group:
539*10465441SEvalZero            src_group['ASFLAGS'] = src_group['ASFLAGS'] + group['ASFLAGS']
540*10465441SEvalZero        else:
541*10465441SEvalZero            src_group['ASFLAGS'] = group['ASFLAGS']
542*10465441SEvalZero
543*10465441SEvalZero    # for local CCFLAGS/CPPPATH/CPPDEFINES
544*10465441SEvalZero    if 'LOCAL_CCFLAGS' in group:
545*10465441SEvalZero        if 'LOCAL_CCFLAGS' in src_group:
546*10465441SEvalZero            src_group['LOCAL_CCFLAGS'] = src_group['LOCAL_CCFLAGS'] + group['LOCAL_CCFLAGS']
547*10465441SEvalZero        else:
548*10465441SEvalZero            src_group['LOCAL_CCFLAGS'] = group['LOCAL_CCFLAGS']
549*10465441SEvalZero    if 'LOCAL_CPPPATH' in group:
550*10465441SEvalZero        if 'LOCAL_CPPPATH' in src_group:
551*10465441SEvalZero            src_group['LOCAL_CPPPATH'] = src_group['LOCAL_CPPPATH'] + group['LOCAL_CPPPATH']
552*10465441SEvalZero        else:
553*10465441SEvalZero            src_group['LOCAL_CPPPATH'] = group['LOCAL_CPPPATH']
554*10465441SEvalZero    if 'LOCAL_CPPDEFINES' in group:
555*10465441SEvalZero        if 'LOCAL_CPPDEFINES' in src_group:
556*10465441SEvalZero            src_group['LOCAL_CPPDEFINES'] = src_group['LOCAL_CPPDEFINES'] + group['LOCAL_CPPDEFINES']
557*10465441SEvalZero        else:
558*10465441SEvalZero            src_group['LOCAL_CPPDEFINES'] = group['LOCAL_CPPDEFINES']
559*10465441SEvalZero
560*10465441SEvalZero    if 'LINKFLAGS' in group:
561*10465441SEvalZero        if 'LINKFLAGS' in src_group:
562*10465441SEvalZero            src_group['LINKFLAGS'] = src_group['LINKFLAGS'] + group['LINKFLAGS']
563*10465441SEvalZero        else:
564*10465441SEvalZero            src_group['LINKFLAGS'] = group['LINKFLAGS']
565*10465441SEvalZero    if 'LIBS' in group:
566*10465441SEvalZero        if 'LIBS' in src_group:
567*10465441SEvalZero            src_group['LIBS'] = src_group['LIBS'] + group['LIBS']
568*10465441SEvalZero        else:
569*10465441SEvalZero            src_group['LIBS'] = group['LIBS']
570*10465441SEvalZero    if 'LIBPATH' in group:
571*10465441SEvalZero        if 'LIBPATH' in src_group:
572*10465441SEvalZero            src_group['LIBPATH'] = src_group['LIBPATH'] + group['LIBPATH']
573*10465441SEvalZero        else:
574*10465441SEvalZero            src_group['LIBPATH'] = group['LIBPATH']
575*10465441SEvalZero    if 'LOCAL_ASFLAGS' in group:
576*10465441SEvalZero        if 'LOCAL_ASFLAGS' in src_group:
577*10465441SEvalZero            src_group['LOCAL_ASFLAGS'] = src_group['LOCAL_ASFLAGS'] + group['LOCAL_ASFLAGS']
578*10465441SEvalZero        else:
579*10465441SEvalZero            src_group['LOCAL_ASFLAGS'] = group['LOCAL_ASFLAGS']
580*10465441SEvalZero
581*10465441SEvalZerodef DefineGroup(name, src, depend, **parameters):
582*10465441SEvalZero    global Env
583*10465441SEvalZero    if not GetDepend(depend):
584*10465441SEvalZero        return []
585*10465441SEvalZero
586*10465441SEvalZero    # find exist group and get path of group
587*10465441SEvalZero    group_path = ''
588*10465441SEvalZero    for g in Projects:
589*10465441SEvalZero        if g['name'] == name:
590*10465441SEvalZero            group_path = g['path']
591*10465441SEvalZero    if group_path == '':
592*10465441SEvalZero        group_path = GetCurrentDir()
593*10465441SEvalZero
594*10465441SEvalZero    group = parameters
595*10465441SEvalZero    group['name'] = name
596*10465441SEvalZero    group['path'] = group_path
597*10465441SEvalZero    if type(src) == type([]):
598*10465441SEvalZero        group['src'] = File(src)
599*10465441SEvalZero    else:
600*10465441SEvalZero        group['src'] = src
601*10465441SEvalZero
602*10465441SEvalZero    if 'CCFLAGS' in group:
603*10465441SEvalZero        Env.AppendUnique(CCFLAGS = group['CCFLAGS'])
604*10465441SEvalZero    if 'CPPPATH' in group:
605*10465441SEvalZero        paths = []
606*10465441SEvalZero        for item in group['CPPPATH']:
607*10465441SEvalZero            paths.append(os.path.abspath(item))
608*10465441SEvalZero        group['CPPPATH'] = paths
609*10465441SEvalZero        Env.AppendUnique(CPPPATH = group['CPPPATH'])
610*10465441SEvalZero    if 'CPPDEFINES' in group:
611*10465441SEvalZero        Env.AppendUnique(CPPDEFINES = group['CPPDEFINES'])
612*10465441SEvalZero    if 'LINKFLAGS' in group:
613*10465441SEvalZero        Env.AppendUnique(LINKFLAGS = group['LINKFLAGS'])
614*10465441SEvalZero    if 'ASFLAGS' in group:
615*10465441SEvalZero        Env.AppendUnique(ASFLAGS = group['ASFLAGS'])
616*10465441SEvalZero    if 'LOCAL_CPPPATH' in group:
617*10465441SEvalZero        paths = []
618*10465441SEvalZero        for item in group['LOCAL_CPPPATH']:
619*10465441SEvalZero            paths.append(os.path.abspath(item))
620*10465441SEvalZero        group['LOCAL_CPPPATH'] = paths
621*10465441SEvalZero
622*10465441SEvalZero    import rtconfig
623*10465441SEvalZero    if rtconfig.PLATFORM == 'gcc':
624*10465441SEvalZero        if 'CCFLAGS' in group:
625*10465441SEvalZero            group['CCFLAGS'] = utils.GCCC99Patch(group['CCFLAGS'])
626*10465441SEvalZero        if 'LOCAL_CCFLAGS' in group:
627*10465441SEvalZero            group['LOCAL_CCFLAGS'] = utils.GCCC99Patch(group['LOCAL_CCFLAGS'])
628*10465441SEvalZero
629*10465441SEvalZero    # check whether to clean up library
630*10465441SEvalZero    if GetOption('cleanlib') and os.path.exists(os.path.join(group['path'], GroupLibFullName(name, Env))):
631*10465441SEvalZero        if group['src'] != []:
632*10465441SEvalZero            print ('Remove library:'+ GroupLibFullName(name, Env))
633*10465441SEvalZero            fn = os.path.join(group['path'], GroupLibFullName(name, Env))
634*10465441SEvalZero            if os.path.exists(fn):
635*10465441SEvalZero                os.unlink(fn)
636*10465441SEvalZero
637*10465441SEvalZero    if 'LIBS' in group:
638*10465441SEvalZero        Env.AppendUnique(LIBS = group['LIBS'])
639*10465441SEvalZero    if 'LIBPATH' in group:
640*10465441SEvalZero        Env.AppendUnique(LIBPATH = group['LIBPATH'])
641*10465441SEvalZero
642*10465441SEvalZero    # check whether to build group library
643*10465441SEvalZero    if 'LIBRARY' in group:
644*10465441SEvalZero        objs = Env.Library(name, group['src'])
645*10465441SEvalZero    else:
646*10465441SEvalZero        # only add source
647*10465441SEvalZero        objs = group['src']
648*10465441SEvalZero
649*10465441SEvalZero    # merge group
650*10465441SEvalZero    for g in Projects:
651*10465441SEvalZero        if g['name'] == name:
652*10465441SEvalZero            # merge to this group
653*10465441SEvalZero            MergeGroup(g, group)
654*10465441SEvalZero            return objs
655*10465441SEvalZero
656*10465441SEvalZero    # add a new group
657*10465441SEvalZero    Projects.append(group)
658*10465441SEvalZero
659*10465441SEvalZero    return objs
660*10465441SEvalZero
661*10465441SEvalZerodef GetCurrentDir():
662*10465441SEvalZero    conscript = File('SConscript')
663*10465441SEvalZero    fn = conscript.rfile()
664*10465441SEvalZero    name = fn.name
665*10465441SEvalZero    path = os.path.dirname(fn.abspath)
666*10465441SEvalZero    return path
667*10465441SEvalZero
668*10465441SEvalZeroPREBUILDING = []
669*10465441SEvalZerodef RegisterPreBuildingAction(act):
670*10465441SEvalZero    global PREBUILDING
671*10465441SEvalZero    assert callable(act), 'Could only register callable objects. %s received' % repr(act)
672*10465441SEvalZero    PREBUILDING.append(act)
673*10465441SEvalZero
674*10465441SEvalZerodef PreBuilding():
675*10465441SEvalZero    global PREBUILDING
676*10465441SEvalZero    for a in PREBUILDING:
677*10465441SEvalZero        a()
678*10465441SEvalZero
679*10465441SEvalZerodef GroupLibName(name, env):
680*10465441SEvalZero    import rtconfig
681*10465441SEvalZero    if rtconfig.PLATFORM == 'armcc':
682*10465441SEvalZero        return name + '_rvds'
683*10465441SEvalZero    elif rtconfig.PLATFORM == 'gcc':
684*10465441SEvalZero        return name + '_gcc'
685*10465441SEvalZero
686*10465441SEvalZero    return name
687*10465441SEvalZero
688*10465441SEvalZerodef GroupLibFullName(name, env):
689*10465441SEvalZero    return env['LIBPREFIX'] + GroupLibName(name, env) + env['LIBSUFFIX']
690*10465441SEvalZero
691*10465441SEvalZerodef BuildLibInstallAction(target, source, env):
692*10465441SEvalZero    lib_name = GetOption('buildlib')
693*10465441SEvalZero    for Group in Projects:
694*10465441SEvalZero        if Group['name'] == lib_name:
695*10465441SEvalZero            lib_name = GroupLibFullName(Group['name'], env)
696*10465441SEvalZero            dst_name = os.path.join(Group['path'], lib_name)
697*10465441SEvalZero            print ('Copy '+lib_name+' => ' +dst_name)
698*10465441SEvalZero            do_copy_file(lib_name, dst_name)
699*10465441SEvalZero            break
700*10465441SEvalZero
701*10465441SEvalZerodef DoBuilding(target, objects):
702*10465441SEvalZero
703*10465441SEvalZero    # merge all objects into one list
704*10465441SEvalZero    def one_list(l):
705*10465441SEvalZero        lst = []
706*10465441SEvalZero        for item in l:
707*10465441SEvalZero            if type(item) == type([]):
708*10465441SEvalZero                lst += one_list(item)
709*10465441SEvalZero            else:
710*10465441SEvalZero                lst.append(item)
711*10465441SEvalZero        return lst
712*10465441SEvalZero
713*10465441SEvalZero    # handle local group
714*10465441SEvalZero    def local_group(group, objects):
715*10465441SEvalZero        if 'LOCAL_CCFLAGS' in group or 'LOCAL_CPPPATH' in group or 'LOCAL_CPPDEFINES' in group or 'LOCAL_ASFLAGS' in group:
716*10465441SEvalZero            CCFLAGS = Env.get('CCFLAGS', '') + group.get('LOCAL_CCFLAGS', '')
717*10465441SEvalZero            CPPPATH = Env.get('CPPPATH', ['']) + group.get('LOCAL_CPPPATH', [''])
718*10465441SEvalZero            CPPDEFINES = Env.get('CPPDEFINES', ['']) + group.get('LOCAL_CPPDEFINES', [''])
719*10465441SEvalZero            ASFLAGS = Env.get('ASFLAGS', '') + group.get('LOCAL_ASFLAGS', '')
720*10465441SEvalZero
721*10465441SEvalZero            for source in group['src']:
722*10465441SEvalZero                objects.append(Env.Object(source, CCFLAGS = CCFLAGS, ASFLAGS = ASFLAGS,
723*10465441SEvalZero                    CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES))
724*10465441SEvalZero
725*10465441SEvalZero            return True
726*10465441SEvalZero
727*10465441SEvalZero        return False
728*10465441SEvalZero
729*10465441SEvalZero    objects = one_list(objects)
730*10465441SEvalZero
731*10465441SEvalZero    program = None
732*10465441SEvalZero    # check whether special buildlib option
733*10465441SEvalZero    lib_name = GetOption('buildlib')
734*10465441SEvalZero    if lib_name:
735*10465441SEvalZero        objects = [] # remove all of objects
736*10465441SEvalZero        # build library with special component
737*10465441SEvalZero        for Group in Projects:
738*10465441SEvalZero            if Group['name'] == lib_name:
739*10465441SEvalZero                lib_name = GroupLibName(Group['name'], Env)
740*10465441SEvalZero                if not local_group(Group, objects):
741*10465441SEvalZero                    objects = Env.Object(Group['src'])
742*10465441SEvalZero
743*10465441SEvalZero                program = Env.Library(lib_name, objects)
744*10465441SEvalZero
745*10465441SEvalZero                # add library copy action
746*10465441SEvalZero                Env.BuildLib(lib_name, program)
747*10465441SEvalZero
748*10465441SEvalZero                break
749*10465441SEvalZero    else:
750*10465441SEvalZero        # remove source files with local flags setting
751*10465441SEvalZero        for group in Projects:
752*10465441SEvalZero            if 'LOCAL_CCFLAGS' in group or 'LOCAL_CPPPATH' in group or 'LOCAL_CPPDEFINES' in group:
753*10465441SEvalZero                for source in group['src']:
754*10465441SEvalZero                    for obj in objects:
755*10465441SEvalZero                        if source.abspath == obj.abspath or (len(obj.sources) > 0 and source.abspath == obj.sources[0].abspath):
756*10465441SEvalZero                            objects.remove(obj)
757*10465441SEvalZero
758*10465441SEvalZero        # re-add the source files to the objects
759*10465441SEvalZero        for group in Projects:
760*10465441SEvalZero            local_group(group, objects)
761*10465441SEvalZero
762*10465441SEvalZero        program = Env.Program(target, objects)
763*10465441SEvalZero
764*10465441SEvalZero    EndBuilding(target, program)
765*10465441SEvalZero
766*10465441SEvalZerodef GenTargetProject(program = None):
767*10465441SEvalZero
768*10465441SEvalZero    if GetOption('target') == 'mdk':
769*10465441SEvalZero        from keil import MDKProject
770*10465441SEvalZero        from keil import MDK4Project
771*10465441SEvalZero        from keil import MDK5Project
772*10465441SEvalZero
773*10465441SEvalZero        template = os.path.isfile('template.Uv2')
774*10465441SEvalZero        if template:
775*10465441SEvalZero            MDKProject('project.Uv2', Projects)
776*10465441SEvalZero        else:
777*10465441SEvalZero            template = os.path.isfile('template.uvproj')
778*10465441SEvalZero            if template:
779*10465441SEvalZero                MDK4Project('project.uvproj', Projects)
780*10465441SEvalZero            else:
781*10465441SEvalZero                template = os.path.isfile('template.uvprojx')
782*10465441SEvalZero                if template:
783*10465441SEvalZero                    MDK5Project('project.uvprojx', Projects)
784*10465441SEvalZero                else:
785*10465441SEvalZero                    print ('No template project file found.')
786*10465441SEvalZero
787*10465441SEvalZero    if GetOption('target') == 'mdk4':
788*10465441SEvalZero        from keil import MDK4Project
789*10465441SEvalZero        MDK4Project('project.uvproj', Projects)
790*10465441SEvalZero
791*10465441SEvalZero    if GetOption('target') == 'mdk5':
792*10465441SEvalZero        from keil import MDK5Project
793*10465441SEvalZero        MDK5Project('project.uvprojx', Projects)
794*10465441SEvalZero
795*10465441SEvalZero    if GetOption('target') == 'iar':
796*10465441SEvalZero        from iar import IARProject
797*10465441SEvalZero        IARProject('project.ewp', Projects)
798*10465441SEvalZero
799*10465441SEvalZero    if GetOption('target') == 'vs':
800*10465441SEvalZero        from vs import VSProject
801*10465441SEvalZero        VSProject('project.vcproj', Projects, program)
802*10465441SEvalZero
803*10465441SEvalZero    if GetOption('target') == 'vs2012':
804*10465441SEvalZero        from vs2012 import VS2012Project
805*10465441SEvalZero        VS2012Project('project.vcxproj', Projects, program)
806*10465441SEvalZero
807*10465441SEvalZero    if GetOption('target') == 'cb':
808*10465441SEvalZero        from codeblocks import CBProject
809*10465441SEvalZero        CBProject('project.cbp', Projects, program)
810*10465441SEvalZero
811*10465441SEvalZero    if GetOption('target') == 'ua':
812*10465441SEvalZero        from ua import PrepareUA
813*10465441SEvalZero        PrepareUA(Projects, Rtt_Root, str(Dir('#')))
814*10465441SEvalZero
815*10465441SEvalZero    if GetOption('target') == 'vsc':
816*10465441SEvalZero        from vsc import GenerateVSCode
817*10465441SEvalZero        GenerateVSCode(Env)
818*10465441SEvalZero
819*10465441SEvalZero    if GetOption('target') == 'cdk':
820*10465441SEvalZero        from cdk import CDKProject
821*10465441SEvalZero        CDKProject('project.cdkproj', Projects)
822*10465441SEvalZero
823*10465441SEvalZero    if GetOption('target') == 'ses':
824*10465441SEvalZero        from ses import SESProject
825*10465441SEvalZero        SESProject(Env)
826*10465441SEvalZero
827*10465441SEvalZerodef EndBuilding(target, program = None):
828*10465441SEvalZero    import rtconfig
829*10465441SEvalZero
830*10465441SEvalZero    need_exit = False
831*10465441SEvalZero
832*10465441SEvalZero    Env['target']  = program
833*10465441SEvalZero    Env['project'] = Projects
834*10465441SEvalZero
835*10465441SEvalZero    if hasattr(rtconfig, 'BSP_LIBRARY_TYPE'):
836*10465441SEvalZero        Env['bsp_lib_type'] = rtconfig.BSP_LIBRARY_TYPE
837*10465441SEvalZero
838*10465441SEvalZero    if hasattr(rtconfig, 'dist_handle'):
839*10465441SEvalZero        Env['dist_handle'] = rtconfig.dist_handle
840*10465441SEvalZero
841*10465441SEvalZero    Env.AddPostAction(target, rtconfig.POST_ACTION)
842*10465441SEvalZero    # Add addition clean files
843*10465441SEvalZero    Clean(target, 'cconfig.h')
844*10465441SEvalZero    Clean(target, 'rtua.py')
845*10465441SEvalZero    Clean(target, 'rtua.pyc')
846*10465441SEvalZero
847*10465441SEvalZero    if GetOption('target'):
848*10465441SEvalZero        GenTargetProject(program)
849*10465441SEvalZero
850*10465441SEvalZero    BSP_ROOT = Dir('#').abspath
851*10465441SEvalZero    if GetOption('make-dist') and program != None:
852*10465441SEvalZero        from mkdist import MkDist
853*10465441SEvalZero        MkDist(program, BSP_ROOT, Rtt_Root, Env)
854*10465441SEvalZero    if GetOption('make-dist-strip') and program != None:
855*10465441SEvalZero        from mkdist import MkDist_Strip
856*10465441SEvalZero        MkDist_Strip(program, BSP_ROOT, Rtt_Root, Env)
857*10465441SEvalZero        need_exit = True
858*10465441SEvalZero    if GetOption('cscope'):
859*10465441SEvalZero        from cscope import CscopeDatabase
860*10465441SEvalZero        CscopeDatabase(Projects)
861*10465441SEvalZero
862*10465441SEvalZero    if not GetOption('help') and not GetOption('target'):
863*10465441SEvalZero        if not os.path.exists(rtconfig.EXEC_PATH):
864*10465441SEvalZero            print ("Error: the toolchain path (" + rtconfig.EXEC_PATH + ") is not exist, please check 'EXEC_PATH' in path or rtconfig.py.")
865*10465441SEvalZero            need_exit = True
866*10465441SEvalZero
867*10465441SEvalZero    if need_exit:
868*10465441SEvalZero        exit(0)
869*10465441SEvalZero
870*10465441SEvalZerodef SrcRemove(src, remove):
871*10465441SEvalZero    if not src:
872*10465441SEvalZero        return
873*10465441SEvalZero
874*10465441SEvalZero    src_bak = src[:]
875*10465441SEvalZero
876*10465441SEvalZero    if type(remove) == type('str'):
877*10465441SEvalZero        if os.path.isabs(remove):
878*10465441SEvalZero            remove = os.path.relpath(remove, GetCurrentDir())
879*10465441SEvalZero        remove = os.path.normpath(remove)
880*10465441SEvalZero
881*10465441SEvalZero        for item in src_bak:
882*10465441SEvalZero            if type(item) == type('str'):
883*10465441SEvalZero                item_str = item
884*10465441SEvalZero            else:
885*10465441SEvalZero                item_str = item.rstr()
886*10465441SEvalZero
887*10465441SEvalZero            if os.path.isabs(item_str):
888*10465441SEvalZero                item_str = os.path.relpath(item_str, GetCurrentDir())
889*10465441SEvalZero            item_str = os.path.normpath(item_str)
890*10465441SEvalZero
891*10465441SEvalZero            if item_str == remove:
892*10465441SEvalZero                src.remove(item)
893*10465441SEvalZero    else:
894*10465441SEvalZero        for remove_item in remove:
895*10465441SEvalZero            remove_str = str(remove_item)
896*10465441SEvalZero            if os.path.isabs(remove_str):
897*10465441SEvalZero                remove_str = os.path.relpath(remove_str, GetCurrentDir())
898*10465441SEvalZero            remove_str = os.path.normpath(remove_str)
899*10465441SEvalZero
900*10465441SEvalZero            for item in src_bak:
901*10465441SEvalZero                if type(item) == type('str'):
902*10465441SEvalZero                    item_str = item
903*10465441SEvalZero                else:
904*10465441SEvalZero                    item_str = item.rstr()
905*10465441SEvalZero
906*10465441SEvalZero                if os.path.isabs(item_str):
907*10465441SEvalZero                    item_str = os.path.relpath(item_str, GetCurrentDir())
908*10465441SEvalZero                item_str = os.path.normpath(item_str)
909*10465441SEvalZero
910*10465441SEvalZero                if item_str == remove_str:
911*10465441SEvalZero                    src.remove(item)
912*10465441SEvalZero
913*10465441SEvalZerodef GetVersion():
914*10465441SEvalZero    import SCons.cpp
915*10465441SEvalZero    import string
916*10465441SEvalZero
917*10465441SEvalZero    rtdef = os.path.join(Rtt_Root, 'include', 'rtdef.h')
918*10465441SEvalZero
919*10465441SEvalZero    # parse rtdef.h to get RT-Thread version
920*10465441SEvalZero    prepcessor = PatchedPreProcessor()
921*10465441SEvalZero    f = open(rtdef, 'r')
922*10465441SEvalZero    contents = f.read()
923*10465441SEvalZero    f.close()
924*10465441SEvalZero    prepcessor.process_contents(contents)
925*10465441SEvalZero    def_ns = prepcessor.cpp_namespace
926*10465441SEvalZero
927*10465441SEvalZero    version = int(filter(lambda ch: ch in '0123456789.', def_ns['RT_VERSION']))
928*10465441SEvalZero    subversion = int(filter(lambda ch: ch in '0123456789.', def_ns['RT_SUBVERSION']))
929*10465441SEvalZero
930*10465441SEvalZero    if 'RT_REVISION' in def_ns:
931*10465441SEvalZero        revision = int(filter(lambda ch: ch in '0123456789.', def_ns['RT_REVISION']))
932*10465441SEvalZero        return '%d.%d.%d' % (version, subversion, revision)
933*10465441SEvalZero
934*10465441SEvalZero    return '0.%d.%d' % (version, subversion)
935*10465441SEvalZero
936*10465441SEvalZerodef GlobSubDir(sub_dir, ext_name):
937*10465441SEvalZero    import os
938*10465441SEvalZero    import glob
939*10465441SEvalZero
940*10465441SEvalZero    def glob_source(sub_dir, ext_name):
941*10465441SEvalZero        list = os.listdir(sub_dir)
942*10465441SEvalZero        src = glob.glob(os.path.join(sub_dir, ext_name))
943*10465441SEvalZero
944*10465441SEvalZero        for item in list:
945*10465441SEvalZero            full_subdir = os.path.join(sub_dir, item)
946*10465441SEvalZero            if os.path.isdir(full_subdir):
947*10465441SEvalZero                src += glob_source(full_subdir, ext_name)
948*10465441SEvalZero        return src
949*10465441SEvalZero
950*10465441SEvalZero    dst = []
951*10465441SEvalZero    src = glob_source(sub_dir, ext_name)
952*10465441SEvalZero    for item in src:
953*10465441SEvalZero        dst.append(os.path.relpath(item, sub_dir))
954*10465441SEvalZero    return dst
955*10465441SEvalZero
956*10465441SEvalZerodef PackageSConscript(package):
957*10465441SEvalZero    from package import BuildPackage
958*10465441SEvalZero
959*10465441SEvalZero    return BuildPackage(package)
960