1+ # Copyright (c) 2021 ARM Limited. All rights reserved.
2+ # SPDX-License-Identifier: Apache-2.0
3+
4+ # This script provides mbed_create_distro(), a function that lets you compile multiple
5+ # apps that use Mbed OS without waiting for Mbed OS to build multiple times.
6+
7+ # You can use it like this:
8+ # mbed_create_distro(mbed_for_my_app mbed-os mbed-storage-kvstore mbed-storage-filesystem)
9+ #
10+ # add_executable(myapp1 MyApp1.cpp)
11+ # target_link_libraries(myapp1 PRIVATE mbed_for_my_app)
12+ # mbed_set_post_build(myapp1)
13+ #
14+ # add_executable(myapp2 MyApp2.cpp)
15+ # target_link_libraries(myapp2 PRIVATE mbed_for_my_app)
16+ # mbed_set_post_build(myapp2)
17+ #
18+ # Both myapp1 and myapp2 will act like they were linked to mbed-os, mbed-storage-kvstore,
19+ # and mbed-storage-filesystem. Note that if you actually did target_link_libraries(myapp1 PRIVATE mbed-os
20+ # mbed-storage-kvstore mbed-storage-filesystem), it would compile a new version of the Mbed OS source
21+ # files for each target. However, using mbed_create_distro(), Mbed OS will only be compiled once.
22+
23+ # Append the value of PROPERTY from SOURCE to the value of PROPERTY on DESTINATION
24+ function (copy_append_property PROPERTY SOURCE DESTINATION )
25+ get_property (PROP_IS_DEFINED TARGET ${SOURCE} PROPERTY ${PROPERTY} SET)
26+ if (PROP_IS_DEFINED)
27+ get_property (PROP_VALUE TARGET ${SOURCE} PROPERTY ${PROPERTY} )
28+ set_property (TARGET ${DESTINATION} APPEND PROPERTY ${PROPERTY} "${PROP_VALUE} " )
29+ endif ()
30+ endfunction (copy_append_property)
31+
32+ # Create a "distribution" of Mbed OS containing the base Mbed and certain modules.
33+ # This distribution only needs to be compiled once and can be referenced in an arbitrary amount of targets.
34+ function (mbed_create_distro NAME ) # ARGN: modules...
35+ add_library (${NAME} OBJECT)
36+ mbed_configure_app_target(${NAME} )
37+
38+ # First link as private dependencies
39+ target_link_libraries (${NAME} PRIVATE ${ARGN} )
40+
41+ # Now copy include dirs, compile defs, and compile options (but NOT interface source files) over
42+ # to the distribution target so they will be passed into things that link to it.
43+ # To do this, we need to recursively traverse the tree of dependencies.
44+ set (REMAINING_MODULES ${ARGN} )
45+ set (COMPLETED_MODULES ${ARGN} )
46+ while (NOT "${REMAINING_MODULES} " STREQUAL "" )
47+
48+ list (GET REMAINING_MODULES 0 CURR_MODULE)
49+
50+ copy_append_property(INTERFACE_COMPILE_DEFINITIONS ${CURR_MODULE} ${NAME} )
51+ copy_append_property(INTERFACE_COMPILE_OPTIONS ${CURR_MODULE} ${NAME} )
52+ copy_append_property(INTERFACE_INCLUDE_DIRECTORIES ${CURR_MODULE} ${NAME} )
53+ copy_append_property(INTERFACE_LINK_OPTIONS ${CURR_MODULE} ${NAME} )
54+
55+ list (REMOVE_AT REMAINING_MODULES 0)
56+ list (APPEND COMPLETED_MODULES ${CURR_MODULE} )
57+
58+ # find sub-modules of this module
59+ get_property (SUBMODULES TARGET ${CURR_MODULE} PROPERTY INTERFACE_LINK_LIBRARIES)
60+ foreach (SUBMODULE ${SUBMODULES} )
61+ if (NOT "${SUBMODULE} " MATCHES "::@" ) # remove CMake internal CMAKE_DIRECTORY_ID_SEP markers
62+ if (NOT ${SUBMODULE} IN_LIST COMPLETED_MODULES)
63+ list (APPEND REMAINING_MODULES ${SUBMODULE} )
64+ endif ()
65+ endif ()
66+ endforeach ()
67+
68+ endwhile ()
69+
70+ endfunction (mbed_create_distro)
0 commit comments