Skip to content

Commit

Permalink
Merge branch 'project-chip:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
nekleo authored Mar 24, 2023
2 parents 5a8ce8c + 275dbe1 commit 2a9f942
Show file tree
Hide file tree
Showing 82 changed files with 1,282 additions and 1,824 deletions.
176 changes: 176 additions & 0 deletions config/common/cmake/chip_gn.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
#
# Copyright (c) 2023 Project CHIP Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

#
# @file
# CMake file defining to setup and build the Matter library
# and other optional libraries like unit tests.
# Matter headers and libraries are exposed to the application
# as a specific interface target.
# Since Matter doesn't provide native CMake support, ExternalProject
# module is used to build the required artifacts with GN meta-build
# system.
#

# ==============================================================================
# Validate paths
# ==============================================================================
if (NOT GN_ROOT_TARGET)
message(FATAL_ERROR "GN_ROOT_TARGET not defined. Please provide the path to your Matter GN project.")
endif()

if (NOT CHIP_ROOT)
get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_LIST_DIR}/../../.. REALPATH)
endif()

# ==============================================================================
# Find required programs
# ==============================================================================
find_package(Python3 REQUIRED)
find_program(GN_EXECUTABLE gn REQUIRED)

# Parse the 'gn --version' output to find the installed version.
set(MIN_GN_VERSION 1851)
execute_process(
COMMAND ${GN_EXECUTABLE} --version
OUTPUT_VARIABLE GN_VERSION
COMMAND_ERROR_IS_FATAL ANY
)
if (GN_VERSION VERSION_LESS MIN_GN_VERSION)
message(FATAL_ERROR "Found unsupported version of gn: ${MIN_GN_VERSION}+ is required")
endif()

# ==============================================================================
# Macros
# ==============================================================================
# Setup and build the Matter library and other optional libraries like unit tests.
# Expose Matter headers & libraries to the application as specific
# interface target.
# [Args]:
# target - interface target name
# Available options are:
# LIB_SHELL Build and add Matter shell library
# LIB_PW_RPC Build and add Matter PW RPC library
# LIB_TESTS Build and add Matter unit tests library
# DEVICE_INFO_EXAMPLE_PROVIDER Add example device info provider support
#
# GN_DEPENDENCIES List of targets that should be built before Matter GN project
macro(matter_build target)
set(options)
set(oneValueArgs
LIB_TESTS
LIB_SHELL
LIB_PW_RPC
DEVICE_INFO_EXAMPLE_PROVIDER
)
set(multiValueArgs GN_DEPENDENCIES)

cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

set(MATTER_LIB_DIR ${CMAKE_CURRENT_BINARY_DIR}/lib)

# Prepare Matter libraries that the application should be linked with
set(MATTER_LIBRARIES -lCHIP)

if (ARG_LIB_SHELL)
list(APPEND MATTER_LIBRARIES -lCHIPShell)
endif()

if (ARG_LIB_PW_RPC)
list(APPEND MATTER_LIBRARIES -lPwRpc)
endif()

if (ARG_DEVICE_INFO_EXAMPLE_PROVIDER)
list(APPEND MATTER_LIBRARIES -lMatterDeviceInfoProviderExample)
endif()

list(TRANSFORM MATTER_LIBRARIES REPLACE
"-l(.*)"
"${MATTER_LIB_DIR}/lib\\1.a"
)

# ==============================================================================
# Define 'chip-gn' target that builds CHIP library(ies) with GN build system
# ==============================================================================
ExternalProject_Add(
chip-gn
PREFIX ${CMAKE_CURRENT_BINARY_DIR}
SOURCE_DIR ${CHIP_ROOT}
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}
CONFIGURE_COMMAND ""
CONFIGURE_HANDLED_BY_BUILD TRUE
BUILD_COMMAND ${CMAKE_COMMAND} -E echo "Starting Matter library build in ${CMAKE_CURRENT_BINARY_DIR}"
COMMAND ${Python3_EXECUTABLE} ${CHIP_ROOT}/config/common/cmake/make_gn_args.py @args.tmp > args.gn.tmp
# Replace the config only if it has changed to avoid triggering unnecessary rebuilds
COMMAND bash -c "(! diff -q args.gn.tmp args.gn && mv args.gn.tmp args.gn) || true"
# Regenerate the ninja build system
COMMAND ${GN_EXECUTABLE}
--root=${CHIP_ROOT}
--root-target=${GN_ROOT_TARGET}
--dotfile=${GN_ROOT_TARGET}/.gn
--script-executable=${Python3_EXECUTABLE}
gen --check --fail-on-unused-args ${CMAKE_CURRENT_BINARY_DIR}
COMMAND ninja
COMMAND ${CMAKE_COMMAND} -E echo "Matter library build complete"
INSTALL_COMMAND ""
# Byproducts are removed by the clean target removing config and .ninja_deps
# allows a rebuild of the external project after the clean target has been run.
BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/args.gn
${CMAKE_CURRENT_BINARY_DIR}/build.ninja
${CMAKE_CURRENT_BINARY_DIR}/.ninja_deps
${CMAKE_CURRENT_BINARY_DIR}/build.ninja.stamp
${MATTER_LIBRARIES}
BUILD_ALWAYS TRUE
USES_TERMINAL_CONFIGURE TRUE
USES_TERMINAL_BUILD TRUE
)

