cmake: Zephyr package now sets ZEPHYR_BASE as cmake cached variable

This commit introduces ZEPHYR_BASE as a cached variable, ensures that
once ZEPHYR_BASE has been set in a project, it is sticky.
Using cached variable also allows users to reconfigure ZEPHYR_BASE if
they so wish.

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
This commit is contained in:
Torsten Rasmussen 2020-03-04 12:34:44 +01:00 committed by Carles Cufí
commit caf596ef1b
3 changed files with 78 additions and 54 deletions

View file

@ -20,15 +20,19 @@ macro(include_boilerplate location)
endif() endif()
endmacro() endmacro()
set(ZEPHYR_BASE $ENV{ZEPHYR_BASE}) set(ENV_ZEPHYR_BASE $ENV{ZEPHYR_BASE})
if((NOT DEFINED ZEPHYR_BASE) AND (DEFINED ENV_ZEPHYR_BASE))
if (ZEPHYR_BASE)
# Get rid of any double folder string before comparison, as example, user provides # Get rid of any double folder string before comparison, as example, user provides
# ZEPHYR_BASE=//path/to//zephyr_base/ # ZEPHYR_BASE=//path/to//zephyr_base/
# must also work. # must also work.
get_filename_component(ZEPHYR_BASE ${ZEPHYR_BASE} ABSOLUTE) get_filename_component(ZEPHYR_BASE ${ENV_ZEPHYR_BASE} ABSOLUTE)
set(ZEPHYR_BASE ${ZEPHYR_BASE} CACHE PATH "Zephyr base")
include_boilerplate("Zephyr base")
return()
endif()
include_boilerplate("zephyr base") if (DEFINED ZEPHYR_BASE)
include_boilerplate("Zephyr base (cached)")
return() return()
endif() endif()
@ -39,28 +43,28 @@ endif()
# Find out the current Zephyr base. # Find out the current Zephyr base.
get_filename_component(CURRENT_ZEPHYR_DIR ${CMAKE_CURRENT_LIST_FILE}/${ZEPHYR_RELATIVE_DIR} ABSOLUTE) get_filename_component(CURRENT_ZEPHYR_DIR ${CMAKE_CURRENT_LIST_FILE}/${ZEPHYR_RELATIVE_DIR} ABSOLUTE)
get_filename_component(PROJECT_WORKTREE_DIR ${CMAKE_CURRENT_LIST_FILE}/${PROJECT_WORKTREE_RELATIVE_DIR} ABSOLUTE) get_filename_component(CURRENT_WORKSPACE_DIR ${CMAKE_CURRENT_LIST_FILE}/${WORKSPACE_RELATIVE_DIR} ABSOLUTE)
string(FIND "${CMAKE_CURRENT_SOURCE_DIR}" "${CURRENT_ZEPHYR_DIR}/" COMMON_INDEX) string(FIND "${CMAKE_CURRENT_SOURCE_DIR}" "${CURRENT_ZEPHYR_DIR}/" COMMON_INDEX)
if (COMMON_INDEX EQUAL 0) if (COMMON_INDEX EQUAL 0)
# Project is in-zephyr-tree. # Project is in Zephyr repository.
# We are in Zephyr tree. # We are in Zephyr repository.
set(ZEPHYR_BASE ${CURRENT_ZEPHYR_DIR}) set(ZEPHYR_BASE ${CURRENT_ZEPHYR_DIR} CACHE PATH "Zephyr base")
include_boilerplate("in-zephyr-tree") include_boilerplate("Zephyr repository")
return() return()
endif() endif()
if(IS_INCLUDED) if(IS_INCLUDED)
# A higher level did the checking and included us and as we are not in-zephyr-tree (checked above) # A higher level did the checking and included us and as we are not in Zephyr repository
# then we must be in work-tree. # (checked above) then we must be in Zephyr workspace.
set(ZEPHYR_BASE ${CURRENT_ZEPHYR_DIR}) set(ZEPHYR_BASE ${CURRENT_ZEPHYR_DIR} CACHE PATH "Zephyr base")
include_boilerplate("in-work-tree") include_boilerplate("Zephyr workspace")
endif() endif()
if(NOT IS_INCLUDED) if(NOT IS_INCLUDED)
string(FIND "${CMAKE_CURRENT_SOURCE_DIR}" "${PROJECT_WORKTREE_DIR}/" COMMON_INDEX) string(FIND "${CMAKE_CURRENT_SOURCE_DIR}" "${CURRENT_WORKSPACE_DIR}/" COMMON_INDEX)
if (COMMON_INDEX EQUAL 0) if (COMMON_INDEX EQUAL 0)
# Project is in-project-worktree-tree. # Project is in Zephyr workspace.
# This means this Zephyr is likely the correct one, but there could be an alternative installed along-side # This means this Zephyr is likely the correct one, but there could be an alternative installed along-side
# Thus, check if there is an even better candidate. # Thus, check if there is an even better candidate.
# This check works the following way. # This check works the following way.
@ -69,20 +73,20 @@ if(NOT IS_INCLUDED)
# comon path with the current sample. # comon path with the current sample.
# and if so, we will retrun here, and let CMake call into the other registered package for real # and if so, we will retrun here, and let CMake call into the other registered package for real
# version checking. # version checking.
check_zephyr_package(PROJECT_WORKTREE_DIR ${PROJECT_WORKTREE_DIR}) check_zephyr_package(CURRENT_WORKSPACE_DIR ${CURRENT_WORKSPACE_DIR})
# We are the best candidate, so let's include boiler plate. # We are the best candidate, so let's include boiler plate.
set(ZEPHYR_BASE ${CURRENT_ZEPHYR_DIR}) set(ZEPHYR_BASE ${CURRENT_ZEPHYR_DIR} CACHE PATH "Zephyr base")
include_boilerplate("in-work-tree") include_boilerplate("Zephyr workspace")
return() return()
endif() endif()
check_zephyr_package(SEARCH_PARENTS) check_zephyr_package(SEARCH_PARENTS)
# Ending here means there were no candidates in-tree of the app. # Ending here means there were no candidates in workspace of the app.
# Thus, the app is build oot. # Thus, the app is built as a Zephyr Freestanding application.
# CMake find_package has already done the version checking, so let's just include boiler plate. # CMake find_package has already done the version checking, so let's just include boiler plate.
# Previous find_package would have cleared Zephyr_FOUND variable, thus set it again. # Previous find_package would have cleared Zephyr_FOUND variable, thus set it again.
set(ZEPHYR_BASE ${CURRENT_ZEPHYR_DIR}) set(ZEPHYR_BASE ${CURRENT_ZEPHYR_DIR} CACHE PATH "Zephyr base")
include_boilerplate("out-of-worktree") include_boilerplate("Freestanding")
endif() endif()

