Merge pull request #2675 from sarahmarshy/toolchain_path_check

Revise checking toolchain path
pull/2734/head
Sam Grove 2016-09-16 17:31:41 -05:00 committed by GitHub
commit a6f4b58405
7 changed files with 99 additions and 49 deletions

View File

@ -27,7 +27,7 @@ ROOT = abspath(join(dirname(__file__), ".."))
sys.path.insert(0, ROOT)
from tools.toolchains import TOOLCHAINS
from tools.toolchains import TOOLCHAINS, TOOLCHAIN_CLASSES, TOOLCHAIN_PATHS
from tools.toolchains import mbedToolchain
from tools.targets import TARGET_NAMES, TARGET_MAP
from tools.options import get_default_options_parser
@ -161,6 +161,7 @@ if __name__ == '__main__':
print mcu_toolchain_matrix(platform_filter=options.general_filter_regex)
exit(0)
# Get target list
targets = options.mcu if options.mcu else TARGET_NAMES
@ -212,6 +213,11 @@ if __name__ == '__main__':
# CPPCHECK code validation
if options.cppcheck_validation:
for toolchain in toolchains:
if not TOOLCHAIN_CLASSES[toolchain].check_executable():
search_path = TOOLCHAIN_PATHS[toolchain] or "No path set"
args_error(parser, "Could not find executable for %s.\n"
"Currently set search path: %s"
% (toolchain, search_path))
for target in targets:
try:
mcu = TARGET_MAP[target]

View File

@ -21,7 +21,7 @@ TEST BUILD & RUN
import sys
from time import sleep
from shutil import copy
from os.path import join, abspath, dirname, isfile, isdir
from os.path import join, abspath, dirname
# Be sure that the tools directory is in the search path
ROOT = abspath(join(dirname(__file__), ".."))
@ -46,8 +46,7 @@ from tools.build_api import mcu_toolchain_matrix
from utils import argparse_filestring_type
from utils import argparse_many
from utils import argparse_dir_not_parent
from argparse import ArgumentTypeError
from tools.toolchains import mbedToolchain
from tools.toolchains import mbedToolchain, TOOLCHAIN_CLASSES, TOOLCHAIN_PATHS
from tools.settings import CLI_COLOR_MAP
if __name__ == '__main__':
@ -232,6 +231,12 @@ if __name__ == '__main__':
else:
notify = None
if not TOOLCHAIN_CLASSES[toolchain].check_executable():
search_path = TOOLCHAIN_PATHS[toolchain] or "No path set"
args_error(parser, "Could not find executable for %s.\n"
"Currently set search path: %s"
%(toolchain,search_path))
# Test
for test_no in p:
test = Test(test_no)

View File

