From 532123aabcd173171da0889cddae97fa994cac3d Mon Sep 17 00:00:00 2001 From: Michael Spang Date: Wed, 21 Apr 2021 22:40:55 -0400 Subject: [PATCH] Read the ZAP file to determine which directories to compile This parses the ZAP file, enumerates enabled clusters, and enables the appropriate directories in src/app/clusters. Some of the directories in src/app/clusters are dead code and do not even compile. Remove those. Based on #5882 --- .../all-clusters-common/BUILD.gn | 30 +--- examples/bridge-app/bridge-common/BUILD.gn | 9 +- examples/chip-tool/BUILD.gn | 5 +- .../lighting-app/lighting-common/BUILD.gn | 9 +- examples/lock-app/lock-common/BUILD.gn | 8 +- examples/tv-app/tv-common/BUILD.gn | 24 +-- examples/window-app/common/BUILD.gn | 5 +- src/app/chip_data_model.gni | 61 +++++-- src/app/zap_cluster_list.py | 158 ++++++++++++++++++ src/darwin/Framework/CHIP/BUILD.gn | 9 +- 10 files changed, 211 insertions(+), 107 deletions(-) create mode 100755 src/app/zap_cluster_list.py diff --git a/examples/all-clusters-app/all-clusters-common/BUILD.gn b/examples/all-clusters-app/all-clusters-common/BUILD.gn index 41fb5bcbd1aedc..d6bbe53239f2d0 100644 --- a/examples/all-clusters-app/all-clusters-common/BUILD.gn +++ b/examples/all-clusters-app/all-clusters-common/BUILD.gn @@ -17,35 +17,7 @@ import("//build_overrides/chip.gni") import("${chip_root}/src/app/chip_data_model.gni") chip_data_model("all-clusters-common") { - cluster_sources = [ - "account-login-server", - "application-launcher-server", - "audio-output-server", - "barrier-control-server", - "basic", - "bindings", - "color-control-server", - "content-launch-server", - "descriptor", - "door-lock-server", - "general-commissioning-server", - "groups-server", - "ias-zone-server", - "identify", - "keypad-input-server", - "level-control", - "low-power-server", - "media-input-server", - "media-playback-server", - "network-commissioning", - "on-off-server", - "operational-credentials", - "ota-server", - "scenes", - "target-navigator-server", - "temperature-measurement-server", - "tv-channel-server", - ] + zap_file = "all-clusters-app.zap" zap_pregenerated_dir = "gen" } diff --git a/examples/bridge-app/bridge-common/BUILD.gn b/examples/bridge-app/bridge-common/BUILD.gn index 16ebe0ce145c93..46b94ab8d49c7c 100644 --- a/examples/bridge-app/bridge-common/BUILD.gn +++ b/examples/bridge-app/bridge-common/BUILD.gn @@ -17,14 +17,7 @@ import("//build_overrides/chip.gni") import("${chip_root}/src/app/chip_data_model.gni") chip_data_model("bridge-common") { - cluster_sources = [ - "basic", - "bindings", - "general-commissioning-server", - "level-control", - "network-commissioning", - "on-off-server", - ] + zap_file = "bridge-app.zap" zap_pregenerated_dir = "gen" } diff --git a/examples/chip-tool/BUILD.gn b/examples/chip-tool/BUILD.gn index 5c736cb3a47922..8bd2c3ec412f36 100644 --- a/examples/chip-tool/BUILD.gn +++ b/examples/chip-tool/BUILD.gn @@ -21,10 +21,7 @@ import("${chip_root}/src/app/chip_data_model.gni") assert(chip_build_tools) chip_data_model("data_model") { - cluster_sources = [ - "media-playback-client", - "thermostat-client", - ] + zap_file = "chip-tool.zap" zap_pregenerated_dir = "gen" diff --git a/examples/lighting-app/lighting-common/BUILD.gn b/examples/lighting-app/lighting-common/BUILD.gn index ef6be3549968eb..c44f5b9875e332 100644 --- a/examples/lighting-app/lighting-common/BUILD.gn +++ b/examples/lighting-app/lighting-common/BUILD.gn @@ -28,14 +28,7 @@ if (chip_enable_pw_rpc) { } chip_data_model("lighting-common") { - cluster_sources = [ - "basic", - "bindings", - "general-commissioning-server", - "level-control", - "network-commissioning", - "on-off-server", - ] + zap_file = "lighting-app.zap" zap_pregenerated_dir = "gen" } diff --git a/examples/lock-app/lock-common/BUILD.gn b/examples/lock-app/lock-common/BUILD.gn index a083bc42bfe2f4..a0eb36cdd585e0 100644 --- a/examples/lock-app/lock-common/BUILD.gn +++ b/examples/lock-app/lock-common/BUILD.gn @@ -17,13 +17,7 @@ import("//build_overrides/chip.gni") import("${chip_root}/src/app/chip_data_model.gni") chip_data_model("lock-common") { - cluster_sources = [ - "basic", - "bindings", - "general-commissioning-server", - "network-commissioning", - "on-off-server", - ] + zap_file = "lock-app.zap" zap_pregenerated_dir = "gen" } diff --git a/examples/tv-app/tv-common/BUILD.gn b/examples/tv-app/tv-common/BUILD.gn index e209ff1f447f7a..bbba32d4081987 100644 --- a/examples/tv-app/tv-common/BUILD.gn +++ b/examples/tv-app/tv-common/BUILD.gn @@ -17,29 +17,7 @@ import("//build_overrides/chip.gni") import("${chip_root}/src/app/chip_data_model.gni") chip_data_model("tv-common") { - cluster_sources = [ - "barrier-control-server", - "basic", - "bindings", - "color-control-server", - "content-launch-server", - "door-lock-client", - "door-lock-server", - "general-commissioning-server", - "groups-client", - "groups-server", - "ias-zone-server", - "identify", - "identify-client", - "level-control", - "low-power-server", - "media-playback-server", - "network-commissioning", - "on-off-server", - "scenes", - "scenes-client", - "temperature-measurement-server", - ] + zap_file = "tv-app.zap" zap_pregenerated_dir = "gen" } diff --git a/examples/window-app/common/BUILD.gn b/examples/window-app/common/BUILD.gn index cae03951f43359..4052665e0f2b77 100644 --- a/examples/window-app/common/BUILD.gn +++ b/examples/window-app/common/BUILD.gn @@ -17,10 +17,7 @@ import("//build_overrides/chip.gni") import("${chip_root}/src/app/chip_data_model.gni") chip_data_model("window-common") { - cluster_sources = [ - "bindings", - "network-commissioning", - ] + zap_file = "window-app.zap" zap_pregenerated_dir = "gen" } diff --git a/src/app/chip_data_model.gni b/src/app/chip_data_model.gni index 0ffe6deb6dd6c1..010fed4ce83bfe 100644 --- a/src/app/chip_data_model.gni +++ b/src/app/chip_data_model.gni @@ -18,14 +18,24 @@ import("${chip_root}/src/lib/core/core.gni") _app_root = get_path_info(".", "abspath") +_zap_cluster_list_script = get_path_info("zap_cluster_list.py", "abspath") + # Defines a source_set for CHIP data model. # # Arguments: # zap_pregenerated_dir # Path to the ZAP "gen" dir. # +# zap_file +# Path to the ZAP input file. +# # cluster_sources -# Names of the clusters to compile. +# Names of the clusters directories to compile. +# Deprecated, specify zap_file instead. +# +# remove_cluster_sources +# Names of the cluster directories to remove. +# TODO - Remove this option once everything compiles. # # use_default_client_callbacks # Include CHIPClientCallbacks.cpp. @@ -53,6 +63,8 @@ template("chip_data_model") { [ "zap_pregenerated_dir", "cluster_sources", + "remove_cluster_sources", + "zap_file", "use_default_client_callbacks", ]) @@ -75,7 +87,6 @@ template("chip_data_model") { "${_app_root}/clusters/messaging-server/messaging-server.h", "${_app_root}/clusters/network-commissioning/network-commissioning.h", "${_app_root}/clusters/on-off-server/on-off-server.h", - "${_app_root}/clusters/scenes-client/scenes-client.h", "${_app_root}/clusters/scenes/scenes-tokens.h", "${_app_root}/clusters/scenes/scenes.h", "${_app_root}/clusters/temperature-measurement-server/temperature-measurement-server.h", @@ -102,22 +113,36 @@ template("chip_data_model") { ] if (defined(invoker.cluster_sources)) { - foreach(cluster, invoker.cluster_sources) { - if (cluster == "door-lock-server") { - sources += [ - "${_app_root}/clusters/${cluster}/door-lock-server-core.cpp", - "${_app_root}/clusters/${cluster}/door-lock-server-logging.cpp", - "${_app_root}/clusters/${cluster}/door-lock-server-schedule.cpp", - "${_app_root}/clusters/${cluster}/door-lock-server-user.cpp", - ] - } else if (cluster == "network-commissioning") { - sources += [ - "${_app_root}/clusters/${cluster}/${cluster}-ember.cpp", - "${_app_root}/clusters/${cluster}/${cluster}.cpp", - ] - } else { - sources += [ "${_app_root}/clusters/${cluster}/${cluster}.cpp" ] - } + _cluster_sources = invoker.cluster_sources + } else if (defined(invoker.zap_file)) { + _zap_path = rebase_path(invoker.zap_file, root_build_dir) + _script_args = [ "--zap_file=" + _zap_path ] + + _cluster_sources = exec_script(_zap_cluster_list_script, + _script_args, + "list lines", + [ invoker.zap_file ]) + } + + if (defined(invoker.remove_cluster_sources)) { + _cluster_sources -= invoker.remove_cluster_sources + } + + foreach(cluster, _cluster_sources) { + if (cluster == "door-lock-server") { + sources += [ + "${_app_root}/clusters/${cluster}/door-lock-server-core.cpp", + "${_app_root}/clusters/${cluster}/door-lock-server-logging.cpp", + "${_app_root}/clusters/${cluster}/door-lock-server-schedule.cpp", + "${_app_root}/clusters/${cluster}/door-lock-server-user.cpp", + ] + } else if (cluster == "network-commissioning") { + sources += [ + "${_app_root}/clusters/${cluster}/${cluster}-ember.cpp", + "${_app_root}/clusters/${cluster}/${cluster}.cpp", + ] + } else { + sources += [ "${_app_root}/clusters/${cluster}/${cluster}.cpp" ] } } diff --git a/src/app/zap_cluster_list.py b/src/app/zap_cluster_list.py new file mode 100755 index 00000000000000..6c2f17d8482032 --- /dev/null +++ b/src/app/zap_cluster_list.py @@ -0,0 +1,158 @@ +#!/usr/bin/env python3 +"""Parses a ZAP input file and outputs directories to compile.""" + +import argparse +import pathlib +import json +import typing +import sys + +# List of directories in src/app/clusters to build for server clusters. +SERVER_CLUSTERS: typing.Dict[str, typing.List[str]] = { + 'ALARM_CLUSTER': [], + 'APPLICATION_BASIC_CLUSTER': [], + 'BARRIER_CONTROL_CLUSTER': ['barrier-control-server'], + 'BASIC_CLUSTER': ['basic'], + 'BINDING_CLUSTER': ['bindings'], + 'COLOR_CONTROL_CLUSTER': ['color-control-server'], + 'COMMISSIONING_CLUSTER': [], + 'CONTENT_LAUNCH_CLUSTER': ['content-launch-server'], + 'DESCRIPTOR_CLUSTER': ['descriptor'], + 'DEVICE_TEMP_CLUSTER': [], + 'DOOR_LOCK_CLUSTER': ['door-lock-server'], + 'GENERAL_COMMISSIONING_CLUSTER': ['general-commissioning-server'], + 'GROUPS_CLUSTER': ['groups-server'], + 'GROUP_KEY_MANAGEMENT_CLUSTER': [], + 'IAS_ZONE_CLUSTER': ['ias-zone-server'], + 'IDENTIFY_CLUSTER': ['identify'], + 'LEVEL_CONTROL_CLUSTER': ['level-control'], + 'LOW_POWER_CLUSTER': ['low-power-server'], + 'MEDIA_PLAYBACK_CLUSTER': ['media-playback-server'], + 'NETWORK_COMMISSIONING_CLUSTER': ['network-commissioning'], + 'OCCUPANCY_SENSING_CLUSTER': [], + 'ON_OFF_CLUSTER': ['on-off-server'], + 'OPERATIONAL_CREDENTIALS_CLUSTER': ['operational-credentials'], + 'OTA_BOOTLOAD_CLUSTER': [], + 'OTA_SERVER_CLUSTER': ['ota-server'], + 'OTA_CLIENT_CLUSTER': [], + 'POWER_CONFIG_CLUSTER': [], + 'PUMP_CONFIG_CONTROL_CLUSTER': [], + 'SCENES_CLUSTER': ['scenes'], + 'TEMP_MEASUREMENT_CLUSTER': ['temperature-measurement-server'], + 'THERMOSTAT_CLUSTER': [], + 'WINDOW_COVERING_CLUSTER': [], + 'ZLL_COMMISSIONING_CLUSTER': [] +} + +# List of directories in src/app/clusters to build for client clusters. +CLIENT_CLUSTERS: typing.Dict[str, typing.List[str]] = { + 'ALARM_CLUSTER': [], + 'APPLICATION_BASIC_CLUSTER': [], + 'BARRIER_CONTROL_CLUSTER': [], + 'BASIC_CLUSTER': [], + 'BINDING_CLUSTER': [], + 'COLOR_CONTROL_CLUSTER': [], + 'COMMISSIONING_CLUSTER': [], + 'CONTENT_LAUNCH_CLUSTER': [], + 'DEVICE_TEMP_CLUSTER': [], + 'DESCRIPTOR_CLUSTER': [], + 'DOOR_LOCK_CLUSTER': [], + 'GENERAL_COMMISSIONING_CLUSTER': [], + 'GROUPS_CLUSTER': [], + 'GROUP_KEY_MANAGEMENT_CLUSTER': [], + 'IAS_ZONE_CLUSTER': ['ias-zone-client'], + 'IDENTIFY_CLUSTER': [], + 'LEVEL_CONTROL_CLUSTER': [], + 'LOW_POWER_CLUSTER': [], + 'MEDIA_PLAYBACK_CLUSTER': ['media-playback-client'], + 'NETWORK_COMMISSIONING_CLUSTER': [], + 'OCCUPANCY_SENSING_CLUSTER': [], + 'ON_OFF_CLUSTER': [], + 'OPERATIONAL_CREDENTIALS_CLUSTER': ['operational-credentials'], + 'OTA_BOOTLOAD_CLUSTER': [], + 'OTA_SERVER_CLUSTER': ['ota-server'], + 'OTA_CLIENT_CLUSTER': [], + 'POWER_CONFIG_CLUSTER': [], + 'PUMP_CONFIG_CONTROL_CLUSTER': [], + 'SCENES_CLUSTER': [], + 'TEMP_MEASUREMENT_CLUSTER': [], + 'THERMOSTAT_CLUSTER': ['thermostat-client'], + 'WINDOW_COVERING_CLUSTER': [], + 'ZLL_COMMISSIONING_CLUSTER': [] +} + + +def get_cluster_sources(clusters: typing.Set[str], + source_map: typing.Dict[str, + typing.List[str]], side: str): + """Returns a list of cluster source directories for the given clusters. + + Returns: + The set of source directories to build. + """ + + cluster_sources: typing.Set[str] = set() + + for cluster in clusters: + if not cluster in source_map: + raise ValueError("Unhandled %s cluster: %s" + " (hint: add to src/app/zap_cluster_list.py)" % (side, cluster)) + + cluster_sources.update(source_map[cluster]) + + return cluster_sources + + +def dump_zapfile_clusters(zap_file_path: pathlib.Path): + """Prints all of the source directories to build for a given ZAP file. + + Arguments: + zap_file_path - Path to the ZAP input file. + """ + + client_clusters: typing.Set[str] = set() + server_clusters: typing.Set[str] = set() + + with open(zap_file_path, "r") as zap_file: + zap_json = json.loads(zap_file.read()) + + for endpoint_type in zap_json.get('endpointTypes'): + for cluster in endpoint_type.get('clusters'): + side: str = cluster.get('side') + if side == 'client': + clusters_set = client_clusters + elif side == 'server': + clusters_set = server_clusters + else: + raise ValueError("Invalid side for cluster: %s" % side) + + if cluster.get('enabled') == 1: + clusters_set.add(cluster.get('define')) + + cluster_sources: typing.Set[str] = set() + + cluster_sources.update( + get_cluster_sources(server_clusters, SERVER_CLUSTERS, 'server')) + + cluster_sources.update( + get_cluster_sources(client_clusters, CLIENT_CLUSTERS, 'client')) + + for cluster in sorted(cluster_sources): + print(cluster) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('--zap_file', + help='Path to .zap file', + type=pathlib.Path) + + args = parser.parse_args() + + dump_zapfile_clusters(args.zap_file) + + sys.exit(0) + + +if __name__ == '__main__': + main() diff --git a/src/darwin/Framework/CHIP/BUILD.gn b/src/darwin/Framework/CHIP/BUILD.gn index ec820f84366b9b..b3de6d3d94063b 100644 --- a/src/darwin/Framework/CHIP/BUILD.gn +++ b/src/darwin/Framework/CHIP/BUILD.gn @@ -65,16 +65,13 @@ static_library("framework") { } chip_data_model("darwin_data_model") { - cluster_sources = [ - "media-playback-client", - "network-commissioning", - ] + zap_file = "chip-tool.zap" zap_pregenerated_dir = "gen" - public_configs = [ ":darwin_config" ] - use_default_client_callbacks = true + + public_configs = [ ":darwin_config" ] } group("CHIP") {