View file

@ -16,7 +16,7 @@ macro(check_zephyr_version)
if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)
if(IS_INCLUDED) if(IS_INCLUDED)
# We are just a candidate, meaning we have been included from other installed module. # We are just a candidate, meaning we have been included from other installed module.
message("\n The following in-zephyr-tree configuration file were considered but not accepted:") message("\n The following Zephyr repository configuration file were considered but not accepted:")
message("\n ${CMAKE_CURRENT_LIST_FILE}, version: ${PACKAGE_VERSION}\n") message("\n ${CMAKE_CURRENT_LIST_FILE}, version: ${PACKAGE_VERSION}\n")
endif() endif()
@ -32,8 +32,14 @@ macro(check_zephyr_version)
endif() endif()
endmacro() endmacro()
# First check to see if user has provided a Zephyr base manually. # First check to see if user has provided a Zephyr base manually and it is first run (cache not set).
set(ZEPHYR_BASE $ENV{ZEPHYR_BASE}) set(ENV_ZEPHYR_BASE $ENV{ZEPHYR_BASE})
if((NOT DEFINED ZEPHYR_BASE) AND (DEFINED ENV_ZEPHYR_BASE))
# Get rid of any double folder string before comparison, as example, user provides
# ZEPHYR_BASE=//path/to//zephyr_base/
# must also work.
get_filename_component(ZEPHYR_BASE $ENV{ZEPHYR_BASE} ABSOLUTE)
endif()
# If ZEPHYR_CANDIDATE is set, it means this file was include instead of called via find_package directly. # If ZEPHYR_CANDIDATE is set, it means this file was include instead of called via find_package directly.
if(ZEPHYR_CANDIDATE) if(ZEPHYR_CANDIDATE)
@ -42,18 +48,16 @@ else()
include(${CMAKE_CURRENT_LIST_DIR}/zephyr_package_search.cmake) include(${CMAKE_CURRENT_LIST_DIR}/zephyr_package_search.cmake)
endif() endif()
if (ZEPHYR_BASE) if((DEFINED ZEPHYR_BASE) OR (DEFINED ENV_ZEPHYR_BASE))
# ZEPHYR_BASE was set in environment, meaning the package version must be ignored and the Zephyr # ZEPHYR_BASE was set in cache from earlier run or in environment (first run),
# pointed to by ZEPHYR_BASE is to be used regardless of version # meaning the package version must be ignored and the Zephyr pointed to by
# ZEPHYR_BASE is to be used regardless of version.
# Get rid of any double folder string before comparison, as example, user provides
# ZEPHYR_BASE=//path/to//zephyr_base/
# must also work.
get_filename_component(ZEPHYR_BASE ${ZEPHYR_BASE} ABSOLUTE)
if (${ZEPHYR_BASE}/share/zephyr-package/cmake STREQUAL ${CMAKE_CURRENT_LIST_DIR}) if (${ZEPHYR_BASE}/share/zephyr-package/cmake STREQUAL ${CMAKE_CURRENT_LIST_DIR})
# We are the Zephyr to be used # We are the Zephyr to be used
set(PACKAGE_VERSION_COMPATIBLE TRUE) set(PACKAGE_VERSION_COMPATIBLE TRUE)
set(PACKAGE_VERSION_EXACT TRUE) set(PACKAGE_VERSION_EXACT TRUE)
elseif ((NOT IS_INCLUDED) AND (DEFINED ZEPHYR_BASE))
check_zephyr_package(ZEPHYR_BASE ${ZEPHYR_BASE} VERSION_CHECK)
else() else()
# User has pointed to a different Zephyr installation, so don't use this version # User has pointed to a different Zephyr installation, so don't use this version
set(PACKAGE_VERSION_COMPATIBLE FALSE) set(PACKAGE_VERSION_COMPATIBLE FALSE)
@ -63,9 +67,9 @@ endif()
# Find out the current Zephyr base. # Find out the current Zephyr base.
get_filename_component(CURRENT_ZEPHYR_DIR ${CMAKE_CURRENT_LIST_DIR}/../../.. ABSOLUTE) get_filename_component(CURRENT_ZEPHYR_DIR ${CMAKE_CURRENT_LIST_DIR}/../../.. ABSOLUTE)
get_filename_component(PROJECT_WORKTREE_DIR ${CMAKE_CURRENT_LIST_DIR}/../../../.. ABSOLUTE) get_filename_component(CURRENT_WORKSPACE_DIR ${CMAKE_CURRENT_LIST_DIR}/../../../.. ABSOLUTE)
# Temporary set local Zephyr base to allow using version.cmake to find this Zephyr tree current version # Temporary set local Zephyr base to allow using version.cmake to find this Zephyr repository current version
set(ZEPHYR_BASE ${CURRENT_ZEPHYR_DIR}) set(ZEPHYR_BASE ${CURRENT_ZEPHYR_DIR})
# Tell version.cmake to not print as printing version for all Zephyr installations being tested # Tell version.cmake to not print as printing version for all Zephyr installations being tested
@ -79,28 +83,28 @@ set(ZEPHYR_BASE)
# Do we share common index, if so, this is the correct version to check. # Do we share common index, if so, this is the correct version to check.
string(FIND "${CMAKE_CURRENT_SOURCE_DIR}" "${CURRENT_ZEPHYR_DIR}/" COMMON_INDEX) string(FIND "${CMAKE_CURRENT_SOURCE_DIR}" "${CURRENT_ZEPHYR_DIR}/" COMMON_INDEX)
if (COMMON_INDEX EQUAL 0) if (COMMON_INDEX EQUAL 0)
# Project is in-zephyr-tree. # Project is a Zephyr repository app.
check_zephyr_version() check_zephyr_version()
return() return()
endif() endif()
if(NOT IS_INCLUDED) if(NOT IS_INCLUDED)
# Only do this if we are an installed CMake Config package and checking for work-tree candidates. # Only do this if we are an installed CMake Config package and checking for workspace candidates.
string(FIND "${CMAKE_CURRENT_SOURCE_DIR}" "${PROJECT_WORKTREE_DIR}/" COMMON_INDEX) string(FIND "${CMAKE_CURRENT_SOURCE_DIR}" "${CURRENT_WORKSPACE_DIR}/" COMMON_INDEX)
if (COMMON_INDEX EQUAL 0) if (COMMON_INDEX EQUAL 0)
# Project is a Zephyr workspace app. # Project is a Zephyr workspace app.
# This means this Zephyr is likely the correct one, but there could be an alternative installed along-side # This means this Zephyr is likely the correct one, but there could be an alternative installed along-side
# Thus, check if there is an even better candidate. # Thus, check if there is an even better candidate.
check_zephyr_package(PROJECT_WORKTREE_DIR ${PROJECT_WORKTREE_DIR} VERSION_CHECK) check_zephyr_package(CURRENT_WORKSPACE_DIR ${CURRENT_WORKSPACE_DIR} VERSION_CHECK)
# We are the best candidate, so let's check our own version. # We are the best candidate, so let's check our own version.
check_zephyr_version() check_zephyr_version()
return() return()
endif() endif()
# Checking for installed candidates which could also be an worktree candidates. # Checking for installed candidates which could also be an workspace candidates.
# This check works the following way. # This check works the following way.
# CMake finds packages will look all packages registered in the user package registry. # CMake finds packages will look all packages registered in the user package registry.
# As this code is processed inside registered packages, we simply test if # As this code is processed inside registered packages, we simply test if
@ -113,7 +117,7 @@ if(NOT IS_INCLUDED)
check_zephyr_package(SEARCH_PARENTS VERSION_CHECK) check_zephyr_package(SEARCH_PARENTS VERSION_CHECK)
endif() endif()
# Ending here means there were no candidates in-tree of the app. # Ending here means there were no candidates in workspace of the app.
# Thus, the app is build oot. # Thus, the app is built as a Zephyr Freestanding application.
# Let's do basic CMake version checking. # Let's do basic CMake version checking.
check_zephyr_version() check_zephyr_version()

