Compile part of a matter application as static library

This question is analog to  Compile part of application as static library but related to a Matter application. In this case, I'd like to separate the compilation of all Matter/CHIP related application parts from my own application code, e.g., to use strict compiler flags for my own code which fail for the Matter/CHIP application parts.

My CMakeLists.txt looks as follows:

cmake_minimum_required(VERSION 3.20.0)

set(CHIP_CFLAGS
    -DDUMMY_VALUE=0xDEADBEEF
)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(
    Empty
    VERSION 0.1
    DESCRIPTION "empty matter application."
)

include(${ZEPHYR_CONNECTEDHOMEIP_MODULE_DIR}/config/nrfconnect/app/enable-gnu-std.cmake)
include(${ZEPHYR_CONNECTEDHOMEIP_MODULE_DIR}/src/app/chip_data_model.cmake)
set(zap_file    "${CMAKE_CURRENT_SOURCE_DIR}/src/zap/template.zap")
set(zap_gen_dir "${CMAKE_CURRENT_SOURCE_DIR}/src/zap-generated")

target_sources(
    app
    PRIVATE
    <my-sources>
)

target_include_directories(
    app
    PRIVATE
    include
    src
)

chip_configure_data_model(
    app
    INCLUDE_SERVER
    BYPASS_IDL
    GEN_DIR ${zap_gen_dir}
    ZAP_FILE ${zap_file}
)

The last part is the relevant bit: chip_configure_data_model adds files from the Matter/CHIP repository to the given target, in this case still "app". What I'd like to do is the following (only repeating the relevant bits):

<...>

target_sources(
    app
    PRIVATE
    <my-sources>
)

<...>

add_library(app-chip STATIC "")
target_link_libraries(app-chip PUBLIC zephyr_interface)
target_link_libraries(app PUBLIC app-chip)

chip_configure_data_model(
    app-chip
    INCLUDE_SERVER
    BYPASS_IDL
    GEN_DIR ${zap_gen_dir}
    ZAP_FILE ${zap_file}
)

CMake detects the files and adds them to the library "app-chip", but it doesn't find the include paths for the Zephyr module Matter/CHIP. I can resolve it by copying the corresponding part from the "kernel.cmake", but I was wondering if there's a cleaner way to provide the required paths for a module to an application library:

<...>

target_sources(
    app
    PRIVATE
    <my-sources>
)

<...>

add_library(app-chip STATIC "")
target_link_libraries(app-chip PUBLIC zephyr_interface)
target_link_libraries(app PUBLIC app-chip)

get_property(ZEPHYR_INTERFACE_LIBS_PROPERTY GLOBAL PROPERTY ZEPHYR_INTERFACE_LIBS)
foreach(boilerplate_lib ${ZEPHYR_INTERFACE_LIBS_PROPERTY})
  string(TOUPPER ${boilerplate_lib} boilerplate_lib_upper_case)
  target_link_libraries_ifdef(
    CONFIG_APP_LINK_WITH_${boilerplate_lib_upper_case}
    app-chip
    PUBLIC
    ${boilerplate_lib}
    )
endforeach()

chip_configure_data_model(
    app-chip
    INCLUDE_SERVER
    BYPASS_IDL
    GEN_DIR ${zap_gen_dir}
    ZAP_FILE ${zap_file}
)

This isn't very clean since it breaks immediately if "kernel.cmake" or some module setup in Zephyr breaks. Is there something like "target_link_libraries(app-chip PUBLIC zephyr_interface)" for Zephyr modules?

