Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 34 additions & 45 deletions tools/cmake/mbed_generate_configuration.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -27,57 +27,43 @@ 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...")
# 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()
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>")
# 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)
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()
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()

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()
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
Expand All @@ -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}"
Expand Down Expand Up @@ -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})
6 changes: 5 additions & 1 deletion tools/python/mbed_tools/build/_internal/cmake_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@
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
Expand All @@ -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(
Expand Down
6 changes: 6 additions & 0 deletions tools/python/mbed_tools/build/_internal/config/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from collections import UserDict
from typing import Any, Iterable, Hashable, List
import pathlib

from mbed_tools.build._internal.config.source import Override, ConfigSetting

Expand All @@ -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:
Expand Down
20 changes: 13 additions & 7 deletions tools/python/mbed_tools/build/_internal/templates/mbed_config.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -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}}
Expand Down
2 changes: 1 addition & 1 deletion tools/python/mbed_tools/build/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
140 changes: 0 additions & 140 deletions tools/python/mbed_tools/cli/build.py

This file was deleted.

Loading
Loading