View file

@ -3,8 +3,8 @@
# Linux/MacOS: ~/.cmake/packages # Linux/MacOS: ~/.cmake/packages
# Windows: Registry database # Windows: Registry database
# Relative directory of worktree project dir as seen from Zephyr package file # Relative directory of workspace project dir as seen from Zephyr package file
set(PROJECT_WORKTREE_RELATIVE_DIR "../../../../..") set(WORKSPACE_RELATIVE_DIR "../../../../..")
# Relative directory of Zephyr dir as seen from Zephyr package file # Relative directory of Zephyr dir as seen from Zephyr package file
set(ZEPHYR_RELATIVE_DIR "../../../..") set(ZEPHYR_RELATIVE_DIR "../../../..")
@ -21,17 +21,22 @@ endmacro()
# This macro can check for additional Zephyr package that has a better match # This macro can check for additional Zephyr package that has a better match
# Options: # Options:
# - PROJECT_WORKTREE_DIR: Search for projects in specified worktree. # - 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. # - 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. # - 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 # - VERSION_CHECK : This is the version check stage by CMake find package
macro(check_zephyr_package) macro(check_zephyr_package)
set(options CHECK_ONLY INCLUDE_FILE SEARCH_PARENTS VERSION_CHECK) set(options CHECK_ONLY INCLUDE_FILE SEARCH_PARENTS VERSION_CHECK)
set(single_args PROJECT_WORKTREE_DIR) set(single_args WORKSPACE_DIR ZEPHYR_BASE)
cmake_parse_arguments(CHECK_ZEPHYR_PACKAGE "${options}" "${single_args}" "" ${ARGN}) cmake_parse_arguments(CHECK_ZEPHYR_PACKAGE "${options}" "${single_args}" "" ${ARGN})
if(CHECK_ZEPHYR_PACKAGE_PROJECT_WORKTREE_DIR) if(CHECK_ZEPHYR_PACKAGE_ZEPHYR_BASE)
set(SEARCH_SETTINGS PATHS ${CHECK_ZEPHYR_PACKAGE_PROJECT_WORKTREE_DIR}/zephyr ${CHECK_ZEPHYR_PACKAGE_PROJECT_WORKTREE_DIR} NO_DEFAULT_PATH) 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() endif()
if(CHECK_ZEPHYR_PACKAGE_SEARCH_PARENTS) if(CHECK_ZEPHYR_PACKAGE_SEARCH_PARENTS)
@ -49,11 +54,22 @@ macro(check_zephyr_package)
list(REMOVE_DUPLICATES Zephyr_CONSIDERED_CONFIGS) list(REMOVE_DUPLICATES Zephyr_CONSIDERED_CONFIGS)
foreach(ZEPHYR_CANDIDATE ${Zephyr_CONSIDERED_CONFIGS}) foreach(ZEPHYR_CANDIDATE ${Zephyr_CONSIDERED_CONFIGS})
if(CHECK_ZEPHYR_PACKAGE_PROJECT_WORKTREE_DIR) if(CHECK_ZEPHYR_PACKAGE_WORKSPACE_DIR)
# Check is done in project tree already, thus check only for pure Zephyr candidates. # 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) get_filename_component(CANDIDATE_DIR ${ZEPHYR_CANDIDATE}/${ZEPHYR_RELATIVE_DIR} ABSOLUTE)
else() else()
get_filename_component(CANDIDATE_DIR ${ZEPHYR_CANDIDATE}/${PROJECT_WORKTREE_RELATIVE_DIR} ABSOLUTE) 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)
return()
endif()
endif() endif()
string(FIND "${CMAKE_CURRENT_SOURCE_DIR}" "${CANDIDATE_DIR}/" COMMON_INDEX) string(FIND "${CMAKE_CURRENT_SOURCE_DIR}" "${CANDIDATE_DIR}/" COMMON_INDEX)