# The purpose of this file is to provide search mechanism for locating Zephyr in-work-tree package # even when they are not installed into CMake package system # Linux/MacOS: ~/.cmake/packages # Windows: Registry database # Relative directory of workspace project dir as seen from Zephyr package file set(WORKSPACE_RELATIVE_DIR "../../../../..") # Relative directory of Zephyr dir as seen from Zephyr package file set(ZEPHYR_RELATIVE_DIR "../../../..") # This function updates Zephyr_DIR to the point to the candidate dir. # For Zephyr 3.0 and earlier, the Zephyr_DIR might in some cases be # `Zephyr_DIR-NOTFOUND` or pointing to the Zephyr package including the # boilerplate code instead of the Zephyr package of the included boilerplate. # This code ensures that when Zephyr releases <=3.0 is loaded, then Zephyr_DIR # will point correctly, see also #43094 which relates to this. function(set_zephyr_dir zephyr_candidate) get_filename_component(zephyr_candidate_dir "${zephyr_candidate}" DIRECTORY) if(NOT "${zephyr_candidate_dir}" STREQUAL "${Zephyr_DIR}") set(Zephyr_DIR ${zephyr_candidate_dir} CACHE PATH "The directory containing a CMake configuration file for Zephyr." FORCE ) endif() endfunction() # This macro returns a list of parent folders to use for later searches. macro(get_search_paths START_PATH SEARCH_PATHS PREFERENCE_LIST) get_filename_component(SEARCH_PATH ${START_PATH} DIRECTORY) while(NOT (SEARCH_PATH STREQUAL SEARCH_PATH_PREV)) foreach(preference ${PREFERENCE_LIST}) list(APPEND SEARCH_PATHS ${SEARCH_PATH}/${preference}) endforeach() list(APPEND SEARCH_PATHS ${SEARCH_PATH}/zephyr) list(APPEND SEARCH_PATHS ${SEARCH_PATH}) set(SEARCH_PATH_PREV ${SEARCH_PATH}) get_filename_component(SEARCH_PATH ${SEARCH_PATH} DIRECTORY) endwhile() endmacro() # This macro can check for additional Zephyr package that has a better match # Options: # - ZEPHYR_BASE : Use the specified ZEPHYR_BASE directly. # - WORKSPACE_DIR : Search for projects in specified workspace. # - SEARCH_PARENTS : Search parent folder of current source file (application) # to locate in-project-tree Zephyr candidates. # - CHECK_ONLY : Only set PACKAGE_VERSION_COMPATIBLE to false if a better candidate # is found, default is to also include the found candidate. # - VERSION_CHECK : This is the version check stage by CMake find package # - CANDIDATES_PREFERENCE_LIST : List of candidate to be preferred, if installed macro(check_zephyr_package) set(options CHECK_ONLY SEARCH_PARENTS VERSION_CHECK) set(single_args WORKSPACE_DIR ZEPHYR_BASE) set(list_args CANDIDATES_PREFERENCE_LIST) cmake_parse_arguments(CHECK_ZEPHYR_PACKAGE "${options}" "${single_args}" "${list_args}" ${ARGN}) if(CHECK_ZEPHYR_PACKAGE_ZEPHYR_BASE) set(SEARCH_SETTINGS PATHS ${CHECK_ZEPHYR_PACKAGE_ZEPHYR_BASE} NO_DEFAULT_PATH) endif() if(CHECK_ZEPHYR_PACKAGE_WORKSPACE_DIR) set(SEARCH_SETTINGS PATHS ${CHECK_ZEPHYR_PACKAGE_WORKSPACE_DIR}/zephyr ${CHECK_ZEPHYR_PACKAGE_WORKSPACE_DIR} NO_DEFAULT_PATH) endif() if(CHECK_ZEPHYR_PACKAGE_SEARCH_PARENTS) get_search_paths(${CMAKE_CURRENT_SOURCE_DIR} SEARCH_PATHS "${CHECK_ZEPHYR_PACKAGE_CANDIDATES_PREFERENCE_LIST}") set(SEARCH_SETTINGS PATHS ${SEARCH_PATHS} NO_DEFAULT_PATH) endif() # Searching for version zero means there will be no match, but we obtain # a list of all potential Zephyr candidates in the tree to consider. find_package(Zephyr 0.0.0 EXACT QUIET ${SEARCH_SETTINGS}) # The find package will also find ourself when searching using installed candidates. # So avoid re-including unless NO_DEFAULT_PATH is set. # NO_DEFAULT_PATH means explicit search and we could be part of a preference list. if(NOT (NO_DEFAULT_PATH IN_LIST SEARCH_SETTINGS)) list(REMOVE_ITEM Zephyr_CONSIDERED_CONFIGS ${CMAKE_CURRENT_LIST_DIR}/ZephyrConfig.cmake) endif() list(REMOVE_DUPLICATES Zephyr_CONSIDERED_CONFIGS) foreach(ZEPHYR_CANDIDATE ${Zephyr_CONSIDERED_CONFIGS}) if(CHECK_ZEPHYR_PACKAGE_WORKSPACE_DIR) # Check is done in Zephyr workspace already, thus check only for pure Zephyr candidates. get_filename_component(CANDIDATE_DIR ${ZEPHYR_CANDIDATE}/${ZEPHYR_RELATIVE_DIR} ABSOLUTE) else() get_filename_component(CANDIDATE_DIR ${ZEPHYR_CANDIDATE}/${WORKSPACE_RELATIVE_DIR} ABSOLUTE) endif() if(CHECK_ZEPHYR_PACKAGE_ZEPHYR_BASE) if(CHECK_ZEPHYR_PACKAGE_VERSION_CHECK) string(REGEX REPLACE "\.cmake$" "Version.cmake" ZEPHYR_VERSION_CANDIDATE ${ZEPHYR_CANDIDATE}) include(${ZEPHYR_VERSION_CANDIDATE} NO_POLICY_SCOPE) return() else() include(${ZEPHYR_CANDIDATE} NO_POLICY_SCOPE) set_zephyr_dir(${ZEPHYR_CANDIDATE}) return() endif() endif() string(FIND "${CMAKE_CURRENT_SOURCE_DIR}" "${CANDIDATE_DIR}/" COMMON_INDEX) if (COMMON_INDEX EQUAL 0) if(CHECK_ZEPHYR_PACKAGE_CHECK_ONLY) # A better candidate exists, thus return set(PACKAGE_VERSION_COMPATIBLE FALSE) return() elseif(ZEPHYR_CANDIDATE STREQUAL ${CMAKE_CURRENT_LIST_DIR}/ZephyrConfig.cmake) # Current Zephyr is preferred one, let's just break the loop and continue processing. break() else() if(CHECK_ZEPHYR_PACKAGE_VERSION_CHECK) string(REGEX REPLACE "\.cmake$" "Version.cmake" ZEPHYR_VERSION_CANDIDATE ${ZEPHYR_CANDIDATE}) include(${ZEPHYR_VERSION_CANDIDATE} NO_POLICY_SCOPE) return() else() include(${ZEPHYR_CANDIDATE} NO_POLICY_SCOPE) set_zephyr_dir(${ZEPHYR_CANDIDATE}) return() endif() endif() endif() endforeach() endmacro()