Clone of official tools

Revision:
43:2a7da56ebd24
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/export/cmake/__init__.py	Tue Sep 25 13:43:09 2018 -0500
@@ -0,0 +1,257 @@
+"""
+mbed SDK
+Copyright (c) 2011-2016 ARM Limited
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+from __future__ import print_function, absolute_import
+from builtins import str
+
+import re
+import shutil
+from os import remove, getcwd, chdir, mkdir
+from os.path import basename, exists
+from subprocess import Popen, PIPE
+
+from jinja2.exceptions import TemplateNotFound
+
+from tools.export.exporters import Exporter, apply_supported_whitelist
+from tools.targets import TARGET_MAP
+
+
+class CMake(Exporter):
+    """Generic CMake template that mimics the behavior of the python build
+    system
+    """
+
+    TEMPLATE = 'CMakeLists.txt'
+
+    MBED_CONFIG_HEADER_SUPPORTED = True
+
+    PREPROCESS_ASM = False
+
+    POST_BINARY_WHITELIST = set([
+        "MCU_NRF51Code.binary_hook",
+        "TEENSY3_1Code.binary_hook",
+        "LPCTargetCode.lpc_patch",
+        "LPC4088Code.binary_hook"
+    ])
+
+    @classmethod
+    def is_target_supported(cls, target_name):
+        target = TARGET_MAP[target_name]
+        return apply_supported_whitelist(
+            cls.TOOLCHAIN, cls.POST_BINARY_WHITELIST, target)
+
+    def generate(self):
+        """Generate the CMakefiles.txt
+        """
+        self.resources.win_to_unix()
+
+        # get all source files including headers, adding headers allows IDEs to detect which files
+        # belong to the project, otherwise headers may be greyed out and not work with inspection
+        # (that is true for CLion and definitely for Visual Code)
+        srcs = set(self.resources.c_sources +
+                   self.resources.cpp_sources +
+                   self.resources.s_sources +
+                   self.resources.headers)
+        srcs = [re.sub(r'^[.]/', '', f) for f in srcs]
+
+        # additional libraries
+        libraries = [self.prepare_lib(basename(lib)) for lib in self.libraries]
+        sys_libs = [self.prepare_sys_lib(lib) for lib in self.toolchain.sys_libs]
+
+        # sort includes reverse, so the deepest dir comes first (ensures short includes)
+        includes = sorted([re.sub(r'^[.]/', '', l) for l in self.resources.inc_dirs], reverse=True)
+
+        ctx = {
+            'name': self.project_name,
+            'target': self.target,
+            'sources': sorted(srcs),
+            'libraries': libraries,
+            'ld_sys_libs': sys_libs,
+            'include_paths': includes,
+            'library_paths': sorted([re.sub(r'^[.]/', '', l) for l in self.resources.lib_dirs]),
+            'linker_script': self.resources.linker_script,
+            'hex_files': self.resources.hex_files,
+            'ar': basename(self.toolchain.ar),
+            'cc': basename(self.toolchain.cc[0]),
+            'cc_flags': " ".join(flag for flag in self.toolchain.cc[1:] if not flag == "-c"),
+            'cxx': basename(self.toolchain.cppc[0]),
+            'cxx_flags': " ".join(flag for flag in self.toolchain.cppc[1:] if not flag == "-c"),
+            'asm': basename(self.toolchain.asm[0]),
+            'asm_flags': " ".join(flag for flag in self.toolchain.asm[1:] if not flag == "-c"),
+            'symbols': sorted(self.toolchain.get_symbols()),
+            'ld': basename(self.toolchain.ld[0]),
+            # fix the missing underscore '_' (see
+            'ld_flags': re.sub("--wrap,_(?!_)", "--wrap,__", " ".join(self.toolchain.ld[1:])),
+            'elf2bin': basename(self.toolchain.elf2bin),
+            'link_script_ext': self.toolchain.LINKER_EXT,
+            'link_script_option': self.LINK_SCRIPT_OPTION,
+            'user_library_flag': self.USER_LIBRARY_FLAG,
+            'needs_asm_preproc': self.PREPROCESS_ASM,
+        }
+
+        if hasattr(self.toolchain, "preproc"):
+            ctx['pp'] = basename(self.toolchain.preproc[0])
+            ctx['pp_flags'] = " ".join(self.toolchain.preproc[1:] +
+                                       self.toolchain.ld[1:])
+        else:
+            ctx['pp'] = None
+            ctx['pp_flags'] = None
+
+        try:
+            self.gen_file('cmake/%s.tmpl' % self.TEMPLATE, ctx, 'CMakeLists.txt')
+        except TemplateNotFound:
+            pass
+
+    @staticmethod
+    def clean(_):
+        remove("CMakeLists.txt")
+        # legacy .build directory cleaned if exists
+        if exists('.build'):
+            shutil.rmtree('.build')
+        if exists('BUILD'):
+            shutil.rmtree('BUILD')
+
+    @staticmethod
+    def build(project_name, log_name="build_log.txt", cleanup=True):
+        """ Build Make project """
+
+        # change into our build directory
+        current_dir = getcwd()
+        if not exists("BUILD"):
+            mkdir("BUILD")
+        chdir("BUILD")
+
+        # > run cmake initial command
+        cmd = ["cmake", ".."]
+
+        # Build the project
+        p = Popen(cmd, stdout=PIPE, stderr=PIPE)
+        out, err = p.communicate()
+        ret_code = p.returncode
+
+        if ret_code == 0:
+            # we create the cmake files inside BUILD, change into and run cmake
+
+            # > run make -j
+            cmd = ["make", "-j"]
+
+            p = Popen(cmd, stdout=PIPE, stderr=PIPE)
+            out, err = p.communicate()
+            ret_code = p.returncode
+
+        # go back to the original directory
+        chdir(current_dir)
+
+        out_string = "=" * 10 + "STDOUT" + "=" * 10 + "\n"
+        out_string += out
+        out_string += "=" * 10 + "STDERR" + "=" * 10 + "\n"
+        out_string += err
+
+        if ret_code == 0:
+            out_string += "SUCCESS"
+        else:
+            out_string += "FAILURE"
+
+        print(out_string)
+
+        if log_name:
+            # Write the output to the log file
+            with open(log_name, 'w+') as f:
+                f.write(out_string)
+
+        # Cleanup the exported and built files
+        if cleanup:
+            remove(log_name)
+            CMake.clean(project_name)
+
+        if ret_code != 0:
+            # Seems like something went wrong.
+            return -1
+        else:
+            return 0
+
+
+class GccArm(CMake):
+    """GCC ARM specific cmake target"""
+    NAME = 'CMake-GCC-ARM'
+    TOOLCHAIN = "GCC_ARM"
+    LINK_SCRIPT_OPTION = "-T"
+    USER_LIBRARY_FLAG = "-L"
+
+    @staticmethod
+    def prepare_lib(libname):
+        if "lib" == libname[:3]:
+            libname = libname[3:-2]
+        return "-l" + libname
+
+    @staticmethod
+    def prepare_sys_lib(libname):
+        return "-l" + libname
+
+# class Arm(CMake):
+#     """ARM Compiler generic cmake target"""
+#     LINK_SCRIPT_OPTION = "--scatter"
+#     USER_LIBRARY_FLAG = "--userlibpath "
+#
+#     @staticmethod
+#     def prepare_lib(libname):
+#         return libname
+#
+#     @staticmethod
+#     def prepare_sys_lib(libname):
+#         return libname
+#
+#     def generate(self):
+#         if self.resources.linker_script:
+#             new_script = self.toolchain.correct_scatter_shebang(
+#                 self.resources.linker_script)
+#             if new_script is not self.resources.linker_script:
+#                 self.resources.linker_script = new_script
+#                 self.generated_files.append(new_script)
+#         return super(Arm, self).generate()
+#
+#
+# class Armc5(Arm):
+#     """ARM Compiler 5 (armcc) specific makefile target"""
+#     NAME = 'CMake-ARMc5'
+#     TOOLCHAIN = "ARM"
+#     PREPROCESS_ASM = True
+#
+#
+# class Armc6(Arm):
+#     """ARM Compiler 6 (armclang) specific generic makefile target"""
+#     NAME = 'CMake-ARMc6'
+#     TOOLCHAIN = "ARMC6"
+#
+#
+# class IAR(CMake):
+#     """IAR specific cmake target"""
+#     NAME = 'CMake-IAR'
+#     TOOLCHAIN = "IAR"
+#     LINK_SCRIPT_OPTION = "--config"
+#     USER_LIBRARY_FLAG = "-L"
+#
+#     @staticmethod
+#     def prepare_lib(libname):
+#         if "lib" == libname[:3]:
+#             libname = libname[3:]
+#         return "-l" + splitext(libname)[0]
+#
+#     @staticmethod
+#     def prepare_sys_lib(libname):
+#         if "lib" == libname[:3]:
+#             libname = libname[3:]
+#         return "-l" + splitext(libname)[0]