1# SPDX-License-Identifier: Apache-2.0 2 3# This file provides Zephyr Config Package functionality. 4# 5# The purpose of this files is to allow users to decide if they want to: 6# - Use ZEPHYR_BASE environment setting for explicitly set select a zephyr installation 7# - Support automatic Zephyr installation lookup through the use of find_package(ZEPHYR) 8 9# First check to see if user has provided a Zephyr base manually. 10# Set Zephyr base to environment setting. 11# It will be empty if not set in environment. 12 13# Internal Zephyr CMake package message macro. 14# 15# This macro is only intended to be used within the Zephyr CMake package. 16# The function `find_package()` supports an optional QUIET argument, and to 17# honor that argument, the package_message() macro will not print messages when 18# said flag has been given. 19# 20# Arguments to zephyr_package_message() are identical to regular CMake message() 21# function. 22macro(zephyr_package_message) 23 if(NOT Zephyr_FIND_QUIETLY) 24 message(${ARGN}) 25 endif() 26endmacro() 27 28macro(include_boilerplate location) 29 set(Zephyr_DIR ${ZEPHYR_BASE}/share/zephyr-package/cmake CACHE PATH 30 "The directory containing a CMake configuration file for Zephyr." FORCE 31 ) 32 list(PREPEND CMAKE_MODULE_PATH ${ZEPHYR_BASE}/cmake/modules) 33 if(ZEPHYR_UNITTEST) 34 zephyr_package_message(DEPRECATION "The ZephyrUnittest CMake package has been deprecated.\n" 35 "ZephyrUnittest has been replaced with Zephyr CMake module 'unittest' \n" 36 "and can be loaded as: 'find_package(Zephyr COMPONENTS unittest)'" 37 ) 38 set(ZephyrUnittest_FOUND True) 39 set(Zephyr_FIND_COMPONENTS unittest) 40 else() 41 set(Zephyr_FOUND True) 42 endif() 43 44 if(NOT DEFINED APPLICATION_SOURCE_DIR) 45 set(APPLICATION_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH 46 "Application Source Directory" 47 ) 48 endif() 49 50 if(NOT DEFINED APPLICATION_BINARY_DIR) 51 set(APPLICATION_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR} CACHE PATH 52 "Application Binary Directory" 53 ) 54 endif() 55 56 set(__build_dir ${APPLICATION_BINARY_DIR}/zephyr) 57 set(PROJECT_BINARY_DIR ${__build_dir}) 58 59 if(NOT NO_BOILERPLATE) 60 list(LENGTH Zephyr_FIND_COMPONENTS components_length) 61 # The module messages are intentionally higher than STATUS to avoid the -- prefix 62 # and make them more visible to users. This does result in them being output 63 # to stderr, but that is an implementation detail of cmake. 64 if(components_length EQUAL 0) 65 zephyr_package_message(NOTICE "Loading Zephyr default modules (${location}).") 66 include(zephyr_default NO_POLICY_SCOPE) 67 else() 68 string(JOIN " " msg_components ${Zephyr_FIND_COMPONENTS}) 69 zephyr_package_message(NOTICE "Loading Zephyr module(s) (${location}): ${msg_components}") 70 foreach(component ${Zephyr_FIND_COMPONENTS}) 71 if(${component} MATCHES "^\([^:]*\):\(.*\)$") 72 string(REPLACE "," ";" SUB_COMPONENTS ${CMAKE_MATCH_2}) 73 set(component ${CMAKE_MATCH_1}) 74 endif() 75 include(${component}) 76 endforeach() 77 endif() 78 else() 79 zephyr_package_message(DEPRECATION "The NO_BOILERPLATE setting has been deprecated.\n" 80 "Please use: 'find_package(Zephyr COMPONENTS <components>)'" 81 ) 82 endif() 83endmacro() 84 85set(ENV_ZEPHYR_BASE $ENV{ZEPHYR_BASE}) 86if((NOT DEFINED ZEPHYR_BASE) AND (DEFINED ENV_ZEPHYR_BASE)) 87 # Get rid of any double folder string before comparison, as example, user provides 88 # ZEPHYR_BASE=//path/to//zephyr_base/ 89 # must also work. 90 get_filename_component(ZEPHYR_BASE ${ENV_ZEPHYR_BASE} ABSOLUTE) 91 set(ZEPHYR_BASE ${ZEPHYR_BASE} CACHE PATH "Zephyr base") 92 include_boilerplate("Zephyr base") 93 return() 94endif() 95 96if (DEFINED ZEPHYR_BASE) 97 include_boilerplate("Zephyr base (cached)") 98 return() 99endif() 100 101# If ZEPHYR_CANDIDATE is set, it means this file was include instead of called via find_package directly. 102if(ZEPHYR_CANDIDATE) 103 set(IS_INCLUDED TRUE) 104else() 105 include(${CMAKE_CURRENT_LIST_DIR}/zephyr_package_search.cmake) 106endif() 107 108# Find out the current Zephyr base. 109get_filename_component(CURRENT_ZEPHYR_DIR ${CMAKE_CURRENT_LIST_FILE}/${ZEPHYR_RELATIVE_DIR} ABSOLUTE) 110get_filename_component(CURRENT_WORKSPACE_DIR ${CMAKE_CURRENT_LIST_FILE}/${WORKSPACE_RELATIVE_DIR} ABSOLUTE) 111 112string(FIND "${CMAKE_CURRENT_SOURCE_DIR}" "${CURRENT_ZEPHYR_DIR}/" COMMON_INDEX) 113if (COMMON_INDEX EQUAL 0) 114 # Project is in Zephyr repository. 115 # We are in Zephyr repository. 116 set(ZEPHYR_BASE ${CURRENT_ZEPHYR_DIR} CACHE PATH "Zephyr base") 117 include_boilerplate("Zephyr repository") 118 return() 119endif() 120 121if(IS_INCLUDED) 122 # A higher level did the checking and included us and as we are not in Zephyr repository 123 # (checked above) then we must be in Zephyr workspace. 124 set(ZEPHYR_BASE ${CURRENT_ZEPHYR_DIR} CACHE PATH "Zephyr base") 125 include_boilerplate("Zephyr workspace") 126endif() 127 128if(NOT IS_INCLUDED) 129 string(FIND "${CMAKE_CURRENT_SOURCE_DIR}" "${CURRENT_WORKSPACE_DIR}/" COMMON_INDEX) 130 if (COMMON_INDEX EQUAL 0) 131 # Project is in Zephyr workspace. 132 # This means this Zephyr is likely the correct one, but there could be an alternative installed along-side 133 # Thus, check if there is an even better candidate. 134 # This check works the following way. 135 # CMake finds packages will look all packages registered in the user package registry. 136 # As this code is processed inside registered packages, we simply test if another package has a 137 # common path with the current sample. 138 # and if so, we will return here, and let CMake call into the other registered package for real 139 # version checking. 140 check_zephyr_package(WORKSPACE_DIR ${CURRENT_WORKSPACE_DIR}) 141 142 if(ZEPHYR_PREFER) 143 check_zephyr_package(SEARCH_PARENTS CANDIDATES_PREFERENCE_LIST ${ZEPHYR_PREFER}) 144 endif() 145 146 # We are the best candidate, so let's include boiler plate. 147 set(ZEPHYR_BASE ${CURRENT_ZEPHYR_DIR} CACHE PATH "Zephyr base") 148 include_boilerplate("Zephyr workspace") 149 return() 150 endif() 151 152 check_zephyr_package(SEARCH_PARENTS CANDIDATES_PREFERENCE_LIST ${ZEPHYR_PREFER}) 153 154 # Ending here means there were no candidates in workspace of the app. 155 # Thus, the app is built as a Zephyr Freestanding application. 156 # CMake find_package has already done the version checking, so let's just include boiler plate. 157 # Previous find_package would have cleared Zephyr_FOUND variable, thus set it again. 158 set(ZEPHYR_BASE ${CURRENT_ZEPHYR_DIR} CACHE PATH "Zephyr base") 159 include_boilerplate("Freestanding") 160endif() 161