Skip to content

Commit 722c2f1

Browse files
author
Jamie Smith
authored
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 dir
1 parent 2fd9d83 commit 722c2f1

File tree

16 files changed

+132
-589
lines changed

16 files changed

+132
-589
lines changed

tools/cmake/mbed_generate_configuration.cmake

Lines changed: 34 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -27,57 +27,43 @@ else()
2727
endif()
2828
set(MBED_INTERNAL_LAST_MBED_TARGET "${MBED_TARGET}" CACHE INTERNAL "Previous mbed target this dir was configured with" FORCE)
2929

30-
# Convert all relative paths to absolute paths, rooted at CMAKE_SOURCE_DIR.
31-
# This makes sure that they are interpreted the same way everywhere.
32-
get_filename_component(MBED_APP_JSON_PATH "${MBED_APP_JSON_PATH}" ABSOLUTE BASE_DIR ${CMAKE_SOURCE_DIR})
33-
get_filename_component(CUSTOM_TARGETS_JSON_PATH "${CUSTOM_TARGETS_JSON_PATH}" ABSOLUTE BASE_DIR ${CMAKE_SOURCE_DIR})
34-
35-
# Make it so that if mbed_app.json or custom_targets.json are modified, CMake is rerun.
36-
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${MBED_APP_JSON_PATH})
37-
if(EXISTS "${CUSTOM_TARGETS_JSON_PATH}" AND (NOT IS_DIRECTORY "${CUSTOM_TARGETS_JSON_PATH}"))
38-
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${CUSTOM_TARGETS_JSON_PATH})
39-
endif()
40-
41-
# Check if mbed_app.json was modified
42-
# Note: if the path is an empty string, get_filename_component(ABSOLUTE) will convert it to a directory,
43-
# so we have to verify that the path we have is a file, not a dir.
44-
if(EXISTS "${MBED_APP_JSON_PATH}" AND (NOT IS_DIRECTORY "${MBED_APP_JSON_PATH}"))
45-
file(TIMESTAMP "${MBED_APP_JSON_PATH}" MBED_APP_JSON_TIMESTAMP "%s" UTC)
46-
else()
47-
set(MBED_APP_JSON_TIMESTAMP "<none>")
48-
endif()
49-
50-
if(NOT MBED_NEED_TO_RECONFIGURE)
51-
if(NOT "${MBED_INTERNAL_LAST_MBED_APP_JSON_TIMESTAMP}" STREQUAL "${MBED_APP_JSON_TIMESTAMP}")
52-
message(STATUS "Mbed: mbed_app.json modified, regenerating configs...")
30+
# Check if the include file is missing (e.g. because a previous attempt to generate it failed)
31+
if(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/mbed_config.cmake)
32+
if(NOT MBED_NEED_TO_RECONFIGURE)
33+
message(STATUS "Mbed: mbed_config.cmake not found, regenerating configs...")
5334
set(MBED_NEED_TO_RECONFIGURE TRUE)
5435
endif()
55-
endif()
56-
set(MBED_INTERNAL_LAST_MBED_APP_JSON_TIMESTAMP "${MBED_APP_JSON_TIMESTAMP}" CACHE INTERNAL "Previous UTC modification timestamp for mbed_app.json" FORCE)
57-
58-
# Check if custom_targets.json was modified
59-
if(EXISTS "${CUSTOM_TARGETS_JSON_PATH}" AND (NOT IS_DIRECTORY "${CUSTOM_TARGETS_JSON_PATH}"))
60-
file(TIMESTAMP "${CUSTOM_TARGETS_JSON_PATH}" CUSTOM_TARGETS_JSON_TIMESTAMP "%s" UTC)
6136
else()
62-
set(CUSTOM_TARGETS_JSON_TIMESTAMP "<none>")
37+
# Include the old version of mbed_config.cmake to get the MBED_CONFIG_JSON_SOURCE_FILES variable used below
38+
include(${CMAKE_CURRENT_BINARY_DIR}/mbed_config.cmake)
6339
endif()
6440

41+
# Check timestamps on all JSON files used to generate the Mbed configuration
6542
if(NOT MBED_NEED_TO_RECONFIGURE)
66-
if(NOT "${MBED_INTERNAL_LAST_CUSTOM_TARGETS_JSON_TIMESTAMP}" STREQUAL "${CUSTOM_TARGETS_JSON_TIMESTAMP}")
67-
message(STATUS "Mbed: custom_targets.json modified, regenerating configs...")
68-
set(MBED_NEED_TO_RECONFIGURE TRUE)
69-
endif()
43+
file(TIMESTAMP ${CMAKE_CURRENT_BINARY_DIR}/mbed_config.cmake MBED_CONFIG_CMAKE_TIMESTAMP "%s" UTC)
44+
45+
foreach(CONFIG_JSON ${MBED_CONFIG_JSON_SOURCE_FILES})
46+
get_filename_component(CONFIG_JSON_ABSPATH ${CONFIG_JSON} ABSOLUTE)
47+
48+
if(NOT EXISTS ${CONFIG_JSON_ABSPATH})
49+
message(STATUS "Mbed: ${CONFIG_JSON} deleted or renamed, regenerating configs...")
50+
set(MBED_NEED_TO_RECONFIGURE TRUE)
51+
break()
52+
endif()
53+
54+
file(TIMESTAMP ${CONFIG_JSON_ABSPATH} CONFIG_JSON_TIMESTAMP "%s" UTC)
55+
if(${CONFIG_JSON_TIMESTAMP} GREATER ${MBED_CONFIG_CMAKE_TIMESTAMP})
56+
message(STATUS "Mbed: ${CONFIG_JSON} modified, regenerating configs...")
57+
set(MBED_NEED_TO_RECONFIGURE TRUE)
58+
break()
59+
endif()
60+
endforeach()
7061
endif()
7162

