1#
2# SPDX-License-Identifier: BSD-3-Clause
3# SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4#
5
6find_package(Python3 COMPONENTS Interpreter REQUIRED)
7
8#
9# Set up any necessary Mbed TLS configuration options. In the case of an
10# inability to build the project with the current set of tools, we allow the
11# user to specify an alternative toolchain and generator.
12#
13
14arm_config_option(
15    NAME MbedTLS_TOOLCHAIN_FILE
16    HELP "MbedTLS toolchain file."
17    DEFAULT "${CMAKE_TOOLCHAIN_FILE}"
18    TYPE FILEPATH
19    ADVANCED)
20
21arm_config_option(
22    NAME MbedTLS_GENERATOR
23    HELP "MbedTLS CMake generator."
24    DEFAULT "${CMAKE_GENERATOR}"
25    TYPE STRING
26    ADVANCED)
27
28arm_config_option(
29    NAME MbedTLS_GENERATOR_PLATFORM
30    HELP "MbedTLS CMake generator platform."
31    DEFAULT "${CMAKE_GENERATOR_PLATFORM}"
32    TYPE STRING
33    ADVANCED)
34
35arm_config_option(
36    NAME MbedTLS_GENERATOR_TOOLSET
37    HELP "MbedTLS CMake generator toolset."
38    DEFAULT "${CMAKE_GENERATOR_TOOLSET}"
39    TYPE STRING
40    ADVANCED)
41
42# Set up MbedTLS build type. Default is "Release".
43arm_config_option(
44    NAME MbedTLS_BUILD_TYPE
45    HELP "MbedTLS build type."
46    STRINGS "Release" "Debug")
47
48message(STATUS "MbedTLS_BUILD_TYPE set to ${MbedTLS_BUILD_TYPE}")
49
50#
51# Set up MbedTLS using our own libc. This is done by getting certain properties
52# from our libc target and applying them to MbedTLS - not ideal, but MbedTLS
53# doesn't provide an interface library for us to use.
54#
55
56get_target_property(system_includes rmm-lib-libc
57    INTERFACE_SYSTEM_INCLUDE_DIRECTORIES)
58get_target_property(includes rmm-lib-libc
59    INTERFACE_INCLUDE_DIRECTORIES)
60get_target_property(definitions rmm-lib-libc
61    INTERFACE_COMPILE_DEFINITIONS)
62get_target_property(options rmm-lib-libc
63    INTERFACE_COMPILE_OPTIONS)
64
65#
66# System include directories appear in both the `SYSTEM_INCLUDE_DIRECTORIES` and
67# `INCLUDE_DIRECTORIES` properties, so filter them out of the latter.
68#
69
70list(REMOVE_ITEM includes ${system_includes})
71
72#
73# Target properties that are not set return `<PROPERTY>-NOTFOUND`. Clear any
74# variables where this occurred.
75#
76
77foreach(set IN ITEMS system_includes includes definitions options)
78    if(NOT ${set})
79        set(${set})
80    endif()
81endforeach()
82
83#
84# Add MbedTLS config header file
85#
86
87list(APPEND includes "${RMM_SOURCE_DIR}/configs/mbedtls")
88list(APPEND definitions "MBEDTLS_CONFIG_FILE=\"<mbedtls_config.h>\"")
89
90#
91# Create compiler flags from the libc properties we retrieved.
92#
93
94list(TRANSFORM system_includes PREPEND "-isystem ")
95list(TRANSFORM includes PREPEND "-I ")
96list(TRANSFORM definitions PREPEND "-D ")
97
98foreach(set IN ITEMS system_includes includes definitions options)
99    string(REPLACE ";" " " ${set} "${${set}}")
100endforeach()
101
102string(PREPEND MbedTLS_C_FLAGS "${definitions} ")
103string(PREPEND MbedTLS_C_FLAGS "${system_includes} ")
104string(PREPEND MbedTLS_C_FLAGS "${includes} ")
105string(PREPEND MbedTLS_C_FLAGS "${options} ")
106
107#
108# Unmark some of these configuration options as advanced, in case building fails
109# in the next step and we want to re-expose them to the user.
110#
111
112mark_as_advanced(CLEAR MbedTLS_TOOLCHAIN_FILE)
113mark_as_advanced(CLEAR MbedTLS_GENERATOR)
114mark_as_advanced(CLEAR MbedTLS_GENERATOR_PLATFORM)
115mark_as_advanced(CLEAR MbedTLS_GENERATOR_TOOLSET)
116mark_as_advanced(CLEAR MbedTLS_C_FLAGS)
117
118#
119# Set up the source, binary and install directories.
120#
121
122set(MbedTLS_SOURCE_DIR "${RMM_SOURCE_DIR}/ext/mbedtls")
123set(MbedTLS_INSTALL_DIR "${RMM_BINARY_DIR}/ext/mbedtls")
124set(MbedTLS_BINARY_DIR "${MbedTLS_INSTALL_DIR}${CMAKE_FILES_DIRECTORY}")
125
126#
127# Detect whether we need to reconfigure the CMake cache from the very start,
128# which we need to do if the user has modified certain one-shot options.
129#
130
131if(MbedTLS_TOOLCHAIN_FILE_CHANGED OR
132   MbedTLS_BUILD_TYPE_CHANGED OR
133   MbedTLS_GENERATOR_CHANGED OR
134   MbedTLS_GENERATOR_PLATFORM_CHANGED OR
135   MbedTLS_GENERATOR_TOOLSET_CHANGED)
136    file(REMOVE "${MbedTLS_BINARY_DIR}/CMakeCache.txt")
137endif()
138
139#
140# Configure, build and install the CMake project.
141#
142
143unset(mbedtls_configure)
144
145list(APPEND mbedtls_configure -G "${MbedTLS_GENERATOR}")
146list(APPEND mbedtls_configure -S "${MbedTLS_SOURCE_DIR}")
147list(APPEND mbedtls_configure -B "${MbedTLS_BINARY_DIR}")
148
149if(MbedTLS_GENERATOR_PLATFORM)
150    list(APPEND mbedtls_configure -A "${MbedTLS_GENERATOR_PLATFORM}")
151endif()
152
153if(MbedTLS_GENERATOR_TOOLSET)
154    list(APPEND mbedtls_configure -T "${MbedTLS_GENERATOR_TOOLSET}")
155endif()
156
157list(APPEND mbedtls_configure -D "CMAKE_INSTALL_PREFIX=${MbedTLS_INSTALL_DIR}")
158list(APPEND mbedtls_configure -D "CMAKE_TOOLCHAIN_FILE=${MbedTLS_TOOLCHAIN_FILE}")
159list(APPEND mbedtls_configure -D "ENABLE_PROGRAMS=NO")
160list(APPEND mbedtls_configure -D "ENABLE_TESTING=NO")
161list(APPEND mbedtls_configure -D "CMAKE_C_COMPILER_WORKS=1")
162if(CMAKE_VERBOSE_MAKEFILE)
163    list(APPEND mbedtls_configure -D "CMAKE_VERBOSE_MAKEFILE=1")
164endif()
165
166#
167# Mbed TLS's build system ignores and overwrites the flags we specify in our
168# toolchain files. Un-overwrite them, because they're there for a good reason.
169#
170
171string(TOUPPER ${MbedTLS_BUILD_TYPE} build_type)
172
173if(RMM_FPU_USE_AT_REL2)
174    # Enable using floating point registers for mbed TLS
175    string(REPLACE "-mgeneral-regs-only" "" FP_CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
176    # Enable using crypto and sha instructions
177    string(REGEX REPLACE "(march=[^\\ ]*)" "\\1+sha3+crypto" FP_CMAKE_C_FLAGS ${FP_CMAKE_C_FLAGS})
178    # Enable using SHA256 and SHA512 instructions in MbedTLS
179    string(APPEND FP_CMAKE_C_FLAGS
180            " -DMBEDTLS_SHA256_USE_A64_CRYPTO_ONLY=1 "
181            " -DMBEDTLS_SHA512_USE_A64_CRYPTO_ONLY=1 ")
182else()
183    set(FP_CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
184endif()
185
186list(APPEND mbedtls_configure
187    -D "CMAKE_C_FLAGS=${FP_CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${build_type}} ${MbedTLS_C_FLAGS}")
188
189execute_process(
190    COMMAND "${CMAKE_COMMAND}"
191        ${mbedtls_configure})
192
193execute_process(
194    COMMAND "${CMAKE_COMMAND}"
195        --build "${MbedTLS_BINARY_DIR}"
196        --config "${MbedTLS_BUILD_TYPE}")
197
198execute_process(
199    COMMAND "${CMAKE_COMMAND}"
200        --install "${MbedTLS_BINARY_DIR}"
201        --config "${MbedTLS_BUILD_TYPE}")
202
203#
204# Mark some of the configuration options as advanced if building succeeded.
205#
206
207mark_as_advanced(FORCE MbedTLS_TOOLCHAIN_FILE)
208mark_as_advanced(FORCE MbedTLS_GENERATOR)
209mark_as_advanced(FORCE MbedTLS_GENERATOR_PLATFORM)
210mark_as_advanced(FORCE MbedTLS_GENERATOR_TOOLSET)
211