Skip to content

Commit

Permalink
cmake: find_package to honor list of zephyr installations to prefer
Browse files Browse the repository at this point in the history
This commit introduces ZEPHYR_PREFER which is a list that user can
specify when compiling an application.

This allows a user who has multiple Zephyr installations in the same
work-tree to provide a list of which Zephyr to prefer.

This is an extension to CMake VERSION field, as a user who is working
with multiple Zephyr installations could face a situation where multiple
Zephyr's is having same version, as example 2.2.99, in which case CMake
version is not sufficient.

Example, workspace looking as:
/projects/workspace/zephyr
/projects/workspace/zephyr-alternate
/projects/workspace/zephyr-wip
/projects/workspace/my_app

To prefer zephyr-alternate, then zephyr-wip the my_app/CMakeLists.txt
should look as:
set(ZEPHYR_PREFER "zephyr-alternate" "zephyr-wip")
find_package(Zephyr)

Signed-off-by: Torsten Rasmussen <[email protected]>
  • Loading branch information
tejlmand authored and carlescufi committed Mar 27, 2020
1 parent e85cfe4 commit 8e929fd
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 16 deletions.
10 changes: 7 additions & 3 deletions share/zephyr-package/cmake/ZephyrConfig.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down
38 changes: 25 additions & 13 deletions share/zephyr-package/cmake/zephyr_package_search.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -40,17 +47,20 @@ 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()

# 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 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})
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 8e929fd

Please sign in to comment.