diff --git a/share/zephyr-package/cmake/ZephyrConfig.cmake b/share/zephyr-package/cmake/ZephyrConfig.cmake index b3befca89d7..7c1e6212ba7 100644 --- a/share/zephyr-package/cmake/ZephyrConfig.cmake +++ b/share/zephyr-package/cmake/ZephyrConfig.cmake @@ -10,8 +10,6 @@ # Set Zephyr base to environment setting. # It will be empty if not set in environment. -include(${CMAKE_CURRENT_LIST_DIR}/zephyr_package_search.cmake) - macro(include_boilerplate location) if(ZEPHYR_UNITTEST) set(ZephyrUnittest_FOUND True) @@ -46,6 +44,8 @@ endif() # If ZEPHYR_CANDIDATE is set, it means this file was include instead of called via find_package directly. if(ZEPHYR_CANDIDATE) set(IS_INCLUDED TRUE) +else() + include(${CMAKE_CURRENT_LIST_DIR}/zephyr_package_search.cmake) endif() # Find out the current Zephyr base. @@ -82,13 +82,17 @@ if(NOT IS_INCLUDED) # version checking. check_zephyr_package(CURRENT_WORKSPACE_DIR ${CURRENT_WORKSPACE_DIR}) + if(ZEPHYR_PREFER) + check_zephyr_package(SEARCH_PARENTS CANDIDATES_PREFERENCE_LIST ${ZEPHYR_PREFER}) + endif() + # We are the best candidate, so let's include boiler plate. set(ZEPHYR_BASE ${CURRENT_ZEPHYR_DIR} CACHE PATH "Zephyr base") include_boilerplate("Zephyr workspace") return() endif() - check_zephyr_package(SEARCH_PARENTS) + check_zephyr_package(SEARCH_PARENTS CANDIDATES_PREFERENCE_LIST ${ZEPHYR_PREFER}) # Ending here means there were no candidates in workspace of the app. # Thus, the app is built as a Zephyr Freestanding application. diff --git a/share/zephyr-package/cmake/zephyr_package_search.cmake b/share/zephyr-package/cmake/zephyr_package_search.cmake index d06becab29a..db24f548d65 100644 --- a/share/zephyr-package/cmake/zephyr_package_search.cmake +++ b/share/zephyr-package/cmake/zephyr_package_search.cmake @@ -10,9 +10,12 @@ set(WORKSPACE_RELATIVE_DIR "../../../../..") set(ZEPHYR_RELATIVE_DIR "../../../..") # This macro returns a list of parent folders to use for later searches. -macro(get_search_paths START_PATH SEARCH_PATHS) +macro(get_search_paths START_PATH SEARCH_PATHS PREFERENCE_LIST) get_filename_component(SEARCH_PATH ${START_PATH} DIRECTORY) while(NOT (SEARCH_PATH STREQUAL "/")) + 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}) get_filename_component(SEARCH_PATH ${SEARCH_PATH} DIRECTORY) @@ -21,15 +24,19 @@ 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 +# - 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 INCLUDE_FILE SEARCH_PARENTS VERSION_CHECK) + set(options CHECK_ONLY SEARCH_PARENTS VERSION_CHECK) set(single_args WORKSPACE_DIR ZEPHYR_BASE) - cmake_parse_arguments(CHECK_ZEPHYR_PACKAGE "${options}" "${single_args}" "" ${ARGN}) + 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) @@ -40,7 +47,7 @@ macro(check_zephyr_package) endif() if(CHECK_ZEPHYR_PACKAGE_SEARCH_PARENTS) - get_search_paths(${CMAKE_CURRENT_SOURCE_DIR} SEARCH_PATHS) + 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() @@ -48,9 +55,12 @@ macro(check_zephyr_package) # 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 in-tree, so to avoid re-including - # this file, it is removed from the list along with any duplicates. - list(REMOVE_ITEM Zephyr_CONSIDERED_CONFIGS ${CMAKE_CURRENT_LIST_DIR}/ZephyrConfig.cmake) + # 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}) @@ -78,8 +88,10 @@ macro(check_zephyr_package) # 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() - # A better candidate exists, thus return if(CHECK_ZEPHYR_PACKAGE_VERSION_CHECK) string(REGEX REPLACE "\.cmake$" "Version.cmake" ZEPHYR_VERSION_CANDIDATE ${ZEPHYR_CANDIDATE}) include(${ZEPHYR_VERSION_CANDIDATE} NO_POLICY_SCOPE)