Skip to content

Commit 773dab5

Browse files
committed
Add --source option to both build.py and make.py. Also add test.py script for compiling and listing tests
1 parent 87a978c commit 773dab5

File tree

4 files changed

+398
-12
lines changed

4 files changed

+398
-12
lines changed

tools/build.py

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
from tools.toolchains import TOOLCHAINS
3131
from tools.targets import TARGET_NAMES, TARGET_MAP
3232
from tools.options import get_default_options_parser
33-
from tools.build_api import build_mbed_libs, build_lib
33+
from tools.build_api import build_library, build_mbed_libs, build_lib
3434
from tools.build_api import mcu_toolchain_matrix
3535
from tools.build_api import static_analysis_scan, static_analysis_scan_lib, static_analysis_scan_library
3636
from tools.build_api import print_build_results
@@ -42,6 +42,15 @@
4242
# Parse Options
4343
parser = get_default_options_parser()
4444

45+
parser.add_option("--source", dest="source_dir",
46+
default=None, help="The source (input) directory", action="append")
47+
48+
parser.add_option("--build", dest="build_dir",
49+
default=None, help="The build (output) directory")
50+
51+
parser.add_option("--no-archive", dest="no_archive", action="store_true",
52+
default=False, help="Do not produce archive (.ar) file, but rather .o")
53+
4554
# Extra libraries
4655
parser.add_option("-r", "--rtos",
4756
action="store_true",
@@ -119,7 +128,7 @@
119128
help='For some commands you can use filter to filter out results')
120129

121130
parser.add_option("-j", "--jobs", type="int", dest="jobs",
122-
default=1, help="Number of concurrent jobs (default 1). Use 0 for auto based on host machine's number of CPUs")
131+
default=0, help="Number of concurrent jobs. Default: 0/auto (based on host machine's number of CPUs)")
123132