if(ARG_GN_DEPENDENCIES)
add_dependencies(chip-gn ${ARG_GN_DEPENDENCIES})
endif()

# ==============================================================================
# Define target that exposes Matter headers & libraries to the application
# ==============================================================================
add_library(${target} INTERFACE)
target_compile_definitions(${target} INTERFACE CHIP_HAVE_CONFIG_H)
target_include_directories(${target} INTERFACE
${CHIP_ROOT}/src
${CHIP_ROOT}/src/include
${CHIP_ROOT}/third_party/nlassert/repo/include
${CHIP_ROOT}/third_party/nlio/repo/include
${CHIP_ROOT}/zzz_generated/app-common
${CMAKE_CURRENT_BINARY_DIR}/gen/include
)

# ==============================================================================
# Link required libraries
# ==============================================================================
target_link_libraries(${target} INTERFACE -Wl,--start-group ${MATTER_LIBRARIES} -Wl,--end-group)
add_dependencies(${target} chip-gn)

if (ARG_LIB_SHELL)
target_link_options(${target} INTERFACE -Wl,--whole-archive ${MATTER_LIB_DIR}/libCHIPShell.a -Wl,--no-whole-archive)
endif()

if (ARG_LIB_TESTS)
target_link_options(${target} INTERFACE -Wl,--whole-archive ${MATTER_LIB_DIR}/libCHIP_tests.a -Wl,--no-whole-archive)
endif()

if (ARG_DEVICE_INFO_EXAMPLE_PROVIDER)
target_include_directories(${target} INTERFACE ${CHIP_ROOT}/examples/providers)
endif()
endmacro()
204 changes: 204 additions & 0 deletions config/common/cmake/chip_gn_args.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
#
# Copyright (c) 2023 Project CHIP Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

#
# @file
# CMake file that allows collecting C/C++ compiler flags passed to
# the Matter build system.
#

include(${CMAKE_CURRENT_LIST_DIR}/util.cmake)

# ==============================================================================
# Configuration variables and define constants
# ==============================================================================

# C/C++ compiler flags passed to the Matter build system
if (NOT MATTER_CFLAGS)
set(MATTER_CFLAGS PARENT_SCOPE)
endif()

# C compiler flags passed to the Matter build system
if (NOT MATTER_CFLAGS_C)
set(MATTER_CFLAGS_C PARENT_SCOPE)
endif()

# C++ compiler flags passed to the Matter build system
if (NOT MATTER_CFLAGS_CC)
set(MATTER_CFLAGS_CC PARENT_SCOPE)
endif()

# GN meta-build system arguments in the form of 'key1 = value1\nkey2 = value2...' string
if (NOT MATTER_GN_ARGS)
set(MATTER_GN_ARGS PARENT_SCOPE)
endif()

# ==============================================================================
# Macros
# ==============================================================================
# Add import GN argument
# [Args]:
# file - path to file that should be imported
macro(matter_add_gn_arg_import file)
string(APPEND MATTER_GN_ARGS "--module\n${file}\n")
endmacro()

# Add string GN argument
# [Args]:
# key - key name
# value - string value
macro(matter_add_gn_arg_string key value)
string(APPEND MATTER_GN_ARGS "--arg-string\n${key}\n${value}\n")
endmacro()

# Add bool GN argument
# [Args]:
# key - bool variable
macro(matter_add_gn_arg_bool key)
if (${ARGN})
string(APPEND MATTER_GN_ARGS "--arg\n${key}\ntrue\n")
else()
string(APPEND MATTER_GN_ARGS "--arg\n${key}\nfalse\n")
endif()
endmacro()

# Add compiler flag GN argument
# [Args]:
# key - key name
# value - compiler flag value
macro(matter_add_gn_arg_cflags key value)
string(APPEND MATTER_GN_ARGS "--arg-cflags\n${key}\n${value}\n")
endmacro()

# Add simple variable GN argument
# [Args]:
# key - variable name
# value - variable value
macro(matter_add_gn_arg key value)
string(APPEND MATTER_GN_ARGS "--arg\n${key}\n${value}\n")
endmacro()

# Add items to Matter common compiler flags
# [Args]:
# flags - flags to add
macro(matter_add_flags flags)
list(APPEND MATTER_CFLAGS ${flags})
endmacro()

# Add items to Matter C compiler flags
# [Args]:
# flags - flags to add
macro(matter_add_cflags flags)
list(APPEND MATTER_CFLAGS_C ${flags})
endmacro()

