Skip to content

Commit ddc823a

Browse files
authored
Merge pull request #2802 from theotherjimmy/toolchain-profiles
[Tools] Add simple build profiles to toolchains
2 parents 49e9627 + 7348b01 commit ddc823a

20 files changed

+457
-231
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ install:
1919
- sudo pip install jinja2
2020
- sudo pip install pytest
2121
- sudo pip install pylint
22+
- sudo pip install hypothesis

docs/Toolchain_Profiles.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Toolchain Profiles User Perspective
2+
3+
A Toolchain or build system Profile is a set of flags that is garenteed to be passed to the underlieing compiler suite.
4+
These flags are stored in a JSON file that may be merged with other JSON files of the same structure.
5+
6+
## JSON Toolchain Profile Format
7+
8+
The JSON object that represents a Toolchain Profile is a dict mapping from Toolchains, like `GCC_ARM`, to their flags, like `-O3`.
9+
The structure is as follows: Each toolchain supported by a Toolchain Profile has an dict in the root dict.
10+
This dict contains a mapping from a flag type to a list of flags that should be passed the corresponding part of the compiler suite.
11+
The required flag types are:
12+
13+
| Key | Description |
14+
|:---------|:--------------------------------------|
15+
| `c` | Flags for the C Compiler |
16+
| `cxx` | Flags for the C++ Compiler |
17+
| `common` | Flags for both the C and C++ Compilers|
18+
| `asm` | Flags for the Assembler |
19+
20+
## Example
21+
22+
An example of a Toolchain Profile is given below:
23+
```json
24+
{
25+
"GCC_ARM": {
26+
"common": ["-c", "-Wall", "-Wextra",
27+
"-Wno-unused-parameter", "-Wno-missing-field-initializers",
28+
"-fmessage-length=0", "-fno-exceptions", "-fno-builtin",
29+
"-ffunction-sections", "-fdata-sections", "-funsigned-char",
30+
"-MMD", "-fno-delete-null-pointer-checks",
31+
"-fomit-frame-pointer", "-Os"],
32+
"asm": ["-x", "assembler-with-cpp"],
33+
"c": ["-std=gnu99"],
34+
"cxx": ["-std=gnu++98", "-fno-rtti", "-Wvla"],
35+
"ld": ["-Wl,--gc-sections", "-Wl,--wrap,main", "-Wl,--wrap,_malloc_r",
36+
"-Wl,--wrap,_free_r", "-Wl,--wrap,_realloc_r",
37+
"-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit"]
38+
},
39+
"ARM": {
40+
"common": ["-c", "--gnu", "-Otime", "--split_sections",
41+
"--apcs=interwork", "--brief_diagnostics", "--restrict",
42+
"--multibyte_chars", "-O3"],
43+
"asm": [],
44+
"c": ["--md", "--no_depend_system_headers", "--c99", "-D__ASSERT_MSG"],
45+
"cxx": ["--cpp", "--no_rtti", "--no_vla"],
46+
"ld": []
47+
},
48+
"IAR": {
49+
"common": [
50+
"--no_wrap_diagnostics", "non-native end of line sequence", "-e",
51+
"--diag_suppress=Pa050,Pa084,Pa093,Pa082", "-Oh"],
52+
"asm": [],
53+
"c": ["--vla"],
54+
"cxx": ["--guard_calls", "--no_static_destruction"],
55+
"ld": ["--skip_dynamic_initialization", "--threaded_lib"]
56+
}
57+
}
58+
```
59+
60+
From this Toolchain profile, we can tell that:
61+
- `GCC_ARM`, `ARM`, and `IAR` compiler suites are supported.
62+
- The `ARM` C and C++ Compilers will be using optimization level `-O3`
63+
- The `IAR` linker will skip dynamic initialization
64+
- etc.
65+
66+
# Toolchain Profile API Perspective
67+
68+
The Toolchains no longer take in an optional argument, `build_profile`, that will contain a map from flag types to lists of flags.
69+
This looks exactly the same in python as it does in the JSON format above.
70+
The meaning of the flags, and which ones are required is the same as the User Perspective
71+
A developer using the API must parse the User provided files themselves and extract the appropriate sub-dict from the file afterwards.
72+
A convienence function that does this for a developer is `tools.options.extract_profile` and will call args_error when a Toolchain Profile JSON file does not provide flags for the selected Toolchain.