@ -35,7 +35,7 @@ from tools.utils import mkdir, ToolException, NotSupportedException, args_error
from tools.test_exporters import ReportExporter, ResultExporterType
from utils import argparse_filestring_type, argparse_lowercase_type, argparse_many
from utils import argparse_dir_not_parent
from tools.toolchains import mbedToolchain
from tools.toolchains import mbedToolchain, TOOLCHAIN_PATHS, TOOLCHAIN_CLASSES
from tools.settings import CLI_COLOR_MAP
if __name__ == '__main__':
@ -115,6 +115,12 @@ if __name__ == '__main__':
args_error(parser, "argument -t/--tool is required")
toolchain = options.tool[0]
if not TOOLCHAIN_CLASSES[toolchain].check_executable():
search_path = TOOLCHAIN_PATHS[toolchain] or "No path set"
args_error(parser, "Could not find executable for %s.\n"
"Currently set search path: %s"
% (toolchain, search_path))
# Find all tests in the relevant paths
for path in all_paths:
all_tests.update(find_tests(path, mcu, toolchain, options.options,
@ -196,6 +202,7 @@ if __name__ == '__main__':
print "Failed to build library"
else:
# Build all the tests
test_build_success, test_build = build_tests(tests, [options.build_dir], options.build_dir, mcu, toolchain,
options=options.options,
clean=options.clean,

View File

@ -27,6 +27,7 @@ from inspect import getmro
from copy import deepcopy
from tools.config import Config
from abc import ABCMeta, abstractmethod
from distutils.spawn import find_executable
from multiprocessing import Pool, cpu_count
from tools.utils import run_cmd, mkdir, rel_path, ToolException, NotSupportedException, split_path, compile_worker
@ -188,23 +189,6 @@ LEGACY_TOOLCHAIN_NAMES = {
}
def check_toolchain_path(function):
"""Check if the path to toolchain is valid. Exit if not.
Use this function as a decorator. Causes a system exit if the path does
not exist. Execute the function as normal if the path does exist.
Positional arguments:
function -- the function to decorate
"""
def perform_check(self, *args, **kwargs):
if not exists(self.toolchain_path) and not exists(self.toolchain_path+'.exe'):
error_string = 'Could not find executable for %s.\n Currently ' \
'set search path: %s'% (self.name, self.toolchain_path)
raise Exception(error_string)
return function(self, *args, **kwargs)
return perform_check
class mbedToolchain:
# Verbose logging
VERBOSE = True
@ -723,7 +707,6 @@ class mbedToolchain:
# THIS METHOD IS BEING CALLED BY THE MBED ONLINE BUILD SYSTEM
# ANY CHANGE OF PARAMETERS OR RETURN VALUES WILL BREAK COMPATIBILITY
@check_toolchain_path
def compile_sources(self, resources, build_path, inc_dirs=None):
# Web IDE progress bar for project build
files_to_compile = resources.s_sources + resources.c_sources + resources.cpp_sources
@ -922,7 +905,6 @@ class mbedToolchain:
else:
raise ToolException(_stderr)
@check_toolchain_path
def build_library(self, objects, dir, name):
needed_update = False
lib = self.STD_LIB_NAME % name
@ -934,7 +916,6 @@ class mbedToolchain:
return needed_update
@check_toolchain_path
def link_program(self, r, tmp_path, name):
needed_update = False
ext = 'bin'
@ -1114,6 +1095,51 @@ class mbedToolchain:
self.config_processed = True
return self.config_file
@staticmethod
def generic_check_executable(tool_key, executable_name, levels_up,
nested_dir=None):
"""
Positional args:
tool_key: the key to index TOOLCHAIN_PATHS
executable_name: the toolchain's named executable (ex. armcc)
levels_up: each toolchain joins the toolchain_path, some
variable directories (bin, include), and the executable name,
so the TOOLCHAIN_PATH value must be appropriately distanced
Keyword args:
nested_dir: the directory within TOOLCHAIN_PATHS where the executable
is found (ex: 'bin' for ARM\bin\armcc (necessary to check for path
that will be used by toolchain's compile)
Returns True if the executable location specified by the user
exists and is valid OR the executable can be found on the PATH.
Returns False otherwise.
"""
# Search PATH if user did not specify a path or specified path doesn't
# exist.
if not TOOLCHAIN_PATHS[tool_key] or not exists(TOOLCHAIN_PATHS[tool_key]):
exe = find_executable(executable_name)
if not exe:
return False
for level in range(levels_up):
# move up the specified number of directories
exe = dirname(exe)
TOOLCHAIN_PATHS[tool_key] = exe
if nested_dir:
subdir = join(TOOLCHAIN_PATHS[tool_key], nested_dir,
executable_name)
else:
subdir = join(TOOLCHAIN_PATHS[tool_key],executable_name)
# User could have specified a path that exists but does not contain exe
return exists(subdir) or exists(subdir +'.exe')
@abstractmethod
def check_executable(self):
"""Returns True if the executable (armcc) location specified by the
user exists OR the executable can be found on the PATH.
Returns False otherwise."""
raise NotImplemented
@abstractmethod
def get_config_option(self, config_header):
"""Generate the compiler option that forces the inclusion of the configuration

View File

@ -16,7 +16,6 @@ limitations under the License.
"""
import re
from os.path import join, dirname, splitext, basename
from distutils.spawn import find_executable
from tools.toolchains import mbedToolchain, TOOLCHAIN_PATHS
from tools.hooks import hook_tool
@ -42,6 +41,13 @@ class ARM(mbedToolchain):
'ld': [],
}
@staticmethod
def check_executable():
"""Returns True if the executable (armcc) location specified by the
user exists OR the executable can be found on the PATH.
Returns False otherwise."""
return mbedToolchain.generic_check_executable("ARM", 'armcc', 2, 'bin')
def __init__(self, target, options=None, notify=None, macros=None, silent=False, extra_verbose=False):
mbedToolchain.__init__(self, target, options, notify, macros, silent, extra_verbose=extra_verbose)
@ -56,11 +62,6 @@ class ARM(mbedToolchain):
else:
cpu = target.core
if not TOOLCHAIN_PATHS['ARM']:
exe = find_executable('armcc')
if exe:
TOOLCHAIN_PATHS['ARM'] = dirname(dirname(exe))
ARM_BIN = join(TOOLCHAIN_PATHS['ARM'], "bin")
ARM_INC = join(TOOLCHAIN_PATHS['ARM'], "include")
@ -86,8 +87,6 @@ class ARM(mbedToolchain):
self.ar = join(ARM_BIN, "armar")
self.elf2bin = join(ARM_BIN, "fromelf")
self.toolchain_path = TOOLCHAIN_PATHS['ARM']
def parse_dependencies(self, dep_path):
dependencies = []
for line in open(dep_path).readlines():

View File

@ -15,8 +15,7 @@ See the License for the specific language governing permissions and
limitations under the License.
"""
import re
from os.path import join, basename, splitext, dirname, exists
from distutils.spawn import find_executable
from os.path import join, basename, splitext
from tools.toolchains import mbedToolchain, TOOLCHAIN_PATHS
from tools.hooks import hook_tool
@ -111,11 +110,6 @@ class GCC(mbedToolchain):
self.ar = join(tool_path, "arm-none-eabi-ar")
self.elf2bin = join(tool_path, "arm-none-eabi-objcopy")
if tool_path:
self.toolchain_path = main_cc
else:
self.toolchain_path = find_executable("arm-none-eabi-gcc") or ''
def parse_dependencies(self, dep_path):
dependencies = []
buff = open(dep_path).readlines()
@ -275,6 +269,13 @@ class GCC(mbedToolchain):
class GCC_ARM(GCC):
@staticmethod
def check_executable():
"""Returns True if the executable (arm-none-eabi-gcc) location
specified by the user exists OR the executable can be found on the PATH.
Returns False otherwise."""
return mbedToolchain.generic_check_executable("GCC_ARM", 'arm-none-eabi-gcc', 1)
def __init__(self, target, options=None, notify=None, macros=None, silent=False, extra_verbose=False):
GCC.__init__(self, target, options, notify, macros, silent, TOOLCHAIN_PATHS['GCC_ARM'], extra_verbose=extra_verbose)
@ -300,6 +301,13 @@ class GCC_ARM(GCC):
class GCC_CR(GCC):
@staticmethod
def check_executable():
"""Returns True if the executable (arm-none-eabi-gcc) location
specified by the user exists OR the executable can be found on the PATH.
Returns False otherwise."""
return mbedToolchain.generic_check_executable("GCC_CR", 'arm-none-eabi-gcc', 1)
def __init__(self, target, options=None, notify=None, macros=None, silent=False, extra_verbose=False):
GCC.__init__(self, target, options, notify, macros, silent, TOOLCHAIN_PATHS['GCC_CR'], extra_verbose=extra_verbose)

View File

@ -16,8 +16,7 @@ limitations under the License.
"""
import re
from os import remove
from os.path import join, exists, dirname, splitext, exists
from distutils.spawn import find_executable
from os.path import join, splitext
from tools.toolchains import mbedToolchain, TOOLCHAIN_PATHS
from tools.hooks import hook_tool
@ -45,6 +44,13 @@ class IAR(mbedToolchain):
'ld': ["--skip_dynamic_initialization", "--threaded_lib"],
}
@staticmethod
def check_executable():
"""Returns True if the executable (arm-none-eabi-gcc) location
specified by the user exists OR the executable can be found on the PATH.
Returns False otherwise."""
return mbedToolchain.generic_check_executable("IAR", 'iccarm', 2, "bin")
def __init__(self, target, options=None, notify=None, macros=None, silent=False, extra_verbose=False):
mbedToolchain.__init__(self, target, options, notify, macros, silent, extra_verbose=extra_verbose)
if target.core == "Cortex-M7F" or target.core == "Cortex-M7FD":
@ -52,11 +58,6 @@ class IAR(mbedToolchain):
else:
cpuchoice = target.core
if not TOOLCHAIN_PATHS['IAR']:
exe = find_executable('iccarm')
if exe:
TOOLCHAIN_PATHS['IAR'] = dirname(dirname(exe))
# flags_cmd are used only by our scripts, the project files have them already defined,
# using this flags results in the errors (duplication)
# asm accepts --cpu Core or --fpu FPU, not like c/c++ --cpu=Core
@ -108,8 +109,6 @@ class IAR(mbedToolchain):
self.ar = join(IAR_BIN, "iarchive")
self.elf2bin = join(IAR_BIN, "ielftool")
self.toolchain_path = TOOLCHAIN_PATHS['IAR']
def parse_dependencies(self, dep_path):
return [(self.CHROOT if self.CHROOT else '')+path.strip() for path in open(dep_path).readlines()
if (path and not path.isspace())]