forked from ARMmbed/mbed-os
-
Notifications
You must be signed in to change notification settings - Fork 17
/
CMakeLists.txt
309 lines (257 loc) · 12.8 KB
/
CMakeLists.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
# Copyright (c) 2020-2021 ARM Limited. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
# This is the boilerplate for Mbed OS
cmake_minimum_required(VERSION 3.19.0 FATAL_ERROR)
cmake_policy(VERSION 3.16...3.22)
# Setup build type (target type, tests/unit tests/real build) ----------------------------------------------------------------------------------
# This block sets up the following variables for all subdirs to use:
# - MBED_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_ENABLE_OS_INTERNAL_TESTS: True if we are building *any* internal Mbed OS tests at all. Enabled by -DMBED_ENABLE_TESTING=TRUE (which is enabled by default when standalone).
# - MBED_BUILD_GREENTEA_TESTS: True to build greentea on-target tests. False to build host UNITTESTS. Defaults to false when standalone.
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
# We are the top level project, so tests or unittests are being built.
set(MBED_IS_STANDALONE TRUE)
else()
# Not the top level project
set(MBED_IS_STANDALONE FALSE)
endif()
# Set up options for testing
option(MBED_ENABLE_TESTING "Whether to enable CTest tests in this project" ${MBED_IS_STANDALONE}) # This option is also created by include(CTest) but we need it here earlier on.
if(MBED_IS_STANDALONE AND MBED_ENABLE_TESTING)
set(MBED_ENABLE_OS_INTERNAL_TESTS TRUE)
option(MBED_BUILD_GREENTEA_TESTS "Build greentea tests instead of unit tests" FALSE)
endif()
# Figure out if this is a native build
if(MBED_IS_STANDALONE)
# Standalone build, use MBED_BUILD_GREENTEA_TESTS to determine if we are building for native or not (user can select)
if(MBED_BUILD_GREENTEA_TESTS)
set(MBED_IS_NATIVE_BUILD FALSE)
else()
set(MBED_IS_NATIVE_BUILD TRUE)
endif()
else()
# Building as a subdir. This means that the top-level project will already have called project(), so we can
# rely on CMake's platform detection.
if(CMAKE_CROSSCOMPILING)
set(MBED_IS_NATIVE_BUILD FALSE)
else()
set(MBED_IS_NATIVE_BUILD TRUE)
endif()
endif()
if(MBED_IS_STANDALONE AND NOT MBED_IS_NATIVE_BUILD)
# For standalone builds, default to looking for mbed-config.cmake in the binary dir
set(MBED_CONFIG_PATH ${CMAKE_CURRENT_BINARY_DIR} CACHE STRING "")
# Initialize Mbed build system
include(${CMAKE_CURRENT_LIST_DIR}/tools/cmake/app.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()
include(mbed_set_linker_script)
endif()
# Print build type
if(MBED_ENABLE_OS_INTERNAL_TESTS)
if(MBED_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()
# If this is Mbed CI and we have an upload method file, include it
if(DEFINED MBED_OS_CI_UPLOAD_METHOD_CONFIG)
include(${MBED_OS_CI_UPLOAD_METHOD_CONFIG})
endif()
# Create core Mbed OS targets and set up build flags ----------------------------------------------------------------------------------
# Create project and find compilers (if not already found)
project(mbed-os LANGUAGES C CXX ASM)
# Add all paths to the module files within Mbed OS
list(APPEND CMAKE_MODULE_PATH
${mbed-os_SOURCE_DIR}/platform/FEATURE_EXPERIMENTAL_API/FEATURE_PSA/TARGET_TFM/TARGET_TFM_LATEST/scripts
${mbed-os_SOURCE_DIR}/targets/TARGET_Cypress/scripts
${mbed-os_SOURCE_DIR}/targets/TARGET_NXP/scripts
${mbed-os_SOURCE_DIR}/targets/TARGET_NUVOTON/scripts/
${mbed-os_SOURCE_DIR}/tools/cmake/upload_methods
)
add_subdirectory(extern)
if(MBED_IS_STANDALONE)
include(CTest)
if((NOT MBED_BUILD_GREENTEA_TESTS) AND MBED_ENABLE_TESTING)
# Building unit tests only.
add_definitions(-DUNITTEST)
add_subdirectory(UNITTESTS)
endif()
endif()
if(MBED_ENABLE_TESTING)
include(mbed_greentea)
endif()
# These targets are made visible here so their source files which
# are spread in different directories can be referenced and can be linked against
# by libraries that depend on them.
add_library(mbed-rtos-flags INTERFACE) # Collects source files that are in mbed-os but not mbed-baremetal
add_library(mbed-rtos-sources INTERFACE) # Collects flags that are in mbed-os but not mbed-baremetal
add_library(mbed-core-flags INTERFACE) # Collects flags common to mbed-baremetal and mbed-os
add_library(mbed-core-sources INTERFACE) # Collects source files common to mbed-baremetal and mbed-os
# Validate selected C library type
# The C library type selected has to match the library that the target can support
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)
message(WARNING
"We noticed that target.c_lib is set to `${MBED_C_LIB}`."
" As the ${MBED_TARGET} target does not support a small C library for the ${MBED_TOOLCHAIN} toolchain,"
" we are using the standard C library instead."
)
set(MBED_C_LIB "std" CACHE STRING "")
endif()
endif()
elseif(NOT ${MBED_C_LIB} IN_LIST MBED_TARGET_SUPPORTED_C_LIBS)
message(FATAL_ERROR
"Invalid `target.c_lib` ('${MBED_C_LIB}') for '${MBED_TARGET}' target."
"\nPossible value(s): ${MBED_TARGET_SUPPORTED_C_LIBS}"
)
endif()
# Validate selected printf library
set(MBED_PRINTF_LIB_TYPES std minimal-printf)
if(NOT ${MBED_PRINTF_LIB} IN_LIST MBED_PRINTF_LIB_TYPES)
message(FATAL_ERROR
"Invalid printf library type '${MBED_PRINTF_LIB}'. Possible values:\n ${MBED_PRINTF_LIB_TYPES}"
)
endif()
mbed_set_cpu_core_definitions(mbed-core-flags)
if(${MBED_TOOLCHAIN_FILE_USED})
mbed_set_profile_options(mbed-core-flags ${MBED_TOOLCHAIN})
mbed_set_c_lib(mbed-core-flags ${MBED_C_LIB})
mbed_set_printf_lib(mbed-core-flags ${MBED_PRINTF_LIB})
target_compile_features(mbed-core-flags
INTERFACE
c_std_11
cxx_std_14
)
endif()
target_compile_definitions(mbed-core-flags
INTERFACE
TARGET_NAME=${MBED_TARGET}
)
# Add MBED_TEST_MODE for backward compatibility with Greentea tests written for use with Mbed CLI 1
if(MBED_ENABLE_OS_INTERNAL_TESTS)
if(NOT MBED_BUILD_GREENTEA_TESTS)
target_compile_definitions(${PROJECT_NAME}
INTERFACE
MBED_TEST_MODE
)
endif()
endif()
# We need to generate a "response file" to pass to the C preprocessor when we preprocess the linker
# script, because of path length limitations on Windows. We set the response file and bind the path
# to a global property here. The MBED_TARGET being built queries this global property when it sets
# the linker script.
#
# We must set this global property before the targets subdirectory is added to the project. This is
# required because the MBED_TARGET depends on the response file. If the path to the response file
# is not defined when the target requests it the config definitions will not be passed to CPP.
mbed_generate_options_for_linker(mbed-core-flags RESPONSE_FILE_PATH)
set_property(GLOBAL PROPERTY LINKER_SCRIPT_PREPROCESS_FLAGS_RESPONSE_FILE ${RESPONSE_FILE_PATH})
# Add compile definitions for backward compatibility with the toolchain
# supported. New source files should instead check for __GNUC__ and __clang__
# for the GCC_ARM and ARM toolchains respectively.
if(${MBED_TOOLCHAIN} STREQUAL "GCC_ARM")
target_compile_definitions(mbed-core-flags
INTERFACE
TOOLCHAIN_GCC_ARM
TOOLCHAIN_GCC
)
elseif(${MBED_TOOLCHAIN} STREQUAL "ARM")
target_compile_definitions(mbed-core-flags
INTERFACE
TOOLCHAIN_ARM
)
endif()
# 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_CMAKE_NAME)
string(REPLACE "_" "-" MBED_TARGET_CMAKE_NAME ${MBED_TARGET_CMAKE_NAME})
string(PREPEND MBED_TARGET_CMAKE_NAME "mbed-")
# Load upload method if one is set up
include(UploadMethodManager)
# Load debug config generator for IDEs
include(mbed_ide_debug_cfg_generator)
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
if(NOT MBED_IS_NATIVE_BUILD)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/generated-headers)
mbed_write_target_config_header(${CMAKE_CURRENT_BINARY_DIR}/generated-headers/mbed-target-config.h MBED_TARGET_DEFINITIONS MBED_CONFIG_DEFINITIONS)
target_compile_options(mbed-core-flags INTERFACE -include ${CMAKE_CURRENT_BINARY_DIR}/generated-headers/mbed-target-config.h)
target_include_directories(mbed-core-flags INTERFACE ${CMAKE_CURRENT_BINARY_DIR}/generated-headers)
endif()
# Include mbed.h and config from generate folder
target_include_directories(mbed-core-flags
INTERFACE
${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().
add_subdirectory(targets)
if((NOT MBED_IS_NATIVE_BUILD) AND (NOT TARGET ${MBED_TARGET_CMAKE_NAME}))
message(FATAL_ERROR "CMake target ${MBED_TARGET_CMAKE_NAME} was not found after scanning the mbed-os/targets \
directory. If this is a custom target, you need to define a target called ${MBED_TARGET_CMAKE_NAME} before doing: \
add_subdirectory(mbed-os)")
endif()
if(NOT MBED_IS_NATIVE_BUILD)
# Disable any requested files from the targets/ directory.
mbed_apply_mcu_target_file_disables()
endif()
add_subdirectory(cmsis)
add_subdirectory(drivers)
add_subdirectory(hal)
add_subdirectory(platform)
add_subdirectory(rtos)
add_subdirectory(storage)
add_subdirectory(events)
add_subdirectory(connectivity)
# The directories below contain optional target libraries
add_subdirectory(drivers/device_key EXCLUDE_FROM_ALL)
add_subdirectory(features EXCLUDE_FROM_ALL)
add_subdirectory(cmsis/CMSIS_5/CMSIS/RTOS2 EXCLUDE_FROM_ALL)
add_subdirectory(cmsis/device/rtos EXCLUDE_FROM_ALL)
# Create top-level targets ----------------------------------------------------------------------------------
if(NOT MBED_IS_NATIVE_BUILD)
# Core Mbed OS libraries
# 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_TARGET_CMAKE_NAME} mbed-core-flags mbed-core-sources)
mbed_create_distro(mbed-os ${MBED_TARGET_CMAKE_NAME} mbed-core-flags mbed-core-sources mbed-rtos-flags mbed-rtos-sources)
# Set up the linker script and hook it up to the top-level OS targets
mbed_setup_linker_script(mbed-baremetal mbed-os ${CMAKE_CURRENT_BINARY_DIR}/generated-headers/mbed-target-config.h)
# Make sure that things linking mbed-core-flags can also get the target-specific include dirs and flags.
mbed_extract_flags(${MBED_TARGET_CMAKE_NAME}-flags ${MBED_TARGET_CMAKE_NAME})
target_link_libraries(mbed-core-flags INTERFACE ${MBED_TARGET_CMAKE_NAME}-flags)
endif()
# Ninja requires to be forced for response files
if ("${CMAKE_GENERATOR}" MATCHES "Ninja")
# known issue ARMClang and Ninja with response files for windows
# https://gitlab.kitware.com/cmake/cmake/-/issues/21093
# This gets fixed in newer cmake version
# https://gitlab.kitware.com/cmake/cmake/-/merge_requests/6484
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()
# If this is the top-level buildscript, run finalize tasks
if(MBED_IS_STANDALONE AND (NOT MBED_IS_NATIVE_BUILD))
mbed_finalize_build()
endif()