diff --git a/components/app_update/Makefile.projbuild b/components/app_update/Makefile.projbuild index 4015a601f..5045d19e4 100644 --- a/components/app_update/Makefile.projbuild +++ b/components/app_update/Makefile.projbuild @@ -50,6 +50,7 @@ $(BLANK_OTA_DATA_FILE): partition_table_get_info blank_ota_data: $(BLANK_OTA_DATA_FILE) erase_ota: partition_table_get_info + $(CHECK_PYTHON_DEPENDENCIES_CMD) @echo $(if $(OTA_DATA_OFFSET), "Erase ota_data [addr=$(OTA_DATA_OFFSET) size=$(OTA_DATA_SIZE)] ...", $(error "ERROR: Partition table does not have ota_data partition.")) $(ESPTOOLPY_SERIAL) erase_region $(OTA_DATA_OFFSET) $(OTA_DATA_SIZE) diff --git a/components/bootloader/Makefile.projbuild b/components/bootloader/Makefile.projbuild index b283c9044..d6c7a2796 100644 --- a/components/bootloader/Makefile.projbuild +++ b/components/bootloader/Makefile.projbuild @@ -50,6 +50,7 @@ ifndef CONFIG_SECURE_BOOT_ENABLED # with 'make flash' and no warnings are printed. bootloader: $(BOOTLOADER_BIN) + $(CHECK_PYTHON_DEPENDENCIES_CMD) @echo $(SEPARATOR) @echo "Bootloader built. Default flash command is:" @echo "$(ESPTOOLPY_WRITE_FLASH) $(BOOTLOADER_OFFSET) $^" @@ -57,6 +58,7 @@ bootloader: $(BOOTLOADER_BIN) ESPTOOL_ALL_FLASH_ARGS += $(BOOTLOADER_OFFSET) $(BOOTLOADER_BIN) bootloader-flash: $(BOOTLOADER_BIN) $(call prereq_if_explicit,erase_flash) + $(CHECK_PYTHON_DEPENDENCIES_CMD) $(ESPTOOLPY_WRITE_FLASH) 0x1000 $^ else ifdef CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH @@ -68,6 +70,7 @@ else ifdef CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH # step, so the device doesn't immediately reset to flash itself. bootloader: $(BOOTLOADER_BIN) + $(CHECK_PYTHON_DEPENDENCIES_CMD) @echo $(SEPARATOR) @echo "Bootloader built. One-time flash command is:" @echo "$(subst hard_reset,no_reset,$(ESPTOOLPY_WRITE_FLASH)) $(BOOTLOADER_OFFSET) $(BOOTLOADER_BIN)" @@ -83,6 +86,7 @@ SECURE_BOOTLOADER_KEY := $(BOOTLOADER_BUILD_DIR)/secure-bootloader-key.bin ifdef CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES $(SECURE_BOOTLOADER_KEY): $(SECURE_BOOT_SIGNING_KEY) + $(CHECK_PYTHON_DEPENDENCIES_CMD) $(ESPSECUREPY) digest_private_key -k $< $@ else $(SECURE_BOOTLOADER_KEY): @@ -106,6 +110,7 @@ bootloader: $(BOOTLOADER_DIGEST_BIN) @echo "* Not recommended to re-use the same secure boot keyfile on multiple production devices." $(BOOTLOADER_DIGEST_BIN): $(BOOTLOADER_BIN) $(SECURE_BOOTLOADER_KEY) + $(CHECK_PYTHON_DEPENDENCIES_CMD) @echo "DIGEST $(notdir $@)" $(ESPSECUREPY) digest_secure_bootloader -k $(SECURE_BOOTLOADER_KEY) -o $@ $< diff --git a/components/esptool_py/Makefile.projbuild b/components/esptool_py/Makefile.projbuild index 25f4b8e6f..8d37f4e2b 100644 --- a/components/esptool_py/Makefile.projbuild +++ b/components/esptool_py/Makefile.projbuild @@ -56,9 +56,11 @@ endif APP_BIN_UNSIGNED ?= $(APP_BIN) $(APP_BIN_UNSIGNED): $(APP_ELF) $(ESPTOOLPY_SRC) + $(CHECK_PYTHON_DEPENDENCIES_CMD) $(ESPTOOLPY) elf2image $(ESPTOOL_FLASH_OPTIONS) $(ESPTOOL_ELF2IMAGE_OPTIONS) -o $@ $< flash: all_binaries $(ESPTOOLPY_SRC) $(call prereq_if_explicit,erase_flash) partition_table_get_info + $(CHECK_PYTHON_DEPENDENCIES_CMD) @echo "Flashing binaries to serial port $(ESPPORT) (app at offset $(APP_OFFSET))..." ifdef CONFIG_SECURE_BOOT_ENABLED @echo "(Secure boot enabled, so bootloader not flashed automatically. See 'make bootloader' output)" @@ -66,6 +68,7 @@ endif $(ESPTOOLPY_WRITE_FLASH) $(ESPTOOL_ALL_FLASH_ARGS) app-flash: $(APP_BIN) $(ESPTOOLPY_SRC) $(call prereq_if_explicit,erase_flash) partition_table_get_info + $(CHECK_PYTHON_DEPENDENCIES_CMD) @echo "Flashing app to serial port $(ESPPORT), offset $(APP_OFFSET)..." $(ESPTOOLPY_WRITE_FLASH) $(APP_OFFSET) $(APP_BIN) @@ -74,6 +77,7 @@ app-flash: $(APP_BIN) $(ESPTOOLPY_SRC) $(call prereq_if_explicit,erase_flash) pa COMPONENT_SUBMODULES += $(COMPONENT_PATH)/esptool erase_flash: + $(CHECK_PYTHON_DEPENDENCIES_CMD) @echo "Erasing entire flash..." $(ESPTOOLPY_SERIAL) erase_flash @@ -90,14 +94,14 @@ endif # note: if you want to run miniterm from command line, can simply run # miniterm.py on the console. The '$(PYTHON) -m serial.tools.miniterm' # is to allow for the $(PYTHON) variable overriding the python path. -simple_monitor: $(call prereq_if_explicit,%flash) +simple_monitor: check_python_dependencies $(call prereq_if_explicit,%flash) $(MONITOR_PYTHON) -m serial.tools.miniterm --rts 0 --dtr 0 --raw $(ESPPORT) $(MONITORBAUD) PRINT_FILTER ?= MONITOR_OPTS := --baud $(MONITORBAUD) --port $(ESPPORT) --toolchain-prefix $(CONFIG_TOOLPREFIX) --make "$(MAKE)" --print_filter "$(PRINT_FILTER)" -monitor: $(call prereq_if_explicit,%flash) +monitor: check_python_dependencies $(call prereq_if_explicit,%flash) $(summary) MONITOR [ -f $(APP_ELF) ] || echo "*** 'make monitor' target requires an app to be compiled and flashed first." [ -f $(APP_ELF) ] || echo "*** Run 'make flash monitor' to build, flash and monitor" diff --git a/components/partition_table/Makefile.projbuild b/components/partition_table/Makefile.projbuild index b53419620..7bbf3f489 100644 --- a/components/partition_table/Makefile.projbuild +++ b/components/partition_table/Makefile.projbuild @@ -57,6 +57,7 @@ PARTITION_TABLE_BIN_UNSIGNED := $(PARTITION_TABLE_BIN) endif $(PARTITION_TABLE_BIN_UNSIGNED): $(PARTITION_TABLE_CSV_PATH) $(SDKCONFIG_MAKEFILE) + $(CHECK_PYTHON_DEPENDENCIES_CMD) @echo "Building partitions from $(PARTITION_TABLE_CSV_PATH)..." $(GEN_ESP32PART) $< $@ @@ -77,6 +78,7 @@ PARTITION_TABLE_FLASH_CMD = $(ESPTOOLPY_SERIAL) write_flash $(PARTITION_TABLE_OF ESPTOOL_ALL_FLASH_ARGS += $(PARTITION_TABLE_OFFSET) $(PARTITION_TABLE_BIN) partition_table: $(PARTITION_TABLE_BIN) partition_table_get_info + $(CHECK_PYTHON_DEPENDENCIES_CMD) @echo "Partition table binary generated. Contents:" @echo $(SEPARATOR) $(GEN_ESP32PART) $< @@ -85,6 +87,7 @@ partition_table: $(PARTITION_TABLE_BIN) partition_table_get_info @echo "$(PARTITION_TABLE_FLASH_CMD)" partition_table-flash: $(PARTITION_TABLE_BIN) + $(CHECK_PYTHON_DEPENDENCIES_CMD) @echo "Flashing partition table..." $(PARTITION_TABLE_FLASH_CMD) diff --git a/docs/en/get-started/index.rst b/docs/en/get-started/index.rst index 188b6938d..96922e882 100644 --- a/docs/en/get-started/index.rst +++ b/docs/en/get-started/index.rst @@ -136,6 +136,18 @@ Setup Path to ESP-IDF The toolchain programs access ESP-IDF using ``IDF_PATH`` environment variable. This variable should be set up on your PC, otherwise projects will not build. Setting may be done manually, each time PC is restarted. Another option is to set up it permanently by defining ``IDF_PATH`` in user profile. To do so, follow instructions specific to :ref:`Windows ` , :ref:`Linux and MacOS ` in section :doc:`add-idf_path-to-profile`. +.. _get-started-get-packages: + +Install the Required Python Packages +==================================== + +Python packages required by ESP-IDF are located in the ``$IDF_PATH/requirements.txt`` file. You can install them by running:: + + sudo pip install -r $IDF_PATH/requirements.txt + +or you can use the following command for installing them into the user install directory on systems where you don't have administrator rights:: + + pip install --user -r $IDF_PATH/requirements.txt .. _get-started-start-project: diff --git a/docs/en/get-started/linux-setup-scratch.rst b/docs/en/get-started/linux-setup-scratch.rst index b2cb96ec3..44644e1d5 100644 --- a/docs/en/get-started/linux-setup-scratch.rst +++ b/docs/en/get-started/linux-setup-scratch.rst @@ -18,6 +18,11 @@ To compile with ESP-IDF you need to get the following packages: sudo pacman -S --needed gcc git make ncurses flex bison gperf python2-pyserial +.. note:: + + Some older (pre-2014) Linux distributions may use ``pyserial`` version 2.x which is not supported by ESP-IDF. + In this case please install a supported version via ``pip`` as it is described in section + :ref:`get-started-get-packages`. Compile the Toolchain from Source ================================= diff --git a/docs/en/get-started/linux-setup.rst b/docs/en/get-started/linux-setup.rst index 277fdb671..440f37c84 100644 --- a/docs/en/get-started/linux-setup.rst +++ b/docs/en/get-started/linux-setup.rst @@ -21,6 +21,11 @@ To compile with ESP-IDF you need to get the following packages: sudo pacman -S --needed gcc git make ncurses flex bison gperf python2-pyserial +.. note:: + + Some older (pre-2014) Linux distributions may use ``pyserial`` version 2.x which is not supported by ESP-IDF. + In this case please install a supported version via ``pip`` as it is described in section + :ref:`get-started-get-packages`. Toolchain Setup =============== diff --git a/docs/en/get-started/macos-setup-scratch.rst b/docs/en/get-started/macos-setup-scratch.rst index 7516158a1..731122723 100644 --- a/docs/en/get-started/macos-setup-scratch.rst +++ b/docs/en/get-started/macos-setup-scratch.rst @@ -9,10 +9,9 @@ Install Prerequisites sudo easy_install pip -- install pyserial:: - - sudo pip install pyserial +.. note:: + ``pip`` will be used later for installing :ref:`the required Python packages `. Compile the Toolchain from Source ================================= diff --git a/docs/en/get-started/macos-setup.rst b/docs/en/get-started/macos-setup.rst index 16123cb03..00e5be431 100644 --- a/docs/en/get-started/macos-setup.rst +++ b/docs/en/get-started/macos-setup.rst @@ -10,10 +10,9 @@ Install Prerequisites sudo easy_install pip -- install pyserial:: - - sudo pip install pyserial +.. note:: + ``pip`` will be used later for installing :ref:`the required Python packages `. Toolchain Setup =============== diff --git a/docs/zh_CN/get-started/index.rst b/docs/zh_CN/get-started/index.rst index 6e38dbdfc..85497278b 100644 --- a/docs/zh_CN/get-started/index.rst +++ b/docs/zh_CN/get-started/index.rst @@ -133,6 +133,12 @@ ESP32 是一套 Wi-Fi (2.4 GHz) 和蓝牙 (4.2) 双模解决方案,集成了 工具链程序使用环境变量 ``IDF_PATH`` 来访问 ESP-IDF。这个变量应该设置在你的 PC 中,否则工程将不能编译。你可以在每次 PC 重启时手工设置,也可以通过在用户配置文件中定义 ``IDF_PATH`` 变量来永久性设置。要永久性设置,请参考 :doc:`add-idf_path-to-profile` 文档中 :ref:`Windows ` 或 :ref:`Linux and MacOS ` 相关的指导进行操作。 +.. _get-started-get-packages: + +Install the Required Python Packages +==================================== + +TODO .. _get-started-start-project: diff --git a/make/project.mk b/make/project.mk index a5fea2f52..305fb3bd5 100644 --- a/make/project.mk +++ b/make/project.mk @@ -13,7 +13,7 @@ .PHONY: build-components menuconfig defconfig all build clean all_binaries check-submodules size size-components size-files size-symbols list-components MAKECMDGOALS ?= all -all: all_binaries +all: all_binaries check_python_dependencies # see below for recipe of 'all' target # # # other components will add dependencies to 'all_binaries'. The @@ -43,12 +43,13 @@ help: @echo "make app-flash - Flash just the app" @echo "make app-clean - Clean just the app" @echo "make print_flash_cmd - Print the arguments for esptool when flash" + @echo "make check_python_dependencies - Check that the required python packages are installed" @echo "" @echo "See also 'make bootloader', 'make bootloader-flash', 'make bootloader-clean', " @echo "'make partition_table', etc, etc." # Non-interactive targets. Mostly, those for which you do not need to build a binary -NON_INTERACTIVE_TARGET += defconfig clean% %clean help list-components print_flash_cmd +NON_INTERACTIVE_TARGET += defconfig clean% %clean help list-components print_flash_cmd check_python_dependencies # dependency checks ifndef MAKE_RESTARTS @@ -421,6 +422,14 @@ else @echo $(ESPTOOLPY_WRITE_FLASH) $(APP_OFFSET) $(APP_BIN) endif +CHECK_PYTHON_DEPENDENCIES_CMD := $(PYTHON) $(IDF_PATH)/tools/check_python_dependencies.py + +.PHONY: check_python_dependencies + +# Notify users when some of the required python packages are not installed +check_python_dependencies: + $(CHECK_PYTHON_DEPENDENCIES_CMD) + all_binaries: $(APP_BIN) $(BUILD_DIR_BASE): @@ -476,16 +485,16 @@ app-clean: $(addprefix component-,$(addsuffix -clean,$(notdir $(COMPONENT_PATHS) $(summary) RM $(APP_ELF) rm -f $(APP_ELF) $(APP_BIN) $(APP_MAP) -size: $(APP_ELF) +size: check_python_dependencies $(APP_ELF) $(PYTHON) $(IDF_PATH)/tools/idf_size.py $(APP_MAP) -size-files: $(APP_ELF) +size-files: check_python_dependencies $(APP_ELF) $(PYTHON) $(IDF_PATH)/tools/idf_size.py --files $(APP_MAP) -size-components: $(APP_ELF) +size-components: check_python_dependencies $(APP_ELF) $(PYTHON) $(IDF_PATH)/tools/idf_size.py --archives $(APP_MAP) -size-symbols: $(APP_ELF) +size-symbols: check_python_dependencies $(APP_ELF) ifndef COMPONENT $(error "ERROR: Please enter the component to look symbols for, e.g. COMPONENT=heap") else diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 000000000..eeffa7e8d --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +# This is a list of python packages needed for IDF. This file is used with pip: +# pip install -r requirements.txt +# +pyserial>=3.0 +future>=0.16.0 diff --git a/tools/check_python_dependencies.py b/tools/check_python_dependencies.py new file mode 100644 index 000000000..9c5f8e855 --- /dev/null +++ b/tools/check_python_dependencies.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python +# +# Copyright 2018 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. + +import os +import sys +try: + import pkg_resources +except: + print('pkg_resources cannot be imported probably because the pip package is not installed and/or using a ' + 'legacy Python interpreter. Please refer to the Get Started section of the ESP-IDF Programming Guide for ' + 'setting up the required packages.') + sys.exit(1) + +req_file = '{}/requirements.txt'.format(os.getenv("IDF_PATH")) + +if __name__ == "__main__": + not_satisfied = [] + with open(req_file) as f: + for line in f: + line = line.strip() + try: + pkg_resources.require(line) + except: + not_satisfied.append(line) + + if len(not_satisfied) > 0: + print('The following Python requirements are not satisfied:') + for requirement in not_satisfied: + print(requirement) + print('Please run "{} -m pip install -r {}" for resolving the issue.'.format(sys.executable, req_file)) + sys.exit(1) + + print('Python requirements are satisfied.') diff --git a/tools/windows/windows_install_prerequisites.sh b/tools/windows/windows_install_prerequisites.sh index 0960f4a17..a08137197 100644 --- a/tools/windows/windows_install_prerequisites.sh +++ b/tools/windows/windows_install_prerequisites.sh @@ -41,8 +41,6 @@ rm -f /mingw32/bin/envsubst.exe python -m pip install --upgrade pip -pip install pyserial - # Automatically download precompiled toolchain, unpack at /opt/xtensa-esp32-elf/ TOOLCHAIN_ZIP=xtensa-esp32-elf-win32-1.22.0-80-g6c4433a-5.2.0.zip echo "Downloading precompiled toolchain ${TOOLCHAIN_ZIP}..."