-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSConstruct
181 lines (159 loc) · 6.68 KB
/
SConstruct
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# -*- mode: python -*-
###############################################################
# This scons build script is used to check the armdebug project
# code for syntax errors. It does not build working executable
# code since it links to external routines.
###############################################################
import os
import os.path
from glob import glob
###############################################################
# Utility functions.
###############################################################
# Similar to env.WhereIs, but always searches os.environ.
def find_on_path(filename):
paths = os.environ.get('PATH')
if not paths:
return None
for p in paths.split(':'):
path = os.path.abspath(os.path.join(p, filename))
if os.path.isfile(path):
return p
return None
# Run the given gcc binary, and parses its output to work out the gcc
# version.
def determine_gcc_version(gcc_binary):
stdout = os.popen('%s --version' % gcc_binary)
gcc_output = stdout.read().split()
stdout.close()
grab_next = False
for token in gcc_output:
if grab_next:
return token
elif token[-1] == ')':
grab_next = True
return None
# Check that a given cross-compiler tool exists. If it does, the path is
# added to the build environment, and the given environment variable is
# set to the tool name.
#
# This is used to check for the presence of a working cross-compiler
# toolchain, and to properly set up the environment to do it. See below
# in the configuration section for details.
def CheckTool(context, envname, toolname=None, hostprefix=None):
toolname = toolname or envname.lower()
if hostprefix is None:
hostprefix = '%s-' % context.env['CROSS_COMPILE_HOST']
toolname = '%s%s' % (hostprefix, toolname)
context.Message("Checking for %s..." % toolname)
toolpath = find_on_path(toolname)
if not toolpath:
context.Result('not found')
return False
else:
context.Result('ok')
context.env[envname] = toolname
context.env.AppendENVPath('PATH', toolpath)
return True
# Find the correct variant and version of libgcc.a in the cross-compiler
# toolchain.
def CheckLibGcc(context, gccname):
context.Message("Locating a cross-compiled libgcc...")
toolpath = find_on_path(gccname)
if not toolpath:
context.Result("%s not found" % toolname)
return False
gcc_version = determine_gcc_version(gccname)
if not gcc_version:
context.Result("Could not determine gcc version")
return False
gcc_install_dir = os.path.split(os.path.normpath(toolpath))[0]
for libdir in ['interwork', 'thumb', '']:
libgcc_path = os.path.join(gcc_install_dir, 'lib', 'gcc',
context.env['CROSS_COMPILE_HOST'],
gcc_version, libdir, 'libgcc.a')
if os.path.isfile(libgcc_path):
break
if not os.path.isfile(libgcc_path):
context.Result("libgcc.a not found")
return False
context.Result("ok - " + libgcc_path)
context.env.Append(LIBGCC=libgcc_path)
return True
def CheckDoxygen(context):
context.Message("Looking for Doxygen...")
doxypath = find_on_path('doxygen')
if doxypath:
context.Result("ok")
context.env.AppendENVPath('PATH', doxypath)
context.env['WITH_DOXYGEN'] = True
else:
context.Result("not found")
context.env['WITH_DOXYGEN'] = False
###############################################################
# Options that can be provided on the commandline
###############################################################
opts = Variables('scons.options', ARGUMENTS)
opts.Add(PathVariable('gccprefix',
'Prefix of the cross-gcc to use (by default arm-none-eabi)',
'arm-none-eabi', PathVariable.PathAccept))
Help('''
Type: 'scons' to build object files.
- To use another cross-gcc than arm-none-eabi-gcc:
scons gccprefix=arm-softfloat-eabi
Options are saved persistent in the file 'scons.options'. That means
after you have called e.g. 'scons gccprefix=arm-softfloat-eabi' it's enough
to call only 'scons' to build both using the new gcc version again.
''')
###############################################################
# Construct and configure a cross-compiler environment
###############################################################
env = Environment(options = opts,
tools = ['gcc', 'as', 'gnulink', 'ar'],
toolpath = ['scons_tools'],
LIBGCC = [], CPPPATH = '#',
WITH_DOXYGEN = False)
opts.Update(env)
opts.Save('scons.options', env)
if not env.GetOption('clean'):
conf = Configure(env, custom_tests = {'CheckTool': CheckTool,
'CheckLibGcc': CheckLibGcc,
'CheckDoxygen': CheckDoxygen})
conf.env['CROSS_COMPILE_HOST'] = env['gccprefix']
if not (conf.CheckTool('CC', 'gcc') and conf.CheckTool('AR') and
conf.CheckTool('OBJCOPY') and conf.CheckTool('LINK', 'ld') and
conf.CheckLibGcc(conf.env['CC'])):
print("Missing or incomplete arm-elf toolchain, cannot continue!")
Exit(1)
env = conf.Finish()
mycflags = ['-mcpu=arm7tdmi', '-Os', '-Wextra', '-Wall', '-Werror',
'-Wno-div-by-zero', '-Wfloat-equal', '-Wshadow',
'-Wpointer-arith', '-Wbad-function-cast',
'-Wmissing-prototypes', '-ffreestanding',
'-fsigned-char', '-ffunction-sections', '-std=gnu99',
'-fdata-sections', '-fomit-frame-pointer', '-msoft-float']
myasflags = ['-Wall', '-Werror', '-Os'];
if str(env['LIBGCC']).find('interwork') != -1:
mycflags.append('-mthumb-interwork')
myasflags.append('-Wa,-mcpu=arm7tdmi,-mfpu=softfpa,-mthumb-interwork')
elif str(env['LIBGCC']).find('thumb') != -1:
mycflags.append('-mthumb')
myasflags.append('-Wa,-mcpu=arm7tdmi,-mfpu=softfpa,-mthumb')
else:
myasflags.append('-Wa,-mcpu=arm7tdmi,-mfpu=softfpa')
mycflags.append('-g')
mycflags.append('-ggdb')
# Big Endian Output (disabled by default)
#mycflags.append('-D__BIG_ENDIAN__')
# Test build for NxOS (Comment out for NXT Firmware)
mycflags.append('-D__NXOS__')
myasflags.append('-g')
myasflags.append('-ggdb')
# Big Endian Output (disabled by default)
#mycflags.append('-D__BIG_ENDIAN__')
# Test build for NxOS (Comment out for NXT Firmware)
myasflags.append('-D__NXOS__')
env.Replace(CCFLAGS = mycflags, ASFLAGS = myasflags )
# Build the baseplate, and all selected application kernels.
numProcs = os.sysconf('SC_NPROCESSORS_ONLN')
SConscript(['SConscript'], 'numProcs env CheckTool')