mirror of https://github.com/wolfSSL/wolfBoot.git
437 lines
17 KiB
CMake
437 lines
17 KiB
CMake
# wolfboot/cmake/cube_ide_config.cmake
|
|
#
|
|
# Copyright (C) 2026 wolfSSL Inc.
|
|
#
|
|
# This file is part of wolfBoot.
|
|
#
|
|
# wolfBoot is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# wolfBoot is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
|
#
|
|
|
|
# Some logic to find the ST Cube IDE in various directories on various systems
|
|
# See also https://www.st.com/resource/en/application_note/an5952-how-to-use-cmake-in-stm32cubeide-stmicroelectronics.pdf
|
|
|
|
# Usage:
|
|
# set(STM32CUBEIDE_DIR "C:/ST/STM32CubeIDE_1.15.0" CACHE PATH "Hint to STM32CubeIDE root")
|
|
# find_package(STM32CubeIDE REQUIRED)
|
|
# message(STATUS "STM32CubeIDE: ${STM32CUBEIDE_EXECUTABLE} (root: ${STM32CUBEIDE_ROOT}, ver: ${STM32CUBEIDE_VERSION})")
|
|
|
|
# Ensure this file is only included and initialized once
|
|
if(CMAKE_VERSION VERSION_LESS 3.10)
|
|
# Fallback path for older CMake
|
|
if(DEFINED CUBE_IDE_CONFIG_CMAKE_INCLUDED)
|
|
return()
|
|
endif()
|
|
else()
|
|
include_guard(GLOBAL)
|
|
endif()
|
|
|
|
if(DEFINED FUNCTIONS_CMAKE_INCLUDED)
|
|
message(STATUS "Found required functions.cmake")
|
|
else()
|
|
message(FATL_ERROR "Missing required functions.cmake")
|
|
endif()
|
|
|
|
# Exclude entire file unless DETECT_CUBEIDE is set to true
|
|
if(DETECT_CUBEIDE)
|
|
|
|
message(STATUS "Begin cube_ide_config.cmake")
|
|
unset(STM32CUBEIDE_ROOT CACHE)
|
|
unset(STM32CUBEIDE_FOUND CACHE)
|
|
unset(STM32CUBEIDE_VERSION CACHE)
|
|
unset(STM32CUBEIDE_EXECUTABLE CACHE)
|
|
|
|
function(_stm32cubeide_set_from_exec PARAM_EXE)
|
|
if(NOT EXISTS "${PARAM_EXE}")
|
|
return()
|
|
endif()
|
|
set(STM32CUBEIDE_EXECUTABLE "${PARAM_EXE}" PARENT_SCOPE)
|
|
# Root: up two dirs works for Linux default; handle macOS bundle separately below.
|
|
get_filename_component(_dir "${PARAM_EXE}" DIRECTORY)
|
|
if(CMAKE_HOST_APPLE AND _dir MATCHES "\\.app/Contents/MacOS$")
|
|
get_filename_component(_root "${_dir}/../.." REALPATH)
|
|
else()
|
|
get_filename_component(_root "${_dir}/.." REALPATH)
|
|
endif()
|
|
|
|
message(STATUS "Found STM32CUBEIDE_ROOT=${_root}")
|
|
set(STM32CUBEIDE_ROOT "${_root}" PARENT_SCOPE)
|
|
|
|
# Version extract from directory names like STM32CubeIDE_1.15.0
|
|
file(TO_CMAKE_PATH "${_root}" _root_norm)
|
|
get_filename_component(_leaf "${_root_norm}" NAME) # e.g. "STM32CubeIDE_1.14.1"
|
|
|
|
set(_ver "")
|
|
set(_mark "STM32CubeIDE_")
|
|
string(FIND "${_leaf}" "${_mark}" _pos)
|
|
if(NOT _pos EQUAL -1)
|
|
string(LENGTH "${_mark}" _mlen)
|
|
math(EXPR _start "${_pos} + ${_mlen}")
|
|
string(SUBSTRING "${_leaf}" ${_start} -1 _ver_raw)
|
|
string(STRIP "${_ver_raw}" _ver)
|
|
endif()
|
|
|
|
if(_ver) # e.g. "1.14.1"
|
|
# set both locally and in parent scope for immediate logging + export
|
|
set(STM32CUBEIDE_VERSION "${_ver}")
|
|
set(STM32CUBEIDE_VERSION "${_ver}" PARENT_SCOPE)
|
|
message(NOTICE "Found STM32CUBEIDE_VERSION=${_ver}")
|
|
else()
|
|
message(VERBOSE "Could not derive version (leaf='${_leaf}', root='${_root_norm}')")
|
|
endif()
|
|
endfunction()
|
|
|
|
# Finds the newest STM32Cube L4 firmware folder under the standard Repository path.
|
|
# Usage:
|
|
# find_newest_stm32cube_fw_l4(OUT_DIR OUT_VER)
|
|
# After the call:
|
|
# OUT_DIR = full path to the newest STM32Cube_FW_L4_Vx.y.z directory
|
|
# OUT_VER = version string x.y.z
|
|
#
|
|
# Optional inputs that you may predefine before calling:
|
|
# CURRENT_USER Used only on Windows if USERPROFILE is not set
|
|
# STM32CUBE_REPO_HINT Override the Repository root folder if you know it already
|
|
#
|
|
# Examples:
|
|
# find_newest_stm32cube_fw_l4(STM32CUBE_L4_ROOT STM32CUBE_L4_VERSION)
|
|
# message(STATUS "STM32Cube L4 root: ${STM32CUBE_L4_ROOT} (version ${STM32CUBE_L4_VERSION})")
|
|
function(find_newest_stm32cube_fw_l4 OUT_DIR OUT_VER)
|
|
set(_repo_root "")
|
|
|
|
# 1) If the caller provided a direct hint, use it
|
|
if(DEFINED STM32CUBE_REPO_HINT AND EXISTS "${STM32CUBE_REPO_HINT}")
|
|
set(_repo_root "${STM32CUBE_REPO_HINT}")
|
|
else()
|
|
# 2) Build the default path based on platform
|
|
if(CMAKE_HOST_WIN32)
|
|
# Prefer USERPROFILE if available
|
|
set(_userprofile "$ENV{USERPROFILE}")
|
|
if(_userprofile STREQUAL "")
|
|
# Fallback to C:/Users/<CURRENT_USER>
|
|
if(NOT DEFINED CURRENT_USER OR CURRENT_USER STREQUAL "")
|
|
set(_env_user "$ENV{USERNAME}")
|
|
if(NOT _env_user STREQUAL "")
|
|
set(CURRENT_USER "${_env_user}")
|
|
endif()
|
|
endif()
|
|
if(DEFINED CURRENT_USER AND NOT CURRENT_USER STREQUAL "")
|
|
set(_repo_root "C:/Users/${CURRENT_USER}/STM32Cube/Repository")
|
|
endif()
|
|
else()
|
|
# Convert backslashes to forward slashes for CMake path sanity
|
|
file(TO_CMAKE_PATH "${_userprofile}" _userprofile_cmake)
|
|
set(_repo_root "${_userprofile_cmake}/STM32Cube/Repository")
|
|
endif()
|
|
else()
|
|
# macOS and Linux
|
|
set(_home "$ENV{HOME}")
|
|
if(NOT _home STREQUAL "")
|
|
file(TO_CMAKE_PATH "${_home}" _home_cmake)
|
|
set(_repo_root "${_home_cmake}/STM32Cube/Repository")
|
|
endif()
|
|
endif()
|
|
endif()
|
|
|
|
# Validate we have a repository root
|
|
if(_repo_root STREQUAL "" OR NOT EXISTS "${_repo_root}")
|
|
set(${OUT_DIR} "" PARENT_SCOPE)
|
|
set(${OUT_VER} "" PARENT_SCOPE)
|
|
message(STATUS "STM32Cube Repository not found. Checked: ${_repo_root}")
|
|
return()
|
|
endif()
|
|
|
|
# 3) Glob STM32Cube L4 folders
|
|
file(GLOB _candidates
|
|
LIST_DIRECTORIES true
|
|
"${_repo_root}/STM32Cube_FW_L4_V*"
|
|
)
|
|
|
|
if(_candidates STREQUAL "")
|
|
set(${OUT_DIR} "" PARENT_SCOPE)
|
|
set(${OUT_VER} "" PARENT_SCOPE)
|
|
message(STATUS "No STM32Cube L4 packages found under: ${_repo_root}")
|
|
return()
|
|
endif()
|
|
|
|
# 4) Pick the highest semantic version using CMake's VERSION comparison
|
|
set(_best_dir "")
|
|
set(_best_ver "")
|
|
|
|
foreach(_dir IN LISTS _candidates)
|
|
get_filename_component(_name "${_dir}" NAME)
|
|
# Expect names like STM32Cube_FW_L4_V1.17.2
|
|
# Extract the numeric version after the V
|
|
string(REGEX MATCH "STM32Cube_FW_L4_V([0-9]+\\.[0-9]+\\.[0-9]+)" _m "${_name}")
|
|
if(_m)
|
|
# Capture group 1 is the version x.y.z
|
|
string(REGEX REPLACE "STM32Cube_FW_L4_V" "" _ver "${_m}")
|
|
if(_best_ver STREQUAL "" OR _best_ver VERSION_LESS _ver)
|
|
set(_best_ver "${_ver}")
|
|
set(_best_dir "${_dir}")
|
|
endif()
|
|
endif()
|
|
endforeach()
|
|
|
|
if(_best_dir STREQUAL "")
|
|
set(${OUT_DIR} "" PARENT_SCOPE)
|
|
set(${OUT_VER} "" PARENT_SCOPE)
|
|
message(STATUS "STM32Cube L4 directories found but no valid version pattern matched under: ${_repo_root}")
|
|
return()
|
|
endif()
|
|
|
|
# 5) Return results
|
|
set(${OUT_DIR} "${_best_dir}" PARENT_SCOPE)
|
|
set(${OUT_VER} "${_best_ver}" PARENT_SCOPE)
|
|
message(STATUS "Found newest STM32Cube L4: ${_best_dir} (version ${_best_ver})")
|
|
endfunction() # find_newest_stm32cube_fw_l4
|
|
|
|
|
|
# 1) Hints from environment or cache
|
|
set(_HINTS "")
|
|
if(DEFINED ENV{STM32CUBEIDE_DIR})
|
|
message(STATUS "Found env STM32CUBEIDE_DIR=$ENV{STM32CUBEIDE_DIR}")
|
|
list(APPEND _HINTS "$ENV{STM32CUBEIDE_DIR}")
|
|
endif()
|
|
|
|
if(DEFINED STM32CUBEIDE_DIR)
|
|
message(STATUS "Found STM32CUBEIDE_DIR=${STM32CUBEIDE_DIR}")
|
|
list(APPEND _HINTS "${STM32CUBEIDE_DIR}")
|
|
endif()
|
|
|
|
if(DEFINED ENV{STM32CUBEIDE_ROOT})
|
|
message(STATUS "Found env STM32CUBEIDE_ROOT=$ENV{STM32CUBEIDE_ROOT}")
|
|
list(APPEND _HINTS "$ENV{STM32CUBEIDE_ROOT}")
|
|
endif()
|
|
|
|
if(DEFINED STM32CUBEIDE_ROOT)
|
|
message(STATUS "Found STM32CUBEIDE_ROOT=${STM32CUBEIDE_ROOT}")
|
|
list(APPEND _HINTS "${STM32CUBEIDE_ROOT}")
|
|
endif()
|
|
|
|
foreach(h ${_HINTS})
|
|
message(STATUS "Looking for STM32CubeIDE.exe in ${h}")
|
|
if(CMAKE_HOST_WIN32)
|
|
if(EXISTS "${h}/STM32CubeIDE.exe")
|
|
_stm32cubeide_set_from_exec("${h}/STM32CubeIDE.exe")
|
|
endif()
|
|
elseif(CMAKE_HOST_APPLE)
|
|
if(EXISTS "${h}/STM32CubeIDE.app/Contents/MacOS/STM32CubeIDE")
|
|
_stm32cubeide_set_from_exec("${h}/STM32CubeIDE.app/Contents/MacOS/STM32CubeIDE")
|
|
elseif(EXISTS "${h}/Contents/MacOS/STM32CubeIDE")
|
|
_stm32cubeide_set_from_exec("${h}/Contents/MacOS/STM32CubeIDE")
|
|
endif()
|
|
else()
|
|
if(EXISTS "${h}/stm32cubeide")
|
|
_stm32cubeide_set_from_exec("${h}/stm32cubeide")
|
|
endif()
|
|
endif()
|
|
endforeach()
|
|
|
|
# 2) PATH search
|
|
if(NOT STM32CUBEIDE_EXECUTABLE)
|
|
if(CMAKE_HOST_WIN32)
|
|
find_program(_CUBE_EXE NAMES "STM32CubeIDE.exe")
|
|
elseif(CMAKE_HOST_APPLE OR CMAKE_HOST_UNIX)
|
|
find_program(_CUBE_EXE NAMES "stm32cubeide")
|
|
endif()
|
|
if(_CUBE_EXE)
|
|
_stm32cubeide_set_from_exec("${_CUBE_EXE}")
|
|
endif()
|
|
endif()
|
|
|
|
# 3) OS-specific probing
|
|
if(NOT STM32CUBEIDE_EXECUTABLE)
|
|
if(CMAKE_HOST_WIN32)
|
|
# Try Registry: uninstall entries often expose InstallLocation
|
|
# 64-bit and 32-bit views
|
|
foreach(_HK
|
|
"HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
|
|
"HKLM\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall")
|
|
execute_process(COMMAND reg query ${_HK} /f STM32CubeIDE /s
|
|
OUTPUT_VARIABLE _reg
|
|
ERROR_VARIABLE _reg_err
|
|
RESULT_VARIABLE _reg_rc)
|
|
if(_reg_rc EQUAL 0 AND _reg MATCHES "InstallLocation\\s+REG_SZ\\s+([^\r\n]+)")
|
|
string(REGEX REPLACE ".*InstallLocation\\s+REG_SZ\\s+([^\r\n]+).*" "\\1" _loc "${_reg}")
|
|
string(REPLACE "\\" "/" _loc "${_loc}")
|
|
if(EXISTS "${_loc}/STM32CubeIDE.exe")
|
|
_stm32cubeide_set_from_exec("${_loc}/STM32CubeIDE.exe")
|
|
endif()
|
|
endif()
|
|
endforeach()
|
|
|
|
# Common default roots
|
|
if(NOT STM32CUBEIDE_EXECUTABLE)
|
|
file(GLOB _candidates
|
|
"C:/ST/STM32CubeIDE_*"
|
|
"C:/Program Files/STMicroelectronics/STM32CubeIDE*"
|
|
"C:/Program Files (x86)/STMicroelectronics/STM32CubeIDE*")
|
|
|
|
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.7")
|
|
list(SORT _candidates COMPARE NATURAL ORDER DESCENDING)
|
|
else()
|
|
list(SORT _candidates)
|
|
list(REVERSE _candidates)
|
|
endif()
|
|
|
|
foreach(_this_c ${_candidates})
|
|
message(STATUS "Looking at ${_this_c}")
|
|
if(EXISTS "${_this_c}/STM32CubeIDE.exe")
|
|
message(STATUS "Found ${_this_c}/STM32CubeIDE.exe")
|
|
_stm32cubeide_set_from_exec("${_this_c}/STM32CubeIDE.exe")
|
|
break()
|
|
endif()
|
|
|
|
if(EXISTS "${_this_c}/STM32CubeIDE/STM32CubeIDE.exe")
|
|
message(STATUS "Found ${_this_c}/STM32CubeIDE/STM32CubeIDE.exe")
|
|
_stm32cubeide_set_from_exec("${_this_c}/STM32CubeIDE/STM32CubeIDE.exe")
|
|
break()
|
|
endif()
|
|
endforeach()
|
|
endif()
|
|
|
|
elseif(CMAKE_HOST_APPLE)
|
|
# Standard Applications folder
|
|
if(EXISTS "/Applications/STM32CubeIDE.app/Contents/MacOS/STM32CubeIDE")
|
|
_stm32cubeide_set_from_exec("/Applications/STM32CubeIDE.app/Contents/MacOS/STM32CubeIDE")
|
|
else()
|
|
# Fall back: scan *.app names
|
|
file(GLOB _apps "/Applications/STM32CubeIDE*.app")
|
|
|
|
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.7")
|
|
list(SORT _apps COMPARE NATURAL ORDER DESCENDING)
|
|
else()
|
|
list(SORT _apps)
|
|
list(REVERSE _apps)
|
|
endif()
|
|
|
|
foreach(app ${_apps})
|
|
if(EXISTS "${app}/Contents/MacOS/STM32CubeIDE")
|
|
_stm32cubeide_set_from_exec("${app}/Contents/MacOS/STM32CubeIDE")
|
|
break()
|
|
endif()
|
|
endforeach()
|
|
|
|
# Spotlight as last resort
|
|
if(NOT STM32CUBEIDE_EXECUTABLE)
|
|
execute_process(COMMAND mdfind "kMDItemCFBundleIdentifier == com.st.stm32cubeide"
|
|
OUTPUT_VARIABLE _mdfind RESULT_VARIABLE _mdrc)
|
|
if(_mdrc EQUAL 0 AND _mdfind)
|
|
string(REGEX MATCH ".*\\.app" _app "${_mdfind}")
|
|
if(_app AND EXISTS "${_app}/Contents/MacOS/STM32CubeIDE")
|
|
_stm32cubeide_set_from_exec("${_app}/Contents/MacOS/STM32CubeIDE")
|
|
endif()
|
|
endif()
|
|
endif()
|
|
endif()
|
|
|
|
else() # Linux
|
|
# Desktop file -> Exec path
|
|
if(EXISTS "/usr/share/applications/stm32cubeide.desktop")
|
|
file(READ "/usr/share/applications/stm32cubeide.desktop" _desk)
|
|
string(REGEX MATCH "Exec=([^ \n\r]+)" _m "${_desk}")
|
|
if(_m)
|
|
string(REGEX REPLACE "Exec=([^ \n\r]+).*" "\\1" _exec "${_desk}")
|
|
# Resolve symlink if any
|
|
execute_process(COMMAND bash -lc "readlink -f \"${_exec}\"" OUTPUT_VARIABLE _rl RESULT_VARIABLE _rc)
|
|
if(_rc EQUAL 0)
|
|
string(STRIP "${_rl}" _rls)
|
|
if(EXISTS "${_rls}")
|
|
_stm32cubeide_set_from_exec("${_rls}")
|
|
endif()
|
|
elseif(EXISTS "${_exec}")
|
|
_stm32cubeide_set_from_exec("${_exec}")
|
|
endif()
|
|
endif()
|
|
endif()
|
|
|
|
# Typical install roots under /opt
|
|
if(NOT STM32CUBEIDE_EXECUTABLE)
|
|
file(GLOB _candidates "/opt/st/stm32cubeide_*")
|
|
|
|
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.7")
|
|
list(SORT _candidates COMPARE NATURAL ORDER DESCENDING)
|
|
else()
|
|
list(SORT _candidates)
|
|
list(REVERSE _candidates)
|
|
endif()
|
|
|
|
foreach(c ${_candidates})
|
|
if(EXISTS "${c}/stm32cubeide")
|
|
_stm32cubeide_set_from_exec("${c}/stm32cubeide")
|
|
break()
|
|
endif()
|
|
endforeach()
|
|
endif()
|
|
endif() # Windows or Mac else Linux
|
|
endif() # !STM32CUBEIDE_EXECUTABLE
|
|
|
|
|
|
include(FindPackageHandleStandardArgs)
|
|
find_package_handle_standard_args(STM32CubeIDE
|
|
REQUIRED_VARS STM32CUBEIDE_EXECUTABLE STM32CUBEIDE_ROOT
|
|
FAIL_MESSAGE "STM32CubeIDE not found. Set STM32CUBEIDE_DIR or add it to PATH."
|
|
)
|
|
|
|
if(STM32CUBEIDE_EXECUTABLE)
|
|
message(STATUS "Found STM32 CubeIDE: ${STM32CUBEIDE_EXECUTABLE}")
|
|
set(STM32CUBEIDE_FOUND TRUE)
|
|
else()
|
|
message(STATUS "Not found: STM32 CubeIDE")
|
|
endif()
|
|
|
|
# The CubeIDE version likely does not match FW version:
|
|
# C:\Users\${CURRENT_USER}\STM32Cube\Repository\STM32Cube_FW_L4_V1.18.0\Drivers\STM32L4xx_HAL_Driver
|
|
# C:/Users/${CURRENT_USER}/STM32Cube/Repository/STM32Cube_FW_L4_V1.14.1/Drivers/
|
|
|
|
message(STATUS "CubeIDE Config WOLFBOOT_TARGET=${WOLFBOOT_TARGET}")
|
|
string(TOLOWER "${WOLFBOOT_TARGET}" _wb_target_lc)
|
|
string(FIND "${_wb_target_lc}" "stm32l4" _pos)
|
|
message(STATUS "Checking if the HAL and CMSIS libraries needed")
|
|
if(_pos EQUAL 0)
|
|
# Only do this for the L4!
|
|
find_newest_stm32cube_fw_l4(STM32CUBE_L4_ROOT STM32CUBE_L4_VERSION)
|
|
set(STM32_HAL_DIR "${STM32CUBE_L4_ROOT}/Drivers/STM32L4xx_HAL_Driver")
|
|
set(CMSIS_DIR "${STM32CUBE_L4_ROOT}/Drivers/CMSIS")
|
|
|
|
if(STM32CUBE_L4_VERSION)
|
|
set(HAL_BASE "${STM32CUBE_L4_ROOT}")
|
|
if(IS_DIRECTORY "${HAL_BASE}")
|
|
message(STATUS "Found HAL_BASE=${HAL_BASE}")
|
|
set(FOUND_HAL_BASE true)
|
|
# CubeIDE
|
|
set_and_echo_dir(HAL_DRV "${HAL_BASE}/Drivers/STM32L4xx_HAL_Driver")
|
|
set_and_echo_dir(HAL_CMSIS_DEV "${HAL_BASE}/Drivers/CMSIS/Device/ST/STM32L4xx/Include")
|
|
set_and_echo_dir(HAL_CMSIS_CORE "${HAL_BASE}/Drivers/CMSIS/Include")
|
|
set_and_echo_dir(HAL_TEMPLATE_INC "${HAL_BASE}/Projects/B-L475E-IOT01A/Templates/Inc")
|
|
else()
|
|
message(STATUS "Not found expected HAL_BASE=${HAL_BASE}")
|
|
endif()
|
|
endif()
|
|
else()
|
|
message(STATUS "WOLFBOOT_TARGET=${WOLFBOOT_TARGET}, not loading HAL and CMSIS libraries.")
|
|
endif() # #STM32L4 detection
|
|
|
|
string(FIND "${_wb_target_lc}" "stm32g0" _pos)
|
|
if(_pos EQUAL 0)
|
|
|
|
endif()
|
|
|
|
mark_as_advanced(STM32CUBEIDE_EXECUTABLE STM32CUBEIDE_ROOT STM32CUBEIDE_VERSION)
|
|
|
|
set(CUBE_IDE_CONFIG_CMAKE_INCLUDED TRUE)
|
|
message(STATUS "End cube_ide_config.cmake")
|
|
|
|
endif() # DETECT_CUBEIDE
|