124133
parser.add_option("-v", "--verbose",
125134
action="store_true",
@@ -224,14 +233,26 @@
224233
tt_id = "%s::%s" % (toolchain, target)
225234
try:
226235
mcu = TARGET_MAP[target]
227-
lib_build_res = build_mbed_libs(mcu, toolchain,
236+
if options.source_dir:
237+
lib_build_res = build_library(options.source_dir, options.build_dir, mcu, toolchain,
238+
options=options.options,
239+
extra_verbose=options.extra_verbose_notify,
240+
verbose=options.verbose,
241+
silent=options.silent,
242+
jobs=options.jobs,
243+
clean=options.clean,
244+
archive=(not options.no_archive),
245+
macros=options.macros)
246+
else:
247+
lib_build_res = build_mbed_libs(mcu, toolchain,
228248
options=options.options,
229249
extra_verbose=options.extra_verbose_notify,
230250
verbose=options.verbose,
231251
silent=options.silent,
232252
jobs=options.jobs,
233253
clean=options.clean,
234254
macros=options.macros)
255+
235256
for lib_id in libraries:
236257
build_lib(lib_id, mcu, toolchain,
237258
options=options.options,

tools/make.py

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import sys
2222
from time import sleep
2323
from shutil import copy
24-
from os.path import join, abspath, dirname
24+
from os.path import join, abspath, dirname, isfile, isdir
2525

2626
# Be sure that the tools directory is in the search path
2727
ROOT = abspath(join(dirname(__file__), ".."))
@@ -42,11 +42,10 @@
4242
from tools.options import get_default_options_parser
4343
from tools.build_api import build_project
4444
try:
45-
import mbed_settings as ps
45+
import tools.private_settings as ps
4646
except:
4747
ps = object()
4848

49-
5049
if __name__ == '__main__':
5150
# Parse Options
5251
parser = get_default_options_parser()
@@ -62,8 +61,8 @@
6261
parser.add_option("-j", "--jobs",
6362
type="int",
6463
dest="jobs",
65-
default=1,
66-
help="Number of concurrent jobs (default 1). Use 0 for auto based on host machine's number of CPUs")
64+
default=0,
65+
help="Number of concurrent jobs. Default: 0/auto (based on host machine's number of CPUs)")
6766

6867
parser.add_option("-v", "--verbose",
6968
action="store_true",
@@ -94,11 +93,13 @@
9493
parser.add_option("--dep", dest="dependencies",
9594
default=None, help="Dependencies")
9695
parser.add_option("--source", dest="source_dir",
97-
default=None, help="The source (input) directory")
96+
default=None, help="The source (input) directory", action="append")
9897
parser.add_option("--duration", type="int", dest="duration",
9998
default=None, help="Duration of the test")
10099
parser.add_option("--build", dest="build_dir",
101100
default=None, help="The build (output) directory")
101+
parser.add_option("-N", "--artifact-name", dest="artifact_name",
102+
default=None, help="The built project's name")
102103
parser.add_option("-d", "--disk", dest="disk",
103104
default=None, help="The mbed disk")
104105
parser.add_option("-s", "--serial", dest="serial",
@@ -165,6 +166,12 @@
165166

166167
(options, args) = parser.parse_args()
167168

169+
if options.source_dir:
170+
for path in options.source_dir :
171+
if not isfile(path) and not isdir(path) :
172+
args_error(parser, "[ERROR] you passed \"{}\" to --source, which does not exist".
173+
format(path))
174+
168175
# Print available tests in order and exit
169176
if options.list_tests is True:
170177
print '\n'.join(map(str, sorted(TEST_MAP.values())))
@@ -248,7 +255,8 @@
248255
verbose=options.verbose,
249256
silent=options.silent,
250257
macros=options.macros,
251-
jobs=options.jobs)
258+
jobs=options.jobs,
259+
name=options.artifact_name)
252260
print 'Image: %s'% bin_file
253261

254262
if options.disk:
@@ -259,7 +267,7 @@
259267
# Import pyserial: https://pypi.python.org/pypi/pyserial
260268
from serial import Serial
261269

262-
sleep(target.program_cycle_s())
270+
sleep(TARGET_MAP[mcu].program_cycle_s())
263271

264272
serial = Serial(options.serial, timeout = 1)
265273
if options.baud:
@@ -291,3 +299,5 @@
291299
traceback.print_exc(file=sys.stdout)
292300
else:
293301
print "[ERROR] %s" % str(e)
302+
303+
sys.exit(1)

tools/test.py

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
#! /usr/bin/env python2
2+
"""
3+
mbed SDK
4+
Copyright (c) 2011-2013 ARM Limited
5+
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+
19+
TEST BUILD & RUN
20+
"""
21+
import sys
22+
import os
23+
import json
24+
25+
ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
26+
sys.path.insert(0, ROOT)
27+
28+
from tools.test_api import test_path_to_name, find_tests, print_tests, build_tests, test_spec_from_test_builds
29+
from tools.options import get_default_options_parser
30+
from tools.build_api import build_project, build_library
31+
from tools.targets import TARGET_MAP
32+
from tools.utils import mkdir
33+
from tools.test_exporters import ReportExporter, ResultExporterType
34+
35+
if __name__ == '__main__':
36+
try:
37+
# Parse Options
38+
parser = get_default_options_parser()
39+
40+
parser.add_option("-D", "",
41+
action="append",
42+
dest="macros",
43+
help="Add a macro definition")
44+
45+
parser.add_option("-j", "--jobs",
46+
type="int",
47+
dest="jobs",
48+
default=0,
49+
help="Number of concurrent jobs. Default: 0/auto (based on host machine's number of CPUs)")
50+
51+
parser.add_option("--source", dest="source_dir",
52+
default=None, help="The source (input) directory (for sources other than tests). Defaults to current directory.", action="append")
53+
54+
parser.add_option("--build", dest="build_dir",
55+
default=None, help="The build (output) directory")
56+
57+
parser.add_option("-l", "--list", action="store_true", dest="list",
58+
default=False, help="List (recursively) available tests in order and exit")
59+
60+
parser.add_option("-p", "--paths", dest="paths",
61+
default=None, help="Limit the tests to those within the specified comma separated list of paths")
62+
63+
format_choices = ["list", "json"]
64+
format_default_choice = "list"
65+
format_help = "Change the format in which tests are listed. Choices include: %s. Default: %s" % (", ".join(format_choices), format_default_choice)
66+
parser.add_option("-f", "--format", type="choice", dest="format",
67+
choices=format_choices, default=format_default_choice, help=format_help)
68+
69+
parser.add_option("-n", "--names", dest="names",
70+
default=None, help="Limit the tests to a comma separated list of names")
71+
72+
parser.add_option("--test-spec", dest="test_spec",
73+
default=None, help="Destination path for a test spec file that can be used by the Greentea automated test tool")
74+
75+
parser.add_option("--build-report-junit", dest="build_report_junit",
76+
default=None, help="Destination path for a build report in the JUnit xml format")
77+
78+
parser.add_option("-v", "--verbose",
79+
action="store_true",
80+
dest="verbose",
81+
default=False,
82+
help="Verbose diagnostic output")
83+
84+
(options, args) = parser.parse_args()
85+
86+
# Filter tests by path if specified
87+
if options.paths:
88+
all_paths = options.paths.split(",")
89+
else:
90+
all_paths = ["."]
91+
92+
all_tests = {}
93+
tests = {}
94+
95+
# Find all tests in the relevant paths
96+
for path in all_paths:
97+
all_tests.update(find_tests(path))
98+
99+
# Filter tests by name if specified
100+
if options.names:
101+
all_names = options.names.split(",")
102+
103+
all_tests_keys = all_tests.keys()
104+
for name in all_names:
105+
if name in all_tests_keys:
106+
tests[name] = all_tests[name]
107+
else:
108+
print "[Warning] Test with name '%s' was not found in the available tests" % (name)
109+
else:
110+
tests = all_tests
111+
112+
if options.list:
113+
# Print available tests in order and exit
114+
print_tests(tests, options.format)
115+
sys.exit(0)
116+
else:
117+
# Build all tests
118+
if not options.build_dir:
119+
print "[ERROR] You must specify a build path"
120+
sys.exit(1)
121+
122+
base_source_paths = options.source_dir
123+
124+
# Default base source path is the current directory
125+
if not base_source_paths:
126+
base_source_paths = ['.']
127+
128+
129+
target = TARGET_MAP[options.mcu]
130+
131+
build_report = {}
132+
build_properties = {}
133+
134+
library_build_success = True
135+
try:
136+
# Build sources
137+
build_library(base_source_paths, options.build_dir, target, options.tool,
138+
options=options.options,
139+
jobs=options.jobs,
140+
clean=options.clean,
141+
report=build_report,
142+
properties=build_properties,
143+
name="mbed-build",
144+
macros=options.macros,
145+
verbose=options.verbose,
146+
archive=False)
147+
except Exception, e:
148+
library_build_success = False
149+
print "Failed to build library"
150+
151+
if library_build_success:
152+
# Build all the tests
153+
test_build_success, test_build = build_tests(tests, [options.build_dir], options.build_dir, target, options.tool,
154+
options=options.options,
155+
clean=options.clean,
156+
report=build_report,
157+
properties=build_properties,
158+
macros=options.macros,
159+
verbose=options.verbose,
160+
jobs=options.jobs)
161+
162+
# If a path to a test spec is provided, write it to a file
163+
if options.test_spec:
164+
test_spec_data = test_spec_from_test_builds(test_build)
165+
166+
# Create the target dir for the test spec if necessary
167+
# mkdir will not create the dir if it already exists
168+
test_spec_dir = os.path.dirname(options.test_spec)
169+
if test_spec_dir:
170+
mkdir(test_spec_dir)
171+
172+
try:
173+
with open(options.test_spec, 'w') as f:
174+
f.write(json.dumps(test_spec_data, indent=2))
175+
except IOError, e:
176+
print "[ERROR] Error writing test spec to file"
177+
print e
178+
179+
# If a path to a JUnit build report spec is provided, write it to a file
180+
if options.build_report_junit:
181+
report_exporter = ReportExporter(ResultExporterType.JUNIT, package="build")
182+
report_exporter.report_to_file(build_report, options.build_report_junit, test_suite_properties=build_properties)
183+
184+
if library_build_success and test_build_success:
185+
sys.exit(0)
186+
else:
187+
sys.exit(1)
188+
189+
except KeyboardInterrupt, e:
190+
print "\n[CTRL+c] exit"
191+
except Exception,e:
192+
import traceback
193+
traceback.print_exc(file=sys.stdout)
194+
print "[ERROR] %s" % str(e)
195+
sys.exit(1)

0 commit comments

Comments
 (0)