From 709daa20e917a4620a600b03f5b6204addf2558c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Mon, 16 Apr 2018 18:55:23 +0200 Subject: [PATCH] cmake: Find a directory that could be used to cache files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To improve the build system's "clean build" runtime we need to cache files in a directory outside of the build directory. Caching files outside of the build directory is is already being done to a certain degree today. For instance, if a user has installed ccache it will cache files in $HOME/.ccache/. This commit locates a directory that is suitable for caching files in a cross-platform way. For instance on Linux this is believed to be $HOME, on Windows this is believed to be %LOCALAPPDATA%. If for whatever reason no environment variables are are found to be suitable we fall back to using $ZEPHYR_BASE/.cache/. For users that often use 'git -clean' the caching mechanism will not work as well, but it will at least be better than no caching at all. Signed-off-by: Sebastian Bøe --- .gitignore | 5 ++++ cmake/app/boilerplate.cmake | 7 +++++ cmake/extensions.cmake | 55 +++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) diff --git a/.gitignore b/.gitignore index 4c78c46e559..a07c8430f13 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,11 @@ build build-* cscope.* .dir + +# The .cache directory will be used to cache toolchain capabilities if +# no suitable out-of-tree directory is found. +.cache + outdir outdir-* scripts/basic/fixdep diff --git a/cmake/app/boilerplate.cmake b/cmake/app/boilerplate.cmake index 1feac864bf1..0d26bb283c0 100644 --- a/cmake/app/boilerplate.cmake +++ b/cmake/app/boilerplate.cmake @@ -274,6 +274,13 @@ set(KERNEL_EXE_NAME ${KERNEL_NAME}.exe) set(KERNEL_STAT_NAME ${KERNEL_NAME}.stat) set(KERNEL_STRIP_NAME ${KERNEL_NAME}.strip) +# Populate USER_CACHE_DIR with a directory that user applications may +# write cache files to. +if(NOT DEFINED USER_CACHE_DIR) + find_appropriate_cache_directory(USER_CACHE_DIR) +endif() +message(STATUS "Cache files will be written to: ${USER_CACHE_DIR}") + include(${BOARD_DIR}/board.cmake OPTIONAL) zephyr_library_named(app) diff --git a/cmake/extensions.cmake b/cmake/extensions.cmake index f1881f62ae4..c88c6c38eb9 100644 --- a/cmake/extensions.cmake +++ b/cmake/extensions.cmake @@ -1023,3 +1023,58 @@ function(check_if_directory_is_writeable dir ok) endif() endfunction() +function(find_appropriate_cache_directory dir) + set(env_suffix_LOCALAPPDATA .cache) + + if(CMAKE_HOST_APPLE) + # On macOS, ~/Library/Caches is the preferred cache directory. + set(env_suffix_HOME Library/Caches) + else() + set(env_suffix_HOME .cache) + endif() + + # Determine which env vars should be checked + if(CMAKE_HOST_APPLE) + set(dirs HOME) + elseif(CMAKE_HOST_WIN32) + set(dirs LOCALAPPDATA) + else() + # Assume Linux when we did not detect 'mac' or 'win' + # + # On Linux, freedesktop.org recommends using $XDG_CACHE_HOME if + # that is defined and defaulting to $HOME/.cache otherwise. + set(dirs + XDG_CACHE_HOME + HOME + ) + endif() + + foreach(env_var ${dirs}) + if(DEFINED ENV{${env_var}}) + set(env_dir $ENV{${env_var}}) + + check_if_directory_is_writeable(${env_dir} ok) + if(${ok}) + # The directory is write-able + set(user_dir ${env_dir}/${env_suffix_${env_var}}) + break() + else() + # The directory was not writeable, keep looking for a suitable + # directory + endif() + endif() + endforeach() + + # Populate local_dir with a suitable directory for caching + # files. Prefer a directory outside of the git repository because it + # is good practice to have clean git repositories. + if(DEFINED user_dir) + # Zephyr's cache files go in the "zephyr" subdirectory of the + # user's cache directory. + set(local_dir ${user_dir}/zephyr) + else() + set(local_dir ${ZEPHYR_BASE}/.cache) + endif() + + set(${dir} ${local_dir} PARENT_SCOPE) +endfunction()