Clone of official tools

Committer:
Anders Blomdell
Date:
Thu Feb 04 17:17:13 2021 +0100
Revision:
47:21ae3e5a7128
Parent:
43:2a7da56ebd24
Add a few normpath calls

Who changed what in which revision?

UserRevisionLine numberNew contents of line
theotherjimmy 43:2a7da56ebd24 1 """
theotherjimmy 43:2a7da56ebd24 2 mbed SDK
theotherjimmy 43:2a7da56ebd24 3 Copyright (c) 2011-2016 ARM Limited
theotherjimmy 43:2a7da56ebd24 4
theotherjimmy 43:2a7da56ebd24 5 Licensed under the Apache License, Version 2.0 (the "License");
theotherjimmy 43:2a7da56ebd24 6 you may not use this file except in compliance with the License.
theotherjimmy 43:2a7da56ebd24 7 You may obtain a copy of the License at
theotherjimmy 43:2a7da56ebd24 8
theotherjimmy 43:2a7da56ebd24 9 http://www.apache.org/licenses/LICENSE-2.0
theotherjimmy 43:2a7da56ebd24 10
theotherjimmy 43:2a7da56ebd24 11 Unless required by applicable law or agreed to in writing, software
theotherjimmy 43:2a7da56ebd24 12 distributed under the License is distributed on an "AS IS" BASIS,
theotherjimmy 43:2a7da56ebd24 13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
theotherjimmy 43:2a7da56ebd24 14 See the License for the specific language governing permissions and
theotherjimmy 43:2a7da56ebd24 15 limitations under the License.
theotherjimmy 43:2a7da56ebd24 16 """
theotherjimmy 43:2a7da56ebd24 17 from __future__ import print_function, absolute_import
theotherjimmy 43:2a7da56ebd24 18 from builtins import str
theotherjimmy 43:2a7da56ebd24 19
theotherjimmy 43:2a7da56ebd24 20 import re
theotherjimmy 43:2a7da56ebd24 21 import shutil
theotherjimmy 43:2a7da56ebd24 22 from os import remove, getcwd, chdir, mkdir
theotherjimmy 43:2a7da56ebd24 23 from os.path import basename, exists
theotherjimmy 43:2a7da56ebd24 24 from subprocess import Popen, PIPE
theotherjimmy 43:2a7da56ebd24 25
theotherjimmy 43:2a7da56ebd24 26 from jinja2.exceptions import TemplateNotFound
theotherjimmy 43:2a7da56ebd24 27
theotherjimmy 43:2a7da56ebd24 28 from tools.export.exporters import Exporter, apply_supported_whitelist
theotherjimmy 43:2a7da56ebd24 29 from tools.targets import TARGET_MAP
theotherjimmy 43:2a7da56ebd24 30
theotherjimmy 43:2a7da56ebd24 31
theotherjimmy 43:2a7da56ebd24 32 class CMake(Exporter):
theotherjimmy 43:2a7da56ebd24 33 """Generic CMake template that mimics the behavior of the python build
theotherjimmy 43:2a7da56ebd24 34 system
theotherjimmy 43:2a7da56ebd24 35 """
theotherjimmy 43:2a7da56ebd24 36
theotherjimmy 43:2a7da56ebd24 37 TEMPLATE = 'CMakeLists.txt'
theotherjimmy 43:2a7da56ebd24 38
theotherjimmy 43:2a7da56ebd24 39 MBED_CONFIG_HEADER_SUPPORTED = True
theotherjimmy 43:2a7da56ebd24 40
theotherjimmy 43:2a7da56ebd24 41 PREPROCESS_ASM = False
theotherjimmy 43:2a7da56ebd24 42
theotherjimmy 43:2a7da56ebd24 43 POST_BINARY_WHITELIST = set([
theotherjimmy 43:2a7da56ebd24 44 "MCU_NRF51Code.binary_hook",
theotherjimmy 43:2a7da56ebd24 45 "TEENSY3_1Code.binary_hook",
theotherjimmy 43:2a7da56ebd24 46 "LPCTargetCode.lpc_patch",
theotherjimmy 43:2a7da56ebd24 47 "LPC4088Code.binary_hook"
theotherjimmy 43:2a7da56ebd24 48 ])
theotherjimmy 43:2a7da56ebd24 49
theotherjimmy 43:2a7da56ebd24 50 @classmethod
theotherjimmy 43:2a7da56ebd24 51 def is_target_supported(cls, target_name):
theotherjimmy 43:2a7da56ebd24 52 target = TARGET_MAP[target_name]
theotherjimmy 43:2a7da56ebd24 53 return apply_supported_whitelist(
theotherjimmy 43:2a7da56ebd24 54 cls.TOOLCHAIN, cls.POST_BINARY_WHITELIST, target)
theotherjimmy 43:2a7da56ebd24 55
theotherjimmy 43:2a7da56ebd24 56 def generate(self):
theotherjimmy 43:2a7da56ebd24 57 """Generate the CMakefiles.txt
theotherjimmy 43:2a7da56ebd24 58 """
theotherjimmy 43:2a7da56ebd24 59 self.resources.win_to_unix()
theotherjimmy 43:2a7da56ebd24 60
theotherjimmy 43:2a7da56ebd24 61 # get all source files including headers, adding headers allows IDEs to detect which files
theotherjimmy 43:2a7da56ebd24 62 # belong to the project, otherwise headers may be greyed out and not work with inspection
theotherjimmy 43:2a7da56ebd24 63 # (that is true for CLion and definitely for Visual Code)
theotherjimmy 43:2a7da56ebd24 64 srcs = set(self.resources.c_sources +
theotherjimmy 43:2a7da56ebd24 65 self.resources.cpp_sources +
theotherjimmy 43:2a7da56ebd24 66 self.resources.s_sources +
theotherjimmy 43:2a7da56ebd24 67 self.resources.headers)
theotherjimmy 43:2a7da56ebd24 68 srcs = [re.sub(r'^[.]/', '', f) for f in srcs]
theotherjimmy 43:2a7da56ebd24 69
theotherjimmy 43:2a7da56ebd24 70 # additional libraries
theotherjimmy 43:2a7da56ebd24 71 libraries = [self.prepare_lib(basename(lib)) for lib in self.libraries]
theotherjimmy 43:2a7da56ebd24 72 sys_libs = [self.prepare_sys_lib(lib) for lib in self.toolchain.sys_libs]
theotherjimmy 43:2a7da56ebd24 73
theotherjimmy 43:2a7da56ebd24 74 # sort includes reverse, so the deepest dir comes first (ensures short includes)
theotherjimmy 43:2a7da56ebd24 75 includes = sorted([re.sub(r'^[.]/', '', l) for l in self.resources.inc_dirs], reverse=True)
theotherjimmy 43:2a7da56ebd24 76
theotherjimmy 43:2a7da56ebd24 77 ctx = {
theotherjimmy 43:2a7da56ebd24 78 'name': self.project_name,
theotherjimmy 43:2a7da56ebd24 79 'target': self.target,
theotherjimmy 43:2a7da56ebd24 80 'sources': sorted(srcs),
theotherjimmy 43:2a7da56ebd24 81 'libraries': libraries,
theotherjimmy 43:2a7da56ebd24 82 'ld_sys_libs': sys_libs,
theotherjimmy 43:2a7da56ebd24 83 'include_paths': includes,
theotherjimmy 43:2a7da56ebd24 84 'library_paths': sorted([re.sub(r'^[.]/', '', l) for l in self.resources.lib_dirs]),
theotherjimmy 43:2a7da56ebd24 85 'linker_script': self.resources.linker_script,
theotherjimmy 43:2a7da56ebd24 86 'hex_files': self.resources.hex_files,
theotherjimmy 43:2a7da56ebd24 87 'ar': basename(self.toolchain.ar),
theotherjimmy 43:2a7da56ebd24 88 'cc': basename(self.toolchain.cc[0]),
theotherjimmy 43:2a7da56ebd24 89 'cc_flags': " ".join(flag for flag in self.toolchain.cc[1:] if not flag == "-c"),
theotherjimmy 43:2a7da56ebd24 90 'cxx': basename(self.toolchain.cppc[0]),
theotherjimmy 43:2a7da56ebd24 91 'cxx_flags': " ".join(flag for flag in self.toolchain.cppc[1:] if not flag == "-c"),
theotherjimmy 43:2a7da56ebd24 92 'asm': basename(self.toolchain.asm[0]),
theotherjimmy 43:2a7da56ebd24 93 'asm_flags': " ".join(flag for flag in self.toolchain.asm[1:] if not flag == "-c"),
theotherjimmy 43:2a7da56ebd24 94 'symbols': sorted(self.toolchain.get_symbols()),
theotherjimmy 43:2a7da56ebd24 95 'ld': basename(self.toolchain.ld[0]),
theotherjimmy 43:2a7da56ebd24 96 # fix the missing underscore '_' (see
theotherjimmy 43:2a7da56ebd24 97 'ld_flags': re.sub("--wrap,_(?!_)", "--wrap,__", " ".join(self.toolchain.ld[1:])),
theotherjimmy 43:2a7da56ebd24 98 'elf2bin': basename(self.toolchain.elf2bin),
theotherjimmy 43:2a7da56ebd24 99 'link_script_ext': self.toolchain.LINKER_EXT,
theotherjimmy 43:2a7da56ebd24 100 'link_script_option': self.LINK_SCRIPT_OPTION,
theotherjimmy 43:2a7da56ebd24 101 'user_library_flag': self.USER_LIBRARY_FLAG,
theotherjimmy 43:2a7da56ebd24 102 'needs_asm_preproc': self.PREPROCESS_ASM,
theotherjimmy 43:2a7da56ebd24 103 }
theotherjimmy 43:2a7da56ebd24 104
theotherjimmy 43:2a7da56ebd24 105 if hasattr(self.toolchain, "preproc"):
theotherjimmy 43:2a7da56ebd24 106 ctx['pp'] = basename(self.toolchain.preproc[0])
theotherjimmy 43:2a7da56ebd24 107 ctx['pp_flags'] = " ".join(self.toolchain.preproc[1:] +
theotherjimmy 43:2a7da56ebd24 108 self.toolchain.ld[1:])
theotherjimmy 43:2a7da56ebd24 109 else:
theotherjimmy 43:2a7da56ebd24 110 ctx['pp'] = None
theotherjimmy 43:2a7da56ebd24 111 ctx['pp_flags'] = None
theotherjimmy 43:2a7da56ebd24 112
theotherjimmy 43:2a7da56ebd24 113 try:
theotherjimmy 43:2a7da56ebd24 114 self.gen_file('cmake/%s.tmpl' % self.TEMPLATE, ctx, 'CMakeLists.txt')
theotherjimmy 43:2a7da56ebd24 115 except TemplateNotFound:
theotherjimmy 43:2a7da56ebd24 116 pass
theotherjimmy 43:2a7da56ebd24 117
theotherjimmy 43:2a7da56ebd24 118 @staticmethod
theotherjimmy 43:2a7da56ebd24 119 def clean(_):
theotherjimmy 43:2a7da56ebd24 120 remove("CMakeLists.txt")
theotherjimmy 43:2a7da56ebd24 121 # legacy .build directory cleaned if exists
theotherjimmy 43:2a7da56ebd24 122 if exists('.build'):
theotherjimmy 43:2a7da56ebd24 123 shutil.rmtree('.build')
theotherjimmy 43:2a7da56ebd24 124 if exists('BUILD'):
theotherjimmy 43:2a7da56ebd24 125 shutil.rmtree('BUILD')
theotherjimmy 43:2a7da56ebd24 126
theotherjimmy 43:2a7da56ebd24 127 @staticmethod
theotherjimmy 43:2a7da56ebd24 128 def build(project_name, log_name="build_log.txt", cleanup=True):
theotherjimmy 43:2a7da56ebd24 129 """ Build Make project """
theotherjimmy 43:2a7da56ebd24 130
theotherjimmy 43:2a7da56ebd24 131 # change into our build directory
theotherjimmy 43:2a7da56ebd24 132 current_dir = getcwd()
theotherjimmy 43:2a7da56ebd24 133 if not exists("BUILD"):
theotherjimmy 43:2a7da56ebd24 134 mkdir("BUILD")
theotherjimmy 43:2a7da56ebd24 135 chdir("BUILD")
theotherjimmy 43:2a7da56ebd24 136
theotherjimmy 43:2a7da56ebd24 137 # > run cmake initial command
theotherjimmy 43:2a7da56ebd24 138 cmd = ["cmake", ".."]
theotherjimmy 43:2a7da56ebd24 139
theotherjimmy 43:2a7da56ebd24 140 # Build the project
theotherjimmy 43:2a7da56ebd24 141 p = Popen(cmd, stdout=PIPE, stderr=PIPE)
theotherjimmy 43:2a7da56ebd24 142 out, err = p.communicate()
theotherjimmy 43:2a7da56ebd24 143 ret_code = p.returncode
theotherjimmy 43:2a7da56ebd24 144
theotherjimmy 43:2a7da56ebd24 145 if ret_code == 0:
theotherjimmy 43:2a7da56ebd24 146 # we create the cmake files inside BUILD, change into and run cmake
theotherjimmy 43:2a7da56ebd24 147
theotherjimmy 43:2a7da56ebd24 148 # > run make -j
theotherjimmy 43:2a7da56ebd24 149 cmd = ["make", "-j"]
theotherjimmy 43:2a7da56ebd24 150
theotherjimmy 43:2a7da56ebd24 151 p = Popen(cmd, stdout=PIPE, stderr=PIPE)
theotherjimmy 43:2a7da56ebd24 152 out, err = p.communicate()
theotherjimmy 43:2a7da56ebd24 153 ret_code = p.returncode
theotherjimmy 43:2a7da56ebd24 154
theotherjimmy 43:2a7da56ebd24 155 # go back to the original directory
theotherjimmy 43:2a7da56ebd24 156 chdir(current_dir)
theotherjimmy 43:2a7da56ebd24 157
theotherjimmy 43:2a7da56ebd24 158 out_string = "=" * 10 + "STDOUT" + "=" * 10 + "\n"
theotherjimmy 43:2a7da56ebd24 159 out_string += out
theotherjimmy 43:2a7da56ebd24 160 out_string += "=" * 10 + "STDERR" + "=" * 10 + "\n"
theotherjimmy 43:2a7da56ebd24 161 out_string += err
theotherjimmy 43:2a7da56ebd24 162
theotherjimmy 43:2a7da56ebd24 163 if ret_code == 0:
theotherjimmy 43:2a7da56ebd24 164 out_string += "SUCCESS"
theotherjimmy 43:2a7da56ebd24 165 else:
theotherjimmy 43:2a7da56ebd24 166 out_string += "FAILURE"
theotherjimmy 43:2a7da56ebd24 167
theotherjimmy 43:2a7da56ebd24 168 print(out_string)
theotherjimmy 43:2a7da56ebd24 169
theotherjimmy 43:2a7da56ebd24 170 if log_name:
theotherjimmy 43:2a7da56ebd24 171 # Write the output to the log file
theotherjimmy 43:2a7da56ebd24 172 with open(log_name, 'w+') as f:
theotherjimmy 43:2a7da56ebd24 173 f.write(out_string)
theotherjimmy 43:2a7da56ebd24 174
theotherjimmy 43:2a7da56ebd24 175 # Cleanup the exported and built files
theotherjimmy 43:2a7da56ebd24 176 if cleanup:
theotherjimmy 43:2a7da56ebd24 177 remove(log_name)
theotherjimmy 43:2a7da56ebd24 178 CMake.clean(project_name)
theotherjimmy 43:2a7da56ebd24 179
theotherjimmy 43:2a7da56ebd24 180 if ret_code != 0:
theotherjimmy 43:2a7da56ebd24 181 # Seems like something went wrong.
theotherjimmy 43:2a7da56ebd24 182 return -1
theotherjimmy 43:2a7da56ebd24 183 else:
theotherjimmy 43:2a7da56ebd24 184 return 0
theotherjimmy 43:2a7da56ebd24 185
theotherjimmy 43:2a7da56ebd24 186
theotherjimmy 43:2a7da56ebd24 187 class GccArm(CMake):
theotherjimmy 43:2a7da56ebd24 188 """GCC ARM specific cmake target"""
theotherjimmy 43:2a7da56ebd24 189 NAME = 'CMake-GCC-ARM'
theotherjimmy 43:2a7da56ebd24 190 TOOLCHAIN = "GCC_ARM"
theotherjimmy 43:2a7da56ebd24 191 LINK_SCRIPT_OPTION = "-T"
theotherjimmy 43:2a7da56ebd24 192 USER_LIBRARY_FLAG = "-L"
theotherjimmy 43:2a7da56ebd24 193
theotherjimmy 43:2a7da56ebd24 194 @staticmethod
theotherjimmy 43:2a7da56ebd24 195 def prepare_lib(libname):
theotherjimmy 43:2a7da56ebd24 196 if "lib" == libname[:3]:
theotherjimmy 43:2a7da56ebd24 197 libname = libname[3:-2]
theotherjimmy 43:2a7da56ebd24 198 return "-l" + libname
theotherjimmy 43:2a7da56ebd24 199
theotherjimmy 43:2a7da56ebd24 200 @staticmethod
theotherjimmy 43:2a7da56ebd24 201 def prepare_sys_lib(libname):
theotherjimmy 43:2a7da56ebd24 202 return "-l" + libname
theotherjimmy 43:2a7da56ebd24 203
theotherjimmy 43:2a7da56ebd24 204 # class Arm(CMake):
theotherjimmy 43:2a7da56ebd24 205 # """ARM Compiler generic cmake target"""
theotherjimmy 43:2a7da56ebd24 206 # LINK_SCRIPT_OPTION = "--scatter"
theotherjimmy 43:2a7da56ebd24 207 # USER_LIBRARY_FLAG = "--userlibpath "
theotherjimmy 43:2a7da56ebd24 208 #
theotherjimmy 43:2a7da56ebd24 209 # @staticmethod
theotherjimmy 43:2a7da56ebd24 210 # def prepare_lib(libname):
theotherjimmy 43:2a7da56ebd24 211 # return libname
theotherjimmy 43:2a7da56ebd24 212 #
theotherjimmy 43:2a7da56ebd24 213 # @staticmethod
theotherjimmy 43:2a7da56ebd24 214 # def prepare_sys_lib(libname):
theotherjimmy 43:2a7da56ebd24 215 # return libname
theotherjimmy 43:2a7da56ebd24 216 #
theotherjimmy 43:2a7da56ebd24 217 # def generate(self):
theotherjimmy 43:2a7da56ebd24 218 # if self.resources.linker_script:
theotherjimmy 43:2a7da56ebd24 219 # new_script = self.toolchain.correct_scatter_shebang(
theotherjimmy 43:2a7da56ebd24 220 # self.resources.linker_script)
theotherjimmy 43:2a7da56ebd24 221 # if new_script is not self.resources.linker_script:
theotherjimmy 43:2a7da56ebd24 222 # self.resources.linker_script = new_script
theotherjimmy 43:2a7da56ebd24 223 # self.generated_files.append(new_script)
theotherjimmy 43:2a7da56ebd24 224 # return super(Arm, self).generate()
theotherjimmy 43:2a7da56ebd24 225 #
theotherjimmy 43:2a7da56ebd24 226 #
theotherjimmy 43:2a7da56ebd24 227 # class Armc5(Arm):
theotherjimmy 43:2a7da56ebd24 228 # """ARM Compiler 5 (armcc) specific makefile target"""
theotherjimmy 43:2a7da56ebd24 229 # NAME = 'CMake-ARMc5'
theotherjimmy 43:2a7da56ebd24 230 # TOOLCHAIN = "ARM"
theotherjimmy 43:2a7da56ebd24 231 # PREPROCESS_ASM = True
theotherjimmy 43:2a7da56ebd24 232 #
theotherjimmy 43:2a7da56ebd24 233 #
theotherjimmy 43:2a7da56ebd24 234 # class Armc6(Arm):
theotherjimmy 43:2a7da56ebd24 235 # """ARM Compiler 6 (armclang) specific generic makefile target"""
theotherjimmy 43:2a7da56ebd24 236 # NAME = 'CMake-ARMc6'
theotherjimmy 43:2a7da56ebd24 237 # TOOLCHAIN = "ARMC6"
theotherjimmy 43:2a7da56ebd24 238 #
theotherjimmy 43:2a7da56ebd24 239 #
theotherjimmy 43:2a7da56ebd24 240 # class IAR(CMake):
theotherjimmy 43:2a7da56ebd24 241 # """IAR specific cmake target"""
theotherjimmy 43:2a7da56ebd24 242 # NAME = 'CMake-IAR'
theotherjimmy 43:2a7da56ebd24 243 # TOOLCHAIN = "IAR"
theotherjimmy 43:2a7da56ebd24 244 # LINK_SCRIPT_OPTION = "--config"
theotherjimmy 43:2a7da56ebd24 245 # USER_LIBRARY_FLAG = "-L"
theotherjimmy 43:2a7da56ebd24 246 #
theotherjimmy 43:2a7da56ebd24 247 # @staticmethod
theotherjimmy 43:2a7da56ebd24 248 # def prepare_lib(libname):
theotherjimmy 43:2a7da56ebd24 249 # if "lib" == libname[:3]:
theotherjimmy 43:2a7da56ebd24 250 # libname = libname[3:]
theotherjimmy 43:2a7da56ebd24 251 # return "-l" + splitext(libname)[0]
theotherjimmy 43:2a7da56ebd24 252 #
theotherjimmy 43:2a7da56ebd24 253 # @staticmethod
theotherjimmy 43:2a7da56ebd24 254 # def prepare_sys_lib(libname):
theotherjimmy 43:2a7da56ebd24 255 # if "lib" == libname[:3]:
theotherjimmy 43:2a7da56ebd24 256 # libname = libname[3:]
theotherjimmy 43:2a7da56ebd24 257 # return "-l" + splitext(libname)[0]