tools/build.py

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
from tools.toolchains import mbedToolchain
3232
from tools.targets import TARGET_NAMES, TARGET_MAP
3333
from tools.options import get_default_options_parser
34+
from tools.options import extract_profile
3435
from tools.build_api import build_library, build_mbed_libs, build_lib
3536
from tools.build_api import mcu_toolchain_matrix
3637
from tools.build_api import static_analysis_scan, static_analysis_scan_lib, static_analysis_scan_library
@@ -222,13 +223,20 @@
222223
try:
223224
mcu = TARGET_MAP[target]
224225
# CMSIS and MBED libs analysis
225-
static_analysis_scan(mcu, toolchain, CPPCHECK_CMD, CPPCHECK_MSG_FORMAT, verbose=options.verbose, jobs=options.jobs)
226+
profile = extract_profile(parser, options, toolchain)
227+
static_analysis_scan(
228+
mcu, toolchain, CPPCHECK_CMD, CPPCHECK_MSG_FORMAT,
229+
verbose=options.verbose, jobs=options.jobs,
230+
build_profile=profile)
226231
for lib_id in libraries:
227232
# Static check for library
228-
static_analysis_scan_lib(lib_id, mcu, toolchain, CPPCHECK_CMD, CPPCHECK_MSG_FORMAT,
229-
options=options.options,
230-
extra_verbose=options.extra_verbose_notify, verbose=options.verbose, jobs=options.jobs, clean=options.clean,
231-
macros=options.macros)
233+
static_analysis_scan_lib(
234+
lib_id, mcu, toolchain, CPPCHECK_CMD,
235+
CPPCHECK_MSG_FORMAT,
236+
extra_verbose=options.extra_verbose_notify,
237+
verbose=options.verbose, jobs=options.jobs,
238+
clean=options.clean, macros=options.macros,
239+
build_profile=profile)
232240
pass
233241
except Exception, e:
234242
if options.verbose:
@@ -248,36 +256,37 @@
248256
else:
249257
try:
250258
mcu = TARGET_MAP[target]
259+
profile = extract_profile(parser, options, toolchain)
251260
if options.source_dir:
252261
lib_build_res = build_library(options.source_dir, options.build_dir, mcu, toolchain,
253-
options=options.options,
254262
extra_verbose=options.extra_verbose_notify,
255263
verbose=options.verbose,
256264
silent=options.silent,
257265
jobs=options.jobs,
258266
clean=options.clean,
259267
archive=(not options.no_archive),
260268
macros=options.macros,
261-
name=options.artifact_name)
269+
name=options.artifact_name,
270+
build_profile=profile)
262271
else:
263272
lib_build_res = build_mbed_libs(mcu, toolchain,
264-
options=options.options,
265273
extra_verbose=options.extra_verbose_notify,
266274
verbose=options.verbose,
267275
silent=options.silent,
268276
jobs=options.jobs,
269277
clean=options.clean,
270-
macros=options.macros)
278+
macros=options.macros,
279+
build_profile=profile)
271280

272281
for lib_id in libraries:
273282
build_lib(lib_id, mcu, toolchain,
274-
options=options.options,
275283
extra_verbose=options.extra_verbose_notify,
276284
verbose=options.verbose,
277285
silent=options.silent,
278286
clean=options.clean,
279287
macros=options.macros,
280-
jobs=options.jobs)
288+
jobs=options.jobs,
289+
build_profile=profile)
281290
if lib_build_res:
282291
successes.append(tt_id)
283292
else:

0 commit comments

Comments
 (0)