Skip to content

Commit b10276c

Browse files
authored
Merge pull request #2173 from theotherjimmy/abstract-base-class
[toolchains]Abstractify the mbedToolchain base class.
2 parents 702707d + bccbe48 commit b10276c

File tree

3 files changed

+191
-0
lines changed

3 files changed

+191
-0
lines changed

.travis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ python:
33

44
script:
55
- PYTHONPATH=. python tools/test/config_test/config_test.py
6+
- py.test tools/test/toolchains/api.py
67
- python tools/build_travis.py
78
before_install:
89
- sudo add-apt-repository -y ppa:terry.guo/gcc-arm-embedded
@@ -15,3 +16,4 @@ install:
1516
- sudo pip install colorama
1617
- sudo pip install prettytable
1718
- sudo pip install jinja2
19+
- sudo pip install pytest

tools/test/toolchains/api.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import sys
2+
import os
3+
4+
ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", ".."))
5+
sys.path.insert(0, ROOT)
6+
7+
from tools.toolchains import TOOLCHAIN_CLASSES, LEGACY_TOOLCHAIN_NAMES
8+
from tools.targets import TARGET_MAP
9+
10+
def test_instantiation():
11+
for name, Class in TOOLCHAIN_CLASSES.items():
12+
CLS = Class(TARGET_MAP["K64F"])
13+
assert name == CLS.name or name == LEGACY_TOOLCHAIN_NAMES[CLS.name]

tools/toolchains/__init__.py

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
from inspect import getmro
2727
from copy import deepcopy
2828
from tools.config import Config
29+
from abc import ABCMeta, abstractmethod
2930

3031
from multiprocessing import Pool, cpu_count
3132
from tools.utils import run_cmd, mkdir, rel_path, ToolException, NotSupportedException, split_path, compile_worker
@@ -213,6 +214,8 @@ class mbedToolchain:
213214

214215
MBED_CONFIG_FILE_NAME="mbed_config.h"
215216

217+
__metaclass__ = ABCMeta
218+
216219
def __init__(self, target, options=None, notify=None, macros=None, silent=False, extra_verbose=False):
217220
self.target = target
218221
self.name = self.__class__.__name__
@@ -825,9 +828,39 @@ def compile_command(self, source, object, includes):
825828

826829
return None
827830

831+
@abstractmethod
832+
def parse_dependencies(self, dep_path):
833+
"""Parse the dependency information generated by the compiler.
834+
835+
Positional arguments:
836+
dep_path -- the path to a file generated by a previous run of the compiler
837+
838+
Return value:
839+
A list of all source files that the dependency file indicated were dependencies
840+
841+
Side effects:
842+
None
843+
"""
844+
raise NotImplemented
845+
828846
def is_not_supported_error(self, output):
829847
return "#error directive: [NOT_SUPPORTED]" in output
830848

849+
@abstractmethod
850+
def parse_output(self, output):
851+
"""Take in compiler output and extract sinlge line warnings and errors from it.
852+
853+
Positional arguments:
854+
output -- a string of all the messages emitted by a run of the compiler
855+
856+
Return value:
857+
None
858+
859+
Side effects:
860+
call self.cc_info or self.notify with a description of the event generated by the compiler
861+
"""
862+
raise NotImplemented
863+
831864
def compile_output(self, output=[]):
832865
_rc = output[0]
833866
_stderr = output[1]
@@ -1035,6 +1068,149 @@ def get_config_header(self):
10351068
self.config_processed = True
10361069
return self.config_file
10371070

