mirror of https://github.com/ARMmbed/mbed-os.git
144 lines
5.0 KiB
Python
144 lines
5.0 KiB
Python
from os.path import join, exists, basename
|
|
from shutil import copyfile, rmtree
|
|
from copy import copy
|
|
import json
|
|
from types import ListType
|
|
|
|
from workspace_tools.utils import mkdir
|
|
from workspace_tools.toolchains import TOOLCHAIN_CLASSES, Resources
|
|
|
|
"""
|
|
src_path: the path of the source directory
|
|
build_path: the path of the build directory
|
|
target: ['LPC1768', 'LPC11U24', 'LPC2368']
|
|
toolchain: ['ARM', 'uARM', 'GCC_ARM', 'GCC_CS', 'GCC_CR']
|
|
library_paths: List of paths to additional libraries
|
|
clean: Rebuild everything if True
|
|
notify: Notify function for logs
|
|
verbose: Write the actual tools command lines if True
|
|
"""
|
|
def build_library(src_paths, build_path, target, toolchain_name,
|
|
libraries_paths=None, name=None, clean=False, notify=None, verbose=False):
|
|
if type(src_paths) != ListType: src_paths = [src_paths]
|
|
|
|
for src_path in src_paths:
|
|
if not exists(src_path):
|
|
raise Exception("The library source folder does not exist: %s", src_path)
|
|
|
|
# Toolchain instance
|
|
toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, notify)
|
|
toolchain.VERBOSE = verbose
|
|
toolchain.build_all = clean
|
|
|
|
# Options
|
|
# By convention the first path should contain the build configuration
|
|
main_src = src_paths[0]
|
|
options_file = join(main_src, 'options.json')
|
|
if exists(options_file):
|
|
try:
|
|
options = json.load(open(options_file))
|
|
except Exception, e:
|
|
raise Exception("Error parsing option file: %s\n\t%s" % (options_file, e))
|
|
else:
|
|
options = {}
|
|
toolchain.set_options(options)
|
|
|
|
# Library name can be set by: function parameter, option file, or directory name (in that order)
|
|
if name is None:
|
|
if 'lib_name' in options:
|
|
name = options['lib_name']
|
|
else:
|
|
name = basename(main_src)
|
|
|
|
toolchain.info("\n>>> BUILD LIBRARY %s (%s, %s)" % (name.upper(), target.name, toolchain_name))
|
|
|
|
# Scan Resources
|
|
resources = []
|
|
for src_path in src_paths:
|
|
resources.append(toolchain.scan_resources(src_path))
|
|
|
|
# Just for the include paths
|
|
lib_resources = Resources()
|
|
if libraries_paths is not None:
|
|
for path in libraries_paths:
|
|
lib_resources.add(toolchain.scan_resources(path))
|
|
|
|
# Create the desired build directory structure
|
|
bin_path = join(build_path, toolchain.obj_path)
|
|
mkdir(bin_path)
|
|
|
|
tmp_path = join(build_path, '.temp', toolchain.obj_path)
|
|
mkdir(tmp_path)
|
|
|
|
# Copy Files
|
|
for resource in resources:
|
|
files_to_be_copied = resource.headers
|
|
if resource.linker_script is not None:
|
|
# Linker script
|
|
files_to_be_copied.append(resource.linker_script)
|
|
toolchain.copy_files(resource.base_path, build_path, files_to_be_copied)
|
|
|
|
# Compile sources
|
|
objects = []
|
|
for resource in resources:
|
|
objects.extend(toolchain.compile_sources(resource, tmp_path, lib_resources.inc_dirs))
|
|
|
|
# Same objects need to remain stand alone
|
|
if 'objects' in options:
|
|
for object in copy(objects):
|
|
filename = basename(object)
|
|
if filename in options['objects']:
|
|
objects.remove(object)
|
|
target = join(bin_path, filename)
|
|
if toolchain.need_update(target, [object]):
|
|
toolchain.info("Copy: %s" % filename)
|
|
copyfile(object, target)
|
|
|
|
# Archive objects in a library
|
|
if objects:
|
|
toolchain.build_library(objects, bin_path, name)
|
|
|
|
|
|
def build_project(src_path, build_path, target, toolchain_name,
|
|
libraries_paths=None, clean=False, notify=None, verbose=False, name=None):
|
|
# Toolchain instance
|
|
toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, notify)
|
|
toolchain.VERBOSE = verbose
|
|
toolchain.build_all = clean
|
|
|
|
if name is None:
|
|
name = basename(src_path)
|
|
toolchain.info("\n>>> BUILD PROJECT: %s (%s, %s)" % (name.upper(), target.name, toolchain_name))
|
|
|
|
# Scan src_path and libraries_paths for resources
|
|
resources = toolchain.scan_resources(src_path)
|
|
if libraries_paths is not None:
|
|
for path in libraries_paths:
|
|
resources.add(toolchain.scan_resources(path))
|
|
|
|
# Build Directory
|
|
if clean:
|
|
if exists(build_path):
|
|
rmtree(build_path)
|
|
mkdir(build_path)
|
|
|
|
# Build Program
|
|
return toolchain.build_program(resources, build_path, name)
|
|
|
|
|
|
# Core mbed libraries
|
|
from workspace_tools.libraries import Library
|
|
|
|
|
|
def build_lib(lib_id, target, toolchain, verbose=False):
|
|
lib = Library(lib_id)
|
|
if lib.is_supported(target, toolchain):
|
|
build_library(lib.source_dir, lib.build_dir, target, toolchain, lib.dependencies, lib.name, verbose=verbose)
|
|
else:
|
|
print '\n\nLibrary "%s" is not yet supported on target %s with toolchain %s' % (lib_id, target.name, toolchain)
|
|
|
|
|
|
def build_mbed_libs(target, toolchain, verbose=False):
|
|
for lib_name in ["%s_cmsis" % target.vendor, "%s_mbed" % target.vendor]:
|
|
build_lib(lib_name, target, toolchain, verbose=verbose)
|