Skip to content

[Tools] Add simple build profiles to toolchains #2802

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Sep 30, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ install:
- sudo pip install jinja2
- sudo pip install pytest
- sudo pip install pylint
- sudo pip install hypothesis
72 changes: 72 additions & 0 deletions docs/Toolchain_Profiles.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Toolchain Profiles User Perspective

A Toolchain or build system Profile is a set of flags that is garenteed to be passed to the underlieing compiler suite.
These flags are stored in a JSON file that may be merged with other JSON files of the same structure.

## JSON Toolchain Profile Format

The JSON object that represents a Toolchain Profile is a dict mapping from Toolchains, like `GCC_ARM`, to their flags, like `-O3`.
The structure is as follows: Each toolchain supported by a Toolchain Profile has an dict in the root dict.
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.
The required flag types are:

| Key | Description |
|:---------|:--------------------------------------|
| `c` | Flags for the C Compiler |
| `cxx` | Flags for the C++ Compiler |
| `common` | Flags for both the C and C++ Compilers|
| `asm` | Flags for the Assembler |

## Example

An example of a Toolchain Profile is given below:
```json
{
"GCC_ARM": {
"common": ["-c", "-Wall", "-Wextra",
"-Wno-unused-parameter", "-Wno-missing-field-initializers",
"-fmessage-length=0", "-fno-exceptions", "-fno-builtin",
"-ffunction-sections", "-fdata-sections", "-funsigned-char",
"-MMD", "-fno-delete-null-pointer-checks",
"-fomit-frame-pointer", "-Os"],
"asm": ["-x", "assembler-with-cpp"],
"c": ["-std=gnu99"],
"cxx": ["-std=gnu++98", "-fno-rtti", "-Wvla"],
"ld": ["-Wl,--gc-sections", "-Wl,--wrap,main", "-Wl,--wrap,_malloc_r",
"-Wl,--wrap,_free_r", "-Wl,--wrap,_realloc_r",
"-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit"]
},
"ARM": {
"common": ["-c", "--gnu", "-Otime", "--split_sections",
"--apcs=interwork", "--brief_diagnostics", "--restrict",
"--multibyte_chars", "-O3"],
"asm": [],
"c": ["--md", "--no_depend_system_headers", "--c99", "-D__ASSERT_MSG"],
"cxx": ["--cpp", "--no_rtti", "--no_vla"],
"ld": []
},
"IAR": {
"common": [
"--no_wrap_diagnostics", "non-native end of line sequence", "-e",
"--diag_suppress=Pa050,Pa084,Pa093,Pa082", "-Oh"],
"asm": [],
"c": ["--vla"],
"cxx": ["--guard_calls", "--no_static_destruction"],
"ld": ["--skip_dynamic_initialization", "--threaded_lib"]
}
}
```

From this Toolchain profile, we can tell that:
- `GCC_ARM`, `ARM`, and `IAR` compiler suites are supported.
- The `ARM` C and C++ Compilers will be using optimization level `-O3`
- The `IAR` linker will skip dynamic initialization
- etc.

# Toolchain Profile API Perspective

The Toolchains no longer take in an optional argument, `build_profile`, that will contain a map from flag types to lists of flags.
This looks exactly the same in python as it does in the JSON format above.
The meaning of the flags, and which ones are required is the same as the User Perspective
A developer using the API must parse the User provided files themselves and extract the appropriate sub-dict from the file afterwards.
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.
31 changes: 20 additions & 11 deletions tools/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from tools.toolchains import mbedToolchain
from tools.targets import TARGET_NAMES, TARGET_MAP
from tools.options import get_default_options_parser
from tools.options import extract_profile
from tools.build_api import build_library, build_mbed_libs, build_lib
from tools.build_api import mcu_toolchain_matrix
from tools.build_api import static_analysis_scan, static_analysis_scan_lib, static_analysis_scan_library
Expand Down Expand Up @@ -222,13 +223,20 @@
try:
mcu = TARGET_MAP[target]
# CMSIS and MBED libs analysis
static_analysis_scan(mcu, toolchain, CPPCHECK_CMD, CPPCHECK_MSG_FORMAT, verbose=options.verbose, jobs=options.jobs)
profile = extract_profile(parser, options, toolchain)
static_analysis_scan(
mcu, toolchain, CPPCHECK_CMD, CPPCHECK_MSG_FORMAT,
verbose=options.verbose, jobs=options.jobs,
build_profile=profile)
for lib_id in libraries:
# Static check for library
static_analysis_scan_lib(lib_id, mcu, toolchain, CPPCHECK_CMD, CPPCHECK_MSG_FORMAT,
options=options.options,
extra_verbose=options.extra_verbose_notify, verbose=options.verbose, jobs=options.jobs, clean=options.clean,
macros=options.macros)
static_analysis_scan_lib(
lib_id, mcu, toolchain, CPPCHECK_CMD,
CPPCHECK_MSG_FORMAT,
extra_verbose=options.extra_verbose_notify,
verbose=options.verbose, jobs=options.jobs,
clean=options.clean, macros=options.macros,
build_profile=profile)
pass
except Exception, e:
if options.verbose:
Expand All @@ -248,36 +256,37 @@
else:
try:
mcu = TARGET_MAP[target]
profile = extract_profile(parser, options, toolchain)
if options.source_dir:
lib_build_res = build_library(options.source_dir, options.build_dir, mcu, toolchain,
options=options.options,
extra_verbose=options.extra_verbose_notify,
verbose=options.verbose,
silent=options.silent,
jobs=options.jobs,
clean=options.clean,
archive=(not options.no_archive),
macros=options.macros,
name=options.artifact_name)
name=options.artifact_name,
build_profile=profile)
else:
lib_build_res = build_mbed_libs(mcu, toolchain,
options=options.options,
extra_verbose=options.extra_verbose_notify,
verbose=options.verbose,
silent=options.silent,
jobs=options.jobs,
clean=options.clean,
macros=options.macros)
macros=options.macros,
build_profile=profile)

for lib_id in libraries:
build_lib(lib_id, mcu, toolchain,
options=options.options,
extra_verbose=options.extra_verbose_notify,
verbose=options.verbose,
silent=options.silent,
clean=options.clean,
macros=options.macros,
jobs=options.jobs)
jobs=options.jobs,
build_profile=profile)
if lib_build_res:
successes.append(tt_id)
else:
Expand Down
Loading