Merge pull request #10313 from P-I-Engineer/patch-1
[inav.git] / cmake / arm-none-eabi-checks.cmake
blobf31a26c3e3a6f613a84b473ca1e9fdc9f401ad9f
1 include(gcc)
2 set(arm_none_eabi_triplet "arm-none-eabi")
4 # Keep version in sync with the distribution files below
5 set(arm_none_eabi_gcc_version "13.2.1")
6 # This is the output directory "pretty" name and URI name prefix
7 set(base_dir_name "arm-gnu-toolchain-13.2.rel1")
8 # This is the name inside the archive, which is no longer evincible from URI, alas
9 set(archive_base_dir_name "arm-gnu-toolchain-13.2.Rel1")
10 set(arm_none_eabi_base_url "https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/${base_dir_name}")
11 # suffix and checksum
12 set(arm_none_eabi_win32 "mingw-w64-i686-arm-none-eabi.zip" 7fd677088038cdf82f33f149e2e943ee)
13 set(arm_none_eabi_linux_amd64 "x86_64-arm-none-eabi.tar.xz" 791754852f8c18ea04da7139f153a5b7)
14 set(arm_none_eabi_linux_aarch64 "aarch64-arm-none-eabi.tar.xz" 5a08122e6d4caf97c6ccd1d29e62599c)
15 set(arm_none_eabi_darwin_amd64 "darwin-x86_64-arm-none-eabi.tar.xz" 41d49840b0fc676d2ae35aab21a58693)
16 set(arm_none_eabi_darwin_aarch64 "darwin-arm64-arm-none-eabi.tar.xz" 2c43e9d72206c1f81227b0a685df5ea6)
18 function(host_uname_machine var)
19     # We need to call uname -m manually, since at the point
20     # this file is included CMAKE_HOST_SYSTEM_PROCESSOR is
21     # empty because we haven't called project() yet.
22     execute_process(COMMAND uname -m
23         OUTPUT_STRIP_TRAILING_WHITESPACE
24         OUTPUT_VARIABLE machine)
26     set(${var} ${machine} PARENT_SCOPE)
27 endfunction()
29 function(arm_none_eabi_gcc_install)
30     set(dist "")
31     if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
32         set(dist ${arm_none_eabi_win32})
33     elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_HOST_SYSTEM_NAME STREQUAL "FreeBSD")
34         if(NOT CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
35             message("-- no compiler binaries available for ${CMAKE_HOST_SYSTEM_NAME}, using Linux binaries as a fallback")
36         endif()
37         host_uname_machine(machine)
38         # Linux returns x86_64, FreeBSD returns amd64
39         if(machine STREQUAL "x86_64" OR machine STREQUAL "amd64")
40             set(dist ${arm_none_eabi_linux_amd64})
41         elseif(machine STREQUAL "aarch64")
42             set(dist ${arm_none_eabi_linux_aarch64})
43         else()
44             message("-- no precompiled ${arm_none_eabi_triplet} toolchain for machine ${machine}")
45         endif()
46     elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
47         host_uname_machine(machine)
48         if(machine STREQUAL "x86_64" OR machine STREQUAL "amd64")
49             set(dist ${arm_none_eabi_darwin_amd64})
50         elseif(machine STREQUAL "aarch64" OR machine STREQUAL "arm64")
51             set(dist ${arm_none_eabi_darwin_aarch64})
52         else()
53             message("-- no precompiled ${arm_none_eabi_triplet} toolchain for machine ${machine}")
54         endif()
55     endif()
57     if(dist STREQUAL "")
58         message(FATAL_ERROR "could not install ${arm_none_eabi_triplet}-gcc automatically")
59     endif()
60     list(GET dist 0 dist_suffix)
61     list(GET dist 1 dist_checksum)
62     set(dist_url "${arm_none_eabi_base_url}-${dist_suffix}")
63     string(REPLACE "/" ";" url_parts ${dist_url})
64     list(LENGTH url_parts n)
65     math(EXPR last "${n} - 1")
66     list(GET url_parts ${last} basename)
67     set(output "${DOWNLOADS_DIR}/${basename}")
68     message("-- downloading ${arm_none_eabi_triplet}-gcc ${arm_none_eabi_gcc_version} from ${dist_url}")
69     file(DOWNLOAD ${dist_url} ${output}
70         INACTIVITY_TIMEOUT 30
71         STATUS status
72         SHOW_PROGRESS
73         EXPECTED_HASH MD5=${dist_checksum}
74         TLS_VERIFY ON
75     )
76     list(GET status 0 status_code)
77     if(NOT status_code EQUAL 0)
78         list(GET status 1 status_message)
79         message(FATAL_ERROR "error downloading ${basename}: ${status_message}")
80     endif()
81     message("-- extracting ${basename}")
82     execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${TOOLS_DIR})
83     execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf ${output}
84         RESULT_VARIABLE status
85         WORKING_DIRECTORY ${TOOLS_DIR}
86     )
87     if(NOT status EQUAL 0)
88         message(FATAL_ERROR "error extracting ${basename}: ${status}")
89     endif()
90     string(REPLACE "." ";" url_parts ${dist_suffix})
91     list(GET url_parts 0 host_dir_name)
92     set(dir_name "${archive_base_dir_name}-${host_dir_name}")
93     file(REMOVE_RECURSE "${TOOLS_DIR}/${base_dir_name}")
94     file(RENAME  "${TOOLS_DIR}/${dir_name}" "${TOOLS_DIR}/${base_dir_name}")
95     # This is **somewhat ugly**
96     # the newlib distributed by ARM generates suprious warnings from re-entrant POSIX functions
97     # that INAV doesn't use. These "harmless" warnings can be surpressed by removing the
98     # errant section from the only libnosys used by INAV ...
99     # So look the other way ... while this is "fixed"
100     execute_process(COMMAND arm-none-eabi-objcopy -w -R .gnu.warning.* "${TOOLS_DIR}/${base_dir_name}/arm-none-eabi/lib/thumb/v7e-m+fp/hard/libnosys.a"
101       RESULT_VARIABLE status
102       WORKING_DIRECTORY ${TOOLS_DIR}
103     )
104     if(NOT status EQUAL 0)
105         message(FATAL_ERROR "error fixing libnosys.a: ${status}")
106     endif()
107 endfunction()
109 function(arm_none_eabi_gcc_add_path)
110     set(gcc_path "${TOOLS_DIR}/${base_dir_name}/bin")
111     if(CMAKE_HOST_SYSTEM MATCHES ".*Windows.*")
112         set(sep "\\;")
113     else()
114         set(sep ":")
115     endif()
116     set(ENV{PATH} "${gcc_path}${sep}$ENV{PATH}")
117 endfunction()
119 function(arm_none_eabi_gcc_check)
120     gcc_get_version(version
121         TRIPLET ${arm_none_eabi_triplet}
122         PROGRAM_NAME prog
123         PROGRAM_PATH prog_path
124     )
125     if(NOT version)
126         message("-- could not find ${prog}")
127         arm_none_eabi_gcc_install()
128         return()
129     endif()
130     message("-- found ${prog} ${version} at ${prog_path}")
131     if(COMPILER_VERSION_CHECK AND NOT arm_none_eabi_gcc_version STREQUAL version)
132         message("-- expecting ${prog} version ${arm_none_eabi_gcc_version}, but got version ${version} instead")
133         arm_none_eabi_gcc_install()
134         return()
135     endif()
136 endfunction()
138 arm_none_eabi_gcc_add_path()
139 arm_none_eabi_gcc_check()