1071+
@abstractmethod
1072+
def get_config_option(self, config_header):
1073+
"""Generate the compiler option that forces the inclusion of the configuration
1074+
header file.
1075+
1076+
Positional arguments:
1077+
config_header -- The configuration header that will be included within all source files
1078+
1079+
Return value:
1080+
A list of the command line arguments that will force the inclusion the specified header
1081+
1082+
Side effects:
1083+
None
1084+
"""
1085+
raise NotImplemented
1086+
1087+
@abstractmethod
1088+
def assemble(self, source, object, includes):
1089+
"""Generate the command line that assembles.
1090+
1091+
Positional arguments:
1092+
source -- a file path that is the file to assemble
1093+
object -- a file path that is the destination object
1094+
includes -- a list of all directories where header files may be found
1095+
1096+
Return value:
1097+
The complete command line, as a list, that would invoke the assembler
1098+
on the source file, include all the include paths, and generate
1099+
the specified object file.
1100+
1101+
Side effects:
1102+
None
1103+
1104+
Note:
1105+
This method should be decorated with @hook_tool.
1106+
"""
1107+
raise NotImplemented
1108+
1109+
@abstractmethod
1110+
def compile_c(self, source, object, includes):
1111+
"""Generate the command line that compiles a C source file.
1112+
1113+
Positional arguments:
1114+
source -- the C source file to compile
1115+
object -- the destination object file
1116+
includes -- a list of all the directories where header files may be found
1117+
1118+
Return value:
1119+
The complete command line, as a list, that would invoke the C compiler
1120+
on the source file, include all the include paths, and generate the
1121+
specified object file.
1122+
1123+
Side effects:
1124+
None
1125+
1126+
Note:
1127+
This method should be decorated with @hook_tool.
1128+
"""
1129+
raise NotImplemented
1130+
1131+
@abstractmethod
1132+
def compile_cpp(self, source, object, includes):
1133+
"""Generate the command line that compiles a C++ source file.
1134+
1135+
Positional arguments:
1136+
source -- the C++ source file to compile
1137+
object -- the destination object file
1138+
includes -- a list of all the directories where header files may be found
1139+
1140+
Return value:
1141+
The complete command line, as a list, that would invoke the C++ compiler
1142+
on the source file, include all the include paths, and generate the
1143+
specified object file.
1144+
1145+
Side effects:
1146+
None
1147+
1148+
Note:
1149+
This method should be decorated with @hook_tool.
1150+
"""
1151+
raise NotImplemented
1152+
1153+
@abstractmethod
1154+
def link(self, output, objects, libraries, lib_dirs, mem_map):
1155+
"""Run the linker to create an executable and memory map.
1156+
1157+
Positional arguments:
1158+
output -- the file name to place the executable in
1159+
objects -- all of the object files to link
1160+
libraries -- all of the required libraries
1161+
lib_dirs -- where the required libraries are located
1162+
mem_map -- the location where the memory map file should be stored
1163+
1164+
Return value:
1165+
None
1166+
1167+
Side effect:
1168+
Runs the linker to produce the executable.
1169+
1170+
Note:
1171+
This method should be decorated with @hook_tool.
1172+
"""
1173+
raise NotImplemented
1174+
1175+
@abstractmethod
1176+
def archive(self, objects, lib_path):
1177+
"""Run the command line that creates an archive.
1178+
1179+
Positional arguhments:
1180+
objects -- a list of all the object files that should be archived
1181+
lib_path -- the file name of the resulting library file
1182+
1183+
Return value:
1184+
None
1185+
1186+
Side effect:
1187+
Runs the archiving tool to produce the library file.
1188+
1189+
Note:
1190+
This method should be decorated with @hook_tool.
1191+
"""
1192+
raise NotImplemented
1193+
1194+
@abstractmethod
1195+
def binary(self, resources, elf, bin):
1196+
"""Run the command line that will Extract a simplified binary file.
1197+
1198+
Positional arguments:
1199+
resources -- A resources object (Is not used in any of the toolchains)
1200+
elf -- the executable file that is to be converted
1201+
bin -- the file name of the to be created simplified binary file
1202+
1203+
Return value:
1204+
None
1205+
1206+
Side effect:
1207+
Runs the elf2bin tool to produce the simplified binary file.
1208+
1209+
Note:
1210+
This method should be decorated with @hook_tool.
1211+
"""
1212+
raise NotImplemented
1213+
10381214
# Return the list of macros geenrated by the build system
10391215
def get_config_macros(self):
10401216
return Config.config_to_macros(self.config_data) if self.config_data else []

0 commit comments

Comments
 (0)