# Add items to Matter CXX compiler flags
# [Args]:
# flags - flags to add
macro(matter_add_cxxflags flags)
list(APPEND MATTER_CFLAGS_CC ${flags})
endmacro()

# Add GNU CPP standard flag to Matter CXX compiler flags
# [Args]:
# std_version - standard version number e.g. 17 for C++17
macro(matter_add_gnu_cpp_standard std_version)
list(APPEND MATTER_CFLAGS_CC -std=gnu++${std_version})
endmacro()

# Get compiler flags from listed targets.
# Collect common compile flags and save them in MATTER_CFLAGS
# Collect C/CXX compile flags and save them in MATTER_CFLAGS_C/MATTER_CFLAGS_CXX
# [Args]:
# targets - list of targets
macro(matter_get_compiler_flags_from_targets targets)
foreach(target ${targets})
get_target_common_compile_flags(EXTERNAL_TARGET_CFLAGS ${target})
get_lang_compile_flags(EXTERNAL_TARGET_CFLAGS_C ${target} C)
get_lang_compile_flags(EXTERNAL_TARGET_CFLAGS_CXX ${target} CXX)
list(APPEND MATTER_CFLAGS ${EXTERNAL_TARGET_CFLAGS})
list(APPEND MATTER_CFLAGS_C ${EXTERNAL_TARGET_CFLAGS_C})
list(APPEND MATTER_CFLAGS_CC ${EXTERNAL_TARGET_CFLAGS_CXX})
# Reset between targets
set(EXTERNAL_TARGET_CFLAGS "")
set(EXTERNAL_TARGET_CFLAGS_C "")
set(EXTERNAL_TARGET_CFLAGS_CXX "")
endforeach()
endmacro()

# Generate the common Matter GN arguments.
# Pass all compilation flags to GN build.
# Available options are:
# DEBUG Debug build
# LIB_SHELL Add Matter shell library
# LIB_PW_RPC Add Matter PW RPC library
# LIB_TESTS Add Matter unit tests library
# DEVICE_INFO_EXAMPLE_PROVIDER Add example device info provider support
# PROJECT_CONFIG Path to the project-specific configuration file
#
macro(matter_common_gn_args)
set(options)
set(oneValueArgs
DEBUG
LIB_TESTS
LIB_SHELL
LIB_PW_RPC
DEVICE_INFO_EXAMPLE_PROVIDER
PROJECT_CONFIG
)
set(multiValueArgs)

cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

convert_list_of_flags_to_string_of_flags(MATTER_CFLAGS MATTER_CFLAGS)
convert_list_of_flags_to_string_of_flags(MATTER_CFLAGS_C MATTER_CFLAGS_C)
convert_list_of_flags_to_string_of_flags(MATTER_CFLAGS_CC MATTER_CFLAGS_CC)

if (MATTER_CFLAGS)
matter_add_gn_arg_cflags ("target_cflags" ${MATTER_CFLAGS})
endif() # MATTER_CFLAGS
if (MATTER_CFLAGS_C)
matter_add_gn_arg_cflags ("target_cflags_c" ${MATTER_CFLAGS_C})
endif() # MATTER_CFLAGS_C
if (MATTER_CFLAGS_CC)
matter_add_gn_arg_cflags ("target_cflags_cc" ${MATTER_CFLAGS_CC})
endif() # MATTER_CFLAGS_CC

matter_add_gn_arg_bool ("is_debug" ${ARG_DEBUG})
matter_add_gn_arg_bool ("chip_build_tests" ${ARG_LIB_TESTS})
matter_add_gn_arg_bool ("chip_build_libshell" ${ARG_LIB_SHELL})

if (ARG_LIB_PW_RPC)
matter_add_gn_arg_bool ("chip_build_pw_rpc_lib" ${ARG_LIB_PW_RPC})
endif() # ARG_LIB_PW_RPC
if (ARG_DEVICE_INFO_EXAMPLE_PROVIDER)
matter_add_gn_arg_bool ("chip_build_example_providers" ${ARG_DEVICE_INFO_EXAMPLE_PROVIDER})
endif() # ARG_DEVICE_INFO_EXAMPLE_PROVIDER
if (ARG_PROJECT_CONFIG)
get_filename_component(PROJECT_CONFIG
${ARG_PROJECT_CONFIG}
REALPATH
BASE_DIR ${CMAKE_SOURCE_DIR}
)
matter_add_gn_arg_string("chip_project_config_include" "<${PROJECT_CONFIG}>")
matter_add_gn_arg_string("chip_system_project_config_include" "<${PROJECT_CONFIG}>")
endif() # CHIP_PROJECT_CONFIG
endmacro()

# Generate the temporary GN arguments file from the settings
macro(matter_generate_args_tmp_file)
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/args.tmp" CONTENT ${MATTER_GN_ARGS})
endmacro()
Loading

0 comments on commit 2a9f942

Please sign in to comment.