FindHAL.cmake 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. # For information about why and how of this file: https://cmake.org/cmake/help/latest/command/find_package.html
  2. # This function gets a list of hal_driver using a given prefix and suffix
  3. #
  4. # out_list_hal_drivers list of hal_drivers found
  5. # hal_drivers_path path to the hal's drivers
  6. # hal_driver_type hal_driver type to find (hal/ll/ex)
  7. function(get_list_hal_drivers out_list_hal_drivers hal_drivers_path hal_driver_type)
  8. #The pattern to retrieve a driver from a file name depends on the hal_driver_type field
  9. if(${hal_driver_type} STREQUAL "hal" OR ${hal_driver_type} STREQUAL "ll")
  10. #This regex match and capture a driver type (stm32xx_hal_(rcc).c or stm32xx_ll_(rcc).c => catches rcc)
  11. set(file_pattern ".+_${hal_driver_type}_([a-z0-9]+)\\.c$")
  12. elseif(${hal_driver_type} STREQUAL "ex")
  13. #This regex match and capture a driver type (stm32xx_hal_(rcc)_ex.c => catches rcc)
  14. set(file_pattern ".+_hal_([a-z0-9]+)_ex\\.c$")
  15. else()
  16. message(FATAL_ERROR "the inputed hal_driver_type(${hal_driver_type}) is not valid.")
  17. endif()
  18. #Retrieving all the .c files from hal_drivers_path
  19. file(GLOB filtered_files
  20. RELATIVE "${hal_drivers_path}/Src"
  21. "${hal_drivers_path}/Src/*.c")
  22. # For all matched .c files keep only those with a driver name pattern (e.g. stm32xx_hal_rcc.c)
  23. list(FILTER filtered_files INCLUDE REGEX ${file_pattern})
  24. # From the files names keep only the driver type part using the regex (stm32xx_hal_(rcc).c or stm32xx_ll_(rcc).c => catches rcc)
  25. list(TRANSFORM filtered_files REPLACE ${file_pattern} "\\1")
  26. #Making a return by reference by seting the output variable to PARENT_SCOPE
  27. set(${out_list_hal_drivers} ${filtered_files} PARENT_SCOPE)
  28. endfunction()
  29. ################################################################################
  30. # Checking the parameters provided to the find_package(HAL ...) call
  31. # The expected parameters are families and or drivers in *any orders*
  32. # Families are valid if on the list of known families.
  33. # Drivers are valid if on the list of valid driver of any family. For this
  34. # reason the requested families must be processed in two steps
  35. # - Step 1 : Checking all the requested families
  36. # - Step 2 : Generating all the valid drivers from requested families
  37. # - Step 3 : Checking the other requested components (Expected to be drivers)
  38. ################################################################################
  39. # Step 1 : Checking all the requested families
  40. foreach(COMP ${HAL_FIND_COMPONENTS})
  41. string(TOUPPER ${COMP} COMP_U)
  42. string(REGEX MATCH "^STM32([CFGHLMUW]P?[0-9BL])([0-9A-Z][0-9M][A-Z][0-9A-Z])?_?(M0PLUS|M4|M7)?.*$" COMP_U ${COMP_U})
  43. if(CMAKE_MATCH_1) #Matches the family part of the provided STM32<FAMILY>[..] component
  44. list(APPEND HAL_FIND_COMPONENTS_FAMILIES ${COMP})
  45. message(TRACE "FindHAL: append COMP ${COMP} to HAL_FIND_COMPONENTS_FAMILIES")
  46. else()
  47. list(APPEND HAL_FIND_COMPONENTS_UNHANDLED ${COMP})
  48. endif()
  49. endforeach()
  50. # If no family requested look for all families
  51. if(NOT HAL_FIND_COMPONENTS_FAMILIES)
  52. set(HAL_FIND_COMPONENTS_FAMILIES ${STM32_SUPPORTED_FAMILIES_LONG_NAME})
  53. endif()
  54. # Step 2 : Generating all the valid drivers from requested families
  55. foreach(family_comp ${HAL_FIND_COMPONENTS_FAMILIES})
  56. string(TOUPPER ${family_comp} family_comp)
  57. string(REGEX MATCH "^STM32([CFGHLMUW]P?[0-9BL])([0-9A-Z][0-9M][A-Z][0-9A-Z])?_?(M0PLUS|M4|M7)?.*$" family_comp ${family_comp})
  58. if(CMAKE_MATCH_1) #Matches the family part of the provided STM32<FAMILY>[..] component
  59. set(FAMILY ${CMAKE_MATCH_1})
  60. string(TOLOWER ${FAMILY} FAMILY_L)
  61. endif()
  62. find_path(HAL_${FAMILY}_PATH
  63. NAMES Inc/stm32${FAMILY_L}xx_hal.h
  64. PATHS "${STM32_HAL_${FAMILY}_PATH}" "${STM32_CUBE_${FAMILY}_PATH}/Drivers/STM32${FAMILY}xx_HAL_Driver"
  65. NO_DEFAULT_PATH
  66. )
  67. if(NOT HAL_${FAMILY}_PATH)
  68. message(FATAL_ERROR "could not find HAL for family ${FAMILY}")
  69. else()
  70. set(HAL_${family_comp}_FOUND TRUE)
  71. endif()
  72. if(CMAKE_MATCH_1) #Matches the family part of the provided STM32<FAMILY>[..] component
  73. get_list_hal_drivers(HAL_DRIVERS_${FAMILY} ${HAL_${FAMILY}_PATH} "hal")
  74. get_list_hal_drivers(HAL_EX_DRIVERS_${FAMILY} ${HAL_${FAMILY}_PATH} "ex")
  75. get_list_hal_drivers(HAL_LL_DRIVERS_${FAMILY} ${HAL_${FAMILY}_PATH} "ll")
  76. list(APPEND HAL_DRIVERS ${HAL_DRIVERS_${FAMILY}})
  77. list(APPEND HAL_LL_DRIVERS ${HAL_LL_DRIVERS_${FAMILY}})
  78. else()
  79. endif()
  80. endforeach()
  81. list(REMOVE_DUPLICATES HAL_DRIVERS)
  82. list(REMOVE_DUPLICATES HAL_LL_DRIVERS)
  83. # Step 3 : Checking the other requested components (Expected to be drivers)
  84. foreach(COMP ${HAL_FIND_COMPONENTS_UNHANDLED})
  85. string(TOLOWER ${COMP} COMP_L)
  86. if(${COMP_L} IN_LIST HAL_DRIVERS)
  87. list(APPEND HAL_FIND_COMPONENTS_DRIVERS ${COMP})
  88. message(TRACE "FindHAL: append COMP ${COMP} to HAL_FIND_COMPONENTS_DRIVERS")
  89. continue()
  90. endif()
  91. string(REGEX REPLACE "^ll_" "" COMP_L ${COMP_L})
  92. if(${COMP_L} IN_LIST HAL_LL_DRIVERS)
  93. list(APPEND HAL_FIND_COMPONENTS_DRIVERS_LL ${COMP})
  94. message(TRACE "FindHAL: append COMP ${COMP} to HAL_FIND_COMPONENTS_DRIVERS_LL")
  95. continue()
  96. endif()
  97. message(FATAL_ERROR "FindHAL: unknown HAL component: ${COMP}")
  98. endforeach()
  99. if(STM32H7 IN_LIST HAL_FIND_COMPONENTS_FAMILIES)
  100. list(REMOVE_ITEM HAL_FIND_COMPONENTS_FAMILIES STM32H7)
  101. list(APPEND HAL_FIND_COMPONENTS_FAMILIES STM32H7_M7 STM32H7_M4)
  102. endif()
  103. if(STM32WB IN_LIST HAL_FIND_COMPONENTS_FAMILIES)
  104. list(REMOVE_ITEM HAL_FIND_COMPONENTS_FAMILIES STM32WB)
  105. list(APPEND HAL_FIND_COMPONENTS_FAMILIES STM32WB_M4)
  106. endif()
  107. if(STM32WL IN_LIST HAL_FIND_COMPONENTS_FAMILIES)
  108. list(REMOVE_ITEM HAL_FIND_COMPONENTS_FAMILIES STM32WL)
  109. list(APPEND HAL_FIND_COMPONENTS_FAMILIES STM32WL_M4 STM32WL_M0PLUS)
  110. endif()
  111. if(STM32MP1 IN_LIST HAL_FIND_COMPONENTS_FAMILIES)
  112. list(REMOVE_ITEM HAL_FIND_COMPONENTS_FAMILIES STM32MP1)
  113. list(APPEND HAL_FIND_COMPONENTS_FAMILIES STM32MP1_M4)
  114. endif()
  115. list(REMOVE_DUPLICATES HAL_FIND_COMPONENTS_FAMILIES)
  116. # when no explicit driver and driver_ll is given to find_component(HAL )
  117. # then search for all supported driver and driver_ll
  118. if((NOT HAL_FIND_COMPONENTS_DRIVERS) AND (NOT HAL_FIND_COMPONENTS_DRIVERS_LL))
  119. set(HAL_FIND_COMPONENTS_DRIVERS ${HAL_DRIVERS})
  120. set(HAL_FIND_COMPONENTS_DRIVERS_LL ${HAL_LL_DRIVERS})
  121. endif()
  122. list(REMOVE_DUPLICATES HAL_FIND_COMPONENTS_DRIVERS)
  123. list(REMOVE_DUPLICATES HAL_FIND_COMPONENTS_DRIVERS_LL)
  124. message(STATUS "Search for HAL families: ${HAL_FIND_COMPONENTS_FAMILIES}")
  125. message(STATUS "Search for HAL drivers: ${HAL_FIND_COMPONENTS_DRIVERS}")
  126. message(STATUS "Search for HAL LL drivers: ${HAL_FIND_COMPONENTS_DRIVERS_LL}")
  127. foreach(COMP ${HAL_FIND_COMPONENTS_FAMILIES})
  128. string(TOUPPER ${COMP} COMP_U)
  129. string(REGEX MATCH "^STM32([CFGHLMUW]P?[0-9BL])([0-9A-Z][0-9M][A-Z][0-9A-Z])?_?(M0PLUS|M4|M7)?.*$" COMP_U ${COMP_U})
  130. if(CMAKE_MATCH_3)
  131. set(CORE ${CMAKE_MATCH_3})
  132. set(CORE_C "::${CORE}")
  133. set(CORE_U "_${CORE}")
  134. else()
  135. unset(CORE)
  136. unset(CORE_C)
  137. unset(CORE_U)
  138. endif()
  139. set(FAMILY ${CMAKE_MATCH_1})
  140. string(TOLOWER ${FAMILY} FAMILY_L)
  141. if((NOT STM32_HAL_${FAMILY}_PATH) AND (NOT STM32_CUBE_${FAMILY}_PATH) AND (DEFINED ENV{STM32_CUBE_${FAMILY}_PATH}))
  142. set(STM32_CUBE_${FAMILY}_PATH $ENV{STM32_CUBE_${FAMILY}_PATH} CACHE PATH "Path to STM32Cube${FAMILY}")
  143. message(STATUS "ENV STM32_CUBE_${FAMILY}_PATH specified, using STM32_CUBE_${FAMILY}_PATH: ${STM32_CUBE_${FAMILY}_PATH}")
  144. endif()
  145. if((NOT STM32_HAL_${FAMILY}_PATH) AND (NOT STM32_CUBE_${FAMILY}_PATH))
  146. set(STM32_CUBE_${FAMILY}_PATH /opt/STM32Cube${FAMILY} CACHE PATH "Path to STM32Cube${FAMILY}")
  147. message(STATUS "Neither STM32_CUBE_${FAMILY}_PATH nor STM32_HAL_${FAMILY}_PATH specified using default STM32_CUBE_${FAMILY}_PATH: ${STM32_CUBE_${FAMILY}_PATH}")
  148. endif()
  149. #Checking HAL patch or release version
  150. unset(VERSION_INFO)
  151. find_file(PACKAGE_FILE NAMES package.xml PATHS ${STM32_CUBE_${FAMILY}_PATH})
  152. if(PACKAGE_FILE)
  153. file(READ ${PACKAGE_FILE} PACKAGE_FILE_CONTENT)
  154. string(REGEX MATCH "PackDescription Release=\"FW.${FAMILY}.([0-9.]+)\"( Patch=\"FW.${FAMILY}.([0-9.]+)\")?" VERSION_INFO ${PACKAGE_FILE_CONTENT})
  155. if(CMAKE_MATCH_3) # This is the "Patch" revision
  156. set(HAL_${COMP}_VERSION ${CMAKE_MATCH_3})
  157. set(HAL_VERSION ${CMAKE_MATCH_3})
  158. else(CMAKE_MATCH_1) #This is the "Release" version
  159. set(HAL_${COMP}_VERSION ${CMAKE_MATCH_1})
  160. set(HAL_VERSION ${CMAKE_MATCH_1})
  161. endif()
  162. endif()
  163. if(NOT VERSION_INFO)
  164. message(STATUS "Could not read the HAL version from package.xml for ${COMP}")
  165. endif()
  166. find_path(HAL_${FAMILY}_PATH
  167. NAMES Inc/stm32${FAMILY_L}xx_hal.h
  168. PATHS "${STM32_HAL_${FAMILY}_PATH}" "${STM32_CUBE_${FAMILY}_PATH}/Drivers/STM32${FAMILY}xx_HAL_Driver"
  169. NO_DEFAULT_PATH
  170. )
  171. if (NOT HAL_${FAMILY}_PATH)
  172. message(DEBUG "Missing HAL_${FAMILY}_PATH path")
  173. continue()
  174. endif()
  175. find_path(HAL_${FAMILY}${CORE_U}_INCLUDE
  176. NAMES stm32${FAMILY_L}xx_hal.h
  177. PATHS "${HAL_${FAMILY}_PATH}/Inc"
  178. NO_DEFAULT_PATH
  179. )
  180. find_file(HAL_${FAMILY}${CORE_U}_SOURCE
  181. NAMES stm32${FAMILY_L}xx_hal.c
  182. PATHS "${HAL_${FAMILY}_PATH}/Src"
  183. NO_DEFAULT_PATH
  184. )
  185. if ((NOT HAL_${FAMILY}${CORE_U}_INCLUDE) OR (NOT HAL_${FAMILY}${CORE_U}_SOURCE))
  186. set(HAL_${COMP}_FOUND FALSE)
  187. message(DEBUG "FindHAL: did not find path to HAL /src or /inc dir")
  188. continue()
  189. endif()
  190. if(NOT (TARGET HAL::STM32::${FAMILY}${CORE_C}))
  191. message(TRACE "FindHAL: creating library HAL::STM32::${FAMILY}${CORE_C}")
  192. add_library(HAL::STM32::${FAMILY}${CORE_C} INTERFACE IMPORTED)
  193. target_link_libraries(HAL::STM32::${FAMILY}${CORE_C} INTERFACE
  194. STM32::${FAMILY}${CORE_C}
  195. CMSIS::STM32::${FAMILY}${CORE_C})
  196. target_include_directories(HAL::STM32::${FAMILY}${CORE_C} INTERFACE "${HAL_${FAMILY}${CORE_U}_INCLUDE}")
  197. target_sources(HAL::STM32::${FAMILY}${CORE_C} INTERFACE "${HAL_${FAMILY}${CORE_U}_SOURCE}")
  198. endif()
  199. foreach(DRV_COMP ${HAL_FIND_COMPONENTS_DRIVERS})
  200. string(TOLOWER ${DRV_COMP} DRV_L)
  201. string(TOUPPER ${DRV_COMP} DRV)
  202. if(NOT (DRV_L IN_LIST HAL_DRIVERS_${FAMILY}))
  203. continue()
  204. endif()
  205. find_file(HAL_${FAMILY}${CORE_U}_${DRV}_SOURCE
  206. NAMES stm32${FAMILY_L}xx_hal_${DRV_L}.c
  207. PATHS "${HAL_${FAMILY}_PATH}/Src"
  208. NO_DEFAULT_PATH
  209. )
  210. list(APPEND HAL_${FAMILY}${CORE_U}_SOURCES "${HAL_${FAMILY}_${DRV}_SOURCE}")
  211. if(NOT HAL_${FAMILY}${CORE_U}_${DRV}_SOURCE)
  212. message(WARNING "Cannot find ${DRV} driver for ${FAMILY}${CORE_U}")
  213. set(HAL_${DRV_COMP}_FOUND FALSE)
  214. continue()
  215. endif()
  216. set(HAL_${DRV_COMP}_FOUND TRUE)
  217. if(HAL_${FAMILY}${CORE_U}_${DRV}_SOURCE AND (NOT (TARGET HAL::STM32::${FAMILY}::${DRV})))
  218. message(TRACE "FindHAL: creating library HAL::STM32::${FAMILY}${CORE_C}::${DRV}")
  219. add_library(HAL::STM32::${FAMILY}${CORE_C}::${DRV} INTERFACE IMPORTED)
  220. target_link_libraries(HAL::STM32::${FAMILY}${CORE_C}::${DRV} INTERFACE HAL::STM32::${FAMILY}${CORE_C})
  221. target_sources(HAL::STM32::${FAMILY}${CORE_C}::${DRV} INTERFACE "${HAL_${FAMILY}${CORE_U}_${DRV}_SOURCE}")
  222. endif()
  223. if(HAL_${FAMILY}${CORE_U}_${DRV}_SOURCE AND (${DRV_L} IN_LIST HAL_EX_DRIVERS_${FAMILY}))
  224. find_file(HAL_${FAMILY}${CORE_U}_${DRV}_EX_SOURCE
  225. NAMES stm32${FAMILY_L}xx_hal_${DRV_L}_ex.c
  226. PATHS "${HAL_${FAMILY}_PATH}/Src"
  227. NO_DEFAULT_PATH
  228. )
  229. list(APPEND HAL_${FAMILY}${CORE_U}_SOURCES "${HAL_${FAMILY}${CORE_U}_${DRV}_EX_SOURCE}")
  230. if(NOT HAL_${FAMILY}${CORE_U}_${DRV}_EX_SOURCE)
  231. message(WARNING "Cannot find ${DRV}Ex driver for ${FAMILY}${CORE_U}")
  232. endif()
  233. if((TARGET HAL::STM32::${FAMILY}${CORE_C}::${DRV}) AND (NOT (TARGET HAL::STM32::${FAMILY}${CORE_C}::${DRV}Ex)))
  234. message(TRACE "FindHAL: creating library HAL::STM32::${FAMILY}${CORE_C}::${DRV}Ex")
  235. add_library(HAL::STM32::${FAMILY}${CORE_C}::${DRV}Ex INTERFACE IMPORTED)
  236. target_link_libraries(HAL::STM32::${FAMILY}${CORE_C}::${DRV}Ex INTERFACE HAL::STM32::${FAMILY}${CORE_C}::${DRV})
  237. target_sources(HAL::STM32::${FAMILY}${CORE_C}::${DRV}Ex INTERFACE "${HAL_${FAMILY}${CORE_U}_${DRV}_EX_SOURCE}")
  238. endif()
  239. endif()
  240. endforeach()
  241. foreach(DRV_COMP ${HAL_FIND_COMPONENTS_DRIVERS_LL})
  242. string(TOLOWER ${DRV_COMP} DRV_L)
  243. string(REGEX REPLACE "^ll_" "" DRV_L ${DRV_L})
  244. string(TOUPPER ${DRV_L} DRV)
  245. if(NOT (DRV_L IN_LIST HAL_LL_DRIVERS_${FAMILY}))
  246. continue()
  247. endif()
  248. find_file(HAL_${FAMILY}${CORE_U}_${DRV}_LL_SOURCE
  249. NAMES stm32${FAMILY_L}xx_ll_${DRV_L}.c
  250. PATHS "${HAL_${FAMILY}_PATH}/Src"
  251. NO_DEFAULT_PATH
  252. )
  253. list(APPEND HAL_${FAMILY}${CORE_U}_SOURCES "${HAL_${FAMILY}_${DRV}_LL_SOURCE}")
  254. if(NOT HAL_${FAMILY}${CORE_U}_${DRV}_LL_SOURCE)
  255. message(WARNING "Cannot find LL_${DRV} driver for ${FAMILY}${CORE_U}")
  256. set(HAL_${DRV_COMP}_FOUND FALSE)
  257. continue()
  258. endif()
  259. set(HAL_${DRV_COMP}_FOUND TRUE)
  260. if(HAL_${FAMILY}${CORE_U}_${DRV}_LL_SOURCE AND (NOT (TARGET HAL::STM32::${FAMILY}${CORE_C}::LL_${DRV})))
  261. message(TRACE "FindHAL: creating library HAL::STM32::${FAMILY}${CORE_C}::LL_${DRV}")
  262. add_library(HAL::STM32::${FAMILY}${CORE_C}::LL_${DRV} INTERFACE IMPORTED)
  263. target_include_directories(HAL::STM32::${FAMILY}${CORE_C}::LL_${DRV} INTERFACE "${HAL_${FAMILY}${CORE_U}_INCLUDE}")
  264. target_sources(HAL::STM32::${FAMILY}${CORE_C}::LL_${DRV} INTERFACE "${HAL_${FAMILY}${CORE_U}_${DRV}_LL_SOURCE}")
  265. endif()
  266. endforeach()
  267. set(HAL_${COMP}_FOUND TRUE)
  268. list(APPEND HAL_INCLUDE_DIRS "${HAL_${FAMILY}${CORE_U}_INCLUDE}")
  269. list(APPEND HAL_SOURCES "${HAL_${FAMILY}${CORE_U}_SOURCES}")
  270. endforeach()
  271. list(REMOVE_DUPLICATES HAL_INCLUDE_DIRS)
  272. list(REMOVE_DUPLICATES HAL_SOURCES)
  273. include(FindPackageHandleStandardArgs)
  274. find_package_handle_standard_args(HAL
  275. REQUIRED_VARS HAL_INCLUDE_DIRS HAL_SOURCES
  276. FOUND_VAR HAL_FOUND
  277. HANDLE_COMPONENTS
  278. )