build: Add CONFIG_APP_PROJECT_VER to set the project version from Kconfig

This commit is contained in:
KonstantinKondrashov 2019-11-27 19:01:40 +08:00 committed by bot
parent 0da18955aa
commit b49a657448
11 changed files with 123 additions and 62 deletions

View file

@ -7,11 +7,18 @@ idf_component_register(SRCS "esp_ota_ops.c"
# linker will ignore this structure as it has no other files depending on it. # linker will ignore this structure as it has no other files depending on it.
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u esp_app_desc") target_link_libraries(${COMPONENT_LIB} INTERFACE "-u esp_app_desc")
if(CONFIG_APP_PROJECT_VER_FROM_CONFIG)
# Ignore current PROJECT_VER (which was set in __project_get_revision()).
# Gets the version from the CONFIG_APP_PROJECT_VER.
idf_build_set_property(PROJECT_VER "${CONFIG_APP_PROJECT_VER}")
endif()
# cut PROJECT_VER and PROJECT_NAME to required 32 characters. # cut PROJECT_VER and PROJECT_NAME to required 32 characters.
idf_build_get_property(project_ver PROJECT_VER) idf_build_get_property(project_ver PROJECT_VER)
idf_build_get_property(project_name PROJECT_NAME) idf_build_get_property(project_name PROJECT_NAME)
string(SUBSTRING "${project_ver}" 0 31 PROJECT_VER_CUT) string(SUBSTRING "${project_ver}" 0 31 PROJECT_VER_CUT)
string(SUBSTRING "${project_name}" 0 31 PROJECT_NAME_CUT) string(SUBSTRING "${project_name}" 0 31 PROJECT_NAME_CUT)
message(STATUS "App \"${PROJECT_NAME_CUT}\" version: ${PROJECT_VER_CUT}")
set_source_files_properties( set_source_files_properties(
SOURCE "esp_app_desc.c" SOURCE "esp_app_desc.c"

View file

@ -22,4 +22,18 @@ menu "Application manager"
The PROJECT_NAME variable from the build system will not affect the firmware image. The PROJECT_NAME variable from the build system will not affect the firmware image.
This value will not be contained in the esp_app_desc structure. This value will not be contained in the esp_app_desc structure.
config APP_PROJECT_VER_FROM_CONFIG
bool "Get the project version from Kconfig"
default n
help
If this is enabled, then config item APP_PROJECT_VER will be used for the variable PROJECT_VER.
Other ways to set PROJECT_VER will be ignored.
config APP_PROJECT_VER
string "Project version"
default "1"
depends on APP_PROJECT_VER_FROM_CONFIG
help
Project version
endmenu # "Application manager" endmenu # "Application manager"

View file

@ -8,49 +8,49 @@
COMPONENT_ADD_LDFLAGS += -u esp_app_desc COMPONENT_ADD_LDFLAGS += -u esp_app_desc
ifndef IS_BOOTLOADER_BUILD ifndef IS_BOOTLOADER_BUILD
GET_PROJECT_VER ?= # If ``CONFIG_APP_PROJECT_VER_FROM_CONFIG`` option is set, the value of ``CONFIG_APP_PROJECT_VER`` will be used
ifeq ("${PROJECT_VER}", "") # Else, if ``PROJECT_VER`` variable set in project Makefile file, its value will be used.
ifeq ("$(wildcard ${PROJECT_PATH}/version.txt)","") # Else, if the ``$PROJECT_PATH/version.txt`` exists, its contents will be used as ``PROJECT_VER``.
# Else, if the project is located inside a Git repository, the output of git describe will be used.
# Otherwise, ``PROJECT_VER`` will be "1".
ifdef CONFIG_APP_PROJECT_VER_FROM_CONFIG
PROJECT_VER:= $(CONFIG_APP_PROJECT_VER)
else
ifneq ("${PROJECT_VER}", "")
PROJECT_VER:= $(PROJECT_VER)
else
ifneq ("$(wildcard ${PROJECT_PATH}/version.txt)","")
PROJECT_VER := $(shell cat ${PROJECT_PATH}/version.txt)
else
GIT_PROJECT_VER := $(shell cd ${PROJECT_PATH} && git describe --always --tags --dirty 2> /dev/null)
ifeq ("${GIT_PROJECT_VER}", "")
PROJECT_VER := "1"
$(info Project is not inside a git repository, or git repository has no commits)
$(info will not use 'git describe' to determine PROJECT_VER.)
else
PROJECT_VER:= $(GIT_PROJECT_VER)
endif # a git repository
endif # version.txt
endif # PROJECT_VER
endif # CONFIG_APP_PROJECT_VER_FROM_CONFIG
GET_PROJECT_VER := $(shell cd ${PROJECT_PATH} && git describe --always --tags --dirty 2> /dev/null) # cut PROJECT_VER and PROJECT_NAME to required 32 characters.
ifeq ("${GET_PROJECT_VER}", "") PROJECT_VER_CUT := $(shell echo "$(PROJECT_VER)" | cut -c 1-31)
GET_PROJECT_VER := "1" PROJECT_NAME_CUT := $(shell echo "$(PROJECT_NAME)" | cut -c 1-31)
$(info Project is not inside a git repository, will not use 'git describe' to determine PROJECT_VER.)
endif
else $(info App "$(PROJECT_NAME_CUT)" version: $(PROJECT_VER_CUT))
# read from version.txt
GET_PROJECT_VER := $(shell cat ${PROJECT_PATH}/version.txt)
endif
endif
# If ``PROJECT_VER`` variable set in project Makefile file, its value will be used.
# Else, if the ``$PROJECT_PATH/version.txt`` exists, its contents will be used as ``PROJECT_VER``.
# Else, if the project is located inside a Git repository, the output of git describe will be used.
# Otherwise, ``PROJECT_VER`` will be "1".
ifeq ("${PROJECT_VER}", "") NEW_DEFINES:= "$(PROJECT_VER_CUT) $(PROJECT_NAME_CUT) $(IDF_VER)"
PROJECT_VER:= $(GET_PROJECT_VER) ifeq ("$(wildcard ${TMP_DEFINES})","")
else OLD_DEFINES:= ""
PROJECT_VER:= $(PROJECT_VER) else
endif OLD_DEFINES:= "$(shell cat $(TMP_DEFINES))"
endif
# cut PROJECT_VER and PROJECT_NAME to required 32 characters. # If NEW_DEFINES (PROJECT_VER, PROJECT_NAME) were changed then rebuild only esp_app_desc.
PROJECT_VER_CUT := $(shell echo "$(PROJECT_VER)" | cut -c 1-31) ifneq (${NEW_DEFINES}, ${OLD_DEFINES})
PROJECT_NAME_CUT := $(shell echo "$(PROJECT_NAME)" | cut -c 1-31) $(shell echo $(NEW_DEFINES) > $(TMP_DEFINES); rm -f esp_app_desc.o;)
endif
$(info App "$(PROJECT_NAME_CUT)" version: $(PROJECT_VER_CUT)) esp_app_desc.o: CPPFLAGS += -D PROJECT_VER=\""$(PROJECT_VER_CUT)"\" -D PROJECT_NAME=\""$(PROJECT_NAME_CUT)"\"
endif # IS_BOOTLOADER_BUILD
NEW_DEFINES:= "$(PROJECT_VER_CUT) $(PROJECT_NAME_CUT) $(IDF_VER)"
ifeq ("$(wildcard ${TMP_DEFINES})","")
OLD_DEFINES:= ""
else
OLD_DEFINES:= "$(shell cat $(TMP_DEFINES))"
endif
# If NEW_DEFINES (PROJECT_VER, PROJECT_NAME) were changed then rebuild only esp_app_desc.
ifneq (${NEW_DEFINES}, ${OLD_DEFINES})
$(shell echo $(NEW_DEFINES) > $(TMP_DEFINES); rm -f esp_app_desc.o;)
endif
esp_app_desc.o: CPPFLAGS += -D PROJECT_VER=\""$(PROJECT_VER_CUT)"\" -D PROJECT_NAME=\""$(PROJECT_NAME_CUT)"\"
endif

View file

@ -193,7 +193,8 @@ The following variables are set at the project level, but exported for use in th
- ``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. - ``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. - ``PROJECT_VER``: Project version.
* If ``PROJECT_VER`` variable is set in project Makefile file, its value will be used. * If :ref:`CONFIG_APP_PROJECT_VER_FROM_CONFIG` option is set, the value of :ref:`CONFIG_APP_PROJECT_VER` will be used.
* Else, if ``PROJECT_VER`` variable is set in project Makefile file, its value will be used.
* Else, if the ``$PROJECT_PATH/version.txt`` exists, its contents will be used as ``PROJECT_VER``. * Else, if the ``$PROJECT_PATH/version.txt`` exists, its contents will be used as ``PROJECT_VER``.
* Else, if the project is located inside a Git repository, the output of git describe will be used. * Else, if the project is located inside a Git repository, the output of git describe will be used.
* Otherwise, ``PROJECT_VER`` will be "1". * Otherwise, ``PROJECT_VER`` will be "1".

View file

@ -368,7 +368,8 @@ from the component CMakeLists.txt:
- ``IDF_TARGET``: Name of the target for which the project is being built. - ``IDF_TARGET``: Name of the target for which the project is being built.
- ``PROJECT_VER``: Project version. - ``PROJECT_VER``: Project version.
* If ``PROJECT_VER`` variable is set in project CMakeLists.txt file, its value will be used. * If :ref:`CONFIG_APP_PROJECT_VER_FROM_CONFIG` option is set, the value of :ref:`CONFIG_APP_PROJECT_VER` will be used.
* Else, if ``PROJECT_VER`` variable is set in project CMakeLists.txt file, its value will be used.
* Else, if the ``PROJECT_DIR/version.txt`` exists, its contents will be used as ``PROJECT_VER``. * Else, if the ``PROJECT_DIR/version.txt`` exists, its contents will be used as ``PROJECT_VER``.
* Else, if the project is located inside a Git repository, the output of git describe will be used. * Else, if the project is located inside a Git repository, the output of git describe will be used.
* Otherwise, ``PROJECT_VER`` will be "1". * Otherwise, ``PROJECT_VER`` will be "1".

View file

@ -155,7 +155,7 @@ To set version in your project manually you need to set ``PROJECT_VER`` variable
(For legacy GNU Make build system: in application Makefile put ``PROJECT_VER = "0.1.0.1"`` before including ``project.mk``.) (For legacy GNU Make build system: in application Makefile put ``PROJECT_VER = "0.1.0.1"`` before including ``project.mk``.)
If ``PROJECT_VER`` variable is not set in the project then it will be retrieved from either ``$(PROJECT_PATH)/version.txt`` file (if present) else using git command ``git describe``. If neither is available then ``PROJECT_VER`` will be set to "1". Application can make use of this by calling :cpp:func:`esp_ota_get_app_description` or :cpp:func:`esp_ota_get_partition_description` functions. If :ref:`CONFIG_APP_PROJECT_VER_FROM_CONFIG` option is set, the value of :ref:`CONFIG_APP_PROJECT_VER` will be used. Otherwise if ``PROJECT_VER`` variable is not set in the project then it will be retrieved from either ``$(PROJECT_PATH)/version.txt`` file (if present) else using git command ``git describe``. If neither is available then ``PROJECT_VER`` will be set to "1". Application can make use of this by calling :cpp:func:`esp_ota_get_app_description` or :cpp:func:`esp_ota_get_partition_description` functions.

View file

@ -109,10 +109,11 @@ If GPIO is not pulled low then the operable of the app will be confirmed.
For ``native_ota_example``, code has been added to demonstrate how to check the version of the application and prevent infinite firmware updates. Only the application with the new version can be downloaded. Version checking is performed after the very first firmware image package has been received, which contains data about the firmware version. The application version can be taken from three places: For ``native_ota_example``, code has been added to demonstrate how to check the version of the application and prevent infinite firmware updates. Only the application with the new version can be downloaded. Version checking is performed after the very first firmware image package has been received, which contains data about the firmware version. The application version can be taken from three places:
1. If ``PROJECT_VER`` variable set in project Cmake/Makefile file, its value will be used. 1. If `CONFIG_APP_PROJECT_VER_FROM_CONFIG` option is set, the value of `CONFIG_APP_PROJECT_VER` will be used.
2. Else, if the ``$PROJECT_PATH/version.txt`` exists, its contents will be used as ``PROJECT_VER``. 2. Else, if ``PROJECT_VER`` variable set in project Cmake/Makefile file, its value will be used.
3. Else, if the project is located inside a Git repository, the output of ``git describe`` will be used. 3. Else, if the ``$PROJECT_PATH/version.txt`` exists, its contents will be used as ``PROJECT_VER``.
4. Otherwise, ``PROJECT_VER`` will be "1". 4. Else, if the project is located inside a Git repository, the output of ``git describe`` will be used.
5. Otherwise, ``PROJECT_VER`` will be "1".
In ``native_ota_example``, ``$PROJECT_PATH/version.txt`` is used to define the version of app. Change the version in the file to compile the new firmware. In ``native_ota_example``, ``$PROJECT_PATH/version.txt`` is used to define the version of app. Change the version in the file to compile the new firmware.

View file

@ -265,6 +265,22 @@ function run_tests()
version+=$(git describe --always --tags --dirty) version+=$(git describe --always --tags --dirty)
grep "${version}" log.log || failure "Project version should have a hash commit" grep "${version}" log.log || failure "Project version should have a hash commit"
print_status "Get the version of app from Kconfig option"
make clean > /dev/null
rm -f sdkconfig.defaults
rm -f sdkconfig
echo "project_version_from_txt" > ${TESTDIR}/template/version.txt
echo "CONFIG_APP_PROJECT_VER_FROM_CONFIG=y" >> sdkconfig.defaults
echo 'CONFIG_APP_PROJECT_VER="project_version_from_Kconfig"' >> sdkconfig.defaults
make defconfig > /dev/null
make >> log.log || failure "Failed to build"
version="App \"app-template\" version: "
version+="project_version_from_Kconfig"
grep "${version}" log.log || failure "Project version should be from Kconfig"
rm -f sdkconfig.defaults
rm -f sdkconfig
rm -f ${TESTDIR}/template/version.txt
print_status "Build fails if partitions don't fit in flash" print_status "Build fails if partitions don't fit in flash"
sed -i.bak "s/CONFIG_ESPTOOLPY_FLASHSIZE.\+//" sdkconfig # remove all flashsize config sed -i.bak "s/CONFIG_ESPTOOLPY_FLASHSIZE.\+//" sdkconfig # remove all flashsize config
echo "CONFIG_ESPTOOLPY_FLASHSIZE_1MB=y" >> sdkconfig # introduce undersize flash echo "CONFIG_ESPTOOLPY_FLASHSIZE_1MB=y" >> sdkconfig # introduce undersize flash

View file

@ -120,10 +120,25 @@ function run_tests()
print_status "Get the version of app from git describe. Project is not inside IDF and do not have a tag only a hash commit." print_status "Get the version of app from git describe. Project is not inside IDF and do not have a tag only a hash commit."
idf.py reconfigure >> log.log || failure "Failed to build" idf.py reconfigure >> log.log || failure "Failed to build"
version="Project version: " version="App \"app-template\" version: "
version+=$(git describe --always --tags --dirty) version+=$(git describe --always --tags --dirty)
grep "${version}" log.log || failure "Project version should have a hash commit" grep "${version}" log.log || failure "Project version should have a hash commit"
print_status "Get the version of app from Kconfig option"
idf.py clean > /dev/null
rm -f sdkconfig.defaults
rm -f sdkconfig
echo "project_version_from_txt" > ${TESTDIR}/template/version.txt
echo "CONFIG_APP_PROJECT_VER_FROM_CONFIG=y" >> sdkconfig.defaults
echo 'CONFIG_APP_PROJECT_VER="project_version_from_Kconfig"' >> sdkconfig.defaults
idf.py build >> log.log || failure "Failed to build"
version="App \"app-template\" version: "
version+="project_version_from_Kconfig"
grep "${version}" log.log || failure "Project version should be from Kconfig"
rm -f sdkconfig.defaults
rm -f sdkconfig
rm -f ${TESTDIR}/template/version.txt
print_status "Moving BUILD_DIR_BASE out of tree" print_status "Moving BUILD_DIR_BASE out of tree"
clean_build_dir clean_build_dir
OUTOFTREE_BUILD=${TESTDIR}/alt_build OUTOFTREE_BUILD=${TESTDIR}/alt_build
@ -555,7 +570,7 @@ endmenu\n" >> ${IDF_PATH}/Kconfig
clean_build_dir clean_build_dir
git branch test_build_system git branch test_build_system
git worktree add ../esp-idf-template-test test_build_system git worktree add ../esp-idf-template-test test_build_system
diff <(idf.py reconfigure | grep "Project version") <(cd ../esp-idf-template-test && idf.py reconfigure | grep "Project version") \ diff <(idf.py reconfigure | grep "App \"app-template\" version: ") <(cd ../esp-idf-template-test && idf.py reconfigure | grep "App \"app-template\" version: ") \
|| failure "Version on worktree should have been properly resolved" || failure "Version on worktree should have been properly resolved"
git worktree remove ../esp-idf-template-test git worktree remove ../esp-idf-template-test

View file

@ -55,7 +55,6 @@ function(__project_get_revision var)
endif() endif()
endif() endif()
endif() endif()
message(STATUS "Project version: ${PROJECT_VER}")
set(${var} "${PROJECT_VER}" PARENT_SCOPE) set(${var} "${PROJECT_VER}" PARENT_SCOPE)
endfunction() endfunction()

View file

@ -18,23 +18,30 @@ set(HEAD_HASH)
file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024) file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024)
string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS) string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS)
set(GIT_DIR "@GIT_DIR@")
# handle git-worktree
if(EXISTS "${GIT_DIR}/commondir")
file(READ "${GIT_DIR}/commondir" GIT_DIR_NEW LIMIT 1024)
string(STRIP "${GIT_DIR_NEW}" GIT_DIR_NEW)
if(NOT IS_ABSOLUTE "${GIT_DIR_NEW}")
get_filename_component(GIT_DIR_NEW ${GIT_DIR}/${GIT_DIR_NEW} ABSOLUTE)
endif()
if(EXISTS "${GIT_DIR_NEW}")
set(GIT_DIR "${GIT_DIR_NEW}")
endif()
endif()
if(HEAD_CONTENTS MATCHES "ref") if(HEAD_CONTENTS MATCHES "ref")
# named branch # named branch
string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}") string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
if(EXISTS "@GIT_DIR@/${HEAD_REF}") if(EXISTS "${GIT_DIR}/${HEAD_REF}")
configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) configure_file("${GIT_DIR}/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
else() elseif(EXISTS "${GIT_DIR}/logs/${HEAD_REF}")
if(EXISTS "@GIT_DIR@/packed-refs") configure_file("${GIT_DIR}/logs/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY) set(HEAD_HASH "${HEAD_REF}")
file(READ "@GIT_DATA@/packed-refs" PACKED_REFS)
if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}")
set(HEAD_HASH "${CMAKE_MATCH_1}")
endif()
endif()
endif() endif()
else() else()
# detached HEAD # detached HEAD
configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY) configure_file("${GIT_DIR}/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
endif() endif()
if(NOT HEAD_HASH) if(NOT HEAD_HASH)