72-
set(MBED_INTERNAL_LAST_CUSTOM_TARGETS_JSON_TIMESTAMP "${CUSTOM_TARGETS_JSON_TIMESTAMP}" CACHE INTERNAL "Previous UTC modification timestamp for custom_targets.json" FORCE)
73-
74-
# Check if the include file is missing (e.g. because a previous attempt to generate it failed)
75-
if(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/mbed_config.cmake)
76-
if(NOT MBED_NEED_TO_RECONFIGURE)
77-
message(STATUS "Mbed: mbed_config.cmake not found, regenerating configs...")
78-
set(MBED_NEED_TO_RECONFIGURE TRUE)
79-
endif()
80-
endif()
63+
# Convert all relative paths to absolute paths, rooted at CMAKE_SOURCE_DIR.
64+
# This makes sure that they are interpreted the same way everywhere.
65+
get_filename_component(MBED_APP_JSON_PATH "${MBED_APP_JSON_PATH}" ABSOLUTE BASE_DIR ${CMAKE_SOURCE_DIR})
66+
get_filename_component(CUSTOM_TARGETS_JSON_PATH "${CUSTOM_TARGETS_JSON_PATH}" ABSOLUTE BASE_DIR ${CMAKE_SOURCE_DIR})
8167

8268
if(MBED_NEED_TO_RECONFIGURE)
8369
# Generate mbed_config.cmake for this target
@@ -98,7 +84,7 @@ if(MBED_NEED_TO_RECONFIGURE)
9884

9985
set(MBEDTOOLS_CONFIGURE_COMMAND ${Python3_EXECUTABLE}
10086
-m mbed_tools.cli.main
101-
-v # without -v, warnings (e.g. "you have tried to override a nonexistent parameter") do not get printed
87+
-v -v # without at least -v, warnings (e.g. "you have tried to override a nonexistent parameter") do not get printed
10288
configure
10389
-t GCC_ARM # GCC_ARM is currently the only supported toolchain
10490
-m "${MBED_TARGET}"
@@ -126,4 +112,7 @@ if(MBED_NEED_TO_RECONFIGURE)
126112
endif()
127113

128114
# Include the generated config file
129-
include(${CMAKE_CURRENT_BINARY_DIR}/mbed_config.cmake)
115+
include(${CMAKE_CURRENT_BINARY_DIR}/mbed_config.cmake)
116+
117+
# Make it so that if any config JSON files are modified, CMake is rerun.
118+
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${MBED_CONFIG_JSON_SOURCE_FILES})

