From e91d436e456553743dbd5d0fd6a89b71887ef4c0 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 3 Feb 2017 16:02:22 +1100 Subject: [PATCH 1/7] build system: Probable fix for errors due to bad config bypassing components See github #311 https://github.com/espressif/esp-idf/issues/311 Should fix weird compiler/linker bugs where config says something is enabled, but build system says it is disabled. Particularly noticeable when WiFi/BT libraries fail to compile/link despite being enabled. Underlying cause is configuration file regenerating, but component Makefiles not reevaluating. Entirely removes the idea that we don't need to generate config for some targets (like 'clean'). We need valid config for these targets, otherwise they don't know which files to clean (etc). --- make/common.mk | 4 ++-- make/project.mk | 7 +------ make/project_config.mk | 19 ++----------------- 3 files changed, 5 insertions(+), 25 deletions(-) diff --git a/make/common.mk b/make/common.mk index 605b8ab86..d19f7eb46 100644 --- a/make/common.mk +++ b/make/common.mk @@ -6,8 +6,8 @@ # # (Note that we only rebuild this makefile automatically for some # targets, see project_config.mk for details.) -SDKCONFIG_MAKEFILE ?= $(abspath $(BUILD_DIR_BASE)/include/config/auto.conf) --include $(SDKCONFIG_MAKEFILE) +SDKCONFIG_MAKEFILE ?= $(BUILD_DIR_BASE)/include/config/auto.conf +include $(SDKCONFIG_MAKEFILE) export SDKCONFIG_MAKEFILE # sub-makes (like bootloader) will reuse this path #Handling of V=1/VERBOSE=1 flag diff --git a/make/project.mk b/make/project.mk index bebb1fc7d..02ef7bb17 100644 --- a/make/project.mk +++ b/make/project.mk @@ -370,12 +370,7 @@ $(BUILD_DIR_BASE)/$(2)/lib$(2).a: $(2)-build # If any component_project_vars.mk file is out of date, the make # process will call this target to rebuild it and then restart. # -# Note: $(SDKCONFIG) is a normal prereq as we need to rebuild these -# files whenever the config changes. $(SDKCONFIG_MAKEFILE) is an -# order-only prereq because if it hasn't been rebuilt, we need to -# build it first - but including it as a normal prereq can lead to -# infinite restarts as the conf process will keep updating it. -$(BUILD_DIR_BASE)/$(2)/component_project_vars.mk: $(1)/component.mk $(COMMON_MAKEFILES) $(SDKCONFIG) | $(BUILD_DIR_BASE)/$(2) $(SDKCONFIG_MAKEFILE) +$(BUILD_DIR_BASE)/$(2)/component_project_vars.mk: $(1)/component.mk $(COMMON_MAKEFILES) $(SDKCONFIG_MAKEFILE) | $(BUILD_DIR_BASE)/$(2) $(call ComponentMake,$(1),$(2)) component_project_vars.mk endef diff --git a/make/project_config.mk b/make/project_config.mk index 011aa1ff0..d33ae1196 100644 --- a/make/project_config.mk +++ b/make/project_config.mk @@ -48,26 +48,11 @@ endif mkdir -p $(BUILD_DIR_BASE)/include/config $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/conf --olddefconfig $(IDF_PATH)/Kconfig -# Work out of whether we have to build the Kconfig makefile -# (auto.conf), or if we're in a situation where we don't need it -NON_CONFIG_TARGETS := clean %-clean help menuconfig defconfig -AUTO_CONF_REGEN_TARGET := $(SDKCONFIG_MAKEFILE) - -# disable AUTO_CONF_REGEN_TARGET if all targets are non-config targets -# (and not building default target) -ifneq ("$(MAKECMDGOALS)","") -ifeq ($(filter $(NON_CONFIG_TARGETS), $(MAKECMDGOALS)),$(MAKECMDGOALS)) -AUTO_CONF_REGEN_TARGET := -# dummy target -$(SDKCONFIG_MAKEFILE): -endif -endif - -$(AUTO_CONF_REGEN_TARGET) $(BUILD_DIR_BASE)/include/sdkconfig.h: $(SDKCONFIG) $(KCONFIG_TOOL_DIR)/conf $(COMPONENT_KCONFIGS) $(COMPONENT_KCONFIGS_PROJBUILD) +$(SDKCONFIG_MAKEFILE) $(BUILD_DIR_BASE)/include/sdkconfig.h: $(SDKCONFIG) $(KCONFIG_TOOL_DIR)/conf $(COMPONENT_KCONFIGS) $(COMPONENT_KCONFIGS_PROJBUILD) $(summary) GENCONFIG mkdir -p $(BUILD_DIR_BASE)/include/config cd $(BUILD_DIR_BASE); $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/conf --silentoldconfig $(IDF_PATH)/Kconfig - touch $(AUTO_CONF_REGEN_TARGET) $(BUILD_DIR_BASE)/include/sdkconfig.h + touch $(SDKCONFIG_MAKEFILE) $(BUILD_DIR_BASE)/include/sdkconfig.h # touch to ensure both output files are newer - as 'conf' can also update sdkconfig (a dependency). Without this, # sometimes you can get an infinite make loop on Windows where sdkconfig always gets regenerated newer # than the target(!) From 3c900323692704b2b860feb23b1f14e2023ad096 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 6 Feb 2017 17:02:07 +1100 Subject: [PATCH 2/7] build system: Fix parallel & double menuconfig issues when sdkconfig missing Fixes misbehaviour of default menuconfig when sdkconfig is missing. (Either appearing twice, or breaking if make -jN is used.) --- make/common.mk | 2 +- make/project_config.mk | 70 +++++++++++++++++++++++++++--------------- 2 files changed, 47 insertions(+), 25 deletions(-) diff --git a/make/common.mk b/make/common.mk index d19f7eb46..4281bad94 100644 --- a/make/common.mk +++ b/make/common.mk @@ -6,7 +6,7 @@ # # (Note that we only rebuild this makefile automatically for some # targets, see project_config.mk for details.) -SDKCONFIG_MAKEFILE ?= $(BUILD_DIR_BASE)/include/config/auto.conf +SDKCONFIG_MAKEFILE ?= $(abspath $(BUILD_DIR_BASE)/include/config/auto.conf) include $(SDKCONFIG_MAKEFILE) export SDKCONFIG_MAKEFILE # sub-makes (like bootloader) will reuse this path diff --git a/make/project_config.mk b/make/project_config.mk index d33ae1196..3537f786b 100644 --- a/make/project_config.mk +++ b/make/project_config.mk @@ -20,44 +20,66 @@ $(KCONFIG_TOOL_DIR)/mconf $(KCONFIG_TOOL_DIR)/conf: MAKEFLAGS=$(ORIGINAL_MAKEFLAGS) CC=$(HOSTCC) LD=$(HOSTLD) \ $(MAKE) -C $(KCONFIG_TOOL_DIR) -# use a wrapper environment for where we run Kconfig tools -KCONFIG_TOOL_ENV=KCONFIG_AUTOHEADER=$(abspath $(BUILD_DIR_BASE)/include/sdkconfig.h) \ - COMPONENT_KCONFIGS="$(COMPONENT_KCONFIGS)" KCONFIG_CONFIG=$(SDKCONFIG) \ - COMPONENT_KCONFIGS_PROJBUILD="$(COMPONENT_KCONFIGS_PROJBUILD)" - -menuconfig: $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig $(call prereq_if_explicit,defconfig) - $(summary) MENUCONFIG - $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig - ifeq ("$(wildcard $(SDKCONFIG))","") -ifeq ("$(call prereq_if_explicit,defconfig)","") -# if not configuration is present and defconfig is not a target, run defconfig then menuconfig -$(SDKCONFIG): defconfig menuconfig +ifeq ("$(filter defconfig, $(MAKECMDGOALS))","") +# if no configuration file is present and defconfig is not a named +# target, run defconfig then menuconfig to get the initial config +$(SDKCONFIG): menuconfig +menuconfig: defconfig else -# otherwise, just defconfig +# otherwise, just run defconfig $(SDKCONFIG): defconfig endif endif +# macro for the commands to run kconfig tools conf or mconf. +# $1 is the name (& args) of the conf tool to run +define RunConf + mkdir -p $(BUILD_DIR_BASE)/include/config + cd $(BUILD_DIR_BASE); KCONFIG_AUTOHEADER=$(abspath $(BUILD_DIR_BASE)/include/sdkconfig.h) \ + COMPONENT_KCONFIGS="$(COMPONENT_KCONFIGS)" KCONFIG_CONFIG=$(SDKCONFIG) \ + COMPONENT_KCONFIGS_PROJBUILD="$(COMPONENT_KCONFIGS_PROJBUILD)" \ + $(KCONFIG_TOOL_DIR)/$1 $(IDF_PATH)/Kconfig +endef + +ifeq ("$(MAKE_RESTARTS)","") +# menuconfig, defconfig and "GENCONFIG" configuration generation only +# ever run on the first make pass, subsequent passes don't run these +# (make often wants to re-run them as the conf tool can regenerate the +# sdkconfig input file as an output file, but this is not what the +# user wants - a single config pass is enough to produce all output +# files.) +# +# To prevent problems missing genconfig, ensure none of these targets +# depend on any prerequisite that may cause a make restart as part of +# the prerequisite's own recipe. + +menuconfig: $(KCONFIG_TOOL_DIR)/mconf + $(summary) MENUCONFIG + $(call RunConf,mconf) + # defconfig creates a default config, based on SDKCONFIG_DEFAULTS if present -defconfig: $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig $(BUILD_DIR_BASE) +defconfig: $(KCONFIG_TOOL_DIR)/conf $(summary) DEFCONFIG ifneq ("$(wildcard $(SDKCONFIG_DEFAULTS))","") cat $(SDKCONFIG_DEFAULTS) >> $(SDKCONFIG) # append defaults to sdkconfig, will override existing values endif - mkdir -p $(BUILD_DIR_BASE)/include/config - $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/conf --olddefconfig $(IDF_PATH)/Kconfig + $(call RunConf,conf --olddefconfig) -$(SDKCONFIG_MAKEFILE) $(BUILD_DIR_BASE)/include/sdkconfig.h: $(SDKCONFIG) $(KCONFIG_TOOL_DIR)/conf $(COMPONENT_KCONFIGS) $(COMPONENT_KCONFIGS_PROJBUILD) +# if neither defconfig or menuconfig are requested, use the GENCONFIG rule to +# ensure generated config files are up to date +$(SDKCONFIG_MAKEFILE) $(BUILD_DIR_BASE)/include/sdkconfig.h: $(KCONFIG_TOOL_DIR)/conf $(SDKCONFIG) $(COMPONENT_KCONFIGS) $(COMPONENT_KCONFIGS_PROJBUILD) | $(call prereq_if_explicit,defconfig) $(call prereq_if_explicit,menuconfig) $(summary) GENCONFIG - mkdir -p $(BUILD_DIR_BASE)/include/config - cd $(BUILD_DIR_BASE); $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/conf --silentoldconfig $(IDF_PATH)/Kconfig - touch $(SDKCONFIG_MAKEFILE) $(BUILD_DIR_BASE)/include/sdkconfig.h -# touch to ensure both output files are newer - as 'conf' can also update sdkconfig (a dependency). Without this, -# sometimes you can get an infinite make loop on Windows where sdkconfig always gets regenerated newer -# than the target(!) + $(call RunConf,conf --silentoldconfig) + touch $(SDKCONFIG_MAKEFILE) $(BUILD_DIR_BASE)/include/sdkconfig.h # ensure newer than sdkconfig -.PHONY: config-clean +else # "$(MAKE_RESTARTS)" != "" +# on subsequent make passes, skip config generation entirely +defconfig: +menuconfig: +endif + +.PHONY: config-clean defconfig menuconfig config-clean: $(summary RM CONFIG) $(MAKE) -C $(KCONFIG_TOOL_DIR) clean From c3544dc0901222dd13fa95690ca7cb12aed62a07 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 6 Feb 2017 17:12:16 +1100 Subject: [PATCH 3/7] Build system: Fix error if librtc submodule not available to bootloader Closes #220 https://github.com/espressif/esp-idf/issues/220 --- components/bootloader/src/main/Makefile.projbuild | 4 ++++ components/bootloader/src/main/component.mk | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 components/bootloader/src/main/Makefile.projbuild diff --git a/components/bootloader/src/main/Makefile.projbuild b/components/bootloader/src/main/Makefile.projbuild new file mode 100644 index 000000000..c368c6841 --- /dev/null +++ b/components/bootloader/src/main/Makefile.projbuild @@ -0,0 +1,4 @@ +# Submodules normally added in component.mk, but fully qualified +# paths can be added at this level (we need binary librtc to be +# available to link bootloader). +COMPONENT_SUBMODULES += $(IDF_PATH)/components/esp32/lib diff --git a/components/bootloader/src/main/component.mk b/components/bootloader/src/main/component.mk index 2069665d1..12fdf8efa 100644 --- a/components/bootloader/src/main/component.mk +++ b/components/bootloader/src/main/component.mk @@ -14,10 +14,10 @@ COMPONENT_ADD_LDFLAGS := -L $(COMPONENT_PATH) -lmain $(addprefix -T ,$(LINKER_SC COMPONENT_ADD_LINKER_DEPS := $(LINKER_SCRIPTS) -ifdef IS_BOOTLOADER_BUILD # following lines are a workaround to link librtc into the # bootloader, until clock setting code is in a source-based esp-idf # component. See also rtc_printf() in bootloader_start.c +# +# See also matching COMPONENT_SUBMODULES line in Makefile.projbuild COMPONENT_ADD_LDFLAGS += -L $(IDF_PATH)/components/esp32/lib/ -lrtc_clk -lrtc COMPONENT_EXTRA_INCLUDES += $(IDF_PATH)/components/esp32/ -endif From d28ee9a25ed504ebf4cdbfc13b6aed00ea766cc9 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 4 Jan 2017 12:36:59 +1100 Subject: [PATCH 4/7] build system: Account for Windows behaviour of make wildcard for some dirs See github #166 --- make/project.mk | 15 ++++++++++++--- tools/windows/eclipse_make.sh | 5 +++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/make/project.mk b/make/project.mk index 02ef7bb17..04015a8a8 100644 --- a/make/project.mk +++ b/make/project.mk @@ -49,14 +49,23 @@ endif # make IDF_PATH a "real" absolute path # * works around the case where a shell character is embedded in the environment variable value. # * changes Windows-style C:/blah/ paths to MSYS/Cygwin style /c/blah -export IDF_PATH:=$(realpath $(wildcard $(IDF_PATH))) +ifeq ("$(OS)","Windows_NT") +# On Windows MSYS2, make wildcard function returns empty string for paths of form /xyz +# where /xyz is a directory inside the MSYS root - so we don't use it. +SANITISED_IDF_PATH:=$(realpath $(IDF_PATH)) +else +SANITISED_IDF_PATH:=$(realpath $(wildcard $(IDF_PATH))) +endif + +export IDF_PATH := $(SANITISED_IDF_PATH) ifndef IDF_PATH $(error IDF_PATH variable is not set to a valid directory.) endif -ifneq ("$(IDF_PATH)","$(realpath $(wildcard $(IDF_PATH)))") -# due to the way make manages variables, this is hard to account for +ifneq ("$(IDF_PATH)","$(SANITISED_IDF_PATH)") +# implies IDF_PATH was overriden on make command line. +# Due to the way make manages variables, this is hard to account for # # if you see this error, do the shell expansion in the shell ie # make IDF_PATH=~/blah not make IDF_PATH="~/blah" diff --git a/tools/windows/eclipse_make.sh b/tools/windows/eclipse_make.sh index 200d798ff..848705fba 100755 --- a/tools/windows/eclipse_make.sh +++ b/tools/windows/eclipse_make.sh @@ -4,6 +4,7 @@ # Eclipse's output parser expects to see output of the form C:/dir/dir/file but our Make # process uses MinGW paths of the form /c/dir/dir/file. So parse these out... # -# (regexp deliberate only matches after a space character to try and avoid false-positives.) +# A little hacky as it looks for any single character of form /X/something. +# echo "Running make in $(pwd)" -make $@ V=1 | sed -E "s@ /([a-z])/(.+)/@ \1:/\2/@g" | sed -E "s@-I/([a-z])/(.+)/@-I\1:/\2/@g" | sed -E "s@-L/([a-z])/(.+)/@-L\1:/\2/@g" +make $@ V=1 | sed -E "s@/([a-z])/([^/+])@\1:/\2@g" From 8dede8f8a46f42661665e9b924b7f455d06ef00a Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 7 Feb 2017 14:21:58 +1100 Subject: [PATCH 5/7] Eclipse: Process Windows paths correctly using cygpath Includes splitting the Windows Eclipse setup doc into a separate page, as it has so many additional steps. Addresses github #17 and #166 https://github.com/espressif/esp-idf/issues/17 https://github.com/espressif/esp-idf/issues/166 --- docs/eclipse-setup-windows.rst | 77 ++++++++++++++++++++++++++++++++++ docs/eclipse-setup.rst | 42 ++++++++++++------- tools/windows/eclipse_make.py | 36 ++++++++++++++++ tools/windows/eclipse_make.sh | 12 ++---- 4 files changed, 144 insertions(+), 23 deletions(-) create mode 100644 docs/eclipse-setup-windows.rst create mode 100644 tools/windows/eclipse_make.py diff --git a/docs/eclipse-setup-windows.rst b/docs/eclipse-setup-windows.rst new file mode 100644 index 000000000..4cf8fe5fb --- /dev/null +++ b/docs/eclipse-setup-windows.rst @@ -0,0 +1,77 @@ +Eclipse IDE on Windows +********************** + +Configuring Eclipse on Windows requires some different steps. The full configuration steps for Windows are shown below. + +(For OS X and Linux instructions, see the :doc:`Eclipse IDE page `.) + +Installing Eclipse IDE +====================== + +Follow the steps under :ref:`Installing Eclipse IDE ` for all platforms. + +.. _eclipse-windows-setup: + +Setting up Eclipse on Windows +============================= + +Once your new Eclipse installation launches, follow these steps: + +Import New Project +------------------ + +* Eclipse makes use of the Makefile support in ESP-IDF. This means you need to start by creating an ESP-IDF project. You can use the idf-template project from github, or open one of the examples in the esp-idf examples subdirectory. + +* Once Eclipse is running, choose File -> Import... + +* In the dialog that pops up, choose "C/C++" -> "Existing Code as Makefile Project" and click Next. + +* On the next page, enter "Existing Code Location" to be the directory of your IDF project. Don't specify the path to the ESP-IDF directory itself (that comes later). The directory you specify should contain a file named "Makefile" (the project Makefile). + +* On the same page, under "Toolchain for Indexer Settings" uncheck "Show only available toolchains that support this platform". + +* On the extended list that appears, choose "Cygwin GCC". Then click Finish. + +*Note: you may see warnings in the UI that Cygwin GCC Toolchain could not be found. This is OK, we're going to reconfigure Eclipse to find our toolchain.* + +Project Properties +------------------ + +* The new project will appear under Project Explorer. Right-click the project and choose Properties from the context menu. + +* Click on the "C/C++ Build" properties page (top-level): + + * Uncheck "Use default build command" and enter this for the custom build command: ``python ${IDF_PATH}/tools/windows/eclipse_make.py``. + +* Click on the "Environment" properties page under "C/C++ Build": + + * Click "Add..." and enter name ``V`` and value ``1``. + + * Click "Add..." again, and enter name ``IDF_PATH``. The value should be the full path where ESP-IDF is installed. The IDF_PATH directory should be specified using forwards slashes not backslashes, ie *C:/Users/MyUser/Development/esp-idf*. + + * Edit the PATH environment variable. Delete the existing value and replace it with ``C:\msys32\usr\bin;C:\msys32\mingw32\bin;C:\msys32\opt\xtensa-esp32-elf\bin`` (If you installed msys32 to a different directory then you'll need to change these paths to match). + +* Click on "C/C++ General" -> "Preprocessor Include Paths, Macros,etc." property page: + + * Click the "Providers" tab + + * In the list of providers, click "CDT GCC Built-in Compiler Settings Cygwin". Under "Command to get compiler specs", replace the text ``${COMMAND}`` at the beginning of the line with ``xtensa-esp32-elf-gcc``. This means the full "Command to get compiler specs" should be ``xtensa-esp32-elf-gcc ${FLAGS} -E -P -v -dD "${INPUTS}"``. + + * In the list of providers, click "CDT GCC Build Output Parser" and type ``xtensa-esp32-elf-`` at the beginning of the Compiler command pattern. This means the full Compiler command pattern should be ``xtensa-esp32-elf-(g?cc)|([gc]\+\+)|(clang)`` + + +Building in Eclipse +------------------- + +Continue from :ref:`Building in Eclipse ` for all platforms. + +Technical Details +================= + +**Of interest to Windows gurus or very curious parties, only.** + +Explanations of the technical reasons for some of these steps. You don't need to know this in order to use esp-idf with Eclipse on Windows, but it may be helpful background knowledge if you plan to do dig into the Eclipse support: + +* The xtensa-esp32-elf-gcc cross-compiler is *not* a Cygwin toolchain, even though we tell Eclipse that it is one. This is because msys2 uses Cygwin and supports Cygwin paths (of the type ``/c/blah`` instead of ``c:/blah`` or ``c:\\blah``). In particular, xtensa-esp32-elf-gcc reports to the Eclipse "built-in compiler settings" function that its built-in include directories are all under ``/usr/``, which is a Unix/Cygwin-style path that Eclipse otherwise can't resolve. By telling Eclipse the compiler is Cygwin, it resolves these paths internally using the ``cygpath`` utility. + +* The same problem occurs when parsing make output from esp-idf. Eclipse parses this output to find header directories, but it can't resolve include directories of the form ``/c/blah`` without using ``cygpath``. There is a heuristic that Eclipse Build Output Parser uses to determine whether it should call ``cygpath``, but for currently unknown reasons the esp-idf configuration doesn't trigger it. For this reason the ``eclipse_make.py`` wrapper script is used to call ``make`` and then use ``cygpath`` to process the output for Eclipse. diff --git a/docs/eclipse-setup.rst b/docs/eclipse-setup.rst index fbad93be6..1716dbf16 100644 --- a/docs/eclipse-setup.rst +++ b/docs/eclipse-setup.rst @@ -1,6 +1,8 @@ Build and Flash with Eclipse IDE ******************************** +.. _eclipse-install-steps: + Installing Eclipse IDE ====================== @@ -8,10 +10,17 @@ The Eclipse IDE gives you a graphical integrated development environment for wri * Start by installing the esp-idf for your platform (see files in this directory with steps for Windows, OS X, Linux). +* We suggest building a project from the command line first, to get a feel for how that process works. You also need to use the command line to configure your esp-idf project (via ``make menuconfig``), this is not currently supported inside Eclipse. + * Download the Eclipse Installer for your platform from eclipse.org_. * When running the Eclipse Installer, choose "Eclipse for C/C++ Development" (in other places you'll see this referred to as CDT.) +Windows Users +============= + +Using ESP-IDF with Eclipse on Windows requires different configuration steps. :ref:`See the Eclipse IDE on Windows guide `. + Setting up Eclipse ================== @@ -20,13 +29,13 @@ Once your new Eclipse installation launches, follow these steps: Import New Project ------------------ -* Eclipse makes use of the Makefile support in ESP-IDF. This means you need to start by creating an ESP-IDF project. You can use the skeleton project from github. +* Eclipse makes use of the Makefile support in ESP-IDF. This means you need to start by creating an ESP-IDF project. You can use the idf-template project from github, or open one of the examples in the esp-idf examples subdirectory. * Once Eclipse is running, choose File -> Import... * In the dialog that pops up, choose "C/C++" -> "Existing Code as Makefile Project" and click Next. -* On the next page, enter "Existing Code Location" to be the directory of your IDF project. Don't specify the path to the ESP-IDF directory itself. +* On the next page, enter "Existing Code Location" to be the directory of your IDF project. Don't specify the path to the ESP-IDF directory itself (that comes later). The directory you specify should contain a file named "Makefile" (the project Makefile). * On the same page, under "Toolchain for Indexer Settings" choose "Cross GCC". Then click Finish. @@ -38,13 +47,7 @@ Project Properties * Click on the "Environment" properties page under "C/C++ Build". Click "Add..." and enter name ``V`` and value ``1``. -* Click "Add..." again, and enter name ``IDF_PATH``. The value should be the full path where ESP-IDF is installed. *Windows users: Use forward-slashes not backslashes for this path, ie C:/Users/MyUser/Development/esp-idf*. - -*Windows users only, follow these two additional steps:* - -* On the same Environment property page, edit the PATH environment variable. Delete the existing value and replace it with ``C:\msys32\usr\bin;C:\msys32\mingw32\bin;C:\msys32\opt\xtensa-esp32-elf\bin`` (If you installed msys32 to a different directory then you'll need to change these paths to match). - -* Click on the "C/C++ Build" top-level properties page then uncheck "Use default build command" and enter this for the custom build command: ``bash ${IDF_PATH}/tools/windows/eclipse_make.sh``. +* Click "Add..." again, and enter name ``IDF_PATH``. The value should be the full path where ESP-IDF is installed. *All users, continue with these steps:* @@ -56,7 +59,22 @@ Navigate to "C/C++ General" -> "Preprocessor Include Paths" property page: * In the list of providers, click "CDT GCC Build Output Parser" and type ``xtensa-esp32-elf-`` at the beginning of the Compiler command pattern. This means the full Compiler command pattern should be ``xtensa-esp32-elf-(g?cc)|([gc]\+\+)|(clang)`` -* Click OK to close the Properties dialog, and choose Project -> Build to build your project. +.. _eclipse-build-project: + +Building in Eclipse +------------------- + +Before your project is first built, Eclipse may show a lot of errors and warnings about undefined values. This is because some source files are automatically generated as part of the esp-idf build process. These errors and warnings will go away after you build the project. + +* Click OK to close the Properties dialog in Eclipse. + +* Outside Eclipse, open a command line prompt. Navigate to your project directory, and run ``make menuconfig`` to configure your project's esp-idf settings. This step currently has to be run outside Eclipse. + +*If you try to build without running a configuration step first, esp-idf will prompt for configuration on the command line - but Eclipse is not able to deal with this, so the build will hang or fail.* + +* Back in Eclipse, choose Project -> Build to build your project. + +**TIP**: If your project had already been built outside Eclipse, you may need to do a Project -> Clean before chosing Project -> Build. This is so Eclipse can see the compiler arguments for all source files. It uses these to determine the header include paths. Flash from Eclipse ------------------ @@ -77,7 +95,3 @@ Follow the same steps to add ``bootloader`` and ``partition_table`` targets, if .. _eclipse.org: http://www.eclipse.org/ -Eclipse Troubleshooting ------------------------ - -* ``*** Make was invoked from ... However please do not run make from the sdk or a component directory; ...`` - Eclipse will detect any directory with a Makefile in it as being a possible directory to run "make" in. All component directories also contain a Makefile (the wrong one), so it is important when using Project -> Make Target to always select the top-level project directory in Project Explorer. diff --git a/tools/windows/eclipse_make.py b/tools/windows/eclipse_make.py new file mode 100644 index 000000000..572e171e2 --- /dev/null +++ b/tools/windows/eclipse_make.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# +# Wrapper to run make and preprocess any paths in the output from MSYS/Cygwin paths +# to Windows paths, for Eclipse +from __future__ import print_function, division +import sys, subprocess, os.path, re + +UNIX_PATH_RE = re.compile(r'(/[^ \'"]+)+') + +paths = {} +def check_path(path): + try: + return paths[path] + except KeyError: + pass + paths[path] = path # cache as failed, replace with success if it works + try: + winpath = subprocess.check_output(["cygpath", "-w", path]).strip() + except subprocess.CalledProcessError: + return path # something went wrong running cygpath, assume this is not a path! + if not os.path.exists(winpath): + return path # not actually a valid path + winpath = winpath.replace("\\", "/") # make consistent with forward-slashes used elsewhere + paths[path] = winpath + return winpath + +def main(): + print("Running make in '%s'" % check_path(os.getcwd())) + make = subprocess.Popen(["make"] + sys.argv[1:] + ["V=1"], stdout=subprocess.PIPE) + for line in iter(make.stdout.readline, ''): + line = re.sub(UNIX_PATH_RE, lambda m: check_path(m.group(0)), line) + print(line.rstrip()) + sys.exit(make.wait()) + +if __name__ == "__main__": + main() diff --git a/tools/windows/eclipse_make.sh b/tools/windows/eclipse_make.sh index 848705fba..769bca269 100755 --- a/tools/windows/eclipse_make.sh +++ b/tools/windows/eclipse_make.sh @@ -1,10 +1,4 @@ #!/bin/bash -# A wrapper for make on Windows with Eclipse -# -# Eclipse's output parser expects to see output of the form C:/dir/dir/file but our Make -# process uses MinGW paths of the form /c/dir/dir/file. So parse these out... -# -# A little hacky as it looks for any single character of form /X/something. -# -echo "Running make in $(pwd)" -make $@ V=1 | sed -E "s@/([a-z])/([^/+])@\1:/\2@g" +echo "eclipse_make.sh has been replaced with eclipse_make.py. Check the Windows Eclipse docs for the new command." +echo "This shell script will continue to work until the next major release." +python ${IDF_PATH}/tools/windows/eclipse_make.py $@ From c0f155f6ff58376c8b17051b24e1a478c058eefe Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 7 Feb 2017 14:28:23 +1100 Subject: [PATCH 6/7] kconfig: Ignore Windows host-compiled executables --- tools/kconfig/.gitignore | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tools/kconfig/.gitignore b/tools/kconfig/.gitignore index be603c4fe..977c274ce 100644 --- a/tools/kconfig/.gitignore +++ b/tools/kconfig/.gitignore @@ -20,3 +20,11 @@ nconf qconf gconf kxgettext + +# configuration programs, Windows +conf.exe +mconf.exe +nconf.exe +qconf.exe +gconf.exe +kxgettext.exe From f29768c404cf7d6eab618002b42d5cb9e67f4e52 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 10 Feb 2017 17:38:24 +1100 Subject: [PATCH 7/7] Build system: Add new BATCH_BUILD flag to disable interactive parts of the build Mostly useful for Eclipse (where accidentally running interactive config hangs the build), but also good for CI and other automated build systems. --- .gitlab-ci.yml | 6 +++--- docs/build-system.rst | 11 +++++++++++ docs/eclipse-setup-windows.rst | 2 +- docs/eclipse-setup.rst | 2 +- make/build_examples.sh | 5 ++++- make/common.mk | 5 +++++ make/project_config.mk | 11 +++++++++++ tools/windows/eclipse_make.py | 2 +- 8 files changed, 37 insertions(+), 7 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8ea64e142..96bc56e3e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -31,6 +31,7 @@ build_template_app: SDK_PATH: "$CI_PROJECT_DIR" IDF_PATH: "$CI_PROJECT_DIR" GIT_STRATEGY: clone + BATCH_BUILD: "1" script: - git clone https://github.com/espressif/esp-idf-template.git @@ -39,13 +40,11 @@ build_template_app: # using on esp-idf. If it doesn't exist then just stick to the default # branch - git checkout ${CI_BUILD_REF_NAME} || echo "Using esp-idf-template default branch..." - - make defconfig # Test debug build (default) - make all V=1 # Now test release build - make clean - sed -i.bak -e's/CONFIG_OPTIMIZATION_LEVEL_DEBUG\=y/CONFIG_OPTIMIZATION_LEVEL_RELEASE=y/' sdkconfig - - make defconfig - make all V=1 # Check if there are any stray printf/ets_printf references in WiFi libs - cd ../components/esp32/lib @@ -63,6 +62,8 @@ build_template_app: SDK_PATH: "$CI_PROJECT_DIR" IDF_PATH: "$CI_PROJECT_DIR" GIT_STRATEGY: clone + BATCH_BUILD: "1" + build_ssc: <<: *build_template @@ -103,7 +104,6 @@ build_esp_idf_tests: script: - cd tools/unit-test-app - git checkout ${CI_BUILD_REF_NAME} || echo "Using default branch..." - - make defconfig - make TESTS_ALL=1 - python UnitTestParser.py diff --git a/docs/build-system.rst b/docs/build-system.rst index 0973eeb31..b3abbd28f 100644 --- a/docs/build-system.rst +++ b/docs/build-system.rst @@ -305,6 +305,17 @@ Second Level: Component Makefiles To better understand the component make process, have a read through the ``component_wrapper.mk`` file and some of the ``component.mk`` files included with esp-idf. +Running Make Non-Interactively +------------------------------ + +When running ``make`` in a situation where you don't want interactive prompts (for example: inside an IDE or an automated build system) append ``BATCH_BUILD=1`` to the make arguments (or set it as an environment variable). + +Setting ``BATCH_BUILD`` implies the following: + +- Verbose output (same as ``V=1``, see below). If you don't want verbose output, also set ``V=0``. +- If the project configuration is missing new configuration items (from new components or esp-idf updates) then the project use the default values, instead of prompting the user for each item. +- If the build system needs to invoke ``menuconfig``, an error is printed and the build fails. + Debugging The Make Process -------------------------- diff --git a/docs/eclipse-setup-windows.rst b/docs/eclipse-setup-windows.rst index 4cf8fe5fb..aeb011c0c 100644 --- a/docs/eclipse-setup-windows.rst +++ b/docs/eclipse-setup-windows.rst @@ -45,7 +45,7 @@ Project Properties * Click on the "Environment" properties page under "C/C++ Build": - * Click "Add..." and enter name ``V`` and value ``1``. + * Click "Add..." and enter name ``BATCH_BUILD`` and value ``1``. * Click "Add..." again, and enter name ``IDF_PATH``. The value should be the full path where ESP-IDF is installed. The IDF_PATH directory should be specified using forwards slashes not backslashes, ie *C:/Users/MyUser/Development/esp-idf*. diff --git a/docs/eclipse-setup.rst b/docs/eclipse-setup.rst index 1716dbf16..140e81e17 100644 --- a/docs/eclipse-setup.rst +++ b/docs/eclipse-setup.rst @@ -45,7 +45,7 @@ Project Properties * The new project will appear under Project Explorer. Right-click the project and choose Properties from the context menu. -* Click on the "Environment" properties page under "C/C++ Build". Click "Add..." and enter name ``V`` and value ``1``. +* Click on the "Environment" properties page under "C/C++ Build". Click "Add..." and enter name ``BATCH_BUILD`` and value ``1``. * Click "Add..." again, and enter name ``IDF_PATH``. The value should be the full path where ESP-IDF is installed. diff --git a/make/build_examples.sh b/make/build_examples.sh index e85ec26a7..ee429309e 100755 --- a/make/build_examples.sh +++ b/make/build_examples.sh @@ -9,6 +9,9 @@ # [ -z ${IDF_PATH} ] && echo "IDF_PATH is not set" && exit 1 +export BATCH_BUILD=1 +export V=0 # only build verbose if there's an error + EXAMPLE_NUM=1 RESULT=0 FAILED_EXAMPLES="" @@ -36,7 +39,7 @@ for category in ${IDF_PATH}/examples/*; do set -e make clean defconfig make $* all 2>&1 | tee $BUILDLOG - ) || { RESULT=$?; FAILED_EXAMPLES+=" ${example}"; make V=1; } # only build verbose if there's an error + ) || { RESULT=$?; FAILED_EXAMPLES+=" ${example}"; make V=1; } # verbose output for errors popd EXAMPLE_NUM=$(( $EXAMPLE_NUM + 1 )) diff --git a/make/common.mk b/make/common.mk index 4281bad94..41a87b3a6 100644 --- a/make/common.mk +++ b/make/common.mk @@ -10,6 +10,11 @@ SDKCONFIG_MAKEFILE ?= $(abspath $(BUILD_DIR_BASE)/include/config/auto.conf) include $(SDKCONFIG_MAKEFILE) export SDKCONFIG_MAKEFILE # sub-makes (like bootloader) will reuse this path +# BATCH_BUILD flag disables interactive terminal features, defaults to verbose build +ifdef BATCH_BUILD +V ?= 1 +endif + #Handling of V=1/VERBOSE=1 flag # # if V=1, $(summary) does nothing and $(details) will echo extra details diff --git a/make/project_config.mk b/make/project_config.mk index 3537f786b..c0369f95f 100644 --- a/make/project_config.mk +++ b/make/project_config.mk @@ -56,7 +56,15 @@ ifeq ("$(MAKE_RESTARTS)","") menuconfig: $(KCONFIG_TOOL_DIR)/mconf $(summary) MENUCONFIG +ifdef BATCH_BUILD + @echo "Can't run interactive configuration inside non-interactive build process." + @echo "" + @echo "Open a command line terminal and run 'make menuconfig' from there." + @echo "See esp-idf documentation for more details." + @exit 1 +else $(call RunConf,mconf) +endif # defconfig creates a default config, based on SDKCONFIG_DEFAULTS if present defconfig: $(KCONFIG_TOOL_DIR)/conf @@ -70,6 +78,9 @@ endif # ensure generated config files are up to date $(SDKCONFIG_MAKEFILE) $(BUILD_DIR_BASE)/include/sdkconfig.h: $(KCONFIG_TOOL_DIR)/conf $(SDKCONFIG) $(COMPONENT_KCONFIGS) $(COMPONENT_KCONFIGS_PROJBUILD) | $(call prereq_if_explicit,defconfig) $(call prereq_if_explicit,menuconfig) $(summary) GENCONFIG +ifdef BATCH_BUILD # can't prompt for new config values like on terminal + $(call RunConf,conf --olddefconfig) +endif $(call RunConf,conf --silentoldconfig) touch $(SDKCONFIG_MAKEFILE) $(BUILD_DIR_BASE)/include/sdkconfig.h # ensure newer than sdkconfig diff --git a/tools/windows/eclipse_make.py b/tools/windows/eclipse_make.py index 572e171e2..e65cfc9cc 100644 --- a/tools/windows/eclipse_make.py +++ b/tools/windows/eclipse_make.py @@ -26,7 +26,7 @@ def check_path(path): def main(): print("Running make in '%s'" % check_path(os.getcwd())) - make = subprocess.Popen(["make"] + sys.argv[1:] + ["V=1"], stdout=subprocess.PIPE) + make = subprocess.Popen(["make"] + sys.argv[1:] + ["BATCH_BUILD=1"], stdout=subprocess.PIPE) for line in iter(make.stdout.readline, ''): line = re.sub(UNIX_PATH_RE, lambda m: check_path(m.group(0)), line) print(line.rstrip())