From 782375c4313564b2e92127b54e02a142efd117f8 Mon Sep 17 00:00:00 2001 From: Lingkai Dong Date: Wed, 21 Apr 2021 18:00:44 +0100 Subject: [PATCH] CMake: Enable improved armclang support in CMake 3.21 CMake versions 3.20 and below always add compiler and linker flags based on `CMAKE_SYSTEM_PROCESSOR`, for example `--cpu=Cortex-M33`. This sometimes overrides flags we set in tools/cmake/cores/*.cmake and results in link failure or unbootable binaries. To workaround this, we added more linker flags to "counter" what CMake automatically adds. From CMake 3.21 onwards, CMake by default does not add flags to armclang anymore, and it fully relies on projects to set all flags. In this case we do not need to set `CMAKE_SYSTEM_PROCESSOR` or use workarounds anymore. We still turn on workarounds when an older version of CMake (3.19 and 3.20) is used, but in the future we might require users to have at least CMake 3.21. --- tools/cmake/app.cmake | 4 +- tools/cmake/cores/Cortex-M33-NS.cmake | 16 ++-- tools/cmake/cores/Cortex-M33.cmake | 16 ++-- tools/cmake/cores/Cortex-M4.cmake | 14 ++-- tools/cmake/mbed_toolchain.cmake | 110 ++++++++++++++++---------- 5 files changed, 99 insertions(+), 61 deletions(-) diff --git a/tools/cmake/app.cmake b/tools/cmake/app.cmake index 60f9f855ff..9f62df8204 100644 --- a/tools/cmake/app.cmake +++ b/tools/cmake/app.cmake @@ -16,7 +16,9 @@ include(mbed_set_post_build) # Load toolchain file if(NOT CMAKE_TOOLCHAIN_FILE OR MBED_TOOLCHAIN_FILE_USED) set(MBED_TOOLCHAIN_FILE_USED TRUE CACHE INTERNAL "") - include(mbed_toolchain) + # We want to bring CMP0123 we set in mbed_toolchain.cmake + # to the whole Mbed OS. + include(mbed_toolchain NO_POLICY_SCOPE) endif() # Specify available build profiles and add options for the selected build profile diff --git a/tools/cmake/cores/Cortex-M33-NS.cmake b/tools/cmake/cores/Cortex-M33-NS.cmake index 8ba132bdd2..e5c3548918 100644 --- a/tools/cmake/cores/Cortex-M33-NS.cmake +++ b/tools/cmake/cores/Cortex-M33-NS.cmake @@ -12,13 +12,15 @@ elseif(${MBED_TOOLCHAIN} STREQUAL "ARM") "-mcpu=cortex-m33+nodsp" "-mfpu=none" ) - list(APPEND link_options - # Necessary as the linker does not always detect - # the architecture from the objectfiles correctly. - # Also, the complete flag should be "--cpu=Cortex-M33.no_dsp.no_fp" - # but this currently conflicts with CMake's compiler test until fixed - "--cpu=Cortex-M33.no_fp" - ) + if(deprecated_system_processor) + # Normally `--cpu` is not needed, because `armlink` can infer + # features from object files. But CMake versions below 3.21 + # automatically add `--cpu=${CMAKE_SYSTEM_PROCESSOR}` which is + # incorrect, so as a workaround we need to add `no_fp`. + list(APPEND link_options + "--cpu=Cortex-M33.no_fp" + ) + endif() endif() function(mbed_set_cpu_core_definitions target) diff --git a/tools/cmake/cores/Cortex-M33.cmake b/tools/cmake/cores/Cortex-M33.cmake index ce9db87db0..ce22f0c5eb 100644 --- a/tools/cmake/cores/Cortex-M33.cmake +++ b/tools/cmake/cores/Cortex-M33.cmake @@ -12,13 +12,15 @@ elseif(${MBED_TOOLCHAIN} STREQUAL "ARM") "-mcpu=cortex-m33+nodsp" "-mfpu=none" ) - list(APPEND link_options - # Necessary as the linker does not always detect - # the architecture from the objectfiles correctly. - # Also, the complete flag should be "--cpu=Cortex-M33.no_dsp.no_fp" - # but this currently conflicts with CMake's compiler test until fixed - "--cpu=Cortex-M33.no_fp" - ) + if(deprecated_system_processor) + # Normally `--cpu` is not needed, because `armlink` can infer + # features from object files. But CMake versions below 3.21 + # automatically add `--cpu=${CMAKE_SYSTEM_PROCESSOR}` which is + # incorrect, so as a workaround we need to add `no_fp`. + list(APPEND link_options + "--cpu=Cortex-M33.no_fp" + ) + endif() endif() function(mbed_set_cpu_core_definitions target) diff --git a/tools/cmake/cores/Cortex-M4.cmake b/tools/cmake/cores/Cortex-M4.cmake index 533da387e9..2245b01cb3 100644 --- a/tools/cmake/cores/Cortex-M4.cmake +++ b/tools/cmake/cores/Cortex-M4.cmake @@ -12,11 +12,15 @@ elseif(${MBED_TOOLCHAIN} STREQUAL "ARM") "-mcpu=cortex-m4" "-mfpu=none" ) -#Necessary as the linker does not always detect -#the architecture from the objectfiles correctly. - list(APPEND link_options - "--cpu=Cortex-M4.no_fp" - ) + if(deprecated_system_processor) + # Normally `--cpu` is not needed, because `armlink` can infer + # features from object files. But CMake versions below 3.21 + # automatically add `--cpu=${CMAKE_SYSTEM_PROCESSOR}` which is + # incorrect, so as a workaround we need to add `no_fp`. + list(APPEND link_options + "--cpu=Cortex-M4.no_fp" + ) + endif() endif() function(mbed_set_cpu_core_definitions target) diff --git a/tools/cmake/mbed_toolchain.cmake b/tools/cmake/mbed_toolchain.cmake index 818aee4bdd..139828921b 100644 --- a/tools/cmake/mbed_toolchain.cmake +++ b/tools/cmake/mbed_toolchain.cmake @@ -22,47 +22,75 @@ function(mbed_generate_options_for_linker target output_response_file_path) file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/compile_time_defs.txt" CONTENT "${_compile_definitions}\n") set(${output_response_file_path} @${CMAKE_CURRENT_BINARY_DIR}/compile_time_defs.txt PARENT_SCOPE) endfunction() -# Set the system processor depending on the CPU core type -if (MBED_CPU_CORE STREQUAL Cortex-A9) - set(CMAKE_SYSTEM_PROCESSOR cortex-a9) -elseif (MBED_CPU_CORE STREQUAL Cortex-A5) - set(CMAKE_SYSTEM_PROCESSOR cortex-a5) -elseif (MBED_CPU_CORE STREQUAL Cortex-M0+) - set(CMAKE_SYSTEM_PROCESSOR cortex-m0plus) -elseif (MBED_CPU_CORE STREQUAL Cortex-M0) - set(CMAKE_SYSTEM_PROCESSOR cortex-m0) -elseif (MBED_CPU_CORE STREQUAL Cortex-M1) - set(CMAKE_SYSTEM_PROCESSOR cortex-m1) -elseif (MBED_CPU_CORE STREQUAL Cortex-M23-NS) - set(CMAKE_SYSTEM_PROCESSOR cortex-m23) -elseif (MBED_CPU_CORE STREQUAL Cortex-M23) - set(CMAKE_SYSTEM_PROCESSOR cortex-m23) -elseif (MBED_CPU_CORE STREQUAL Cortex-M3) - set(CMAKE_SYSTEM_PROCESSOR cortex-m3) -elseif (MBED_CPU_CORE STREQUAL Cortex-M33-NS) - set(CMAKE_SYSTEM_PROCESSOR cortex-m33) -elseif (MBED_CPU_CORE STREQUAL Cortex-M33) - set(CMAKE_SYSTEM_PROCESSOR cortex-m33) -elseif (MBED_CPU_CORE STREQUAL Cortex-M33F-NS) - set(CMAKE_SYSTEM_PROCESSOR cortex-m33) -elseif (MBED_CPU_CORE STREQUAL Cortex-M33F) - set(CMAKE_SYSTEM_PROCESSOR cortex-m33) -elseif (MBED_CPU_CORE STREQUAL Cortex-M33FE-NS) - set(CMAKE_SYSTEM_PROCESSOR cortex-m33) -elseif (MBED_CPU_CORE STREQUAL Cortex-M33FE) - set(CMAKE_SYSTEM_PROCESSOR cortex-m33) -elseif (MBED_CPU_CORE STREQUAL Cortex-M4) - set(CMAKE_SYSTEM_PROCESSOR cortex-m4) -elseif (MBED_CPU_CORE STREQUAL Cortex-M4F) - set(CMAKE_SYSTEM_PROCESSOR cortex-m4) -elseif (MBED_CPU_CORE STREQUAL Cortex-M55) - set(CMAKE_SYSTEM_PROCESSOR cortex-m55) -elseif (MBED_CPU_CORE STREQUAL Cortex-M7) - set(CMAKE_SYSTEM_PROCESSOR cortex-m7) -elseif (MBED_CPU_CORE STREQUAL Cortex-M7F) - set(CMAKE_SYSTEM_PROCESSOR cortex-m7) -elseif (MBED_CPU_CORE STREQUAL Cortex-M7FD) - set(CMAKE_SYSTEM_PROCESSOR cortex-m7) + +# Backward compatibility with older CMake which uses CMAKE_SYSTEM_PROCESSOR to +# automatically add compile and link options for the Arm Compiler. +# Note: From version 3.21, CMake by default (policy CMP0123 set to NEW) does not +# use this macro anymore, and projects have full control over compile and link +# options. This is because the old algorithm based on CMAKE_SYSTEM_PROCESSOR +# is too restrictive and does not support things like Cortex-M33.no_dsp.no_fp. +if(MBED_TOOLCHAIN STREQUAL "ARM") + if(NOT POLICY CMP0123) + # Old versions of CMake do not have CMP0123. + # In the future, support for old versions of CMake will be + # dropped from Mbed OS. + set(deprecated_system_processor ON) + else() + cmake_policy(GET CMP0123 policy_CMP0123) + if("${policy_CMP0123}" STREQUAL "") + # CMP0123 is unset if an old `cmake_minimum_required()` is used with a + # new CMake. Enable new CMP0123 to take advantage of the improvement + # and dismiss deprecation warnings from CMake. + cmake_policy(SET CMP0123 NEW) + elseif("${policy_CMP0123}" STREQUAL "OLD") + # Respect old CMP0123 forced by user application + set(deprecated_system_processor ON) + endif() + endif() +endif() + +if(deprecated_system_processor) + if (MBED_CPU_CORE STREQUAL Cortex-A9) + set(CMAKE_SYSTEM_PROCESSOR cortex-a9) + elseif (MBED_CPU_CORE STREQUAL Cortex-A5) + set(CMAKE_SYSTEM_PROCESSOR cortex-a5) + elseif (MBED_CPU_CORE STREQUAL Cortex-M0+) + set(CMAKE_SYSTEM_PROCESSOR cortex-m0plus) + elseif (MBED_CPU_CORE STREQUAL Cortex-M0) + set(CMAKE_SYSTEM_PROCESSOR cortex-m0) + elseif (MBED_CPU_CORE STREQUAL Cortex-M1) + set(CMAKE_SYSTEM_PROCESSOR cortex-m1) + elseif (MBED_CPU_CORE STREQUAL Cortex-M23-NS) + set(CMAKE_SYSTEM_PROCESSOR cortex-m23) + elseif (MBED_CPU_CORE STREQUAL Cortex-M23) + set(CMAKE_SYSTEM_PROCESSOR cortex-m23) + elseif (MBED_CPU_CORE STREQUAL Cortex-M3) + set(CMAKE_SYSTEM_PROCESSOR cortex-m3) + elseif (MBED_CPU_CORE STREQUAL Cortex-M33-NS) + set(CMAKE_SYSTEM_PROCESSOR cortex-m33) + elseif (MBED_CPU_CORE STREQUAL Cortex-M33) + set(CMAKE_SYSTEM_PROCESSOR cortex-m33) + elseif (MBED_CPU_CORE STREQUAL Cortex-M33F-NS) + set(CMAKE_SYSTEM_PROCESSOR cortex-m33) + elseif (MBED_CPU_CORE STREQUAL Cortex-M33F) + set(CMAKE_SYSTEM_PROCESSOR cortex-m33) + elseif (MBED_CPU_CORE STREQUAL Cortex-M33FE-NS) + set(CMAKE_SYSTEM_PROCESSOR cortex-m33) + elseif (MBED_CPU_CORE STREQUAL Cortex-M33FE) + set(CMAKE_SYSTEM_PROCESSOR cortex-m33) + elseif (MBED_CPU_CORE STREQUAL Cortex-M4) + set(CMAKE_SYSTEM_PROCESSOR cortex-m4) + elseif (MBED_CPU_CORE STREQUAL Cortex-M4F) + set(CMAKE_SYSTEM_PROCESSOR cortex-m4) + elseif (MBED_CPU_CORE STREQUAL Cortex-M55) + set(CMAKE_SYSTEM_PROCESSOR cortex-m55) + elseif (MBED_CPU_CORE STREQUAL Cortex-M7) + set(CMAKE_SYSTEM_PROCESSOR cortex-m7) + elseif (MBED_CPU_CORE STREQUAL Cortex-M7F) + set(CMAKE_SYSTEM_PROCESSOR cortex-m7) + elseif (MBED_CPU_CORE STREQUAL Cortex-M7FD) + set(CMAKE_SYSTEM_PROCESSOR cortex-m7) + endif() endif() # Compiler setup