Parents
  • After stumbling through include and linking order problems, this is what I've come up with.

    cmake_minimum_required(VERSION 3.20.0)
    set(CHIP_CFLAGS -DDUMMY_VALUE=0xDEADBEEF)
    
    find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
    project(
        Empty
        VERSION 0.1
        DESCRIPTION "empty matter application."
    )
    include(${ZEPHYR_CONNECTEDHOMEIP_MODULE_DIR}/config/nrfconnect/app/enable-gnu-std.cmake)
    include(${ZEPHYR_CONNECTEDHOMEIP_MODULE_DIR}/src/app/chip_data_model.cmake)
    
    set(zap_file    "${CMAKE_CURRENT_SOURCE_DIR}/src/zap/template.zap")
    set(zap_gen_pwd "${CMAKE_CURRENT_SOURCE_DIR}/src")
    set(zap_gen_dir "${zap_gen_pwd}/zap-generated")
    
    target_sources(app PRIVATE src/main.cpp ...)
    target_include_directories(app PRIVATE include src)
    
    target_compile_options(
        app
        PRIVATE
        # TODO: required since i'm using Matter/CHIP in my "app" files too ...
        "-DCHIP_ADDRESS_RESOLVE_IMPL_INCLUDE_HEADER=<lib/address_resolve/AddressResolve_DefaultImpl.h>"
    )
    
    add_library(app-chip OBJECT "")
    target_include_directories(app-chip PRIVATE ${zap_gen_pwd})
    target_link_libraries(
        app-chip
        PUBLIC
        zephyr
        chip
    )
    
    chip_configure_data_model(
        app-chip
        INCLUDE_SERVER
        BYPASS_IDL
        GEN_DIR ${zap_gen_dir}
        ZAP_FILE ${zap_file}
    )
    
    target_link_libraries(app PUBLIC app-chip)
    

    Sadly, this doesn't help my use case since compiler errors are propagated through includes. And since C++ uses header files for implementation, and since I'm still using Matter/CHIP includes in my sources the compiler screams at me for stuff that I'm not responsible for (shadowed variables, unused parameters, etc.).

    The cleanest solution would of course still be to separate the Matter/CHIP parts into a module or somehow else _completely_ decouple Matter/CHIP from other more strict implementation parts.

Reply
  • After stumbling through include and linking order problems, this is what I've come up with.

    cmake_minimum_required(VERSION 3.20.0)
    set(CHIP_CFLAGS -DDUMMY_VALUE=0xDEADBEEF)
    
    find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
    project(
        Empty
        VERSION 0.1
        DESCRIPTION "empty matter application."
    )
    include(${ZEPHYR_CONNECTEDHOMEIP_MODULE_DIR}/config/nrfconnect/app/enable-gnu-std.cmake)
    include(${ZEPHYR_CONNECTEDHOMEIP_MODULE_DIR}/src/app/chip_data_model.cmake)
    
    set(zap_file    "${CMAKE_CURRENT_SOURCE_DIR}/src/zap/template.zap")
    set(zap_gen_pwd "${CMAKE_CURRENT_SOURCE_DIR}/src")
    set(zap_gen_dir "${zap_gen_pwd}/zap-generated")
    
    target_sources(app PRIVATE src/main.cpp ...)
    target_include_directories(app PRIVATE include src)
    
    target_compile_options(
        app
        PRIVATE
        # TODO: required since i'm using Matter/CHIP in my "app" files too ...
        "-DCHIP_ADDRESS_RESOLVE_IMPL_INCLUDE_HEADER=<lib/address_resolve/AddressResolve_DefaultImpl.h>"
    )
    
    add_library(app-chip OBJECT "")
    target_include_directories(app-chip PRIVATE ${zap_gen_pwd})
    target_link_libraries(
        app-chip
        PUBLIC
        zephyr
        chip
    )
    
    chip_configure_data_model(
        app-chip
        INCLUDE_SERVER
        BYPASS_IDL
        GEN_DIR ${zap_gen_dir}
        ZAP_FILE ${zap_file}
    )
    
    target_link_libraries(app PUBLIC app-chip)
    

    Sadly, this doesn't help my use case since compiler errors are propagated through includes. And since C++ uses header files for implementation, and since I'm still using Matter/CHIP includes in my sources the compiler screams at me for stuff that I'm not responsible for (shadowed variables, unused parameters, etc.).

    The cleanest solution would of course still be to separate the Matter/CHIP parts into a module or somehow else _completely_ decouple Matter/CHIP from other more strict implementation parts.

Children
No Data
Related