tools/python/mbed_tools/build/_internal/cmake_file.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,11 @@ def render_mbed_config_cmake_template(config: Config, toolchain_name: str, targe
3030
env.filters["to_hex"] = to_hex
3131
template = env.get_template(TEMPLATE_NAME)
3232
config["supported_c_libs"] = [x for x in config["supported_c_libs"][toolchain_name.lower()]]
33-
context = {"target_name": target_name, "toolchain_name": toolchain_name, **config}
33+
34+
context = {"target_name": target_name,
35+
"toolchain_name": toolchain_name,
36+
"json_sources": config.json_sources,
37+
**config}
3438
return template.render(context)
3539

3640

tools/python/mbed_tools/build/_internal/config/assemble_build_config.py

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,15 @@
99
from pathlib import Path
1010
from typing import Iterable, List, Optional, Set
1111

12+
from setuptools.build_meta import build_editable
13+
14+
from mbed_tools.project import MbedProgram
1215
from mbed_tools.build._internal.config.config import Config
1316
from mbed_tools.build._internal.config import source
1417
from mbed_tools.build._internal.find_files import LabelFilter, RequiresFilter, filter_files, find_files
1518

1619

17-
def assemble_config(target_attributes: dict, search_paths: Iterable[Path], mbed_app_file: Optional[Path]) -> Config:
20+
def assemble_config(target_attributes: dict, program: MbedProgram) -> Config:
1821
"""Assemble config for given target and program directory.
1922
2023
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_
2932
3033
Args:
3134
target_attributes: Mapping of target specific config parameters.
32-
search_paths: Iterable of paths to search for mbed_lib.json files.
33-
mbed_app_file: The path to mbed_app.json. This can be None.
35+
program: MbedProgram to build the config for
3436
"""
3537
mbed_lib_files: Set[Path] = set()
3638

37-
for path in search_paths:
39+
for path in [program.root, program.mbed_os.root]:
3840
mbed_lib_files.update(find_files("mbed_lib.json", path.absolute().resolve()))
3941
mbed_lib_files.update(find_files("mbed_lib.json5", path.absolute().resolve()))
4042

41-
return _assemble_config_from_sources(target_attributes, list(mbed_lib_files), mbed_app_file)
43+
config = _assemble_config_from_sources(target_attributes, list(mbed_lib_files), program.files.app_config_file)
44+
45+
# Set up the config source path list using the path to every JSON
46+
config.json_sources.extend(mbed_lib_files)
47+
if program.files.app_config_file is not None:
48+
config.json_sources.append(program.files.app_config_file)
49+
config.json_sources.append(program.mbed_os.targets_json_file)
50+
config.json_sources.append(program.mbed_os.cmsis_mcu_descriptions_json_file)
51+
if program.files.custom_targets_json.exists():
52+
config.json_sources.append(program.files.custom_targets_json)
53+
54+
# Make all JSON sources relative paths to the program root
55+
def make_relative_if_possible(path: Path):
56+
# Sadly, Pathlib did not gain a better way to do this until newer python versions.
57+
try:
58+
return path.relative_to(program.root)
59+
except ValueError:
60+
return path
61+
62+
config.json_sources = [make_relative_if_possible(program.root) for json_source in config.json_sources]
63+
64+
return config
4265

4366

4467
def _assemble_config_from_sources(

tools/python/mbed_tools/build/_internal/config/config.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
from collections import UserDict
99
from typing import Any, Iterable, Hashable, List
10+
import pathlib
1011

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

@@ -21,6 +22,11 @@ class Config(UserDict):
2122
Applies overrides, appends macros, and updates config settings.
2223
"""
2324

25+
# List of JSON files used to create this config. Dumped to CMake at the end of configuration
26+
# so that it can regenerate configuration if the JSONs change.
27+
# All paths will be relative to the Mbed program root directory, or absolute if outside said directory.
28+
json_sources: List[pathlib.Path] = []
29+
2430
def __setitem__(self, key: Hashable, item: Any) -> None:
2531
"""Set an item based on its key."""
2632
if key == CONFIG_SECTION:

tools/python/mbed_tools/build/_internal/templates/mbed_config.tmpl

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,19 @@
66

77
include_guard(GLOBAL)
88

9-
set(MBED_TOOLCHAIN "{{toolchain_name}}" CACHE STRING "")
10-
set(MBED_TARGET "{{target_name}}" CACHE STRING "")
11-
set(MBED_CPU_CORE "{{core}}" CACHE STRING "")
12-
set(MBED_C_LIB "{{c_lib}}" CACHE STRING "")
13-
set(MBED_PRINTF_LIB "{{printf_lib}}" CACHE STRING "")
14-
set(MBED_OUTPUT_EXT "{{OUTPUT_EXT}}" CACHE STRING "")
15-
set(MBED_GREENTEA_TEST_RESET_TIMEOUT "{{forced_reset_timeout}}" CACHE STRING "")
9+
set(MBED_TOOLCHAIN "{{toolchain_name}}")
10+
set(MBED_CPU_CORE "{{core}}")
11+
set(MBED_C_LIB "{{c_lib}}")
12+
set(MBED_PRINTF_LIB "{{printf_lib}}")
13+
set(MBED_OUTPUT_EXT "{{OUTPUT_EXT}}")
14+
set(MBED_GREENTEA_TEST_RESET_TIMEOUT "{{forced_reset_timeout}}")
15+
16+
# JSON files used to generate this config. If any of these change, the Python config generation
17+
# scripts must be rerun.
18+
set(MBED_CONFIG_JSON_SOURCE_FILES {% for json_source in json_sources | sort %}
19+
"{{json_source.as_posix()}}"
20+
{%- endfor %}
21+
)
1622

1723
list(APPEND MBED_TARGET_SUPPORTED_C_LIBS {% for supported_c_lib in supported_c_libs %}
1824
{{supported_c_lib}}

tools/python/mbed_tools/build/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def generate_config(target_name: str, toolchain: str, program: MbedProgram) -> T
3838
target_build_attributes = get_target_by_name(target_name, targets_data)
3939
incorporate_memory_bank_data_from_cmsis(target_build_attributes, program)
4040
config = assemble_config(
41-
target_build_attributes, [program.root, program.mbed_os.root], program.files.app_config_file
41+
target_build_attributes, program
4242
)
4343

4444
# Process memory banks and save JSON data for other tools (e.g. memap) to use

tools/python/mbed_tools/cli/build.py

Lines changed: 0 additions & 140 deletions
This file was deleted.

0 commit comments

Comments
 (0)