| # 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() |