diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 48a9624ef..6ca788c66 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -855,6 +855,18 @@ check_permissions: script: - tools/ci/check-executable.sh +check_version: + <<: *check_job_template + # Don't run this for feature/bugfix branches, so that it is possible to modify + # esp_idf_version.h in a branch before tagging the next version. + only: + - master + - /^release\/v/ + - /^v\d+\.\d+(\.\d+)?($|-)/ + script: + - export IDF_PATH=$PWD + - tools/ci/check_idf_version.sh + check_examples_cmake_make: <<: *check_job_template except: diff --git a/components/esp_common/include/esp_idf_version.h b/components/esp_common/include/esp_idf_version.h new file mode 100644 index 000000000..52601ca8f --- /dev/null +++ b/components/esp_common/include/esp_idf_version.h @@ -0,0 +1,58 @@ +// Copyright 2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +/** Major version number (X.x.x) */ +#define ESP_IDF_VERSION_MAJOR 4 +/** Minor version number (x.X.x) */ +#define ESP_IDF_VERSION_MINOR 0 +/** Patch version number (x.x.X) */ +#define ESP_IDF_VERSION_PATCH 0 + +/** + * Macro to convert IDF version number into an integer + * + * To be used in comparisons, such as ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0) + */ +#define ESP_IDF_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch)) + +/** + * Current IDF version, as an integer + * + * To be used in comparisons, such as ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0) + */ +#define ESP_IDF_VERSION ESP_IDF_VERSION_VAL(ESP_IDF_VERSION_MAJOR, \ + ESP_IDF_VERSION_MINOR, \ + ESP_IDF_VERSION_PATCH) + +/** + * Return full IDF version string, same as 'git describe' output. + * + * @note If you are printing the ESP-IDF version in a log file or other information, + * this function provides more information than using the numerical version macros. + * For example, numerical version macros don't differentiate between development, + * pre-release and release versions, but the output of this function does. + * + * @return constant string from IDF_VER + */ +const char* esp_get_idf_version(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_common/include/esp_system.h b/components/esp_common/include/esp_system.h index 97dc91622..13c8f198d 100644 --- a/components/esp_common/include/esp_system.h +++ b/components/esp_common/include/esp_system.h @@ -20,6 +20,7 @@ #include "esp_err.h" #include "esp_attr.h" #include "esp_bit_defs.h" +#include "esp_idf_version.h" #include "sdkconfig.h" @@ -311,14 +312,6 @@ esp_err_t esp_derive_local_mac(uint8_t* local_mac, const uint8_t* universal_mac) const char* system_get_sdk_version(void) __attribute__ ((deprecated)); /** @endcond */ -/** - * Get IDF version - * - * @return constant string from IDF_VER - */ -const char* esp_get_idf_version(void); - - /** * @brief Chip models */ diff --git a/docs/Doxyfile b/docs/Doxyfile index cd92c6909..0673440bd 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -179,6 +179,8 @@ INPUT = \ ## Base MAC address ## NOTE: for line below header_file.inc is not used ../../components/esp_common/include/esp_system.h \ + ## IDF version + ../../components/esp_common/include/esp_idf_version.h \ ## ## ULP Coprocessor - API Guides ## diff --git a/docs/en/api-guides/build-system-cmake.rst b/docs/en/api-guides/build-system-cmake.rst index a3c068bf9..b52448122 100644 --- a/docs/en/api-guides/build-system-cmake.rst +++ b/docs/en/api-guides/build-system-cmake.rst @@ -350,6 +350,7 @@ from the component CMakeLists.txt: - ``PROJECT_DIR``: Absolute path of the project directory containing the project CMakeLists. Same as the ``CMAKE_SOURCE_DIR`` variable. - ``COMPONENTS``: Names of all components that are included in this build, formatted as a semicolon-delimited CMake list. - ``IDF_VER``: Git version of ESP-IDF (produced by ``git describe``) +- ``IDF_VERSION_MAJOR``, ``IDF_VERSION_MINOR``, ``IDF_VERSION_PATCH``: Components of ESP-IDF version, to be used in conditional expressions. Note that this information is less precise than that provided by ``IDF_VER`` variable. ``v4.0-dev-*``, ``v4.0-beta1``, ``v4.0-rc1`` and ``v4.0`` will all have the same values of ``IDF_VERSION_*`` variables, but different ``IDF_VER`` values. - ``IDF_TARGET``: Name of the target for which the project is being built. - ``PROJECT_VER``: Project version. diff --git a/docs/en/api-guides/build-system.rst b/docs/en/api-guides/build-system.rst index 8c85c65d3..5f936c05f 100644 --- a/docs/en/api-guides/build-system.rst +++ b/docs/en/api-guides/build-system.rst @@ -188,6 +188,7 @@ The following variables are set at the project level, but exported for use in th - ``CC``, ``LD``, ``AR``, ``OBJCOPY``: Full paths to each tool from the gcc xtensa cross-toolchain. - ``HOSTCC``, ``HOSTLD``, ``HOSTAR``: Full names of each tool from the host native toolchain. - ``IDF_VER``: ESP-IDF version, retrieved from either ``$(IDF_PATH)/version.txt`` file (if present) else using git command ``git describe``. Recommended format here is single liner that specifies major IDF release version, e.g. ``v2.0`` for a tagged release or ``v2.0-275-g0efaa4f`` for an arbitrary commit. Application can make use of this by calling :cpp:func:`esp_get_idf_version`. +- ``IDF_VERSION_MAJOR``, ``IDF_VERSION_MINOR``, ``IDF_VERSION_PATCH``: Components of ESP-IDF version, to be used in conditional expressions. Note that this information is less precise than that provided by ``IDF_VER`` variable. ``v4.0-dev-*``, ``v4.0-beta1``, ``v4.0-rc1`` and ``v4.0`` will all have the same values of ``ESP_IDF_VERSION_*`` variables, but different ``IDF_VER`` values. - ``PROJECT_VER``: Project version. * If ``PROJECT_VER`` variable is set in project Makefile file, its value will be used. diff --git a/docs/en/api-reference/system/system.rst b/docs/en/api-reference/system/system.rst index a15860e8a..719452c3f 100644 --- a/docs/en/api-reference/system/system.rst +++ b/docs/en/api-reference/system/system.rst @@ -109,6 +109,21 @@ SDK version :cpp:func:`esp_get_idf_version` returns a string describing the IDF version which was used to compile the application. This is the same value as the one available through ``IDF_VER`` variable of the build system. The version string generally has the format of ``git describe`` output. +To get the version at build time, additional version macros are provided. They can be used to enable or disable parts of the program depending on IDF version. + +* :c:macro:`ESP_IDF_VERSION_MAJOR`, :c:macro:`ESP_IDF_VERSION_MINOR`, :c:macro:`ESP_IDF_VERSION_PATCH` are defined to integers representing major, minor, and patch version. + +* :c:macro:`ESP_IDF_VERSION_VAL` and :c:macro:`ESP_IDF_VERSION` can be used when implementing version checks: + + .. code-block:: c + + #include "esp_idf_version.h" + + #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0) + // enable functionality present in IDF v4.0 + #endif + + App version ----------- Application version is stored in :cpp:class:`esp_app_desc_t` structure. It is located in DROM sector and has a fixed offset from the beginning of the binary file. @@ -125,5 +140,6 @@ API Reference ------------- .. include:: /_build/inc/esp_system.inc +.. include:: /_build/inc/esp_idf_version.inc diff --git a/docs/zh_CN/api-guides/build-system-cmake.rst b/docs/zh_CN/api-guides/build-system-cmake.rst index 96b46aa92..43935a3ae 100644 --- a/docs/zh_CN/api-guides/build-system-cmake.rst +++ b/docs/zh_CN/api-guides/build-system-cmake.rst @@ -315,6 +315,7 @@ ESP-IDF 在搜索所有待构建的组件时,会按照 ``COMPONENT_DIRS`` 指 - ``COMPONENTS``:此次构建中包含的所有组件的名称,具体格式为用分号隔开的 CMake 列表。 - ``CONFIG_*``:项目配置中的每个值在 cmake 中都对应一个以 ``CONFIG_`` 开头的变量。更多详细信息请参阅 :doc:`Kconfig `。 - ``IDF_VER``:ESP-IDF 的 git 版本号,由 ``git describe`` 命令生成。 +- ``IDF_VERSION_MAJOR``, ``IDF_VERSION_MINOR``, ``IDF_VERSION_PATCH``: ESP-IDF 的组件版本,可用于条件表达式。请注意这些信息的精确度不如 ``IDF_VER`` 变量,版本号 ``v4.0-dev-*``, ``v4.0-beta1``, ``v4.0-rc1`` 和 ``v4.0`` 对应的 ``IDF_VERSION_*`` 变量值是相同的,但是 ``IDF_VER`` 的值是不同的。 - ``IDF_TARGET``:项目的硬件目标名称。 - ``PROJECT_VER``:项目版本号。 diff --git a/docs/zh_CN/api-guides/build-system.rst b/docs/zh_CN/api-guides/build-system.rst index 366f7d79f..60bba24ef 100644 --- a/docs/zh_CN/api-guides/build-system.rst +++ b/docs/zh_CN/api-guides/build-system.rst @@ -176,6 +176,7 @@ ESP-IDF 搜索组件时,会按照 ``COMPONENT_DIRS`` 指定的顺序依次进 - ``CC``,``LD``,``AR``,``OBJCOPY``: gcc xtensa 交叉编译工具链中每个工具的完整路径。 - ``HOSTCC``,``HOSTLD``,``HOSTAR``: 主机本地工具链中每个工具的全名。 - ``IDF_VER``: ESP-IDF 的版本号,可以通过检索 ``$(IDF_PATH)/version.txt`` 文件(假如存在的话)或者使用 git 命令 ``git describe`` 来获取。这里推荐的格式是在一行中指定主 IDF 的发布版本号,例如标记为 ``v2.0`` 的发布版本或者是标记任意一次提交记录的 ``v2.0-275-g0efaa4f``。应用程序可以通过调用 :cpp:func:`esp_get_idf_version` 函数来使用该变量。 +- ``IDF_VERSION_MAJOR``, ``IDF_VERSION_MINOR``, ``IDF_VERSION_PATCH``: ESP-IDF 的组件版本,可用于条件表达式。请注意这些信息的精确度不如 ``IDF_VER`` 变量,版本号 ``v4.0-dev-*``, ``v4.0-beta1``, ``v4.0-rc1`` 和 ``v4.0`` 对应的 ``IDF_VERSION_*`` 变量值是相同的,但是 ``IDF_VER`` 的值是不同的。 如果您在 ``component.mk`` 文件中修改这些变量,这并不会影响其它组件的构建,但可能会使您的组件变得难以构建或调试。 diff --git a/make/common.mk b/make/common.mk index 6280ca4a8..bb0000a10 100644 --- a/make/common.mk +++ b/make/common.mk @@ -38,6 +38,9 @@ ifdef CONFIG_SDK_MAKE_WARN_UNDEFINED_VARIABLES MAKEFLAGS += --warn-undefined-variables endif +# Get version variables +include $(IDF_PATH)/make/version.mk + # General make utilities # convenience variable for printing an 80 asterisk wide separator line diff --git a/make/project.mk b/make/project.mk index 2f1def70d..bd375afaf 100644 --- a/make/project.mk +++ b/make/project.mk @@ -126,7 +126,7 @@ export PROJECT_PATH endif # A list of the "common" makefiles, to use as a target dependency -COMMON_MAKEFILES := $(abspath $(IDF_PATH)/make/project.mk $(IDF_PATH)/make/common.mk $(IDF_PATH)/make/component_wrapper.mk $(firstword $(MAKEFILE_LIST))) +COMMON_MAKEFILES := $(abspath $(IDF_PATH)/make/project.mk $(IDF_PATH)/make/common.mk $(IDF_PATH)/make/version.mk $(IDF_PATH)/make/component_wrapper.mk $(firstword $(MAKEFILE_LIST))) export COMMON_MAKEFILES # The directory where we put all objects/libraries/binaries. The project Makefile can diff --git a/make/version.mk b/make/version.mk new file mode 100644 index 000000000..9dcda422a --- /dev/null +++ b/make/version.mk @@ -0,0 +1,3 @@ +IDF_VERSION_MAJOR := 4 +IDF_VERSION_MINOR := 0 +IDF_VERSION_PATCH := 0 diff --git a/tools/ci/check_idf_version.sh b/tools/ci/check_idf_version.sh new file mode 100755 index 000000000..36fdf003f --- /dev/null +++ b/tools/ci/check_idf_version.sh @@ -0,0 +1,62 @@ +#!/bin/bash + +set -u +set -e + +echo "Checking if IDF version in esp_idf_version.h matches 'git describe' output" + +function get_ver_from_header() { + # Get the 3rd word from '#define ESP_IDF_VERSION_X ' line. + grep -E "^#define ${1}" components/esp_common/include/esp_idf_version.h | awk '{print $3;}' +} + +function get_ver_from_make() { + grep -E "^${1} :=" make/version.mk | awk '{print $3;}' +} + +function get_ver_from_cmake() { + grep -E "^set\(${1}" tools/cmake/version.cmake | sed -En "s/set\(${1} ([0-9])\)/\1/p" +} + +header_ver_major=$(get_ver_from_header ESP_IDF_VERSION_MAJOR) +header_ver_minor=$(get_ver_from_header ESP_IDF_VERSION_MINOR) +header_ver_patch=$(get_ver_from_header ESP_IDF_VERSION_PATCH) +version_from_header="${header_ver_major}.${header_ver_minor}.${header_ver_patch}" + +make_ver_major=$(get_ver_from_make IDF_VERSION_MAJOR) +make_ver_minor=$(get_ver_from_make IDF_VERSION_MINOR) +make_ver_patch=$(get_ver_from_make IDF_VERSION_PATCH) +version_from_make="${make_ver_major}.${make_ver_minor}.${make_ver_patch}" + +cmake_ver_major=$(get_ver_from_cmake IDF_VERSION_MAJOR) +cmake_ver_minor=$(get_ver_from_cmake IDF_VERSION_MINOR) +cmake_ver_patch=$(get_ver_from_cmake IDF_VERSION_PATCH) +version_from_cmake="${cmake_ver_major}.${cmake_ver_minor}.${cmake_ver_patch}" + +git_desc=$(git describe --tags) +git_desc_regex="^v([0-9]+)\.([0-9]+)(\.([0-9]+))?.*$" +if [[ ! ${git_desc} =~ ${git_desc_regex} ]]; then + echo "Could not determine the version from 'git describe' output: ${git_desc}" + exit 1 +fi +version_from_git="${BASH_REMATCH[1]}.${BASH_REMATCH[2]}.${BASH_REMATCH[4]:-0}" + +echo "From esp_idf_version.h: ${version_from_header}" +echo "From version.mk: ${version_from_make}" +echo "From version.cmake: ${version_from_cmake}" +echo "From git describe: ${version_from_git}" + +if [[ "${version_from_header}" != "${version_from_git}" ]]; then + echo "esp_idf_version.h does not match 'git describe' output" + exit 1 +fi + +if [[ "${version_from_make}" != "${version_from_git}" ]]; then + echo "version.mk does not match 'git describe' output" + exit 1 +fi + +if [[ "${version_from_cmake}" != "${version_from_git}" ]]; then + echo "version.cmake does not match 'git describe' output" + exit 1 +fi diff --git a/tools/ci/executable-list.txt b/tools/ci/executable-list.txt index 14071ab2e..49bb91626 100644 --- a/tools/ci/executable-list.txt +++ b/tools/ci/executable-list.txt @@ -21,6 +21,7 @@ docs/gen-version-specific-includes.py tools/ci/apply_bot_filter.py tools/ci/build_examples.sh tools/ci/build_examples_cmake.sh +tools/ci/check_idf_version.sh tools/ci/check-executable.sh tools/ci/check-line-endings.sh tools/ci/checkout_project_ref.py diff --git a/tools/cmake/idf.cmake b/tools/cmake/idf.cmake index 9d45fd9dd..e97d83fcd 100644 --- a/tools/cmake/idf.cmake +++ b/tools/cmake/idf.cmake @@ -38,6 +38,7 @@ if(NOT __idf_env_set) include(utilities) include(targets) include(ldgen) + include(version) __build_init("${idf_path}") diff --git a/tools/cmake/version.cmake b/tools/cmake/version.cmake new file mode 100644 index 000000000..265ab33b7 --- /dev/null +++ b/tools/cmake/version.cmake @@ -0,0 +1,3 @@ +set(IDF_VERSION_MAJOR 4) +set(IDF_VERSION_MINOR 0) +set(IDF_VERSION_PATCH 0)