diff --git a/tools/make.py b/tools/make.py index e8d5a06d8b..4434931f8e 100644 --- a/tools/make.py +++ b/tools/make.py @@ -21,8 +21,7 @@ TEST BUILD & RUN import sys from time import sleep from shutil import copy -from os.path import join, abspath, dirname, exists -from distutils.spawn import find_executable +from os.path import join, abspath, dirname # Be sure that the tools directory is in the search path ROOT = abspath(join(dirname(__file__), "..")) diff --git a/tools/toolchains/__init__.py b/tools/toolchains/__init__.py index 92f5f2e1f1..28a485d63a 100644 --- a/tools/toolchains/__init__.py +++ b/tools/toolchains/__init__.py @@ -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 @@ -1091,6 +1092,44 @@ 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 get_config_option(self, config_header): """Generate the compiler option that forces the inclusion of the configuration diff --git a/tools/toolchains/arm.py b/tools/toolchains/arm.py index 26f6441833..7ec6bad145 100644 --- a/tools/toolchains/arm.py +++ b/tools/toolchains/arm.py @@ -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, dirname, splitext, basename, exists -from distutils.spawn import find_executable +from os.path import join, dirname, splitext, basename from tools.toolchains import mbedToolchain, TOOLCHAIN_PATHS from tools.hooks import hook_tool @@ -47,12 +46,7 @@ class ARM(mbedToolchain): """Returns True if the executable (armcc) location specified by the user exists OR the executable can be found on the PATH. Returns False otherwise.""" - if not TOOLCHAIN_PATHS["ARM"] or not exists(TOOLCHAIN_PATHS['ARM']): - exe = find_executable('armcc') - if not exe: - return False - TOOLCHAIN_PATHS['ARM'] = dirname(dirname(exe)) - return True + 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) diff --git a/tools/toolchains/gcc.py b/tools/toolchains/gcc.py index fc54c25dae..451711a93d 100644 --- a/tools/toolchains/gcc.py +++ b/tools/toolchains/gcc.py @@ -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 @@ -275,12 +274,7 @@ class GCC_ARM(GCC): """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.""" - if not TOOLCHAIN_PATHS["GCC_ARM"] or not exists(TOOLCHAIN_PATHS['GCC_ARM']): - exe = find_executable('arm-none-eabi-gcc') - if not exe: - return False - TOOLCHAIN_PATHS['GCC_ARM'] = dirname(exe) - return True + 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) @@ -312,12 +306,7 @@ class GCC_CR(GCC): """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.""" - if not TOOLCHAIN_PATHS["GCC_CR"] or not exists(TOOLCHAIN_PATHS['GCC_CR']): - exe = find_executable('arm-none-eabi-gcc') - if not exe: - return False - TOOLCHAIN_PATHS['GCC_CR'] = dirname(exe) - return True + 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) diff --git a/tools/toolchains/iar.py b/tools/toolchains/iar.py index 01ac99846d..447761944d 100644 --- a/tools/toolchains/iar.py +++ b/tools/toolchains/iar.py @@ -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 @@ -50,12 +49,7 @@ class IAR(mbedToolchain): """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.""" - if not TOOLCHAIN_PATHS["IAR"] or not exists(TOOLCHAIN_PATHS['IAR']): - exe = find_executable('iccarm') - if not exe: - return False - TOOLCHAIN_PATHS['IAR'] = dirname(dirname(exe)) - return True + 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)