mirror of https://github.com/ARMmbed/mbed-os.git
Set up CMake configure dependencies on all JSON files used in the configuration (#409)
* Set up CMake configure dependencies on all JSON files used in the configuration * Remove unneeded cmake-build-dir option, we already have output * Oops use namespace * Fix comment * Don't explode if given paths outside the root dirpull/15531/head
parent
2fd9d83098
commit
722c2f1196
|
@ -27,58 +27,44 @@ else()
|
|||
endif()
|
||||
set(MBED_INTERNAL_LAST_MBED_TARGET "${MBED_TARGET}" CACHE INTERNAL "Previous mbed target this dir was configured with" FORCE)
|
||||
|
||||
# Convert all relative paths to absolute paths, rooted at CMAKE_SOURCE_DIR.
|
||||
# This makes sure that they are interpreted the same way everywhere.
|
||||
get_filename_component(MBED_APP_JSON_PATH "${MBED_APP_JSON_PATH}" ABSOLUTE BASE_DIR ${CMAKE_SOURCE_DIR})
|
||||
get_filename_component(CUSTOM_TARGETS_JSON_PATH "${CUSTOM_TARGETS_JSON_PATH}" ABSOLUTE BASE_DIR ${CMAKE_SOURCE_DIR})
|
||||
|
||||
# Make it so that if mbed_app.json or custom_targets.json are modified, CMake is rerun.
|
||||
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${MBED_APP_JSON_PATH})
|
||||
if(EXISTS "${CUSTOM_TARGETS_JSON_PATH}" AND (NOT IS_DIRECTORY "${CUSTOM_TARGETS_JSON_PATH}"))
|
||||
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${CUSTOM_TARGETS_JSON_PATH})
|
||||
endif()
|
||||
|
||||
# Check if mbed_app.json was modified
|
||||
# Note: if the path is an empty string, get_filename_component(ABSOLUTE) will convert it to a directory,
|
||||
# so we have to verify that the path we have is a file, not a dir.
|
||||
if(EXISTS "${MBED_APP_JSON_PATH}" AND (NOT IS_DIRECTORY "${MBED_APP_JSON_PATH}"))
|
||||
file(TIMESTAMP "${MBED_APP_JSON_PATH}" MBED_APP_JSON_TIMESTAMP "%s" UTC)
|
||||
else()
|
||||
set(MBED_APP_JSON_TIMESTAMP "<none>")
|
||||
endif()
|
||||
|
||||
if(NOT MBED_NEED_TO_RECONFIGURE)
|
||||
if(NOT "${MBED_INTERNAL_LAST_MBED_APP_JSON_TIMESTAMP}" STREQUAL "${MBED_APP_JSON_TIMESTAMP}")
|
||||
message(STATUS "Mbed: mbed_app.json modified, regenerating configs...")
|
||||
set(MBED_NEED_TO_RECONFIGURE TRUE)
|
||||
endif()
|
||||
endif()
|
||||
set(MBED_INTERNAL_LAST_MBED_APP_JSON_TIMESTAMP "${MBED_APP_JSON_TIMESTAMP}" CACHE INTERNAL "Previous UTC modification timestamp for mbed_app.json" FORCE)
|
||||
|
||||
# Check if custom_targets.json was modified
|
||||
if(EXISTS "${CUSTOM_TARGETS_JSON_PATH}" AND (NOT IS_DIRECTORY "${CUSTOM_TARGETS_JSON_PATH}"))
|
||||
file(TIMESTAMP "${CUSTOM_TARGETS_JSON_PATH}" CUSTOM_TARGETS_JSON_TIMESTAMP "%s" UTC)
|
||||
else()
|
||||
set(CUSTOM_TARGETS_JSON_TIMESTAMP "<none>")
|
||||
endif()
|
||||
|
||||
if(NOT MBED_NEED_TO_RECONFIGURE)
|
||||
if(NOT "${MBED_INTERNAL_LAST_CUSTOM_TARGETS_JSON_TIMESTAMP}" STREQUAL "${CUSTOM_TARGETS_JSON_TIMESTAMP}")
|
||||
message(STATUS "Mbed: custom_targets.json modified, regenerating configs...")
|
||||
set(MBED_NEED_TO_RECONFIGURE TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(MBED_INTERNAL_LAST_CUSTOM_TARGETS_JSON_TIMESTAMP "${CUSTOM_TARGETS_JSON_TIMESTAMP}" CACHE INTERNAL "Previous UTC modification timestamp for custom_targets.json" FORCE)
|
||||
|
||||
# Check if the include file is missing (e.g. because a previous attempt to generate it failed)
|
||||
if(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/mbed_config.cmake)
|
||||
if(NOT MBED_NEED_TO_RECONFIGURE)
|
||||
message(STATUS "Mbed: mbed_config.cmake not found, regenerating configs...")
|
||||
set(MBED_NEED_TO_RECONFIGURE TRUE)
|
||||
endif()
|
||||
else()
|
||||
# Include the old version of mbed_config.cmake to get the MBED_CONFIG_JSON_SOURCE_FILES variable used below
|
||||
include(${CMAKE_CURRENT_BINARY_DIR}/mbed_config.cmake)
|
||||
endif()
|
||||
|
||||
# Check timestamps on all JSON files used to generate the Mbed configuration
|
||||
if(NOT MBED_NEED_TO_RECONFIGURE)
|
||||
file(TIMESTAMP ${CMAKE_CURRENT_BINARY_DIR}/mbed_config.cmake MBED_CONFIG_CMAKE_TIMESTAMP "%s" UTC)
|
||||
|
||||
foreach(CONFIG_JSON ${MBED_CONFIG_JSON_SOURCE_FILES})
|
||||
get_filename_component(CONFIG_JSON_ABSPATH ${CONFIG_JSON} ABSOLUTE)
|
||||
|
||||
if(NOT EXISTS ${CONFIG_JSON_ABSPATH})
|
||||
message(STATUS "Mbed: ${CONFIG_JSON} deleted or renamed, regenerating configs...")
|
||||
set(MBED_NEED_TO_RECONFIGURE TRUE)
|
||||
break()
|
||||
endif()
|
||||
|
||||
file(TIMESTAMP ${CONFIG_JSON_ABSPATH} CONFIG_JSON_TIMESTAMP "%s" UTC)
|
||||
if(${CONFIG_JSON_TIMESTAMP} GREATER ${MBED_CONFIG_CMAKE_TIMESTAMP})
|
||||
message(STATUS "Mbed: ${CONFIG_JSON} modified, regenerating configs...")
|
||||
set(MBED_NEED_TO_RECONFIGURE TRUE)
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
# Convert all relative paths to absolute paths, rooted at CMAKE_SOURCE_DIR.
|
||||
# This makes sure that they are interpreted the same way everywhere.
|
||||
get_filename_component(MBED_APP_JSON_PATH "${MBED_APP_JSON_PATH}" ABSOLUTE BASE_DIR ${CMAKE_SOURCE_DIR})
|
||||
get_filename_component(CUSTOM_TARGETS_JSON_PATH "${CUSTOM_TARGETS_JSON_PATH}" ABSOLUTE BASE_DIR ${CMAKE_SOURCE_DIR})
|
||||
|
||||
if(MBED_NEED_TO_RECONFIGURE)
|
||||
# Generate mbed_config.cmake for this target
|
||||
if(EXISTS "${MBED_APP_JSON_PATH}" AND (NOT IS_DIRECTORY "${MBED_APP_JSON_PATH}"))
|
||||
|
@ -98,7 +84,7 @@ if(MBED_NEED_TO_RECONFIGURE)
|
|||
|
||||
set(MBEDTOOLS_CONFIGURE_COMMAND ${Python3_EXECUTABLE}
|
||||
-m mbed_tools.cli.main
|
||||
-v # without -v, warnings (e.g. "you have tried to override a nonexistent parameter") do not get printed
|
||||
-v -v # without at least -v, warnings (e.g. "you have tried to override a nonexistent parameter") do not get printed
|
||||
configure
|
||||
-t GCC_ARM # GCC_ARM is currently the only supported toolchain
|
||||
-m "${MBED_TARGET}"
|
||||
|
@ -126,4 +112,7 @@ if(MBED_NEED_TO_RECONFIGURE)
|
|||
endif()
|
||||
|
||||
# Include the generated config file
|
||||
include(${CMAKE_CURRENT_BINARY_DIR}/mbed_config.cmake)
|
||||
include(${CMAKE_CURRENT_BINARY_DIR}/mbed_config.cmake)
|
||||
|
||||
# Make it so that if any config JSON files are modified, CMake is rerun.
|
||||
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${MBED_CONFIG_JSON_SOURCE_FILES})
|
|
@ -30,7 +30,11 @@ def render_mbed_config_cmake_template(config: Config, toolchain_name: str, targe
|
|||
env.filters["to_hex"] = to_hex
|
||||
template = env.get_template(TEMPLATE_NAME)
|
||||
config["supported_c_libs"] = [x for x in config["supported_c_libs"][toolchain_name.lower()]]
|
||||
context = {"target_name": target_name, "toolchain_name": toolchain_name, **config}
|
||||
|
||||
context = {"target_name": target_name,
|
||||
"toolchain_name": toolchain_name,
|
||||
"json_sources": config.json_sources,
|
||||
**config}
|
||||
return template.render(context)
|
||||
|
||||
|
||||
|
|
|
@ -9,12 +9,15 @@ from dataclasses import dataclass
|
|||
from pathlib import Path
|
||||
from typing import Iterable, List, Optional, Set
|
||||
|
||||
from setuptools.build_meta import build_editable
|
||||
|
||||
from mbed_tools.project import MbedProgram
|
||||
from mbed_tools.build._internal.config.config import Config
|
||||
from mbed_tools.build._internal.config import source
|
||||
from mbed_tools.build._internal.find_files import LabelFilter, RequiresFilter, filter_files, find_files
|
||||
|
||||
|
||||
def assemble_config(target_attributes: dict, search_paths: Iterable[Path], mbed_app_file: Optional[Path]) -> Config:
|
||||
def assemble_config(target_attributes: dict, program: MbedProgram) -> Config:
|
||||
"""Assemble config for given target and program directory.
|
||||
|
||||
Mbed library and application specific config parameters are parsed from mbed_lib.json and mbed_app.json files
|
||||
|
@ -29,16 +32,36 @@ def assemble_config(target_attributes: dict, search_paths: Iterable[Path], mbed_
|
|||
|
||||
Args:
|
||||
target_attributes: Mapping of target specific config parameters.
|
||||
search_paths: Iterable of paths to search for mbed_lib.json files.
|
||||
mbed_app_file: The path to mbed_app.json. This can be None.
|
||||
program: MbedProgram to build the config for
|
||||
"""
|
||||
mbed_lib_files: Set[Path] = set()
|
||||
|
||||
for path in search_paths:
|
||||
for path in [program.root, program.mbed_os.root]:
|
||||
mbed_lib_files.update(find_files("mbed_lib.json", path.absolute().resolve()))
|
||||
mbed_lib_files.update(find_files("mbed_lib.json5", path.absolute().resolve()))
|
||||
|
||||
return _assemble_config_from_sources(target_attributes, list(mbed_lib_files), mbed_app_file)
|
||||
config = _assemble_config_from_sources(target_attributes, list(mbed_lib_files), program.files.app_config_file)
|
||||
|
||||
# Set up the config source path list using the path to every JSON
|
||||
config.json_sources.extend(mbed_lib_files)
|
||||
if program.files.app_config_file is not None:
|
||||
config.json_sources.append(program.files.app_config_file)
|
||||
config.json_sources.append(program.mbed_os.targets_json_file)
|
||||
config.json_sources.append(program.mbed_os.cmsis_mcu_descriptions_json_file)
|
||||
if program.files.custom_targets_json.exists():
|
||||
config.json_sources.append(program.files.custom_targets_json)
|
||||
|
||||
# Make all JSON sources relative paths to the program root
|
||||
def make_relative_if_possible(path: Path):
|
||||
# Sadly, Pathlib did not gain a better way to do this until newer python versions.
|
||||
try:
|
||||
return path.relative_to(program.root)
|
||||
except ValueError:
|
||||
return path
|
||||
|
||||
config.json_sources = [make_relative_if_possible(program.root) for json_source in config.json_sources]
|
||||
|
||||
return config
|
||||
|
||||
|
||||
def _assemble_config_from_sources(
|
||||
|
|
|
@ -7,6 +7,7 @@ import logging
|
|||
|
||||
from collections import UserDict
|
||||
from typing import Any, Iterable, Hashable, List
|
||||
import pathlib
|
||||
|
||||
from mbed_tools.build._internal.config.source import Override, ConfigSetting
|
||||
|
||||
|
@ -21,6 +22,11 @@ class Config(UserDict):
|
|||
Applies overrides, appends macros, and updates config settings.
|
||||
"""
|
||||
|
||||
# List of JSON files used to create this config. Dumped to CMake at the end of configuration
|
||||
# so that it can regenerate configuration if the JSONs change.
|
||||
# All paths will be relative to the Mbed program root directory, or absolute if outside said directory.
|
||||
json_sources: List[pathlib.Path] = []
|
||||
|
||||
def __setitem__(self, key: Hashable, item: Any) -> None:
|
||||
"""Set an item based on its key."""
|
||||
if key == CONFIG_SECTION:
|
||||
|
|
|
@ -6,13 +6,19 @@
|
|||
|
||||
include_guard(GLOBAL)
|
||||
|
||||
set(MBED_TOOLCHAIN "{{toolchain_name}}" CACHE STRING "")
|
||||
set(MBED_TARGET "{{target_name}}" CACHE STRING "")
|
||||
set(MBED_CPU_CORE "{{core}}" CACHE STRING "")
|
||||
set(MBED_C_LIB "{{c_lib}}" CACHE STRING "")
|
||||
set(MBED_PRINTF_LIB "{{printf_lib}}" CACHE STRING "")
|
||||
set(MBED_OUTPUT_EXT "{{OUTPUT_EXT}}" CACHE STRING "")
|
||||
set(MBED_GREENTEA_TEST_RESET_TIMEOUT "{{forced_reset_timeout}}" CACHE STRING "")
|
||||
set(MBED_TOOLCHAIN "{{toolchain_name}}")
|
||||
set(MBED_CPU_CORE "{{core}}")
|
||||
set(MBED_C_LIB "{{c_lib}}")
|
||||
set(MBED_PRINTF_LIB "{{printf_lib}}")
|
||||
set(MBED_OUTPUT_EXT "{{OUTPUT_EXT}}")
|
||||
set(MBED_GREENTEA_TEST_RESET_TIMEOUT "{{forced_reset_timeout}}")
|
||||
|
||||
# JSON files used to generate this config. If any of these change, the Python config generation
|
||||
# scripts must be rerun.
|
||||
set(MBED_CONFIG_JSON_SOURCE_FILES {% for json_source in json_sources | sort %}
|
||||
"{{json_source.as_posix()}}"
|
||||
{%- endfor %}
|
||||
)
|
||||
|
||||
list(APPEND MBED_TARGET_SUPPORTED_C_LIBS {% for supported_c_lib in supported_c_libs %}
|
||||
{{supported_c_lib}}
|
||||
|
|
|
@ -38,7 +38,7 @@ def generate_config(target_name: str, toolchain: str, program: MbedProgram) -> T
|
|||
target_build_attributes = get_target_by_name(target_name, targets_data)
|
||||
incorporate_memory_bank_data_from_cmsis(target_build_attributes, program)
|
||||
config = assemble_config(
|
||||
target_build_attributes, [program.root, program.mbed_os.root], program.files.app_config_file
|
||||
target_build_attributes, program
|
||||
)
|
||||
|
||||
# Process memory banks and save JSON data for other tools (e.g. memap) to use
|
||||
|
|
|
@ -1,140 +0,0 @@
|
|||
#
|
||||
# Copyright (c) 2020-2021 Arm Limited and Contributors. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
"""Command to build/compile an Mbed project using CMake."""
|
||||
import os
|
||||
import pathlib
|
||||
import shutil
|
||||
|
||||
from typing import Optional, Tuple
|
||||
|
||||
import click
|
||||
|
||||
from mbed_tools.build import build_project, generate_build_system, generate_config, flash_binary
|
||||
from mbed_tools.devices import find_connected_device, find_all_connected_devices
|
||||
from mbed_tools.project import MbedProgram
|
||||
from mbed_tools.sterm import terminal
|
||||
|
||||
|
||||
@click.command(name="compile", help="Build an Mbed project.")
|
||||
@click.option(
|
||||
"-t",
|
||||
"--toolchain",
|
||||
type=click.Choice(["ARM", "GCC_ARM"], case_sensitive=False),
|
||||
required=True,
|
||||
help="The toolchain you are using to build your app.",
|
||||
)
|
||||
@click.option("-m", "--mbed-target", required=True, help="A build target for an Mbed-enabled device, e.g. K64F.")
|
||||
@click.option("-b", "--profile", default="develop", help="The build type (release, develop or debug).")
|
||||
@click.option("-c", "--clean", is_flag=True, default=False, help="Perform a clean build.")
|
||||
@click.option(
|
||||
"-p",
|
||||
"--program-path",
|
||||
default=os.getcwd(),
|
||||
help="Path to local Mbed program. By default it is the current working directory.",
|
||||
)
|
||||
@click.option(
|
||||
"--mbed-os-path", type=click.Path(), default=None, help="Path to local Mbed OS directory.",
|
||||
)
|
||||
@click.option(
|
||||
"--custom-targets-json", type=click.Path(), default=None, help="Path to custom_targets.json.",
|
||||
)
|
||||
@click.option(
|
||||
"--app-config", type=click.Path(), default=None, help="Path to application configuration file.",
|
||||
)
|
||||
@click.option(
|
||||
"-f", "--flash", is_flag=True, default=False, help="Flash the binary onto a device",
|
||||
)
|
||||
@click.option(
|
||||
"-s", "--sterm", is_flag=True, default=False, help="Launch a serial terminal to the device.",
|
||||
)
|
||||
@click.option(
|
||||
"--baudrate",
|
||||
default=9600,
|
||||
show_default=True,
|
||||
help="Change the serial baud rate (ignored unless --sterm is also given).",
|
||||
)
|
||||
def build(
|
||||
program_path: str,
|
||||
profile: str,
|
||||
toolchain: str,
|
||||
mbed_target: str,
|
||||
clean: bool,
|
||||
flash: bool,
|
||||
sterm: bool,
|
||||
baudrate: int,
|
||||
mbed_os_path: str,
|
||||
custom_targets_json: str,
|
||||
app_config: str,
|
||||
) -> None:
|
||||
"""Configure and build an Mbed project using CMake and Ninja.
|
||||
|
||||
If the CMake configuration step has already been run previously (i.e a CMake build tree exists), then just try to
|
||||
build the project immediately using Ninja.
|
||||
|
||||
Args:
|
||||
program_path: Path to the Mbed project.
|
||||
mbed_os_path: The path to the local Mbed OS directory.
|
||||
profile: The Mbed build profile (debug, develop or release).
|
||||
custom_targets_json: Path to custom_targets.json.
|
||||
toolchain: The toolchain to use for the build.
|
||||
mbed_target: The name of the Mbed target to build for.
|
||||
app_config: the path to the application configuration file
|
||||
clean: Perform a clean build.
|
||||
flash: Flash the binary onto a device.
|
||||
sterm: Open a serial terminal to the connected target.
|
||||
baudrate: Change the serial baud rate (ignored unless --sterm is also given).
|
||||
"""
|
||||
mbed_target, target_id = _get_target_id(mbed_target)
|
||||
|
||||
cmake_build_subdir = pathlib.Path(mbed_target.upper(), profile.lower(), toolchain.upper())
|
||||
if mbed_os_path is None:
|
||||
program = MbedProgram.from_existing(pathlib.Path(program_path), cmake_build_subdir)
|
||||
else:
|
||||
program = MbedProgram.from_existing(pathlib.Path(program_path), cmake_build_subdir, pathlib.Path(mbed_os_path))
|
||||
build_tree = program.files.cmake_build_dir
|
||||
if clean and build_tree.exists():
|
||||
shutil.rmtree(build_tree)
|
||||
|
||||
click.echo("Configuring project and generating build system...")
|
||||
if custom_targets_json is not None:
|
||||
program.files.custom_targets_json = pathlib.Path(custom_targets_json)
|
||||
if app_config is not None:
|
||||
program.files.app_config_file = pathlib.Path(app_config)
|
||||
config, _ = generate_config(mbed_target.upper(), toolchain, program)
|
||||
generate_build_system(program.root, build_tree, profile)
|
||||
|
||||
click.echo("Building Mbed project...")
|
||||
build_project(build_tree)
|
||||
|
||||
if flash or sterm:
|
||||
if target_id is not None or sterm:
|
||||
devices = [find_connected_device(mbed_target, target_id)]
|
||||
else:
|
||||
devices = find_all_connected_devices(mbed_target)
|
||||
|
||||
if flash:
|
||||
for dev in devices:
|
||||
hex_file = "OUTPUT_EXT" in config and config["OUTPUT_EXT"] == "hex"
|
||||
flashed_path = flash_binary(dev.mount_points[0].resolve(), program.root, build_tree, mbed_target, hex_file)
|
||||
click.echo(f"Copied {str(flashed_path.resolve())} to {len(devices)} device(s).")
|
||||
|
||||
if sterm:
|
||||
dev = devices[0]
|
||||
if dev.serial_port is None:
|
||||
raise click.ClickException(
|
||||
f"The connected device {dev.mbed_board.board_name} does not have an associated serial port."
|
||||
" Reconnect the device and try again."
|
||||
)
|
||||
|
||||
terminal.run(dev.serial_port, baudrate)
|
||||
|
||||
|
||||
def _get_target_id(target: str) -> Tuple[str, Optional[int]]:
|
||||
if "[" in target:
|
||||
target_name, target_id = target.replace("]", "").split("[", maxsplit=1)
|
||||
if target_id.isdigit() and int(target_id) >= 0:
|
||||
return (target_name, int(target_id))
|
||||
raise click.ClickException("When using the format mbed-target[ID], ID must be a positive integer or 0.")
|
||||
return (target, None)
|
|
@ -25,8 +25,10 @@ from mbed_tools.build import generate_config
|
|||
help="The toolchain you are using to build your app.",
|
||||
)
|
||||
@click.option("-m", "--mbed-target", required=True, help="A build target for an Mbed-enabled device, eg. K64F")
|
||||
@click.option("-b", "--profile", default="develop", help="The build type (release, develop or debug).")
|
||||
@click.option("-o", "--output-dir", type=click.Path(), default=None, help="Path to output directory.")
|
||||
@click.option("-o", "--output-dir",
|
||||
type=click.Path(path_type=pathlib.Path),
|
||||
required=True,
|
||||
help="Path to output directory (CMake binary dir)")
|
||||
@click.option(
|
||||
"-p",
|
||||
"--program-path",
|
||||
|
@ -43,10 +45,9 @@ from mbed_tools.build import generate_config
|
|||
def configure(
|
||||
toolchain: str,
|
||||
mbed_target: str,
|
||||
profile: str,
|
||||
program_path: str,
|
||||
mbed_os_path: str,
|
||||
output_dir: str,
|
||||
output_dir: pathlib.Path,
|
||||
custom_targets_json: str,
|
||||
app_config: str
|
||||
) -> None:
|
||||
|
@ -63,21 +64,17 @@ def configure(
|
|||
custom_targets_json: the path to custom_targets.json
|
||||
toolchain: the toolchain you are using (eg. GCC_ARM, ARM)
|
||||
mbed_target: the target you are building for (eg. K64F)
|
||||
profile: The Mbed build profile (debug, develop or release).
|
||||
program_path: the path to the local Mbed program
|
||||
mbed_os_path: the path to the local Mbed OS directory
|
||||
output_dir: the path to the output directory
|
||||
app_config: the path to the application configuration file
|
||||
"""
|
||||
cmake_build_subdir = pathlib.Path(mbed_target.upper(), profile.lower(), toolchain.upper())
|
||||
if mbed_os_path is None:
|
||||
program = MbedProgram.from_existing(pathlib.Path(program_path), cmake_build_subdir)
|
||||
program = MbedProgram.from_existing(pathlib.Path(program_path), output_dir)
|
||||
else:
|
||||
program = MbedProgram.from_existing(pathlib.Path(program_path), cmake_build_subdir, pathlib.Path(mbed_os_path))
|
||||
program = MbedProgram.from_existing(pathlib.Path(program_path), output_dir, pathlib.Path(mbed_os_path).resolve())
|
||||
if custom_targets_json is not None:
|
||||
program.files.custom_targets_json = pathlib.Path(custom_targets_json)
|
||||
if output_dir is not None:
|
||||
program.files.cmake_build_dir = pathlib.Path(output_dir)
|
||||
if app_config is not None:
|
||||
program.files.app_config_file = pathlib.Path(app_config)
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@ from mbed_tools.lib.logging import set_log_level, MbedToolsHandler
|
|||
from mbed_tools.cli.configure import configure
|
||||
from mbed_tools.cli.list_connected_devices import list_connected_devices
|
||||
from mbed_tools.cli.project_management import new, import_, deploy
|
||||
from mbed_tools.cli.build import build
|
||||
from mbed_tools.cli.sterm import sterm
|
||||
from mbed_tools.cli.cmsis_mcu_descr import cmsis_mcu_descr
|
||||
|
||||
|
@ -78,7 +77,6 @@ cli.add_command(list_connected_devices, "detect")
|
|||
cli.add_command(new, "new")
|
||||
cli.add_command(deploy, "deploy")
|
||||
cli.add_command(import_, "import")
|
||||
cli.add_command(build, "compile")
|
||||
cli.add_command(sterm, "sterm")
|
||||
cli.add_command(cmsis_mcu_descr)
|
||||
|
||||
|
|
|
@ -3,16 +3,24 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
"""Command to launch a serial terminal to a connected Mbed device."""
|
||||
from typing import Any, Optional
|
||||
from typing import Any, Optional, Tuple
|
||||
|
||||
import click
|
||||
|
||||
from mbed_tools.cli.build import _get_target_id
|
||||
from mbed_tools.devices import find_connected_device, get_connected_devices
|
||||
from mbed_tools.devices.exceptions import MbedDevicesError
|
||||
from mbed_tools.sterm import terminal
|
||||
|
||||
|
||||
def _get_target_id(target: str) -> Tuple[str, Optional[int]]:
|
||||
if "[" in target:
|
||||
target_name, target_id = target.replace("]", "").split("[", maxsplit=1)
|
||||
if target_id.isdigit() and int(target_id) >= 0:
|
||||
return (target_name, int(target_id))
|
||||
raise click.ClickException("When using the format mbed-target[ID], ID must be a positive integer or 0.")
|
||||
return (target, None)
|
||||
|
||||
|
||||
@click.command(
|
||||
help="Open a serial terminal to a connected Mbed Enabled device, or connect to a user-specified COM port."
|
||||
)
|
||||
|
|
|
@ -99,12 +99,12 @@ class MbedProgramFiles:
|
|||
)
|
||||
|
||||
@classmethod
|
||||
def from_existing(cls, root_path: Path, build_subdir: Path) -> "MbedProgramFiles":
|
||||
def from_existing(cls, root_path: Path, build_dir: Path) -> "MbedProgramFiles":
|
||||
"""Create MbedProgramFiles from a directory containing an existing program.
|
||||
|
||||
Args:
|
||||
root_path: The path containing the MbedProgramFiles.
|
||||
build_subdir: The subdirectory of BUILD_DIR to use for CMake build.
|
||||
build_dir: The directory to use for CMake build.
|
||||
"""
|
||||
app_config: Optional[Path] = None
|
||||
if (root_path / APP_CONFIG_FILE_NAME_JSON5).exists():
|
||||
|
@ -126,13 +126,12 @@ class MbedProgramFiles:
|
|||
cmakelists_file = root_path / CMAKELISTS_FILE_NAME
|
||||
if not cmakelists_file.exists():
|
||||
logger.warning("No CMakeLists.txt found in the program root.")
|
||||
cmake_build_dir = root_path / BUILD_DIR / build_subdir
|
||||
|
||||
return cls(
|
||||
app_config_file=app_config,
|
||||
mbed_os_ref=mbed_os_file,
|
||||
cmakelists_file=cmakelists_file,
|
||||
cmake_build_dir=cmake_build_dir,
|
||||
cmake_build_dir=build_dir,
|
||||
custom_targets_json=custom_targets_json,
|
||||
)
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#
|
||||
"""Mbed Program abstraction layer."""
|
||||
import logging
|
||||
import pathlib
|
||||
|
||||
from pathlib import Path
|
||||
from typing import Dict
|
||||
|
@ -29,7 +30,7 @@ class MbedProgram:
|
|||
* A collection of references to external libraries, defined in .lib files located in the program source tree
|
||||
"""
|
||||
|
||||
def __init__(self, program_files: MbedProgramFiles, mbed_os: MbedOS) -> None:
|
||||
def __init__(self, program_files: MbedProgramFiles, mbed_os: MbedOS, root_path: pathlib.Path) -> None:
|
||||
"""Initialise the program attributes.
|
||||
|
||||
Args:
|
||||
|
@ -37,7 +38,7 @@ class MbedProgram:
|
|||
mbed_os: An instance of `MbedOS` holding paths to locations in the local copy of the Mbed OS source.
|
||||
"""
|
||||
self.files = program_files
|
||||
self.root = self.files.mbed_os_ref.parent
|
||||
self.root = root_path
|
||||
self.mbed_os = mbed_os
|
||||
|
||||
@classmethod
|
||||
|
@ -63,17 +64,17 @@ class MbedProgram:
|
|||
program_files = MbedProgramFiles.from_new(dir_path)
|
||||
logger.info(f"Creating git repository for the Mbed program '{dir_path}'")
|
||||
mbed_os = MbedOS.from_new(dir_path / MBED_OS_DIR_NAME)
|
||||
return cls(program_files, mbed_os)
|
||||
return cls(program_files, mbed_os, dir_path)
|
||||
|
||||
@classmethod
|
||||
def from_existing(
|
||||
cls, dir_path: Path, build_subdir: Path, mbed_os_path: Path = None, check_mbed_os: bool = True,
|
||||
cls, dir_path: Path, build_dir: Path, mbed_os_path: Path = None, check_mbed_os: bool = True,
|
||||
) -> "MbedProgram":
|
||||
"""Create an MbedProgram from an existing program directory.
|
||||
|
||||
Args:
|
||||
dir_path: Directory containing an Mbed program.
|
||||
build_subdir: The subdirectory for the CMake build tree.
|
||||
build_dir: The directory for the CMake build tree.
|
||||
mbed_os_path: Directory containing Mbed OS.
|
||||
check_mbed_os: If True causes an exception to be raised if the Mbed OS source directory does not
|
||||
exist.
|
||||
|
@ -88,7 +89,7 @@ class MbedProgram:
|
|||
program_root = dir_path
|
||||
|
||||
logger.info(f"Found existing Mbed program at path '{program_root}'")
|
||||
program = MbedProgramFiles.from_existing(program_root, build_subdir)
|
||||
program = MbedProgramFiles.from_existing(program_root, build_dir)
|
||||
|
||||
try:
|
||||
mbed_os = MbedOS.from_existing(mbed_os_path, check_mbed_os)
|
||||
|
@ -98,7 +99,7 @@ class MbedProgram:
|
|||
"\nYou may need to resolve the mbed-os.lib reference. You can do this by performing a `deploy`."
|
||||
)
|
||||
|
||||
return cls(program, mbed_os)
|
||||
return cls(program, mbed_os, program_root)
|
||||
|
||||
|
||||
def parse_url(name_or_url: str) -> Dict[str, str]:
|
||||
|
|
|
@ -1,338 +0,0 @@
|
|||
#
|
||||
# Copyright (c) 2020-2021 Arm Limited and Contributors. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
import contextlib
|
||||
import os
|
||||
import pathlib
|
||||
|
||||
from tempfile import TemporaryDirectory
|
||||
from unittest import TestCase, mock
|
||||
|
||||
from click.testing import CliRunner
|
||||
|
||||
import sys
|
||||
print(sys.path)
|
||||
|
||||
from mbed_tools.cli.build import build
|
||||
from mbed_tools.project._internal.project_data import BUILD_DIR
|
||||
from mbed_tools.build.config import CMAKE_CONFIG_FILE
|
||||
|
||||
|
||||
DEFAULT_BUILD_ARGS = ["-t", "GCC_ARM", "-m", "K64F"]
|
||||
DEFAULT_BUILD_SUBDIR = pathlib.Path("K64F", "develop", "GCC_ARM")
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def mock_project_directory(
|
||||
program, mbed_config_exists=False, build_tree_exists=False, build_subdir=DEFAULT_BUILD_SUBDIR
|
||||
):
|
||||
with TemporaryDirectory() as tmp_dir:
|
||||
root = pathlib.Path(tmp_dir, "test-project")
|
||||
root.mkdir()
|
||||
program.root = root
|
||||
program.files.cmake_build_dir = root / BUILD_DIR / build_subdir
|
||||
program.files.cmake_config_file = root / BUILD_DIR / build_subdir / CMAKE_CONFIG_FILE
|
||||
if mbed_config_exists:
|
||||
program.files.cmake_config_file.parent.mkdir(exist_ok=True, parents=True)
|
||||
program.files.cmake_config_file.touch(exist_ok=True)
|
||||
|
||||
if build_tree_exists:
|
||||
program.files.cmake_build_dir.mkdir(exist_ok=True, parents=True)
|
||||
|
||||
yield
|
||||
|
||||
|
||||
@mock.patch("mbed_tools.cli.build.generate_build_system")
|
||||
@mock.patch("mbed_tools.cli.build.build_project")
|
||||
@mock.patch("mbed_tools.cli.build.MbedProgram")
|
||||
@mock.patch("mbed_tools.cli.build.generate_config")
|
||||
class TestBuildCommand(TestCase):
|
||||
def test_searches_for_mbed_program_at_default_project_path(
|
||||
self, generate_config, mbed_program, build_project, generate_build_system
|
||||
):
|
||||
runner = CliRunner()
|
||||
runner.invoke(build, DEFAULT_BUILD_ARGS)
|
||||
|
||||
mbed_program.from_existing.assert_called_once_with(pathlib.Path(os.getcwd()), DEFAULT_BUILD_SUBDIR)
|
||||
|
||||
def test_searches_for_mbed_program_at_user_defined_project_root(
|
||||
self, generate_config, mbed_program, build_project, generate_build_system
|
||||
):
|
||||
project_path = "my-blinky"
|
||||
|
||||
runner = CliRunner()
|
||||
runner.invoke(build, ["-p", project_path, *DEFAULT_BUILD_ARGS])
|
||||
|
||||
mbed_program.from_existing.assert_called_once_with(pathlib.Path(project_path), DEFAULT_BUILD_SUBDIR)
|
||||
|
||||
def test_calls_generate_build_system_if_build_tree_nonexistent(
|
||||
self, generate_config, mbed_program, build_project, generate_build_system
|
||||
):
|
||||
program = mbed_program.from_existing()
|
||||
with mock_project_directory(program, mbed_config_exists=True, build_tree_exists=False):
|
||||
generate_config.return_value = [mock.MagicMock(), mock.MagicMock()]
|
||||
|
||||
runner = CliRunner()
|
||||
runner.invoke(build, DEFAULT_BUILD_ARGS)
|
||||
|
||||
generate_build_system.assert_called_once_with(program.root, program.files.cmake_build_dir, "develop")
|
||||
|
||||
def test_generate_config_called_if_config_script_nonexistent(
|
||||
self, generate_config, mbed_program, build_project, generate_build_system
|
||||
):
|
||||
program = mbed_program.from_existing()
|
||||
with mock_project_directory(
|
||||
program, mbed_config_exists=False, build_subdir=pathlib.Path("K64F", "develop", "GCC_ARM")
|
||||
):
|
||||
target = "k64f"
|
||||
toolchain = "gcc_arm"
|
||||
|
||||
runner = CliRunner()
|
||||
runner.invoke(build, ["-t", toolchain, "-m", target])
|
||||
|
||||
generate_config.assert_called_once_with(target.upper(), toolchain.upper(), program)
|
||||
|
||||
def test_raises_if_gen_config_toolchain_not_passed_when_required(
|
||||
self, generate_config, mbed_program, build_project, generate_build_system
|
||||
):
|
||||
program = mbed_program.from_existing()
|
||||
with mock_project_directory(program, mbed_config_exists=False):
|
||||
target = "k64f"
|
||||
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(build, ["-m", target])
|
||||
|
||||
self.assertIsNotNone(result.exception)
|
||||
self.assertRegex(result.output, "--toolchain")
|
||||
|
||||
def test_raises_if_gen_config_target_not_passed_when_required(
|
||||
self, generate_config, mbed_program, build_project, generate_build_system
|
||||
):
|
||||
program = mbed_program.from_existing()
|
||||
with mock_project_directory(program, mbed_config_exists=False):
|
||||
toolchain = "gcc_arm"
|
||||
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(build, ["-t", toolchain])
|
||||
|
||||
self.assertIsNotNone(result.exception)
|
||||
self.assertRegex(result.output, "--mbed-target")
|
||||
|
||||
def test_raises_if_target_identifier_not_int(
|
||||
self, generate_config, mbed_program, build_project, generate_build_system
|
||||
):
|
||||
target = "K64F[foo]"
|
||||
|
||||
result = CliRunner().invoke(build, ["-m", target, "-t", "gcc_arm"])
|
||||
self.assertIsNotNone(result.exception)
|
||||
self.assertRegex(result.output, "ID")
|
||||
|
||||
def test_raises_if_target_identifier_negative(
|
||||
self, generate_config, mbed_program, build_project, generate_build_system
|
||||
):
|
||||
target = "K64F[-1]"
|
||||
|
||||
result = CliRunner().invoke(build, ["-m", target, "-t", "gcc_arm"])
|
||||
self.assertIsNotNone(result.exception)
|
||||
self.assertRegex(result.output, "ID")
|
||||
|
||||
def test_build_system_regenerated_when_mbed_os_path_passed(
|
||||
self, generate_config, mbed_program, build_project, generate_build_system
|
||||
):
|
||||
program = mbed_program.from_existing()
|
||||
with mock_project_directory(
|
||||
program,
|
||||
mbed_config_exists=True,
|
||||
build_tree_exists=True,
|
||||
build_subdir=pathlib.Path("K64F", "develop", "GCC_ARM"),
|
||||
):
|
||||
generate_config.return_value = [mock.MagicMock(), mock.MagicMock()]
|
||||
|
||||
toolchain = "gcc_arm"
|
||||
target = "k64f"
|
||||
mbed_os_path = "./extern/mbed-os"
|
||||
|
||||
runner = CliRunner()
|
||||
runner.invoke(build, ["-t", toolchain, "-m", target, "--mbed-os-path", mbed_os_path])
|
||||
|
||||
generate_config.assert_called_once_with(target.upper(), toolchain.upper(), program)
|
||||
generate_build_system.assert_called_once_with(program.root, program.files.cmake_build_dir, "develop")
|
||||
|
||||
def test_custom_targets_location_used_when_passed(
|
||||
self, generate_config, mbed_program, build_project, generate_build_system
|
||||
):
|
||||
program = mbed_program.from_existing()
|
||||
with mock_project_directory(program, mbed_config_exists=True, build_tree_exists=True):
|
||||
toolchain = "gcc_arm"
|
||||
target = "k64f"
|
||||
custom_targets_json_path = pathlib.Path("custom", "custom_targets.json")
|
||||
|
||||
runner = CliRunner()
|
||||
runner.invoke(build, ["-t", toolchain, "-m", target, "--custom-targets-json", custom_targets_json_path])
|
||||
|
||||
generate_config.assert_called_once_with(target.upper(), toolchain.upper(), program)
|
||||
self.assertEqual(program.files.custom_targets_json, custom_targets_json_path)
|
||||
|
||||
def test_app_config_used_when_passed(
|
||||
self, generate_config, mbed_program, build_project, generate_build_system
|
||||
):
|
||||
program = mbed_program.from_existing()
|
||||
with mock_project_directory(program, mbed_config_exists=True, build_tree_exists=True):
|
||||
toolchain = "gcc_arm"
|
||||
target = "k64f"
|
||||
app_config_path = pathlib.Path("alternative_config.json")
|
||||
|
||||
runner = CliRunner()
|
||||
runner.invoke(build, ["-t", toolchain, "-m", target, "--app-config", app_config_path])
|
||||
|
||||
generate_config.assert_called_once_with(target.upper(), toolchain.upper(), program)
|
||||
self.assertEqual(program.files.app_config_file, app_config_path)
|
||||
|
||||
def test_profile_used_when_passed(
|
||||
self, generate_config, mbed_program, build_project, generate_build_system
|
||||
):
|
||||
program = mbed_program.from_existing()
|
||||
mbed_program.reset_mock() # clear call count from previous line
|
||||
|
||||
with mock_project_directory(program, mbed_config_exists=True, build_tree_exists=True):
|
||||
generate_config.return_value = [mock.MagicMock(), mock.MagicMock()]
|
||||
|
||||
toolchain = "gcc_arm"
|
||||
target = "k64f"
|
||||
profile = "release"
|
||||
|
||||
runner = CliRunner()
|
||||
runner.invoke(build, ["-t", toolchain, "-m", target, "--profile", profile])
|
||||
|
||||
mbed_program.from_existing.assert_called_once_with(
|
||||
pathlib.Path(os.getcwd()),
|
||||
pathlib.Path(target.upper(), profile, toolchain.upper())
|
||||
)
|
||||
generate_config.assert_called_once_with(target.upper(), toolchain.upper(), program)
|
||||
generate_build_system.assert_called_once_with(program.root, program.files.cmake_build_dir, profile)
|
||||
|
||||
def test_build_folder_removed_when_clean_flag_passed(
|
||||
self, generate_config, mbed_program, build_project, generate_build_system
|
||||
):
|
||||
program = mbed_program.from_existing()
|
||||
with mock_project_directory(
|
||||
program,
|
||||
mbed_config_exists=True,
|
||||
build_tree_exists=True,
|
||||
build_subdir=pathlib.Path("K64F", "develop", "GCC_ARM"),
|
||||
):
|
||||
generate_config.return_value = [mock.MagicMock(), mock.MagicMock()]
|
||||
|
||||
toolchain = "gcc_arm"
|
||||
target = "k64f"
|
||||
|
||||
runner = CliRunner()
|
||||
runner.invoke(build, ["-t", toolchain, "-m", target, "-c"])
|
||||
|
||||
generate_config.assert_called_once_with(target.upper(), toolchain.upper(), program)
|
||||
generate_build_system.assert_called_once_with(program.root, program.files.cmake_build_dir, "develop")
|
||||
self.assertFalse(program.files.cmake_build_dir.exists())
|
||||
|
||||
@mock.patch("mbed_tools.cli.build.flash_binary")
|
||||
@mock.patch("mbed_tools.cli.build.find_all_connected_devices")
|
||||
def test_build_flash_options_bin_target(
|
||||
self,
|
||||
mock_find_devices,
|
||||
flash_binary,
|
||||
generate_config,
|
||||
mbed_program,
|
||||
build_project,
|
||||
generate_build_system,
|
||||
):
|
||||
# A target with bin images does not need OUTPUT_EXT defined
|
||||
generate_config.return_value = [mock.MagicMock(), mock.MagicMock()]
|
||||
mock_find_devices.return_value = [mock.MagicMock()]
|
||||
runner = CliRunner()
|
||||
runner.invoke(build, ["--flash", *DEFAULT_BUILD_ARGS])
|
||||
call_args = flash_binary.call_args
|
||||
args, kwargs = call_args
|
||||
flash_binary.assert_called_once_with(args[0], args[1], args[2], args[3], False)
|
||||
|
||||
@mock.patch("mbed_tools.cli.build.flash_binary")
|
||||
@mock.patch("mbed_tools.cli.build.find_all_connected_devices")
|
||||
def test_build_flash_options_hex_target(
|
||||
self,
|
||||
mock_find_devices,
|
||||
flash_binary,
|
||||
generate_config,
|
||||
mbed_program,
|
||||
build_project,
|
||||
generate_build_system,
|
||||
):
|
||||
generate_config.return_value = [{"OUTPUT_EXT": "hex"}, mock.MagicMock()]
|
||||
mock_find_devices.return_value = [mock.MagicMock()]
|
||||
runner = CliRunner()
|
||||
runner.invoke(build, ["--flash", *DEFAULT_BUILD_ARGS])
|
||||
call_args = flash_binary.call_args
|
||||
args, kwargs = call_args
|
||||
flash_binary.assert_called_once_with(args[0], args[1], args[2], args[3], True)
|
||||
|
||||
@mock.patch("mbed_tools.cli.build.flash_binary")
|
||||
@mock.patch("mbed_tools.cli.build.find_all_connected_devices")
|
||||
def test_build_flash_both_two_devices(
|
||||
self,
|
||||
mock_find_devices,
|
||||
flash_binary,
|
||||
generate_config,
|
||||
mbed_program,
|
||||
build_project,
|
||||
generate_build_system,
|
||||
):
|
||||
generate_config.return_value = [mock.MagicMock(), mock.MagicMock()]
|
||||
mock_find_devices.return_value = [mock.MagicMock(), mock.MagicMock()]
|
||||
runner = CliRunner()
|
||||
runner.invoke(build, ["--flash", *DEFAULT_BUILD_ARGS])
|
||||
self.assertEqual(flash_binary.call_count, 2)
|
||||
|
||||
@mock.patch("mbed_tools.cli.build.flash_binary")
|
||||
@mock.patch("mbed_tools.cli.build.find_connected_device")
|
||||
def test_build_flash_only_identifier_device(
|
||||
self,
|
||||
mock_find_device,
|
||||
flash_binary,
|
||||
generate_config,
|
||||
mbed_program,
|
||||
build_project,
|
||||
generate_build_system,
|
||||
):
|
||||
generate_config.return_value = [mock.MagicMock(), mock.MagicMock()]
|
||||
mock_find_device.return_value = mock.MagicMock()
|
||||
runner = CliRunner()
|
||||
runner.invoke(build, ["--flash", "-m", "K64F[1]", "-t", "GCC_ARM"])
|
||||
self.assertEqual(flash_binary.call_count, 1)
|
||||
|
||||
@mock.patch("mbed_tools.cli.build.terminal")
|
||||
@mock.patch("mbed_tools.cli.build.find_connected_device")
|
||||
def test_sterm_is_started_when_flag_passed(
|
||||
self, mock_find_device, mock_terminal, generate_config, mbed_program, build_project, generate_build_system
|
||||
):
|
||||
target = "K64F"
|
||||
serial_port = "tty.k64f"
|
||||
baud = 115200
|
||||
mock_find_device.return_value = mock.Mock(serial_port=serial_port)
|
||||
generate_config.return_value = [mock.MagicMock(), mock.MagicMock()]
|
||||
|
||||
CliRunner().invoke(build, ["-m", target, "-t", "gcc_arm", "--sterm", "--baudrate", baud])
|
||||
|
||||
mock_find_device.assert_called_once_with(target, None)
|
||||
mock_terminal.run.assert_called_once_with(serial_port, baud)
|
||||
|
||||
@mock.patch("mbed_tools.cli.build.terminal")
|
||||
@mock.patch("mbed_tools.cli.build.find_connected_device")
|
||||
def test_raises_if_device_does_not_have_serial_port_and_sterm_flag_given(
|
||||
self, mock_find_device, mock_terminal, generate_config, mbed_program, build_project, generate_build_system
|
||||
):
|
||||
target = "K64F"
|
||||
serial_port = None
|
||||
mock_find_device.return_value = mock.Mock(serial_port=serial_port)
|
||||
generate_config.return_value = [mock.MagicMock(), mock.MagicMock()]
|
||||
|
||||
output = CliRunner().invoke(build, ["-m", target, "-t", "gcc_arm", "--sterm"])
|
||||
self.assertEqual(type(output.exception), SystemExit)
|
||||
mock_terminal.assert_not_called()
|
|
@ -15,14 +15,14 @@ class TestConfigureCommand(TestCase):
|
|||
@mock.patch("mbed_tools.cli.configure.generate_config")
|
||||
@mock.patch("mbed_tools.cli.configure.MbedProgram")
|
||||
def test_generate_config_called_with_correct_arguments(self, program, generate_config):
|
||||
CliRunner().invoke(configure, ["-m", "k64f", "-t", "gcc_arm"])
|
||||
CliRunner().invoke(configure, ["-m", "k64f", "-t", "gcc_arm", "-o", "some_output_dir"])
|
||||
|
||||
generate_config.assert_called_once_with("K64F", "GCC_ARM", program.from_existing())
|
||||
|
||||
@mock.patch("mbed_tools.cli.configure.generate_config")
|
||||
@mock.patch("mbed_tools.cli.configure.MbedProgram")
|
||||
def test_generate_config_called_with_mbed_os_path(self, program, generate_config):
|
||||
CliRunner().invoke(configure, ["-m", "k64f", "-t", "gcc_arm", "--mbed-os-path", "./extern/mbed-os"])
|
||||
CliRunner().invoke(configure, ["-m", "k64f", "-t", "gcc_arm", "--mbed-os-path", "./extern/mbed-os", "-o", "some_output_dir"])
|
||||
|
||||
generate_config.assert_called_once_with("K64F", "GCC_ARM", program.from_existing())
|
||||
|
||||
|
@ -32,29 +32,19 @@ class TestConfigureCommand(TestCase):
|
|||
program = program.from_existing()
|
||||
custom_targets_json_path = pathlib.Path("custom", "custom_targets.json")
|
||||
CliRunner().invoke(
|
||||
configure, ["-t", "gcc_arm", "-m", "k64f", "--custom-targets-json", custom_targets_json_path]
|
||||
configure, ["-t", "gcc_arm", "-m", "k64f", "--custom-targets-json", custom_targets_json_path, "-o", "some_output_dir"]
|
||||
)
|
||||
|
||||
generate_config.assert_called_once_with("K64F", "GCC_ARM", program)
|
||||
self.assertEqual(program.files.custom_targets_json, custom_targets_json_path)
|
||||
|
||||
@mock.patch("mbed_tools.cli.configure.generate_config")
|
||||
@mock.patch("mbed_tools.cli.configure.MbedProgram")
|
||||
def test_custom_output_directory_used_when_passed(self, program, generate_config):
|
||||
program = program.from_existing()
|
||||
output_dir = pathlib.Path("build")
|
||||
CliRunner().invoke(configure, ["-t", "gcc_arm", "-m", "k64f", "-o", output_dir])
|
||||
|
||||
generate_config.assert_called_once_with("K64F", "GCC_ARM", program)
|
||||
self.assertEqual(program.files.cmake_build_dir, output_dir)
|
||||
|
||||
@mock.patch("mbed_tools.cli.configure.generate_config")
|
||||
@mock.patch("mbed_tools.cli.configure.MbedProgram")
|
||||
def test_app_config_used_when_passed(self, program, generate_config):
|
||||
program = program.from_existing()
|
||||
app_config_path = pathlib.Path("alternative_config.json")
|
||||
CliRunner().invoke(
|
||||
configure, ["-t", "gcc_arm", "-m", "k64f", "--app-config", app_config_path]
|
||||
configure, ["-t", "gcc_arm", "-m", "k64f", "--app-config", app_config_path, "-o", "some_output_dir"]
|
||||
)
|
||||
|
||||
generate_config.assert_called_once_with("K64F", "GCC_ARM", program)
|
||||
|
@ -62,20 +52,19 @@ class TestConfigureCommand(TestCase):
|
|||
|
||||
@mock.patch("mbed_tools.cli.configure.generate_config")
|
||||
@mock.patch("mbed_tools.cli.configure.MbedProgram")
|
||||
def test_profile_used_when_passed(self, program, generate_config):
|
||||
def test_output_dir_passed(self, program, generate_config):
|
||||
test_program = program.from_existing()
|
||||
program.reset_mock() # clear call count from previous line
|
||||
|
||||
toolchain = "gcc_arm"
|
||||
target = "k64f"
|
||||
profile = "release"
|
||||
|
||||
CliRunner().invoke(
|
||||
configure, ["-t", toolchain, "-m", target, "--profile", profile]
|
||||
configure, ["-t", toolchain, "-m", target, "-o", "some_output_dir"]
|
||||
)
|
||||
|
||||
program.from_existing.assert_called_once_with(
|
||||
pathlib.Path("."),
|
||||
pathlib.Path(target.upper(), profile, toolchain.upper())
|
||||
pathlib.Path("some_output_dir")
|
||||
)
|
||||
generate_config.assert_called_once_with("K64F", "GCC_ARM", test_program)
|
||||
|
|
|
@ -10,7 +10,7 @@ import pytest
|
|||
from mbed_tools.project import MbedProgram
|
||||
from mbed_tools.project.exceptions import ExistingProgram, ProgramNotFound, MbedOSNotFound
|
||||
from mbed_tools.project.mbed_program import _find_program_root, parse_url
|
||||
from mbed_tools.project._internal.project_data import MbedProgramFiles
|
||||
from mbed_tools.project._internal.project_data import MbedProgramFiles, BUILD_DIR
|
||||
from python_tests.mbed_tools.project.factories import make_mbed_program_files, make_mbed_os_files
|
||||
|
||||
|
||||
|
@ -40,7 +40,7 @@ class TestInitialiseProgram:
|
|||
|
||||
program = from_new_set_target_toolchain(program_root)
|
||||
|
||||
assert program.files == MbedProgramFiles.from_existing(program_root, DEFAULT_BUILD_SUBDIR)
|
||||
assert program.files == MbedProgramFiles.from_existing(program_root, program_root / BUILD_DIR / DEFAULT_BUILD_SUBDIR)
|
||||
|
||||
def test_from_new_local_dir_generates_valid_program_creating_directory_in_cwd(self, tmp_path):
|
||||
old_cwd = os.getcwd()
|
||||
|
@ -52,7 +52,7 @@ class TestInitialiseProgram:
|
|||
|
||||
program = from_new_set_target_toolchain(program_root)
|
||||
|
||||
assert program.files == MbedProgramFiles.from_existing(program_root, DEFAULT_BUILD_SUBDIR)
|
||||
assert program.files == MbedProgramFiles.from_existing(program_root, program_root / BUILD_DIR / DEFAULT_BUILD_SUBDIR)
|
||||
finally:
|
||||
os.chdir(old_cwd)
|
||||
|
||||
|
@ -64,7 +64,7 @@ class TestInitialiseProgram:
|
|||
|
||||
program = from_new_set_target_toolchain(program_root)
|
||||
|
||||
assert program.files == MbedProgramFiles.from_existing(program_root, DEFAULT_BUILD_SUBDIR)
|
||||
assert program.files == MbedProgramFiles.from_existing(program_root, program_root / BUILD_DIR / DEFAULT_BUILD_SUBDIR)
|
||||
|
||||
def test_from_existing_raises_if_path_is_not_a_program(self, tmp_path):
|
||||
fs_root = pathlib.Path(tmp_path, "foo")
|
||||
|
@ -72,21 +72,21 @@ class TestInitialiseProgram:
|
|||
program_root = fs_root / "programfoo"
|
||||
|
||||
with pytest.raises(ProgramNotFound):
|
||||
MbedProgram.from_existing(program_root, DEFAULT_BUILD_SUBDIR)
|
||||
MbedProgram.from_existing(program_root, program_root / BUILD_DIR / DEFAULT_BUILD_SUBDIR)
|
||||
|
||||
def test_from_existing_raises_if_no_mbed_os_dir_found_and_check_mbed_os_is_true(self, tmp_path):
|
||||
fs_root = pathlib.Path(tmp_path, "foo")
|
||||
make_mbed_program_files(fs_root)
|
||||
|
||||
with pytest.raises(MbedOSNotFound):
|
||||
MbedProgram.from_existing(fs_root, DEFAULT_BUILD_SUBDIR, check_mbed_os=True)
|
||||
MbedProgram.from_existing(fs_root, fs_root / BUILD_DIR / DEFAULT_BUILD_SUBDIR, check_mbed_os=True)
|
||||
|
||||
def test_from_existing_returns_valid_program(self, tmp_path):
|
||||
fs_root = pathlib.Path(tmp_path, "foo")
|
||||
make_mbed_program_files(fs_root)
|
||||
make_mbed_os_files(fs_root / "mbed-os")
|
||||
|
||||
program = MbedProgram.from_existing(fs_root, DEFAULT_BUILD_SUBDIR)
|
||||
program = MbedProgram.from_existing(fs_root, fs_root / BUILD_DIR / DEFAULT_BUILD_SUBDIR)
|
||||
|
||||
assert program.files.app_config_file.exists()
|
||||
assert program.mbed_os.root.exists()
|
||||
|
@ -98,7 +98,7 @@ class TestInitialiseProgram:
|
|||
make_mbed_program_files(fs_root)
|
||||
make_mbed_os_files(mbed_os_path)
|
||||
|
||||
program = MbedProgram.from_existing(fs_root, DEFAULT_BUILD_SUBDIR, mbed_os_path)
|
||||
program = MbedProgram.from_existing(fs_root, fs_root / BUILD_DIR / DEFAULT_BUILD_SUBDIR, mbed_os_path)
|
||||
|
||||
assert program.files.app_config_file.exists()
|
||||
assert program.mbed_os.root.exists()
|
||||
|
|
|
@ -53,8 +53,9 @@ class TestConfigureRegression(TestCase):
|
|||
pathlib.Path(tmpDirPath / "mbed-os" / "targets").mkdir()
|
||||
pathlib.Path(tmpDirPath / "mbed-os" / "targets" / "targets.json5").write_text(target_json)
|
||||
pathlib.Path(tmpDirPath / "mbed-os" / "targets" / "cmsis_mcu_descriptions.json5").write_text("{}")
|
||||
pathlib.Path(tmpDirPath / "cmake-build-debug").mkdir()
|
||||
|
||||
result = CliRunner().invoke(
|
||||
configure, ["-m", "Target", "-t", "gcc_arm", "-p", tmpDir], catch_exceptions=False
|
||||
configure, ["-m", "Target", "-t", "gcc_arm", "-p", tmpDir, "-o", str(tmpDirPath / "cmake-build-debug")], catch_exceptions=False
|
||||
)
|
||||
self.assertIn("mbed_config.cmake has been generated and written to", result.output)
|
||||
|
|
Loading…
Reference in New Issue