diff --git a/.gitignore b/.gitignore index 3e907cf..3d4dce2 100644 --- a/.gitignore +++ b/.gitignore @@ -104,3 +104,6 @@ CMakeFiles/ cmake_build/ Testing/ + +# CLion +cmake-build-*/ \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index f2f5629..f0cbb94 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,23 +4,79 @@ # This is the boilerplate for Mbed OS cmake_minimum_required(VERSION 3.19.0 FATAL_ERROR) +cmake_policy(VERSION 3.16...3.22) -option(BUILD_GREENTEA_TESTS "Build greentea tests only." OFF) +# Setup build type (target type, tests/unit tests/real build) ---------------------------------------------------------------------------------- +# This block sets up the following variables for all subdirs to use: +# - MBED_OS_IS_STANDALONE: True if Mbed OS is the top-level project. False if Mbed is being built as part of an application. +# - MBED_IS_NATIVE_BUILD: True if we are building for the host machine. False if we are building for a microcontroller +# - MBED_OS_ENABLE_TESTS: True if we are building *any* internal Mbed OS tests at all. Enabled by -DBUILD_TESTING=TRUE (which is enabled by default when standalone). +# - BUILD_GREENTEA_TESTS: True to build greentea on-target tests. False to build host UNITTESTS. -if(BUILD_GREENTEA_TESTS) - # Usually we rely on the application to set MBED_CONFIG_PATH and include - # app.cmake. They are both required if we're building an application to run - # on an mbed-target. - set(MBED_CONFIG_PATH ${CMAKE_CURRENT_BINARY_DIR} CACHE STRING "") - # TODO: Remove when https://github.com/ARMmbed/mbed-os/issues/14518 is fixed - include(${CMAKE_CURRENT_LIST_DIR}/tools/cmake/app.cmake) +if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + # We are the top level project, so tests or unittests are being built. + set(MBED_OS_IS_STANDALONE TRUE) +else() + # Not the top level project + set(MBED_OS_IS_STANDALONE FALSE) endif() -if(${CMAKE_CROSSCOMPILING}) +if(CMAKE_CROSSCOMPILING) + set(MBED_IS_NATIVE_BUILD FALSE) +else() + set(MBED_IS_NATIVE_BUILD TRUE) +endif() + +if(MBED_IS_NATIVE_BUILD) + # Pick up some include files that are needed later + list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/tools/cmake) +endif() + +if(MBED_IS_NATIVE_BUILD) + # Pick up some include files that are needed later + list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/tools/cmake) + include(mbed_create_distro) +else() + # Grab the Mbed configs for this target include(${MBED_CONFIG_PATH}/mbed_config.cmake) include(mbed_set_linker_script) endif() +# Set up options for testing +option(BUILD_TESTING "Whether to enable CTest tests in this project" ${MBED_OS_IS_STANDALONE}) # This option is also created by include(CTest) but we need it here earlier on. +if(MBED_OS_IS_STANDALONE AND BUILD_TESTING) + set(MBED_OS_ENABLE_TESTS TRUE) + option(BUILD_GREENTEA_TESTS "Build greentea tests instead of unit tests" ${CMAKE_CROSSCOMPILING}) +endif() + +if(MBED_OS_IS_STANDALONE) + # For standalong builds, look for mbed-config.cmake in the top level mbed os dir + set(MBED_CONFIG_PATH ${CMAKE_CURRENT_BINARY_DIR} CACHE STRING "") +endif() + +if(MBED_IS_NATIVE_BUILD) + # Pick up some include files that are needed later + list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/tools/cmake) + include(mbed_create_distro) +else() + # Grab the Mbed configs for this target + include(${MBED_CONFIG_PATH}/mbed_config.cmake) + include(mbed_set_linker_script) +endif() + +# Print build type +if(MBED_OS_ENABLE_TESTS) + if(BUILD_GREENTEA_TESTS) + message(STATUS "Mbed: Compiling Greentea on-target tests for ${MBED_TARGET}") + else() + message(STATUS "Mbed: Compiling host UNITTESTS for native execution") + endif() +else() + message(STATUS "Mbed: Not building any Mbed OS tests.") +endif() + +# Create core Mbed OS targets and set up build flags ---------------------------------------------------------------------------------- + project(mbed-os) # Add all paths to the list files within Mbed OS @@ -30,7 +86,7 @@ add_subdirectory(extern) -if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME) +if(MBED_OS_IS_STANDALONE) include(CTest) if((NOT BUILD_GREENTEA_TESTS) AND BUILD_TESTING) @@ -49,7 +105,7 @@ # Validate selected C library type # The C library type selected has to match the library that the target can support -if(${CMAKE_CROSSCOMPILING}) +if(NOT MBED_IS_NATIVE_BUILD) if(${MBED_C_LIB} STREQUAL "small") if(NOT "small" IN_LIST MBED_TARGET_SUPPORTED_C_LIBS) if("std" IN_LIST MBED_TARGET_SUPPORTED_C_LIBS) @@ -96,7 +152,7 @@ ) # Add MBED_TEST_MODE for backward compatibility with Greentea tests written for use with Mbed CLI 1 - if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING) + if(MBED_OS_ENABLE_TESTS) if(NOT BUILD_GREENTEA_TESTS) target_compile_definitions(${PROJECT_NAME} INTERFACE @@ -136,9 +192,18 @@ endif() endif() +if(MBED_IS_NATIVE_BUILD) + # Fix issue on Windows with object files hitting a limit for number of sections + if(CMAKE_SYSTEM_NAME STREQUAL "Windows") + add_compile_options(-Wa,-mbig-obj) + endif() +endif() + # Generate target config header and include it in all files -mbed_write_target_config_header(${CMAKE_CURRENT_BINARY_DIR}/mbed-target-config.h MBED_TARGET_DEFINITIONS MBED_CONFIG_DEFINITIONS) -target_compile_options(mbed-core INTERFACE -include ${CMAKE_CURRENT_BINARY_DIR}/mbed-target-config.h) +if(NOT MBED_IS_NATIVE_BUILD) + mbed_write_target_config_header(${CMAKE_CURRENT_BINARY_DIR}/mbed-target-config.h MBED_TARGET_DEFINITIONS MBED_CONFIG_DEFINITIONS) + target_compile_options(mbed-core INTERFACE -include ${CMAKE_CURRENT_BINARY_DIR}/mbed-target-config.h) +endif() # Include mbed.h and config from generate folder target_include_directories(mbed-core @@ -146,6 +211,8 @@ ${CMAKE_CURRENT_SOURCE_DIR} ) +# Recurse to subdirs ---------------------------------------------------------------------------------- + # Include targets/ first, because any post-build hook needs to be defined # before other parts of Mbed OS can add greentea tests which require # mbed_set_post_build(). @@ -167,21 +234,24 @@ add_subdirectory(cmsis/CMSIS_5/CMSIS/RTOS2 EXCLUDE_FROM_ALL) add_subdirectory(cmsis/device/rtos EXCLUDE_FROM_ALL) +# Create top-level targets ---------------------------------------------------------------------------------- -if(${CMAKE_CROSSCOMPILING}) +if(NOT MBED_IS_NATIVE_BUILD) # Ensure the words that make up the Mbed target name are separated with a hyphen, lowercase, and with the `mbed-` prefix. string(TOLOWER ${MBED_TARGET} MBED_TARGET_CONVERTED) string(REPLACE "_" "-" MBED_TARGET_CONVERTED ${MBED_TARGET_CONVERTED}) string(PREPEND MBED_TARGET_CONVERTED "mbed-") endif() -# Core Mbed OS library -# mbed-baremetal contains baremetal sources + target sources + target compile flags. -# mbed-os will be a superset of mbed-baremetal, also containing the RTOS sources and RTOS flags. -# Note that many different source files will compile differently depending on if the RTOS is in use. -# So, it's needed to compile the core sources twice, once for RTOS and once for non-RTOS. -mbed_create_distro(mbed-baremetal mbed-core ${MBED_TARGET_CONVERTED}) -mbed_create_distro(mbed-os mbed-core mbed-rtos ${MBED_TARGET_CONVERTED}) +if(NOT MBED_IS_NATIVE_BUILD) + # Core Mbed OS library + # mbed-baremetal contains baremetal sources + target sources + target compile flags. + # mbed-os will be a superset of mbed-baremetal, also containing the RTOS sources and RTOS flags. + # Note that many different source files will compile differently depending on if the RTOS is in use. + # So, it's needed to compile the core sources twice, once for RTOS and once for non-RTOS. + mbed_create_distro(mbed-baremetal mbed-core ${MBED_TARGET_CONVERTED}) + mbed_create_distro(mbed-os mbed-core mbed-rtos ${MBED_TARGET_CONVERTED}) +endif() # Ninja requires to be forced for response files if ("${CMAKE_GENERATOR}" MATCHES "Ninja") @@ -192,8 +262,4 @@ if((CMAKE_HOST_SYSTEM_NAME MATCHES "Windows") AND ((${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.22.0") OR (NOT CMAKE_CXX_COMPILER_ID MATCHES "ARMClang"))) set(CMAKE_NINJA_FORCE_RESPONSE_FILE 1 CACHE INTERNAL "") endif() -endif() - -# TODO: Remove once all example applications have removed it -function(mbed_configure_app_target target) -endfunction() +endif() \ No newline at end of file diff --git a/cmsis/CMakeLists.txt b/cmsis/CMakeLists.txt index ecfe69c..1dbef1b 100644 --- a/cmsis/CMakeLists.txt +++ b/cmsis/CMakeLists.txt @@ -4,6 +4,6 @@ add_subdirectory(CMSIS_5) add_subdirectory(device) -if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING) +if(MBED_OS_ENABLE_TESTS) add_subdirectory(tests/UNITTESTS/doubles) endif() diff --git a/connectivity/CMakeLists.txt b/connectivity/CMakeLists.txt index 1a3bfd4..edef969 100644 --- a/connectivity/CMakeLists.txt +++ b/connectivity/CMakeLists.txt @@ -24,7 +24,7 @@ add_library(mbed-ppp INTERFACE) add_library(mbed-wifi INTERFACE) -if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING) +if(MBED_OS_ENABLE_TESTS) # Add these subdirectories for tests add_subdirectory(cellular) add_subdirectory(drivers) diff --git a/connectivity/FEATURE_BLE/CMakeLists.txt b/connectivity/FEATURE_BLE/CMakeLists.txt index fbd35db..2cb86ee 100644 --- a/connectivity/FEATURE_BLE/CMakeLists.txt +++ b/connectivity/FEATURE_BLE/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) 2020 ARM Limited. All rights reserved. # SPDX-License-Identifier: Apache-2.0 -if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING) +if(MBED_OS_ENABLE_TESTS) if(NOT BUILD_GREENTEA_TESTS) add_subdirectory(tests/UNITTESTS) endif() diff --git a/connectivity/cellular/CMakeLists.txt b/connectivity/cellular/CMakeLists.txt index 1c87aed..1128385 100644 --- a/connectivity/cellular/CMakeLists.txt +++ b/connectivity/cellular/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) 2020 ARM Limited. All rights reserved. # SPDX-License-Identifier: Apache-2.0 -if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING) +if(MBED_OS_ENABLE_TESTS) if(BUILD_GREENTEA_TESTS) # add greentea test else() diff --git a/connectivity/libraries/CMakeLists.txt b/connectivity/libraries/CMakeLists.txt index 21af84b..d47bbda 100644 --- a/connectivity/libraries/CMakeLists.txt +++ b/connectivity/libraries/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) 2020 ARM Limited. All rights reserved. # SPDX-License-Identifier: Apache-2.0 -if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING) +if(MBED_OS_ENABLE_TESTS) if(NOT BUILD_GREENTEA_TESTS) add_subdirectory(tests/UNITTESTS) endif() diff --git a/connectivity/lorawan/CMakeLists.txt b/connectivity/lorawan/CMakeLists.txt index d30bdac..9e5a5dc 100644 --- a/connectivity/lorawan/CMakeLists.txt +++ b/connectivity/lorawan/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) 2020 ARM Limited. All rights reserved. # SPDX-License-Identifier: Apache-2.0 -if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING) +if(MBED_OS_ENABLE_TESTS) if(BUILD_GREENTEA_TESTS) # add greentea test else() diff --git a/connectivity/mbedtls/CMakeLists.txt b/connectivity/mbedtls/CMakeLists.txt index 7bacaa6..68e7e4c 100644 --- a/connectivity/mbedtls/CMakeLists.txt +++ b/connectivity/mbedtls/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) 2020 ARM Limited. All rights reserved. # SPDX-License-Identifier: Apache-2.0 -if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING) +if(MBED_OS_ENABLE_TESTS) if(NOT BUILD_GREENTEA_TESTS) add_subdirectory(tests/UNITTESTS) endif() diff --git a/connectivity/netsocket/CMakeLists.txt b/connectivity/netsocket/CMakeLists.txt index d9748a1..5f463d3 100644 --- a/connectivity/netsocket/CMakeLists.txt +++ b/connectivity/netsocket/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) 2020 ARM Limited. All rights reserved. # SPDX-License-Identifier: Apache-2.0 -if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING) +if(MBED_OS_ENABLE_TESTS) if(BUILD_GREENTEA_TESTS) # add greentea test else() diff --git a/connectivity/nfc/CMakeLists.txt b/connectivity/nfc/CMakeLists.txt index a1c48ac..79964e3 100644 --- a/connectivity/nfc/CMakeLists.txt +++ b/connectivity/nfc/CMakeLists.txt @@ -3,7 +3,7 @@ add_subdirectory(libraries) -if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING) +if(MBED_OS_ENABLE_TESTS) if(BUILD_GREENTEA_TESTS) add_subdirectory(tests/TESTS) endif() diff --git a/drivers/CMakeLists.txt b/drivers/CMakeLists.txt index a0b5fea..0e92b77 100644 --- a/drivers/CMakeLists.txt +++ b/drivers/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) 2020 ARM Limited. All rights reserved. # SPDX-License-Identifier: Apache-2.0 -if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING) +if(MBED_OS_ENABLE_TESTS) if(BUILD_GREENTEA_TESTS) add_subdirectory(tests/TESTS) else() diff --git a/events/CMakeLists.txt b/events/CMakeLists.txt index 6e7a6c6..99feb99 100644 --- a/events/CMakeLists.txt +++ b/events/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) 2020 ARM Limited. All rights reserved. # SPDX-License-Identifier: Apache-2.0 -if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING) +if(MBED_OS_ENABLE_TESTS) if(BUILD_GREENTEA_TESTS) # add greentea test else() diff --git a/hal/CMakeLists.txt b/hal/CMakeLists.txt index 3af169e..8e1b090 100644 --- a/hal/CMakeLists.txt +++ b/hal/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) 2020-2021 ARM Limited. All rights reserved. # SPDX-License-Identifier: Apache-2.0 -if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING) +if(MBED_OS_ENABLE_TESTS) if(BUILD_GREENTEA_TESTS) # add greentea test else() diff --git a/platform/CMakeLists.txt b/platform/CMakeLists.txt index 8d03c0d..4831804 100644 --- a/platform/CMakeLists.txt +++ b/platform/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) 2020 ARM Limited. All rights reserved. # SPDX-License-Identifier: Apache-2.0 -if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING) +if(MBED_OS_ENABLE_TESTS) if(BUILD_GREENTEA_TESTS) add_subdirectory(tests/TESTS) else() diff --git a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/CMakeLists.txt b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/CMakeLists.txt index ab07695..d1acd89 100644 --- a/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/CMakeLists.txt +++ b/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_MBED_PSA_SRV/CMakeLists.txt @@ -73,7 +73,7 @@ add_subdirectory(test_abstraction_layers) -if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING) +if(MBED_OS_ENABLE_TESTS) if(BUILD_GREENTEA_TESTS) add_subdirectory(TESTS) endif() diff --git a/platform/tests/UNITTESTS/doubles/platform/mbed_retarget.h b/platform/tests/UNITTESTS/doubles/platform/mbed_retarget.h index e99d421..5662a8e 100644 --- a/platform/tests/UNITTESTS/doubles/platform/mbed_retarget.h +++ b/platform/tests/UNITTESTS/doubles/platform/mbed_retarget.h @@ -18,7 +18,7 @@ #ifndef RETARGET_H #define RETARGET_H -#include +#include #include #include diff --git a/rtos/CMakeLists.txt b/rtos/CMakeLists.txt index 2f32976..3f1f9f6 100644 --- a/rtos/CMakeLists.txt +++ b/rtos/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) 2020 ARM Limited. All rights reserved. # SPDX-License-Identifier: Apache-2.0 -if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING) +if(MBED_OS_ENABLE_TESTS) if(BUILD_GREENTEA_TESTS) add_subdirectory(tests/TESTS) else() diff --git a/storage/blockdevice/CMakeLists.txt b/storage/blockdevice/CMakeLists.txt index 8b77f0f..cf10ad3 100644 --- a/storage/blockdevice/CMakeLists.txt +++ b/storage/blockdevice/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) 2020 ARM Limited. All rights reserved. # SPDX-License-Identifier: Apache-2.0 -if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING) +if(MBED_OS_ENABLE_TESTS) if(BUILD_GREENTEA_TESTS) # add greentea test else() diff --git a/storage/blockdevice/COMPONENT_QSPIF/CMakeLists.txt b/storage/blockdevice/COMPONENT_QSPIF/CMakeLists.txt index 54b7d11..22f0de6 100644 --- a/storage/blockdevice/COMPONENT_QSPIF/CMakeLists.txt +++ b/storage/blockdevice/COMPONENT_QSPIF/CMakeLists.txt @@ -12,7 +12,7 @@ source/QSPIFBlockDevice.cpp ) -if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING) +if(MBED_OS_ENABLE_TESTS) if (NOT BUILD_GREENTEA_TESTS) add_subdirectory(UNITTESTS) endif() diff --git a/storage/filesystem/CMakeLists.txt b/storage/filesystem/CMakeLists.txt index 5d6fca3..c2b2f4f 100644 --- a/storage/filesystem/CMakeLists.txt +++ b/storage/filesystem/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) 2020 ARM Limited. All rights reserved. # SPDX-License-Identifier: Apache-2.0 -if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING) +if(MBED_OS_ENABLE_TESTS) if(BUILD_GREENTEA_TESTS) # add greentea test else() diff --git a/storage/kvstore/CMakeLists.txt b/storage/kvstore/CMakeLists.txt index 1d0feee..dfb078a 100644 --- a/storage/kvstore/CMakeLists.txt +++ b/storage/kvstore/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) 2020 ARM Limited. All rights reserved. # SPDX-License-Identifier: Apache-2.0 -if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING) +if(MBED_OS_ENABLE_TESTS) if(BUILD_GREENTEA_TESTS) # add greentea test else() diff --git a/storage/kvstore/filesystemstore/CMakeLists.txt b/storage/kvstore/filesystemstore/CMakeLists.txt index 49b2d34..70453fd 100644 --- a/storage/kvstore/filesystemstore/CMakeLists.txt +++ b/storage/kvstore/filesystemstore/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) 2020 ARM Limited. All rights reserved. # SPDX-License-Identifier: Apache-2.0 -if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING) +if(MBED_OS_ENABLE_TESTS) if(BUILD_GREENTEA_TESTS) # add greentea test else() diff --git a/storage/kvstore/tdbstore/CMakeLists.txt b/storage/kvstore/tdbstore/CMakeLists.txt index 82cd283..f324732 100644 --- a/storage/kvstore/tdbstore/CMakeLists.txt +++ b/storage/kvstore/tdbstore/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (c) 2020 ARM Limited. All rights reserved. # SPDX-License-Identifier: Apache-2.0 -if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING) +if(MBED_OS_ENABLE_TESTS) if(BUILD_GREENTEA_TESTS) # add greentea test else() diff --git a/tools/cmake/create_distro.cmake b/tools/cmake/create_distro.cmake deleted file mode 100644 index c4f396b..0000000 --- a/tools/cmake/create_distro.cmake +++ /dev/null @@ -1,69 +0,0 @@ -# Copyright (c) 2021 ARM Limited. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 - -# This script provides mbed_create_distro(), a function that lets you compile multiple -# apps that use Mbed OS without waiting for Mbed OS to build multiple times. - -# You can use it like this: -# mbed_create_distro(mbed_for_my_app mbed-os mbed-storage-kvstore mbed-storage-filesystem) -# -# add_executable(myapp1 MyApp1.cpp) -# target_link_libraries(myapp1 PRIVATE mbed_for_my_app) -# mbed_set_post_build(myapp1) -# -# add_executable(myapp2 MyApp2.cpp) -# target_link_libraries(myapp2 PRIVATE mbed_for_my_app) -# mbed_set_post_build(myapp2) -# -# Both myapp1 and myapp2 will act like they were linked to mbed-os, mbed-storage-kvstore, -# and mbed-storage-filesystem. Note that if you actually did target_link_libraries(myapp1 PRIVATE mbed-os -# mbed-storage-kvstore mbed-storage-filesystem), it would compile a new version of the Mbed OS source -# files for each target. However, using mbed_create_distro(), Mbed OS will only be compiled once. - -# Append the value of PROPERTY from SOURCE to the value of PROPERTY on DESTINATION -function(copy_append_property PROPERTY SOURCE DESTINATION) - get_property(PROP_IS_DEFINED TARGET ${SOURCE} PROPERTY ${PROPERTY} SET) - if(PROP_IS_DEFINED) - get_property(PROP_VALUE TARGET ${SOURCE} PROPERTY ${PROPERTY}) - set_property(TARGET ${DESTINATION} APPEND PROPERTY ${PROPERTY} "${PROP_VALUE}") - endif() -endfunction(copy_append_property) - -# Create a "distribution" of Mbed OS containing the base Mbed and certain modules. -# This distribution only needs to be compiled once and can be referenced in an arbitrary amount of targets. -function(mbed_create_distro NAME) # ARGN: modules... - add_library(${NAME} OBJECT EXCLUDE_FROM_ALL) - - # First link as private dependencies - target_link_libraries(${NAME} PRIVATE ${ARGN}) - - # Now copy include dirs, compile defs, and compile options (but NOT interface source files) over - # to the distribution target so they will be passed into things that link to it. - # To do this, we need to recursively traverse the tree of dependencies. - set(REMAINING_MODULES ${ARGN}) - set(COMPLETED_MODULES ${ARGN}) - while(NOT "${REMAINING_MODULES}" STREQUAL "") - - list(GET REMAINING_MODULES 0 CURR_MODULE) - - copy_append_property(INTERFACE_COMPILE_DEFINITIONS ${CURR_MODULE} ${NAME}) - copy_append_property(INTERFACE_COMPILE_OPTIONS ${CURR_MODULE} ${NAME}) - copy_append_property(INTERFACE_INCLUDE_DIRECTORIES ${CURR_MODULE} ${NAME}) - copy_append_property(INTERFACE_LINK_OPTIONS ${CURR_MODULE} ${NAME}) - - list(REMOVE_AT REMAINING_MODULES 0) - list(APPEND COMPLETED_MODULES ${CURR_MODULE}) - - # find sub-modules of this module - get_property(SUBMODULES TARGET ${CURR_MODULE} PROPERTY INTERFACE_LINK_LIBRARIES) - foreach(SUBMODULE ${SUBMODULES}) - if(NOT "${SUBMODULE}" MATCHES "::@") # remove CMake internal CMAKE_DIRECTORY_ID_SEP markers - if(NOT ${SUBMODULE} IN_LIST COMPLETED_MODULES) - list(APPEND REMAINING_MODULES ${SUBMODULE}) - endif() - endif() - endforeach() - - endwhile() - -endfunction(mbed_create_distro) \ No newline at end of file diff --git a/tools/cmake/mbed_create_distro.cmake b/tools/cmake/mbed_create_distro.cmake new file mode 100644 index 0000000..c4f396b --- /dev/null +++ b/tools/cmake/mbed_create_distro.cmake @@ -0,0 +1,69 @@ +# Copyright (c) 2021 ARM Limited. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +# This script provides mbed_create_distro(), a function that lets you compile multiple +# apps that use Mbed OS without waiting for Mbed OS to build multiple times. + +# You can use it like this: +# mbed_create_distro(mbed_for_my_app mbed-os mbed-storage-kvstore mbed-storage-filesystem) +# +# add_executable(myapp1 MyApp1.cpp) +# target_link_libraries(myapp1 PRIVATE mbed_for_my_app) +# mbed_set_post_build(myapp1) +# +# add_executable(myapp2 MyApp2.cpp) +# target_link_libraries(myapp2 PRIVATE mbed_for_my_app) +# mbed_set_post_build(myapp2) +# +# Both myapp1 and myapp2 will act like they were linked to mbed-os, mbed-storage-kvstore, +# and mbed-storage-filesystem. Note that if you actually did target_link_libraries(myapp1 PRIVATE mbed-os +# mbed-storage-kvstore mbed-storage-filesystem), it would compile a new version of the Mbed OS source +# files for each target. However, using mbed_create_distro(), Mbed OS will only be compiled once. + +# Append the value of PROPERTY from SOURCE to the value of PROPERTY on DESTINATION +function(copy_append_property PROPERTY SOURCE DESTINATION) + get_property(PROP_IS_DEFINED TARGET ${SOURCE} PROPERTY ${PROPERTY} SET) + if(PROP_IS_DEFINED) + get_property(PROP_VALUE TARGET ${SOURCE} PROPERTY ${PROPERTY}) + set_property(TARGET ${DESTINATION} APPEND PROPERTY ${PROPERTY} "${PROP_VALUE}") + endif() +endfunction(copy_append_property) + +# Create a "distribution" of Mbed OS containing the base Mbed and certain modules. +# This distribution only needs to be compiled once and can be referenced in an arbitrary amount of targets. +function(mbed_create_distro NAME) # ARGN: modules... + add_library(${NAME} OBJECT EXCLUDE_FROM_ALL) + + # First link as private dependencies + target_link_libraries(${NAME} PRIVATE ${ARGN}) + + # Now copy include dirs, compile defs, and compile options (but NOT interface source files) over + # to the distribution target so they will be passed into things that link to it. + # To do this, we need to recursively traverse the tree of dependencies. + set(REMAINING_MODULES ${ARGN}) + set(COMPLETED_MODULES ${ARGN}) + while(NOT "${REMAINING_MODULES}" STREQUAL "") + + list(GET REMAINING_MODULES 0 CURR_MODULE) + + copy_append_property(INTERFACE_COMPILE_DEFINITIONS ${CURR_MODULE} ${NAME}) + copy_append_property(INTERFACE_COMPILE_OPTIONS ${CURR_MODULE} ${NAME}) + copy_append_property(INTERFACE_INCLUDE_DIRECTORIES ${CURR_MODULE} ${NAME}) + copy_append_property(INTERFACE_LINK_OPTIONS ${CURR_MODULE} ${NAME}) + + list(REMOVE_AT REMAINING_MODULES 0) + list(APPEND COMPLETED_MODULES ${CURR_MODULE}) + + # find sub-modules of this module + get_property(SUBMODULES TARGET ${CURR_MODULE} PROPERTY INTERFACE_LINK_LIBRARIES) + foreach(SUBMODULE ${SUBMODULES}) + if(NOT "${SUBMODULE}" MATCHES "::@") # remove CMake internal CMAKE_DIRECTORY_ID_SEP markers + if(NOT ${SUBMODULE} IN_LIST COMPLETED_MODULES) + list(APPEND REMAINING_MODULES ${SUBMODULE}) + endif() + endif() + endforeach() + + endwhile() + +endfunction(mbed_create_distro) \ No newline at end of file