mirror of https://github.com/ARMmbed/mbed-os.git
add cmake exporter for CLion use
parent
c2784c8962
commit
07b21abc75
|
@ -33,6 +33,7 @@ from tools.export import embitz, coide, kds, simplicity, atmelstudio, mcuxpresso
|
||||||
from tools.export import sw4stm32, e2studio, zip, cmsis, uvision, cdt, vscode
|
from tools.export import sw4stm32, e2studio, zip, cmsis, uvision, cdt, vscode
|
||||||
from tools.export import gnuarmeclipse
|
from tools.export import gnuarmeclipse
|
||||||
from tools.export import qtcreator
|
from tools.export import qtcreator
|
||||||
|
from tools.export import cmake
|
||||||
from tools.export import nb
|
from tools.export import nb
|
||||||
from tools.targets import TARGET_NAMES
|
from tools.targets import TARGET_NAMES
|
||||||
|
|
||||||
|
@ -63,7 +64,8 @@ EXPORTERS = {
|
||||||
'qtcreator': qtcreator.QtCreator,
|
'qtcreator': qtcreator.QtCreator,
|
||||||
'vscode_gcc_arm' : vscode.VSCodeGcc,
|
'vscode_gcc_arm' : vscode.VSCodeGcc,
|
||||||
'vscode_iar' : vscode.VSCodeIAR,
|
'vscode_iar' : vscode.VSCodeIAR,
|
||||||
'vscode_armc5' : vscode.VSCodeArmc5
|
'vscode_armc5' : vscode.VSCodeArmc5,
|
||||||
|
'cmake_gcc_arm': cmake.GccArm
|
||||||
}
|
}
|
||||||
|
|
||||||
ERROR_MESSAGE_UNSUPPORTED_TOOLCHAIN = """
|
ERROR_MESSAGE_UNSUPPORTED_TOOLCHAIN = """
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
# This file was automagically generated by mbed.org.
|
||||||
|
# If you would like to add your own targets, create a
|
||||||
|
# project.cmake file locally in your project directory.
|
||||||
|
|
||||||
|
CMAKE_MINIMUM_REQUIRED(VERSION 3.9)
|
||||||
|
SET(CMAKE_SYSTEM_NAME Generic)
|
||||||
|
#SET(CMAKE_SYSTEM_PROCESSOR arm)
|
||||||
|
SET(CMAKE_CROSSCOMPILING TRUE)
|
||||||
|
|
||||||
|
# force compiler settings
|
||||||
|
SET(CMAKE_C_COMPILER_WORKS TRUE)
|
||||||
|
SET(CMAKE_CXX_COMPILER_WORKS TRUE)
|
||||||
|
|
||||||
|
SET(CMAKE_ASM_COMPILER_INIT "{{asm}}")
|
||||||
|
SET(CMAKE_C_COMPILER_INIT "{{cc}}")
|
||||||
|
SET(CMAKE_CXX_COMPILER_INIT "{{cxx}}")
|
||||||
|
SET(CMAKE_CXX_LINK_EXECUTABLE "{{ld}}")
|
||||||
|
|
||||||
|
{% if pp -%}
|
||||||
|
SET(PREPROC "{{pp}}")
|
||||||
|
{%- endif %}
|
||||||
|
{% if hex_files %}
|
||||||
|
SET(SREC_CAT "srec_cat")
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
|
# here starts the project
|
||||||
|
PROJECT({{name}} C CXX ASM)
|
||||||
|
#SET(CMAKE_VERBOSE_MAKEFILE ON)
|
||||||
|
|
||||||
|
SET(CMAKE_C_FLAGS "{{cc_flags}} -include mbed_config.h")
|
||||||
|
SET(CMAKE_CXX_FLAGS "{{cxx_flags}} -include mbed_config.h")
|
||||||
|
SET(CMAKE_ASM_FLAGS "{{asm_flags}} -include mbed_config.h")
|
||||||
|
SET(CMAKE_LINKER_FLAGS "{{ld_flags}}")
|
||||||
|
|
||||||
|
SET(LD_SYS_LIBS "{{ld_sys_libs|join(" ")}}")
|
||||||
|
SET(ELF2BIN {{elf2bin}})
|
||||||
|
|
||||||
|
SET(CMAKE_EXE_LINKER_FLAGS "{{ld_flags}} {{link_script_option}} ${LD_SYS_LIBS}")
|
||||||
|
|
||||||
|
ADD_DEFINITIONS(
|
||||||
|
{% for d in symbols %}-D{{d}}
|
||||||
|
{% endfor %})
|
||||||
|
INCLUDE_DIRECTORIES(
|
||||||
|
{% for p in include_paths %}{{p}}
|
||||||
|
{% endfor %})
|
||||||
|
|
||||||
|
{% for libname,libsrcs in libs.items() %}
|
||||||
|
# target for library "{{libname}}"
|
||||||
|
ADD_LIBRARY({{libname}} STATIC EXCLUDE_FROM_ALL
|
||||||
|
{% for libsrc in libsrcs %}{{libsrc}}
|
||||||
|
{% endfor %})
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
# executable {{name}}
|
||||||
|
ADD_EXECUTABLE({{name}} EXCLUDE_FROM_ALL
|
||||||
|
{% for src in sources %}{{src}}
|
||||||
|
{% endfor %})
|
||||||
|
TARGET_LINK_LIBRARIES({{name}}
|
||||||
|
{% for libname in libs %}{{libname}}
|
||||||
|
{% endfor %})
|
||||||
|
|
||||||
|
##########################################################################
|
||||||
|
# mbed-cli specific targets
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
# detect the build type and select the corresponding cli profile
|
||||||
|
SET(MBED_BUILD_PROFILE "")
|
||||||
|
STRING(TOLOWER ${CMAKE_BUILD_TYPE} LOWERCASE_CMAKE_BUILD_TYPE)
|
||||||
|
IF(LOWERCASE_CMAKE_BUILD_TYPE MATCHES debug)
|
||||||
|
SET(MBED_BUILD_PROFILE "mbed-os/tools/profiles/debug.json")
|
||||||
|
ELSEIF(LOWERCASE_CMAKE_BUILD_TYPE MATCHES relwithdebinfo)
|
||||||
|
SET(MBED_BUILD_PROFILE "mbed-os/tools/profiles/develop.json")
|
||||||
|
ELSEIF(LOWERCASE_CMAKE_BUILD_TYPE MATCHES release)
|
||||||
|
SET(MBED_BUILD_PROFILE "mbed-os/tools/profiles/release.json")
|
||||||
|
ELSEIF(LOWERCASE_CMAKE_BUILD_TYPE MATCHES minsizerel)
|
||||||
|
SET(MBED_BUILD_PROFILE "mbed-os/tools/profiles/release.json")
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(WARNING "Build type '${CMAKE_BUILD_TYPE}' is unknown, using debug profile")
|
||||||
|
SET(MBED_BUILD_PROFILE "mbed-os/tools/profiles/debug.json")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
# optional custom target to build via mbed-cli
|
||||||
|
MESSAGE(STATUS "Creating target 01-{{name}} for mbed compilation...")
|
||||||
|
ADD_CUSTOM_TARGET(01-{{name}} ALL
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E echo "mbed compile --build BUILD/${CMAKE_BUILD_TYPE} ${MBED_BUILD_PROFILE}"
|
||||||
|
COMMAND mbed compile --build BUILD/${CMAKE_BUILD_TYPE} --profile ${MBED_BUILD_PROFILE}
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
SOURCES ${SOURCE_FILES} ${SYS_SOURCE_FILES})
|
||||||
|
|
||||||
|
IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/project.cmake)
|
||||||
|
INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/project.cmake)
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(STATUS "Add a local project.cmake file to add your own targets.")
|
||||||
|
ENDIF()
|
|
@ -0,0 +1,15 @@
|
||||||
|
# CLion CMakeLists.txt Generator
|
||||||
|
|
||||||
|
This exporter generates a CMakeLists.txt file that can be used to
|
||||||
|
develop mbed using [IntelliJ CLion](https://www.jetbrains.com/clion/).
|
||||||
|
|
||||||
|
It will not create a functional CMake build system that mimics the
|
||||||
|
mbed build system, but rather uses the mbed-cli itself to compile
|
||||||
|
the targets. The generated files help CLion to understand the
|
||||||
|
includes and dependencies of your code.
|
||||||
|
|
||||||
|
Run the following command to create/overwrite your CMakeLists.txt.
|
||||||
|
```
|
||||||
|
mbed export -i cmake_gcc_arm
|
||||||
|
```
|
||||||
|
> Run the command again if files or libraries have been added or removed.
|
|
@ -0,0 +1,225 @@
|
||||||
|
"""
|
||||||
|
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.
|
||||||
|
"""
|
||||||
|
import re
|
||||||
|
import shutil
|
||||||
|
from os import remove
|
||||||
|
from os.path import splitext, basename, exists
|
||||||
|
from subprocess import Popen, PIPE
|
||||||
|
|
||||||
|
from jinja2.exceptions import TemplateNotFound
|
||||||
|
|
||||||
|
from tools.export.exporters import Exporter
|
||||||
|
from tools.utils import NotSupportedException
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def is_target_supported(cls, target_name):
|
||||||
|
return True
|
||||||
|
|
||||||
|
def generate(self):
|
||||||
|
"""Generate the CMakefiles.txt
|
||||||
|
"""
|
||||||
|
self.resources.win_to_unix()
|
||||||
|
|
||||||
|
sources = set(self.resources.c_sources + \
|
||||||
|
self.resources.cpp_sources + \
|
||||||
|
self.resources.s_sources + \
|
||||||
|
self.resources.headers)
|
||||||
|
|
||||||
|
libnames = [l[:-4] for l in self.resources.lib_refs]
|
||||||
|
libs = {re.sub(r'^[.]/', '', l): sorted([f for f in sources if f.startswith(l)]) for l in libnames}
|
||||||
|
libs = {k: v for k, v in libs.items() if len(v) != 0}
|
||||||
|
srcs = sorted([f for f in sources if f not in [item for sublist in libs.values() for item in sublist]])
|
||||||
|
|
||||||
|
libraries = [self.prepare_lib(basename(lib)) for lib
|
||||||
|
in self.resources.libraries]
|
||||||
|
sys_libs = [self.prepare_sys_lib(lib) for lib
|
||||||
|
in self.toolchain.sys_libs]
|
||||||
|
|
||||||
|
ctx = {
|
||||||
|
'name': self.project_name,
|
||||||
|
'target': self.target,
|
||||||
|
'sources': srcs,
|
||||||
|
'libs': libs,
|
||||||
|
'libraries': libraries,
|
||||||
|
'ld_sys_libs': sys_libs,
|
||||||
|
'include_paths': sorted(list(set(self.resources.inc_dirs))),
|
||||||
|
'library_paths': sorted(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(self.toolchain.cc[1:]),
|
||||||
|
'cxx': basename(self.toolchain.cppc[0]),
|
||||||
|
'cxx_flags': " ".join(self.toolchain.cppc[1:]),
|
||||||
|
'asm': basename(self.toolchain.asm[0]),
|
||||||
|
'asm_flags': " ".join(self.toolchain.asm[1:]),
|
||||||
|
'symbols': self.toolchain.get_symbols(),
|
||||||
|
'ld': basename(self.toolchain.ld[0]),
|
||||||
|
'ld_flags': " ".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'] = " ".join(["\'" + part + "\'" for part
|
||||||
|
in ([basename(self.toolchain.preproc[0])] +
|
||||||
|
self.toolchain.preproc[1:] +
|
||||||
|
self.toolchain.ld[1:])])
|
||||||
|
else:
|
||||||
|
ctx['pp'] = None
|
||||||
|
|
||||||
|
for templatefile in ['cmake/%s.tmpl' % self.TEMPLATE]:
|
||||||
|
try:
|
||||||
|
self.gen_file(templatefile, ctx, 'CMakeLists.txt')
|
||||||
|
break
|
||||||
|
except TemplateNotFound:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
raise NotSupportedException("This make tool is in development")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def build(project_name, log_name="build_log.txt", cleanup=True):
|
||||||
|
""" Build Make project """
|
||||||
|
# > Make -j
|
||||||
|
cmd = ["make", "-j"]
|
||||||
|
|
||||||
|
# Build the project
|
||||||
|
p = Popen(cmd, stdout=PIPE, stderr=PIPE)
|
||||||
|
out, err = p.communicate()
|
||||||
|
ret_code = p.returncode
|
||||||
|
|
||||||
|
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("CMakeLists.txt")
|
||||||
|
remove(log_name)
|
||||||
|
# legacy .build directory cleaned if exists
|
||||||
|
if exists('.build'):
|
||||||
|
shutil.rmtree('.build')
|
||||||
|
if exists('BUILD'):
|
||||||
|
shutil.rmtree('BUILD')
|
||||||
|
|
||||||
|
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]
|
Loading…
Reference in New Issue