Clone of official tools

Committer:
theotherjimmy
Date:
Tue Sep 25 13:43:09 2018 -0500
Revision:
43:2a7da56ebd24
Release 5.10.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
theotherjimmy 43:2a7da56ebd24 1 # mbed SDK
theotherjimmy 43:2a7da56ebd24 2 # Copyright (c) 2011-2013 ARM Limited
theotherjimmy 43:2a7da56ebd24 3 #
theotherjimmy 43:2a7da56ebd24 4 # Licensed under the Apache License, Version 2.0 (the "License");
theotherjimmy 43:2a7da56ebd24 5 # you may not use this file except in compliance with the License.
theotherjimmy 43:2a7da56ebd24 6 # You may obtain a copy of the License at
theotherjimmy 43:2a7da56ebd24 7 #
theotherjimmy 43:2a7da56ebd24 8 # http://www.apache.org/licenses/LICENSE-2.0
theotherjimmy 43:2a7da56ebd24 9 #
theotherjimmy 43:2a7da56ebd24 10 # Unless required by applicable law or agreed to in writing, software
theotherjimmy 43:2a7da56ebd24 11 # distributed under the License is distributed on an "AS IS" BASIS,
theotherjimmy 43:2a7da56ebd24 12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
theotherjimmy 43:2a7da56ebd24 13 # See the License for the specific language governing permissions and
theotherjimmy 43:2a7da56ebd24 14 # limitations under the License.
theotherjimmy 43:2a7da56ebd24 15
theotherjimmy 43:2a7da56ebd24 16 """
theotherjimmy 43:2a7da56ebd24 17 # The scanning rules and Resources object.
theotherjimmy 43:2a7da56ebd24 18
theotherjimmy 43:2a7da56ebd24 19 A project in Mbed OS contains metadata in the file system as directory names.
theotherjimmy 43:2a7da56ebd24 20 These directory names adhere to a set of rules referred to as scanning rules.
theotherjimmy 43:2a7da56ebd24 21 The following are the English version of the scanning rules:
theotherjimmy 43:2a7da56ebd24 22
theotherjimmy 43:2a7da56ebd24 23 Directory names starting with "TEST_", "TARGET_", "TOOLCHAIN_" and "FEATURE_"
theotherjimmy 43:2a7da56ebd24 24 are excluded from a build unless one of the following is true:
theotherjimmy 43:2a7da56ebd24 25 * The suffix after "TARGET_" is a target label (see target.labels).
theotherjimmy 43:2a7da56ebd24 26 * The suffix after "TOOLCHAIN_" is a toolchain label, defined by the
theotherjimmy 43:2a7da56ebd24 27 inheritance hierarchy of the toolchain class.
theotherjimmy 43:2a7da56ebd24 28 * The suffix after "FEATURE_" is a member of `target.features`.
theotherjimmy 43:2a7da56ebd24 29
theotherjimmy 43:2a7da56ebd24 30
theotherjimmy 43:2a7da56ebd24 31 """
theotherjimmy 43:2a7da56ebd24 32
theotherjimmy 43:2a7da56ebd24 33 from __future__ import print_function, division, absolute_import
theotherjimmy 43:2a7da56ebd24 34
theotherjimmy 43:2a7da56ebd24 35 import fnmatch
theotherjimmy 43:2a7da56ebd24 36 import re
theotherjimmy 43:2a7da56ebd24 37 from collections import namedtuple, defaultdict
theotherjimmy 43:2a7da56ebd24 38 from copy import copy
theotherjimmy 43:2a7da56ebd24 39 from itertools import chain
theotherjimmy 43:2a7da56ebd24 40 from os import walk, sep
theotherjimmy 43:2a7da56ebd24 41 from os.path import (join, splitext, dirname, relpath, basename, split, normcase,
theotherjimmy 43:2a7da56ebd24 42 abspath, exists)
theotherjimmy 43:2a7da56ebd24 43
theotherjimmy 43:2a7da56ebd24 44 from .ignore import MbedIgnoreSet, IGNORE_FILENAME
theotherjimmy 43:2a7da56ebd24 45
theotherjimmy 43:2a7da56ebd24 46 # Support legacy build conventions: the original mbed build system did not have
theotherjimmy 43:2a7da56ebd24 47 # standard labels for the "TARGET_" and "TOOLCHAIN_" specific directories, but
theotherjimmy 43:2a7da56ebd24 48 # had the knowledge of a list of these directories to be ignored.
theotherjimmy 43:2a7da56ebd24 49 LEGACY_IGNORE_DIRS = set([
theotherjimmy 43:2a7da56ebd24 50 # Legacy Targets
theotherjimmy 43:2a7da56ebd24 51 'LPC11U24',
theotherjimmy 43:2a7da56ebd24 52 'LPC1768',
theotherjimmy 43:2a7da56ebd24 53 'LPC2368',
theotherjimmy 43:2a7da56ebd24 54 'LPC4088',
theotherjimmy 43:2a7da56ebd24 55 'LPC812',
theotherjimmy 43:2a7da56ebd24 56 'KL25Z',
theotherjimmy 43:2a7da56ebd24 57
theotherjimmy 43:2a7da56ebd24 58 # Legacy Toolchains
theotherjimmy 43:2a7da56ebd24 59 'ARM',
theotherjimmy 43:2a7da56ebd24 60 'uARM',
theotherjimmy 43:2a7da56ebd24 61 'IAR',
theotherjimmy 43:2a7da56ebd24 62 'GCC_ARM',
theotherjimmy 43:2a7da56ebd24 63 'GCC_CS',
theotherjimmy 43:2a7da56ebd24 64 'GCC_CR',
theotherjimmy 43:2a7da56ebd24 65 'GCC_CW',
theotherjimmy 43:2a7da56ebd24 66 'GCC_CW_EWL',
theotherjimmy 43:2a7da56ebd24 67 'GCC_CW_NEWLIB',
theotherjimmy 43:2a7da56ebd24 68 'ARMC6',
theotherjimmy 43:2a7da56ebd24 69
theotherjimmy 43:2a7da56ebd24 70 # Tests, here for simplicity
theotherjimmy 43:2a7da56ebd24 71 'TESTS',
theotherjimmy 43:2a7da56ebd24 72 'TEST_APPS',
theotherjimmy 43:2a7da56ebd24 73 ])
theotherjimmy 43:2a7da56ebd24 74 LEGACY_TOOLCHAIN_NAMES = {
theotherjimmy 43:2a7da56ebd24 75 'ARM_STD':'ARM',
theotherjimmy 43:2a7da56ebd24 76 'ARM_MICRO': 'uARM',
theotherjimmy 43:2a7da56ebd24 77 'GCC_ARM': 'GCC_ARM',
theotherjimmy 43:2a7da56ebd24 78 'GCC_CR': 'GCC_CR',
theotherjimmy 43:2a7da56ebd24 79 'IAR': 'IAR',
theotherjimmy 43:2a7da56ebd24 80 'ARMC6': 'ARMC6',
theotherjimmy 43:2a7da56ebd24 81 }
theotherjimmy 43:2a7da56ebd24 82
theotherjimmy 43:2a7da56ebd24 83
theotherjimmy 43:2a7da56ebd24 84 FileRef = namedtuple("FileRef", "name path")
theotherjimmy 43:2a7da56ebd24 85
theotherjimmy 43:2a7da56ebd24 86 class FileType(object):
theotherjimmy 43:2a7da56ebd24 87 C_SRC = "c"
theotherjimmy 43:2a7da56ebd24 88 CPP_SRC = "c++"
theotherjimmy 43:2a7da56ebd24 89 ASM_SRC = "s"
theotherjimmy 43:2a7da56ebd24 90 HEADER = "header"
theotherjimmy 43:2a7da56ebd24 91 INC_DIR = "inc"
theotherjimmy 43:2a7da56ebd24 92 LIB_DIR = "libdir"
theotherjimmy 43:2a7da56ebd24 93 LIB = "lib"
theotherjimmy 43:2a7da56ebd24 94 OBJECT = "o"
theotherjimmy 43:2a7da56ebd24 95 HEX = "hex"
theotherjimmy 43:2a7da56ebd24 96 BIN = "bin"
theotherjimmy 43:2a7da56ebd24 97 JSON = "json"
theotherjimmy 43:2a7da56ebd24 98 LD_SCRIPT = "ld"
theotherjimmy 43:2a7da56ebd24 99 LIB_REF = "libref"
theotherjimmy 43:2a7da56ebd24 100 BLD_REF = "bldref"
theotherjimmy 43:2a7da56ebd24 101 REPO_DIR = "repodir"
theotherjimmy 43:2a7da56ebd24 102
theotherjimmy 43:2a7da56ebd24 103 def __init__(self):
theotherjimmy 43:2a7da56ebd24 104 raise NotImplemented
theotherjimmy 43:2a7da56ebd24 105
theotherjimmy 43:2a7da56ebd24 106 class Resources(object):
theotherjimmy 43:2a7da56ebd24 107 ALL_FILE_TYPES = [
theotherjimmy 43:2a7da56ebd24 108 FileType.C_SRC,
theotherjimmy 43:2a7da56ebd24 109 FileType.CPP_SRC,
theotherjimmy 43:2a7da56ebd24 110 FileType.ASM_SRC,
theotherjimmy 43:2a7da56ebd24 111 FileType.HEADER,
theotherjimmy 43:2a7da56ebd24 112 FileType.INC_DIR,
theotherjimmy 43:2a7da56ebd24 113 FileType.LIB_DIR,
theotherjimmy 43:2a7da56ebd24 114 FileType.LIB,
theotherjimmy 43:2a7da56ebd24 115 FileType.OBJECT,
theotherjimmy 43:2a7da56ebd24 116 FileType.HEX,
theotherjimmy 43:2a7da56ebd24 117 FileType.BIN,
theotherjimmy 43:2a7da56ebd24 118 FileType.JSON,
theotherjimmy 43:2a7da56ebd24 119 FileType.LD_SCRIPT,
theotherjimmy 43:2a7da56ebd24 120 FileType.LIB_REF,
theotherjimmy 43:2a7da56ebd24 121 FileType.BLD_REF,
theotherjimmy 43:2a7da56ebd24 122 FileType.REPO_DIR,
theotherjimmy 43:2a7da56ebd24 123 ]
theotherjimmy 43:2a7da56ebd24 124
theotherjimmy 43:2a7da56ebd24 125 def __init__(self, notify, collect_ignores=False):
theotherjimmy 43:2a7da56ebd24 126 # publicly accessible things
theotherjimmy 43:2a7da56ebd24 127 self.ignored_dirs = []
theotherjimmy 43:2a7da56ebd24 128
theotherjimmy 43:2a7da56ebd24 129 # Pre-mbed 2.0 ignore dirs
theotherjimmy 43:2a7da56ebd24 130 self._legacy_ignore_dirs = (LEGACY_IGNORE_DIRS)
theotherjimmy 43:2a7da56ebd24 131
theotherjimmy 43:2a7da56ebd24 132 # Primate parameters
theotherjimmy 43:2a7da56ebd24 133 self._notify = notify
theotherjimmy 43:2a7da56ebd24 134 self._collect_ignores = collect_ignores
theotherjimmy 43:2a7da56ebd24 135
theotherjimmy 43:2a7da56ebd24 136 # Storage for file references, indexed by file type
theotherjimmy 43:2a7da56ebd24 137 self._file_refs = defaultdict(set)
theotherjimmy 43:2a7da56ebd24 138
theotherjimmy 43:2a7da56ebd24 139 # Incremental scan related
theotherjimmy 43:2a7da56ebd24 140 self._label_paths = []
theotherjimmy 43:2a7da56ebd24 141 self._labels = {
theotherjimmy 43:2a7da56ebd24 142 "TARGET": [], "TOOLCHAIN": [], "FEATURE": [], "COMPONENT": []
theotherjimmy 43:2a7da56ebd24 143 }
theotherjimmy 43:2a7da56ebd24 144 self._prefixed_labels = set()
theotherjimmy 43:2a7da56ebd24 145
theotherjimmy 43:2a7da56ebd24 146 # Path seperator style (defaults to OS-specific seperator)
theotherjimmy 43:2a7da56ebd24 147 self._sep = sep
theotherjimmy 43:2a7da56ebd24 148
theotherjimmy 43:2a7da56ebd24 149 self._ignoreset = MbedIgnoreSet()
theotherjimmy 43:2a7da56ebd24 150
theotherjimmy 43:2a7da56ebd24 151 def ignore_dir(self, directory):
theotherjimmy 43:2a7da56ebd24 152 if self._collect_ignores:
theotherjimmy 43:2a7da56ebd24 153 self.ignored_dirs.append(directory)
theotherjimmy 43:2a7da56ebd24 154
theotherjimmy 43:2a7da56ebd24 155 def _collect_duplicates(self, dupe_dict, dupe_headers):
theotherjimmy 43:2a7da56ebd24 156 for filename in self.s_sources + self.c_sources + self.cpp_sources:
theotherjimmy 43:2a7da56ebd24 157 objname, _ = splitext(basename(filename))
theotherjimmy 43:2a7da56ebd24 158 dupe_dict.setdefault(objname, set())
theotherjimmy 43:2a7da56ebd24 159 dupe_dict[objname] |= set([filename])
theotherjimmy 43:2a7da56ebd24 160 for filename in self.headers:
theotherjimmy 43:2a7da56ebd24 161 headername = basename(filename)
theotherjimmy 43:2a7da56ebd24 162 dupe_headers.setdefault(headername, set())
theotherjimmy 43:2a7da56ebd24 163 dupe_headers[headername] |= set([headername])
theotherjimmy 43:2a7da56ebd24 164 return dupe_dict, dupe_headers
theotherjimmy 43:2a7da56ebd24 165
theotherjimmy 43:2a7da56ebd24 166 def detect_duplicates(self):
theotherjimmy 43:2a7da56ebd24 167 """Detect all potential ambiguities in filenames and report them with
theotherjimmy 43:2a7da56ebd24 168 a toolchain notification
theotherjimmy 43:2a7da56ebd24 169 """
theotherjimmy 43:2a7da56ebd24 170 count = 0
theotherjimmy 43:2a7da56ebd24 171 dupe_dict, dupe_headers = self._collect_duplicates(dict(), dict())
theotherjimmy 43:2a7da56ebd24 172 for objname, filenames in dupe_dict.items():
theotherjimmy 43:2a7da56ebd24 173 if len(filenames) > 1:
theotherjimmy 43:2a7da56ebd24 174 count+=1
theotherjimmy 43:2a7da56ebd24 175 self._notify.tool_error(
theotherjimmy 43:2a7da56ebd24 176 "Object file %s.o is not unique! It could be made from: %s"\
theotherjimmy 43:2a7da56ebd24 177 % (objname, " ".join(filenames)))
theotherjimmy 43:2a7da56ebd24 178 for headername, locations in dupe_headers.items():
theotherjimmy 43:2a7da56ebd24 179 if len(locations) > 1:
theotherjimmy 43:2a7da56ebd24 180 count+=1
theotherjimmy 43:2a7da56ebd24 181 self._notify.tool_error(
theotherjimmy 43:2a7da56ebd24 182 "Header file %s is not unique! It could be: %s" %\
theotherjimmy 43:2a7da56ebd24 183 (headername, " ".join(locations)))
theotherjimmy 43:2a7da56ebd24 184 return count
theotherjimmy 43:2a7da56ebd24 185
theotherjimmy 43:2a7da56ebd24 186 def win_to_unix(self):
theotherjimmy 43:2a7da56ebd24 187 self._sep = "/"
theotherjimmy 43:2a7da56ebd24 188 if self._sep != sep:
theotherjimmy 43:2a7da56ebd24 189 for file_type in self.ALL_FILE_TYPES:
theotherjimmy 43:2a7da56ebd24 190 v = [f._replace(name=f.name.replace(sep, self._sep)) for
theotherjimmy 43:2a7da56ebd24 191 f in self.get_file_refs(file_type)]
theotherjimmy 43:2a7da56ebd24 192 self._file_refs[file_type] = v
theotherjimmy 43:2a7da56ebd24 193
theotherjimmy 43:2a7da56ebd24 194 def __str__(self):
theotherjimmy 43:2a7da56ebd24 195 s = []
theotherjimmy 43:2a7da56ebd24 196
theotherjimmy 43:2a7da56ebd24 197 for (label, file_type) in (
theotherjimmy 43:2a7da56ebd24 198 ('Include Directories', FileType.INC_DIR),
theotherjimmy 43:2a7da56ebd24 199 ('Headers', FileType.HEADER),
theotherjimmy 43:2a7da56ebd24 200
theotherjimmy 43:2a7da56ebd24 201 ('Assembly sources', FileType.ASM_SRC),
theotherjimmy 43:2a7da56ebd24 202 ('C sources', FileType.C_SRC),
theotherjimmy 43:2a7da56ebd24 203 ('C++ sources', FileType.CPP_SRC),
theotherjimmy 43:2a7da56ebd24 204
theotherjimmy 43:2a7da56ebd24 205 ('Library directories', FileType.LIB_DIR),
theotherjimmy 43:2a7da56ebd24 206 ('Objects', FileType.OBJECT),
theotherjimmy 43:2a7da56ebd24 207 ('Libraries', FileType.LIB),
theotherjimmy 43:2a7da56ebd24 208
theotherjimmy 43:2a7da56ebd24 209 ('Hex files', FileType.HEX),
theotherjimmy 43:2a7da56ebd24 210 ('Bin files', FileType.BIN),
theotherjimmy 43:2a7da56ebd24 211 ('Linker script', FileType.LD_SCRIPT)
theotherjimmy 43:2a7da56ebd24 212 ):
theotherjimmy 43:2a7da56ebd24 213 resources = self.get_file_refs(file_type)
theotherjimmy 43:2a7da56ebd24 214 if resources:
theotherjimmy 43:2a7da56ebd24 215 s.append('%s:\n ' % label + '\n '.join(
theotherjimmy 43:2a7da56ebd24 216 "%s -> %s" % (name, path) for name, path in resources))
theotherjimmy 43:2a7da56ebd24 217
theotherjimmy 43:2a7da56ebd24 218 return '\n'.join(s)
theotherjimmy 43:2a7da56ebd24 219
theotherjimmy 43:2a7da56ebd24 220
theotherjimmy 43:2a7da56ebd24 221 def _add_labels(self, prefix, labels):
theotherjimmy 43:2a7da56ebd24 222 self._labels[prefix].extend(labels)
theotherjimmy 43:2a7da56ebd24 223 self._prefixed_labels |= set("%s_%s" % (prefix, label) for label in labels)
theotherjimmy 43:2a7da56ebd24 224 for path, base_path, into_path in self._label_paths:
theotherjimmy 43:2a7da56ebd24 225 if basename(path) in self._prefixed_labels:
theotherjimmy 43:2a7da56ebd24 226 self.add_directory(path, base_path, into_path)
theotherjimmy 43:2a7da56ebd24 227 self._label_paths = [(p, b, i) for p, b, i in self._label_paths
theotherjimmy 43:2a7da56ebd24 228 if basename(p) not in self._prefixed_labels]
theotherjimmy 43:2a7da56ebd24 229
theotherjimmy 43:2a7da56ebd24 230 def add_target_labels(self, target):
theotherjimmy 43:2a7da56ebd24 231 self._add_labels("TARGET", target.labels)
theotherjimmy 43:2a7da56ebd24 232 self._add_labels("COMPONENT", target.components)
theotherjimmy 43:2a7da56ebd24 233 self.add_features(target.features)
theotherjimmy 43:2a7da56ebd24 234
theotherjimmy 43:2a7da56ebd24 235 def add_features(self, features):
theotherjimmy 43:2a7da56ebd24 236 self._add_labels("FEATURE", features)
theotherjimmy 43:2a7da56ebd24 237
theotherjimmy 43:2a7da56ebd24 238 def add_toolchain_labels(self, toolchain):
theotherjimmy 43:2a7da56ebd24 239 for prefix, value in toolchain.get_labels().items():
theotherjimmy 43:2a7da56ebd24 240 self._add_labels(prefix, value)
theotherjimmy 43:2a7da56ebd24 241 self._legacy_ignore_dirs -= set(
theotherjimmy 43:2a7da56ebd24 242 [toolchain.target.name, LEGACY_TOOLCHAIN_NAMES[toolchain.name]])
theotherjimmy 43:2a7da56ebd24 243
theotherjimmy 43:2a7da56ebd24 244 def add_ignore_patterns(self, root, base_path, patterns):
theotherjimmy 43:2a7da56ebd24 245 real_base = relpath(root, base_path)
theotherjimmy 43:2a7da56ebd24 246 self._ignoreset.add_ignore_patterns(real_base, patterns)
theotherjimmy 43:2a7da56ebd24 247
theotherjimmy 43:2a7da56ebd24 248 def _not_current_label(self, dirname, label_type):
theotherjimmy 43:2a7da56ebd24 249 return (dirname.startswith(label_type + "_") and
theotherjimmy 43:2a7da56ebd24 250 dirname[len(label_type) + 1:] not in self._labels[label_type])
theotherjimmy 43:2a7da56ebd24 251
theotherjimmy 43:2a7da56ebd24 252 def add_file_ref(self, file_type, file_name, file_path):
theotherjimmy 43:2a7da56ebd24 253 if sep != self._sep:
theotherjimmy 43:2a7da56ebd24 254 ref = FileRef(file_name.replace(sep, self._sep), file_path)
theotherjimmy 43:2a7da56ebd24 255 else:
theotherjimmy 43:2a7da56ebd24 256 ref = FileRef(file_name, file_path)
theotherjimmy 43:2a7da56ebd24 257 self._file_refs[file_type].add(ref)
theotherjimmy 43:2a7da56ebd24 258
theotherjimmy 43:2a7da56ebd24 259 def get_file_refs(self, file_type):
theotherjimmy 43:2a7da56ebd24 260 """Return a list of FileRef for every file of the given type"""
theotherjimmy 43:2a7da56ebd24 261 return list(self._file_refs[file_type])
theotherjimmy 43:2a7da56ebd24 262
theotherjimmy 43:2a7da56ebd24 263 def _all_parents(self, files):
theotherjimmy 43:2a7da56ebd24 264 for name in files:
theotherjimmy 43:2a7da56ebd24 265 components = name.split(self._sep)
theotherjimmy 43:2a7da56ebd24 266 start_at = 2 if components[0] in set(['', '.']) else 1
theotherjimmy 43:2a7da56ebd24 267 for index, directory in reversed(list(enumerate(components))[start_at:]):
theotherjimmy 43:2a7da56ebd24 268 if directory in self._prefixed_labels:
theotherjimmy 43:2a7da56ebd24 269 start_at = index + 1
theotherjimmy 43:2a7da56ebd24 270 break
theotherjimmy 43:2a7da56ebd24 271 for n in range(start_at, len(components)):
theotherjimmy 43:2a7da56ebd24 272 parent = self._sep.join(components[:n])
theotherjimmy 43:2a7da56ebd24 273 yield parent
theotherjimmy 43:2a7da56ebd24 274
theotherjimmy 43:2a7da56ebd24 275 def _get_from_refs(self, file_type, key):
theotherjimmy 43:2a7da56ebd24 276 if file_type is FileType.INC_DIR:
theotherjimmy 43:2a7da56ebd24 277 parents = set(self._all_parents(self._get_from_refs(
theotherjimmy 43:2a7da56ebd24 278 FileType.HEADER, key)))
theotherjimmy 43:2a7da56ebd24 279 parents.add(".")
theotherjimmy 43:2a7da56ebd24 280 else:
theotherjimmy 43:2a7da56ebd24 281 parents = set()
theotherjimmy 43:2a7da56ebd24 282 return sorted(
theotherjimmy 43:2a7da56ebd24 283 list(parents) + [key(f) for f in self.get_file_refs(file_type)]
theotherjimmy 43:2a7da56ebd24 284 )
theotherjimmy 43:2a7da56ebd24 285
theotherjimmy 43:2a7da56ebd24 286
theotherjimmy 43:2a7da56ebd24 287 def get_file_names(self, file_type):
theotherjimmy 43:2a7da56ebd24 288 return self._get_from_refs(file_type, lambda f: f.name)
theotherjimmy 43:2a7da56ebd24 289
theotherjimmy 43:2a7da56ebd24 290 def get_file_paths(self, file_type):
theotherjimmy 43:2a7da56ebd24 291 return self._get_from_refs(file_type, lambda f: f.path)
theotherjimmy 43:2a7da56ebd24 292
theotherjimmy 43:2a7da56ebd24 293 def add_files_to_type(self, file_type, files):
theotherjimmy 43:2a7da56ebd24 294 for f in files:
theotherjimmy 43:2a7da56ebd24 295 self.add_file_ref(file_type, f, f)
theotherjimmy 43:2a7da56ebd24 296
theotherjimmy 43:2a7da56ebd24 297 @property
theotherjimmy 43:2a7da56ebd24 298 def inc_dirs(self):
theotherjimmy 43:2a7da56ebd24 299 return self.get_file_names(FileType.INC_DIR)
theotherjimmy 43:2a7da56ebd24 300
theotherjimmy 43:2a7da56ebd24 301 @property
theotherjimmy 43:2a7da56ebd24 302 def headers(self):
theotherjimmy 43:2a7da56ebd24 303 return self.get_file_names(FileType.HEADER)
theotherjimmy 43:2a7da56ebd24 304
theotherjimmy 43:2a7da56ebd24 305 @property
theotherjimmy 43:2a7da56ebd24 306 def s_sources(self):
theotherjimmy 43:2a7da56ebd24 307 return self.get_file_names(FileType.ASM_SRC)
theotherjimmy 43:2a7da56ebd24 308
theotherjimmy 43:2a7da56ebd24 309 @property
theotherjimmy 43:2a7da56ebd24 310 def c_sources(self):
theotherjimmy 43:2a7da56ebd24 311 return self.get_file_names(FileType.C_SRC)
theotherjimmy 43:2a7da56ebd24 312
theotherjimmy 43:2a7da56ebd24 313 @property
theotherjimmy 43:2a7da56ebd24 314 def cpp_sources(self):
theotherjimmy 43:2a7da56ebd24 315 return self.get_file_names(FileType.CPP_SRC)
theotherjimmy 43:2a7da56ebd24 316
theotherjimmy 43:2a7da56ebd24 317 @property
theotherjimmy 43:2a7da56ebd24 318 def lib_dirs(self):
theotherjimmy 43:2a7da56ebd24 319 return self.get_file_names(FileType.LIB_DIR)
theotherjimmy 43:2a7da56ebd24 320
theotherjimmy 43:2a7da56ebd24 321 @property
theotherjimmy 43:2a7da56ebd24 322 def objects(self):
theotherjimmy 43:2a7da56ebd24 323 return self.get_file_names(FileType.OBJECT)
theotherjimmy 43:2a7da56ebd24 324
theotherjimmy 43:2a7da56ebd24 325 @property
theotherjimmy 43:2a7da56ebd24 326 def libraries(self):
theotherjimmy 43:2a7da56ebd24 327 return self.get_file_names(FileType.LIB)
theotherjimmy 43:2a7da56ebd24 328
theotherjimmy 43:2a7da56ebd24 329 @property
theotherjimmy 43:2a7da56ebd24 330 def lib_builds(self):
theotherjimmy 43:2a7da56ebd24 331 return self.get_file_names(FileType.BLD_REF)
theotherjimmy 43:2a7da56ebd24 332
theotherjimmy 43:2a7da56ebd24 333 @property
theotherjimmy 43:2a7da56ebd24 334 def lib_refs(self):
theotherjimmy 43:2a7da56ebd24 335 return self.get_file_names(FileType.LIB_REF)
theotherjimmy 43:2a7da56ebd24 336
theotherjimmy 43:2a7da56ebd24 337 @property
theotherjimmy 43:2a7da56ebd24 338 def linker_script(self):
theotherjimmy 43:2a7da56ebd24 339 options = self.get_file_names(FileType.LD_SCRIPT)
theotherjimmy 43:2a7da56ebd24 340 if options:
theotherjimmy 43:2a7da56ebd24 341 return options[0]
theotherjimmy 43:2a7da56ebd24 342 else:
theotherjimmy 43:2a7da56ebd24 343 return None
theotherjimmy 43:2a7da56ebd24 344
theotherjimmy 43:2a7da56ebd24 345 @property
theotherjimmy 43:2a7da56ebd24 346 def hex_files(self):
theotherjimmy 43:2a7da56ebd24 347 return self.get_file_names(FileType.HEX)
theotherjimmy 43:2a7da56ebd24 348
theotherjimmy 43:2a7da56ebd24 349 @property
theotherjimmy 43:2a7da56ebd24 350 def bin_files(self):
theotherjimmy 43:2a7da56ebd24 351 return self.get_file_names(FileType.BIN)
theotherjimmy 43:2a7da56ebd24 352
theotherjimmy 43:2a7da56ebd24 353 @property
theotherjimmy 43:2a7da56ebd24 354 def json_files(self):
theotherjimmy 43:2a7da56ebd24 355 return self.get_file_names(FileType.JSON)
theotherjimmy 43:2a7da56ebd24 356
theotherjimmy 43:2a7da56ebd24 357 def add_directory(
theotherjimmy 43:2a7da56ebd24 358 self,
theotherjimmy 43:2a7da56ebd24 359 path,
theotherjimmy 43:2a7da56ebd24 360 base_path=None,
theotherjimmy 43:2a7da56ebd24 361 into_path=None,
theotherjimmy 43:2a7da56ebd24 362 exclude_paths=None,
theotherjimmy 43:2a7da56ebd24 363 ):
theotherjimmy 43:2a7da56ebd24 364 """ Scan a directory and include its resources in this resources obejct
theotherjimmy 43:2a7da56ebd24 365
theotherjimmy 43:2a7da56ebd24 366 Positional arguments:
theotherjimmy 43:2a7da56ebd24 367 path - the path to search for resources
theotherjimmy 43:2a7da56ebd24 368
theotherjimmy 43:2a7da56ebd24 369 Keyword arguments
theotherjimmy 43:2a7da56ebd24 370 base_path - If this is part of an incremental scan, include the origin
theotherjimmy 43:2a7da56ebd24 371 directory root of the scan here
theotherjimmy 43:2a7da56ebd24 372 into_path - Pretend that scanned files are within the specified
theotherjimmy 43:2a7da56ebd24 373 directory within a project instead of using their actual path
theotherjimmy 43:2a7da56ebd24 374 exclude_paths - A list of paths that are to be excluded from a build
theotherjimmy 43:2a7da56ebd24 375 """
theotherjimmy 43:2a7da56ebd24 376 self._notify.progress("scan", abspath(path))
theotherjimmy 43:2a7da56ebd24 377
theotherjimmy 43:2a7da56ebd24 378 if base_path is None:
theotherjimmy 43:2a7da56ebd24 379 base_path = path
theotherjimmy 43:2a7da56ebd24 380 if into_path is None:
theotherjimmy 43:2a7da56ebd24 381 into_path = path
theotherjimmy 43:2a7da56ebd24 382 if self._collect_ignores and path in self.ignored_dirs:
theotherjimmy 43:2a7da56ebd24 383 self.ignored_dirs.remove(path)
theotherjimmy 43:2a7da56ebd24 384 if exclude_paths:
theotherjimmy 43:2a7da56ebd24 385 self.add_ignore_patterns(
theotherjimmy 43:2a7da56ebd24 386 path, base_path, [join(e, "*") for e in exclude_paths])
theotherjimmy 43:2a7da56ebd24 387
theotherjimmy 43:2a7da56ebd24 388 for root, dirs, files in walk(path, followlinks=True):
theotherjimmy 43:2a7da56ebd24 389 # Check if folder contains .mbedignore
theotherjimmy 43:2a7da56ebd24 390 if IGNORE_FILENAME in files:
theotherjimmy 43:2a7da56ebd24 391 real_base = relpath(root, base_path)
theotherjimmy 43:2a7da56ebd24 392 self._ignoreset.add_mbedignore(
theotherjimmy 43:2a7da56ebd24 393 real_base, join(root, IGNORE_FILENAME))
theotherjimmy 43:2a7da56ebd24 394
theotherjimmy 43:2a7da56ebd24 395 root_path =join(relpath(root, base_path))
theotherjimmy 43:2a7da56ebd24 396 if self._ignoreset.is_ignored(join(root_path,"")):
theotherjimmy 43:2a7da56ebd24 397 self.ignore_dir(root_path)
theotherjimmy 43:2a7da56ebd24 398 dirs[:] = []
theotherjimmy 43:2a7da56ebd24 399 continue
theotherjimmy 43:2a7da56ebd24 400
theotherjimmy 43:2a7da56ebd24 401 for d in copy(dirs):
theotherjimmy 43:2a7da56ebd24 402 dir_path = join(root, d)
theotherjimmy 43:2a7da56ebd24 403 if d == '.hg' or d == '.git':
theotherjimmy 43:2a7da56ebd24 404 fake_path = join(into_path, relpath(dir_path, base_path))
theotherjimmy 43:2a7da56ebd24 405 self.add_file_ref(FileType.REPO_DIR, fake_path, dir_path)
theotherjimmy 43:2a7da56ebd24 406
theotherjimmy 43:2a7da56ebd24 407 if (any(self._not_current_label(d, t) for t
theotherjimmy 43:2a7da56ebd24 408 in self._labels.keys())):
theotherjimmy 43:2a7da56ebd24 409 self._label_paths.append((dir_path, base_path, into_path))
theotherjimmy 43:2a7da56ebd24 410 self.ignore_dir(dir_path)
theotherjimmy 43:2a7da56ebd24 411 dirs.remove(d)
theotherjimmy 43:2a7da56ebd24 412 elif (d.startswith('.') or d in self._legacy_ignore_dirs or
theotherjimmy 43:2a7da56ebd24 413 self._ignoreset.is_ignored(join(root_path, d, ""))):
theotherjimmy 43:2a7da56ebd24 414 self.ignore_dir(dir_path)
theotherjimmy 43:2a7da56ebd24 415 dirs.remove(d)
theotherjimmy 43:2a7da56ebd24 416
theotherjimmy 43:2a7da56ebd24 417 # Add root to include paths
theotherjimmy 43:2a7da56ebd24 418 root = root.rstrip("/")
theotherjimmy 43:2a7da56ebd24 419
theotherjimmy 43:2a7da56ebd24 420 for file in files:
theotherjimmy 43:2a7da56ebd24 421 file_path = join(root, file)
theotherjimmy 43:2a7da56ebd24 422 self._add_file(file_path, base_path, into_path)
theotherjimmy 43:2a7da56ebd24 423
theotherjimmy 43:2a7da56ebd24 424 _EXT = {
theotherjimmy 43:2a7da56ebd24 425 ".c": FileType.C_SRC,
theotherjimmy 43:2a7da56ebd24 426 ".cc": FileType.CPP_SRC,
theotherjimmy 43:2a7da56ebd24 427 ".cpp": FileType.CPP_SRC,
theotherjimmy 43:2a7da56ebd24 428 ".s": FileType.ASM_SRC,
theotherjimmy 43:2a7da56ebd24 429 ".h": FileType.HEADER,
theotherjimmy 43:2a7da56ebd24 430 ".hh": FileType.HEADER,
theotherjimmy 43:2a7da56ebd24 431 ".hpp": FileType.HEADER,
theotherjimmy 43:2a7da56ebd24 432 ".o": FileType.OBJECT,
theotherjimmy 43:2a7da56ebd24 433 ".hex": FileType.HEX,
theotherjimmy 43:2a7da56ebd24 434 ".bin": FileType.BIN,
theotherjimmy 43:2a7da56ebd24 435 ".json": FileType.JSON,
theotherjimmy 43:2a7da56ebd24 436 ".a": FileType.LIB,
theotherjimmy 43:2a7da56ebd24 437 ".ar": FileType.LIB,
theotherjimmy 43:2a7da56ebd24 438 ".sct": FileType.LD_SCRIPT,
theotherjimmy 43:2a7da56ebd24 439 ".ld": FileType.LD_SCRIPT,
theotherjimmy 43:2a7da56ebd24 440 ".icf": FileType.LD_SCRIPT,
theotherjimmy 43:2a7da56ebd24 441 ".lib": FileType.LIB_REF,
theotherjimmy 43:2a7da56ebd24 442 ".bld": FileType.BLD_REF,
theotherjimmy 43:2a7da56ebd24 443 }
theotherjimmy 43:2a7da56ebd24 444
theotherjimmy 43:2a7da56ebd24 445 _DIR_EXT = {
theotherjimmy 43:2a7da56ebd24 446 ".a": FileType.LIB_DIR,
theotherjimmy 43:2a7da56ebd24 447 ".ar": FileType.LIB_DIR,
theotherjimmy 43:2a7da56ebd24 448 }
theotherjimmy 43:2a7da56ebd24 449
theotherjimmy 43:2a7da56ebd24 450 def _add_file(self, file_path, base_path, into_path):
theotherjimmy 43:2a7da56ebd24 451 """ Add a single file into the resources object that was found by
theotherjimmy 43:2a7da56ebd24 452 scanning starting as base_path
theotherjimmy 43:2a7da56ebd24 453 """
theotherjimmy 43:2a7da56ebd24 454
theotherjimmy 43:2a7da56ebd24 455 if (self._ignoreset.is_ignored(relpath(file_path, base_path)) or
theotherjimmy 43:2a7da56ebd24 456 basename(file_path).startswith(".")):
theotherjimmy 43:2a7da56ebd24 457 self.ignore_dir(relpath(file_path, base_path))
theotherjimmy 43:2a7da56ebd24 458 return
theotherjimmy 43:2a7da56ebd24 459
theotherjimmy 43:2a7da56ebd24 460 fake_path = join(into_path, relpath(file_path, base_path))
theotherjimmy 43:2a7da56ebd24 461 _, ext = splitext(file_path)
theotherjimmy 43:2a7da56ebd24 462 try:
theotherjimmy 43:2a7da56ebd24 463 file_type = self._EXT[ext.lower()]
theotherjimmy 43:2a7da56ebd24 464 self.add_file_ref(file_type, fake_path, file_path)
theotherjimmy 43:2a7da56ebd24 465 except KeyError:
theotherjimmy 43:2a7da56ebd24 466 pass
theotherjimmy 43:2a7da56ebd24 467 try:
theotherjimmy 43:2a7da56ebd24 468 dir_type = self._DIR_EXT[ext.lower()]
theotherjimmy 43:2a7da56ebd24 469 self.add_file_ref(dir_type, dirname(fake_path), dirname(file_path))
theotherjimmy 43:2a7da56ebd24 470 except KeyError:
theotherjimmy 43:2a7da56ebd24 471 pass
theotherjimmy 43:2a7da56ebd24 472
theotherjimmy 43:2a7da56ebd24 473
theotherjimmy 43:2a7da56ebd24 474 def scan_with_toolchain(self, src_paths, toolchain, dependencies_paths=None,
theotherjimmy 43:2a7da56ebd24 475 inc_dirs=None, exclude=True):
theotherjimmy 43:2a7da56ebd24 476 """ Scan resources using initialized toolcain
theotherjimmy 43:2a7da56ebd24 477
theotherjimmy 43:2a7da56ebd24 478 Positional arguments
theotherjimmy 43:2a7da56ebd24 479 src_paths - the paths to source directories
theotherjimmy 43:2a7da56ebd24 480 toolchain - valid toolchain object
theotherjimmy 43:2a7da56ebd24 481
theotherjimmy 43:2a7da56ebd24 482 Keyword arguments
theotherjimmy 43:2a7da56ebd24 483 dependencies_paths - dependency paths that we should scan for include dirs
theotherjimmy 43:2a7da56ebd24 484 inc_dirs - additional include directories which should be added to
theotherjimmy 43:2a7da56ebd24 485 the scanner resources
theotherjimmy 43:2a7da56ebd24 486 exclude - Exclude the toolchain's build directory from the resources
theotherjimmy 43:2a7da56ebd24 487 """
theotherjimmy 43:2a7da56ebd24 488 self.add_toolchain_labels(toolchain)
theotherjimmy 43:2a7da56ebd24 489 for path in src_paths:
theotherjimmy 43:2a7da56ebd24 490 if exists(path):
theotherjimmy 43:2a7da56ebd24 491 into_path = relpath(path).strip(".\\/")
theotherjimmy 43:2a7da56ebd24 492 if exclude:
theotherjimmy 43:2a7da56ebd24 493 self.add_directory(
theotherjimmy 43:2a7da56ebd24 494 path,
theotherjimmy 43:2a7da56ebd24 495 into_path=into_path,
theotherjimmy 43:2a7da56ebd24 496 exclude_paths=[toolchain.build_dir]
theotherjimmy 43:2a7da56ebd24 497 )
theotherjimmy 43:2a7da56ebd24 498 else:
theotherjimmy 43:2a7da56ebd24 499 self.add_directory(path, into_path=into_path)
theotherjimmy 43:2a7da56ebd24 500
theotherjimmy 43:2a7da56ebd24 501 # Scan dependency paths for include dirs
theotherjimmy 43:2a7da56ebd24 502 if dependencies_paths is not None:
theotherjimmy 43:2a7da56ebd24 503 toolchain.progress("dep", dependencies_paths)
theotherjimmy 43:2a7da56ebd24 504 for dep in dependencies_paths:
theotherjimmy 43:2a7da56ebd24 505 lib_self = self.__class__(self._notify, self._collect_ignores)\
theotherjimmy 43:2a7da56ebd24 506 .scan_with_toolchain([dep], toolchain)
theotherjimmy 43:2a7da56ebd24 507 self.inc_dirs.extend(lib_self.inc_dirs)
theotherjimmy 43:2a7da56ebd24 508
theotherjimmy 43:2a7da56ebd24 509 # Add additional include directories if passed
theotherjimmy 43:2a7da56ebd24 510 if inc_dirs:
theotherjimmy 43:2a7da56ebd24 511 if isinstance(inc_dirs, list):
theotherjimmy 43:2a7da56ebd24 512 self.inc_dirs.extend(inc_dirs)
theotherjimmy 43:2a7da56ebd24 513 else:
theotherjimmy 43:2a7da56ebd24 514 self.inc_dirs.append(inc_dirs)
theotherjimmy 43:2a7da56ebd24 515
theotherjimmy 43:2a7da56ebd24 516 # Load self into the config system which might expand/modify self
theotherjimmy 43:2a7da56ebd24 517 # based on config data
theotherjimmy 43:2a7da56ebd24 518 toolchain.config.load_resources(self)
theotherjimmy 43:2a7da56ebd24 519
theotherjimmy 43:2a7da56ebd24 520 # Set the toolchain's configuration data
theotherjimmy 43:2a7da56ebd24 521 toolchain.set_config_data(toolchain.config.get_config_data())
theotherjimmy 43:2a7da56ebd24 522
theotherjimmy 43:2a7da56ebd24 523 return self
theotherjimmy 43:2a7da56ebd24 524
theotherjimmy 43:2a7da56ebd24 525 def scan_with_config(self, src_paths, config):
theotherjimmy 43:2a7da56ebd24 526 if config.target:
theotherjimmy 43:2a7da56ebd24 527 self.add_target_labels(config.target)
theotherjimmy 43:2a7da56ebd24 528 for path in src_paths:
theotherjimmy 43:2a7da56ebd24 529 if exists(path):
theotherjimmy 43:2a7da56ebd24 530 self.add_directory(path)
theotherjimmy 43:2a7da56ebd24 531 config.load_resources(self)
theotherjimmy 43:2a7da56ebd24 532 return self
theotherjimmy 43:2a7da56ebd24 533