1# The purpose of this file is to provide search mechanism for locating Zephyr in-work-tree package 2# even when they are not installed into CMake package system 3# Linux/MacOS: ~/.cmake/packages 4# Windows: Registry database 5 6# Relative directory of workspace project dir as seen from Zephyr package file 7set(WORKSPACE_RELATIVE_DIR "../../../../..") 8 9# Relative directory of Zephyr dir as seen from Zephyr package file 10set(ZEPHYR_RELATIVE_DIR "../../../..") 11 12# This function updates Zephyr_DIR to the point to the candidate dir. 13# For Zephyr 3.0 and earlier, the Zephyr_DIR might in some cases be 14# `Zephyr_DIR-NOTFOUND` or pointing to the Zephyr package including the 15# boilerplate code instead of the Zephyr package of the included boilerplate. 16# This code ensures that when Zephyr releases <=3.0 is loaded, then Zephyr_DIR 17# will point correctly, see also #43094 which relates to this. 18function(set_zephyr_dir zephyr_candidate) 19 get_filename_component(zephyr_candidate_dir "${zephyr_candidate}" DIRECTORY) 20 if(NOT "${zephyr_candidate_dir}" STREQUAL "${Zephyr_DIR}") 21 set(Zephyr_DIR ${zephyr_candidate_dir} CACHE PATH 22 "The directory containing a CMake configuration file for Zephyr." FORCE 23 ) 24 endif() 25endfunction() 26 27# This macro returns a list of parent folders to use for later searches. 28macro(get_search_paths START_PATH SEARCH_PATHS PREFERENCE_LIST) 29 get_filename_component(SEARCH_PATH ${START_PATH} DIRECTORY) 30 while(NOT (SEARCH_PATH STREQUAL SEARCH_PATH_PREV)) 31 foreach(preference ${PREFERENCE_LIST}) 32 list(APPEND SEARCH_PATHS ${SEARCH_PATH}/${preference}) 33 endforeach() 34 list(APPEND SEARCH_PATHS ${SEARCH_PATH}/zephyr) 35 list(APPEND SEARCH_PATHS ${SEARCH_PATH}) 36 set(SEARCH_PATH_PREV ${SEARCH_PATH}) 37 get_filename_component(SEARCH_PATH ${SEARCH_PATH} DIRECTORY) 38 endwhile() 39endmacro() 40 41# This macro can check for additional Zephyr package that has a better match 42# Options: 43# - ZEPHYR_BASE : Use the specified ZEPHYR_BASE directly. 44# - WORKSPACE_DIR : Search for projects in specified workspace. 45# - SEARCH_PARENTS : Search parent folder of current source file (application) 46# to locate in-project-tree Zephyr candidates. 47# - CHECK_ONLY : Only set PACKAGE_VERSION_COMPATIBLE to false if a better candidate 48# is found, default is to also include the found candidate. 49# - VERSION_CHECK : This is the version check stage by CMake find package 50# - CANDIDATES_PREFERENCE_LIST : List of candidate to be preferred, if installed 51macro(check_zephyr_package) 52 set(options CHECK_ONLY SEARCH_PARENTS VERSION_CHECK) 53 set(single_args WORKSPACE_DIR ZEPHYR_BASE) 54 set(list_args CANDIDATES_PREFERENCE_LIST) 55 cmake_parse_arguments(CHECK_ZEPHYR_PACKAGE "${options}" "${single_args}" "${list_args}" ${ARGN}) 56 57 if(CHECK_ZEPHYR_PACKAGE_ZEPHYR_BASE) 58 set(SEARCH_SETTINGS PATHS ${CHECK_ZEPHYR_PACKAGE_ZEPHYR_BASE} NO_DEFAULT_PATH) 59 endif() 60 61 if(CHECK_ZEPHYR_PACKAGE_WORKSPACE_DIR) 62 set(SEARCH_SETTINGS PATHS ${CHECK_ZEPHYR_PACKAGE_WORKSPACE_DIR}/zephyr ${CHECK_ZEPHYR_PACKAGE_WORKSPACE_DIR} NO_DEFAULT_PATH) 63 endif() 64 65 if(CHECK_ZEPHYR_PACKAGE_SEARCH_PARENTS) 66 get_search_paths(${CMAKE_CURRENT_SOURCE_DIR} SEARCH_PATHS "${CHECK_ZEPHYR_PACKAGE_CANDIDATES_PREFERENCE_LIST}") 67 set(SEARCH_SETTINGS PATHS ${SEARCH_PATHS} NO_DEFAULT_PATH) 68 endif() 69 70 # Searching for version zero means there will be no match, but we obtain 71 # a list of all potential Zephyr candidates in the tree to consider. 72 find_package(Zephyr 0.0.0 EXACT QUIET ${SEARCH_SETTINGS}) 73 74 # The find package will also find ourself when searching using installed candidates. 75 # So avoid re-including unless NO_DEFAULT_PATH is set. 76 # NO_DEFAULT_PATH means explicit search and we could be part of a preference list. 77 if(NOT (NO_DEFAULT_PATH IN_LIST SEARCH_SETTINGS)) 78 list(REMOVE_ITEM Zephyr_CONSIDERED_CONFIGS ${CMAKE_CURRENT_LIST_DIR}/ZephyrConfig.cmake) 79 endif() 80 list(REMOVE_DUPLICATES Zephyr_CONSIDERED_CONFIGS) 81 82 foreach(ZEPHYR_CANDIDATE ${Zephyr_CONSIDERED_CONFIGS}) 83 if(CHECK_ZEPHYR_PACKAGE_WORKSPACE_DIR) 84 # Check is done in Zephyr workspace already, thus check only for pure Zephyr candidates. 85 get_filename_component(CANDIDATE_DIR ${ZEPHYR_CANDIDATE}/${ZEPHYR_RELATIVE_DIR} ABSOLUTE) 86 else() 87 get_filename_component(CANDIDATE_DIR ${ZEPHYR_CANDIDATE}/${WORKSPACE_RELATIVE_DIR} ABSOLUTE) 88 endif() 89 90 if(CHECK_ZEPHYR_PACKAGE_ZEPHYR_BASE) 91 if(CHECK_ZEPHYR_PACKAGE_VERSION_CHECK) 92 string(REGEX REPLACE "\.cmake$" "Version.cmake" ZEPHYR_VERSION_CANDIDATE ${ZEPHYR_CANDIDATE}) 93 include(${ZEPHYR_VERSION_CANDIDATE} NO_POLICY_SCOPE) 94 return() 95 else() 96 include(${ZEPHYR_CANDIDATE} NO_POLICY_SCOPE) 97 set_zephyr_dir(${ZEPHYR_CANDIDATE}) 98 return() 99 endif() 100 endif() 101 102 string(FIND "${CMAKE_CURRENT_SOURCE_DIR}" "${CANDIDATE_DIR}/" COMMON_INDEX) 103 if (COMMON_INDEX EQUAL 0) 104 if(CHECK_ZEPHYR_PACKAGE_CHECK_ONLY) 105 # A better candidate exists, thus return 106 set(PACKAGE_VERSION_COMPATIBLE FALSE) 107 return() 108 elseif(ZEPHYR_CANDIDATE STREQUAL ${CMAKE_CURRENT_LIST_DIR}/ZephyrConfig.cmake) 109 # Current Zephyr is preferred one, let's just break the loop and continue processing. 110 break() 111 else() 112 if(CHECK_ZEPHYR_PACKAGE_VERSION_CHECK) 113 string(REGEX REPLACE "\.cmake$" "Version.cmake" ZEPHYR_VERSION_CANDIDATE ${ZEPHYR_CANDIDATE}) 114 include(${ZEPHYR_VERSION_CANDIDATE} NO_POLICY_SCOPE) 115 return() 116 else() 117 include(${ZEPHYR_CANDIDATE} NO_POLICY_SCOPE) 118 set_zephyr_dir(${ZEPHYR_CANDIDATE}) 119 return() 120 endif() 121 endif() 122 endif() 123 endforeach() 124endmacro() 125