From 873c515ee38a3dc318a32143cd30e26902c9c140 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 25 Jul 2018 14:30:15 +1000 Subject: [PATCH 1/3] docs: Add version-specific include files, version documentation * "git clone" command and a small version header are generated depending on git properties. * Add Versions page with details about each version * Make it clear using master branch is living on the "bleeding edge" --- docs/Makefile | 61 +++++---- docs/_static/choose_version.png | Bin 0 -> 22448 bytes docs/gen-version-specific-includes.py | 140 ++++++++++++++++++++ docs/get-started/index.rst | 32 ++--- docs/index.rst | 1 + docs/versions.rst | 178 ++++++++++++++++++++++++++ 6 files changed, 364 insertions(+), 48 deletions(-) create mode 100644 docs/_static/choose_version.png create mode 100755 docs/gen-version-specific-includes.py create mode 100644 docs/versions.rst diff --git a/docs/Makefile b/docs/Makefile index cc32abbd5..5cbe84797 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -9,7 +9,7 @@ BUILDDIR = _build # User-friendly check for sphinx-build ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) -$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) +$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don\'t have Sphinx installed, grab it from http://sphinx-doc.org/) endif # Internal variables. @@ -19,10 +19,10 @@ ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) -w # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext dependencies version-specific-includes help: - @echo "Please use \`make ' where is one of" + @echo "Please use \`make \' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @@ -44,43 +44,46 @@ help: @echo " xml to make Docutils-native XML files" @echo " pseudoxml to make pseudoxml-XML files for display purposes" @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" + @echo " doctest to run all doctests embedded in the documentation (if enabled) " clean: rm -rf $(BUILDDIR)/* -html: +# Add any dependencies for Sphinx code generation here +dependencies: version-specific-includes + +html: dependencies $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." -dirhtml: +dirhtml: dependencies $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." -singlehtml: +singlehtml: dependencies $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." -pickle: +pickle: dependencies $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." -json: +json: dependencies $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." -htmlhelp: +htmlhelp: dependencies $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." -qthelp: +qthelp: dependencies $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ @@ -89,7 +92,7 @@ qthelp: @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/ReadtheDocsTemplate.qhc" -devhelp: +devhelp: dependencies $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @@ -98,70 +101,70 @@ devhelp: @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/ReadtheDocsTemplate" @echo "# devhelp" -epub: +epub: dependencies $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." -latex: +latex: dependencies $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." -latexpdf: +latexpdf: dependencies $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." $(MAKE) -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." -latexpdfja: +latexpdfja: dependencies $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through platex and dvipdfmx..." $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." -text: +text: dependencies $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." -man: +man: dependencies $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." -texinfo: +texinfo: dependencies $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." @echo "Run \`make' in that directory to run these through makeinfo" \ "(use \`make info' here to do that automatically)." -info: +info: dependencies $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo "Running Texinfo files through makeinfo..." make -C $(BUILDDIR)/texinfo info @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." -gettext: +gettext: dependencies $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale @echo @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." -changes: +changes: dependencies $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." -linkcheck: +linkcheck: dependencies $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." -gh-linkcheck: +gh-linkcheck: dependencies @echo "Checking for hardcoded GitHub links" @if (find ../ -name '*.rst' | xargs grep \ 'https://github.com/espressif/esp-idf/tree\|https://github.com/espressif/esp-idf/blob\|https://github.com/espressif/esp-idf/raw'\ @@ -185,17 +188,21 @@ gh-linkcheck: fi @echo "No hardcoded links found" -doctest: +doctest: dependencies $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." -xml: +xml: dependencies $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml @echo @echo "Build finished. The XML files are in $(BUILDDIR)/xml." -pseudoxml: +pseudoxml: dependencies $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml @echo @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." + +version-specific-includes: + mkdir -p $(BUILDDIR)/inc + ./gen-version-specific-includes.py en $(BUILDDIR)/inc diff --git a/docs/_static/choose_version.png b/docs/_static/choose_version.png new file mode 100644 index 0000000000000000000000000000000000000000..c8927df118dddf510599750fe1da789bb6a48888 GIT binary patch literal 22448 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 NQ-!OPE1Lz7{1-`mq51#- literal 0 HcmV?d00001 diff --git a/docs/gen-version-specific-includes.py b/docs/gen-version-specific-includes.py new file mode 100755 index 000000000..313b15b6b --- /dev/null +++ b/docs/gen-version-specific-includes.py @@ -0,0 +1,140 @@ +#!/usr/bin/env python +# +# Python script to generate ReSTructured Text .inc snippets +# with version-based content for this IDF version + +import subprocess +import os +import sys +import re + +TEMPLATES = { + "en" : { + "git-clone" : { + "template" : """ +To obtain a local copy: open terminal, navigate to the directory you want to put ESP-IDF, and clone the repository using ``git clone`` command:: + + cd ~/esp + git clone %(clone_args)s--recursive https://github.com/espressif/esp-idf.git + +ESP-IDF will be downloaded into ``~/esp/esp-idf``. + +.. note:: + + %(extra_note)s + +.. note:: + + %(zipfile_note)s +""" + ,"master" : 'This command will clone the master branch, which has the latest development ("bleeding edge") version of ESP-IDF. It is fully functional and updated on weekly basis with the most recent features and bugfixes.' + ,"branch" : 'The ``git clone`` option ``-b %s`` tells git to clone the %s in the ESP-IDF repository corresponding to this version of the documentation.' + ,"zipfile" : { + "stable" : 'As a fallback, it is also possible to download a zip file of this stable release from the `Releases page`_. Do not download the "Source code" zip file(s) generated automatically by GitHub, they do not work with ESP-IDF.' + ,"unstable" : 'GitHub\'s "Download zip file" feature does not work with ESP-IDF, a ``git clone`` is required. As a fallback, `Stable version`_ can be installed without Git.' + }, # zipfile + }, # git-clone + "version-note" : { + "master" : """ +.. note:: + This is documentation for the master branch (latest version) of ESP-IDF. This version is under continual development. `Stable version`_ documentation is available, as well as other :doc:`/versions`. +""" + ,"stable" : """ +.. note:: + This is documentation for stable version %s of ESP-IDF. Other :doc:`/versions` are also available. +""" + ,"branch" : """ +.. note:: + This is documentation for %s ``%s`` of ESP-IDF. Other :doc:`/versions` are also available. +""" + }, # version-note + }, # en +} + + +def main(): + if len(sys.argv) != 3: + print("Usage: gen-git-clone.py ") + sys.exit(1) + + language = sys.argv[1] + out_dir = sys.argv[2] + if not os.path.exists(out_dir): + print("Output directory %s not found" % out_dir) + sys.exit(1) + + template = TEMPLATES[language] + + version, ver_type, is_stable = get_version() + + write_git_clone_inc(template["git-clone"], out_dir, version, ver_type, is_stable) + write_version_note(template["version-note"], out_dir, version, ver_type, is_stable) + print("Done") + + +def write_git_clone_inc(template, out_dir, version, ver_type, is_stable): + zipfile = template["zipfile"] + if version == "master": + args = { + "clone_args" : "", + "extra_note" : template["master"], + "zipfile_note" : zipfile["unstable"] + } + else: + args = { + "clone_args" : "-b %s " % version, + "extra_note" : template["branch"] % (version, ver_type), + "zipfile_note" : zipfile["stable"] if is_stable else zipfile["unstable"] + } + out_file = os.path.join(out_dir, "git-clone.inc") + with open(out_file, "w") as f: + f.write(template["template"] % args) + print("%s written" % out_file) + + +def write_version_note(template, out_dir, version, ver_type, is_stable): + if version == "master": + content = template["master"] + elif ver_type == "tag" and is_stable: + content = template["stable"] % version + else: + content = template["branch"] % (ver_type, version) + out_file = os.path.join(out_dir, "version-note.inc") + with open(out_file, "w") as f: + f.write(content) + print("%s written" % out_file) + + +def get_version(): + """ + Returns a tuple of (name of branch/tag, type branch/tag, is_stable) + """ + # Trust what RTD says our version is, if it is set + version = os.environ.get("READTHEDOCS_VERSION", None) + if version == "latest": + return ("master", "branch", False) + + # Otherwise, use git to look for a tag + try: + tag = subprocess.check_output(["git", "describe", "--tags", "--exact-match"]).strip() + is_stable = re.match(r"v[0-9\.]+$", tag) is not None + return (tag, "tag", is_stable) + except subprocess.CalledProcessError: + pass + + # No tag, look for a branch + refs = subprocess.check_output(["git", "for-each-ref", "--points-at", "HEAD", "--format", "%(refname)"]) + print("refs:\n%s" % refs) + refs = refs.split("\n") + # Note: this looks for branches in 'origin' because GitLab CI doesn't check out a local branch + branches = [ r.replace("refs/remotes/origin/","").strip() for r in refs if r.startswith("refs/remotes/origin/") ] + if len(branches) == 0: + # last resort, return the commit (may happen on Gitlab CI sometimes, unclear why) + return (subprocess.check_output(["git", "rev-parse", "--short", "HEAD"]).strip(), "commit", False) + if "master" in branches: + return ("master", "branch", False) + else: + return (branches[0], "branch", False) # take whatever the first branch is + +if __name__ == "__main__": + main() diff --git a/docs/get-started/index.rst b/docs/get-started/index.rst index 68c8f2ff0..98b97809f 100644 --- a/docs/get-started/index.rst +++ b/docs/get-started/index.rst @@ -4,6 +4,7 @@ Get Started This document is intended to help users set up the software environment for developement of applications using hardware based on the Espressif ESP32. Through a simple example we would like to illustrate how to use ESP-IDF (Espressif IoT Development Framework), including the menu based configuration, compiling the ESP-IDF and firmware download to ESP32 boards. +.. include:: /_build/inc/version-note.inc Introduction ============ @@ -113,19 +114,18 @@ Get ESP-IDF .. highlight:: bash -Besides the toolchain (that contains programs to compile and build the application), you also need ESP32 specific API / libraries. They are provided by Espressif in `ESP-IDF repository `_. To get it, open terminal, navigate to the directory you want to put ESP-IDF, and clone it using ``git clone`` command:: +Besides the toolchain (that contains programs to compile and build the application), you also need ESP32 specific API / libraries. They are provided by Espressif in `ESP-IDF repository `_. - cd ~/esp - git clone --recursive https://github.com/espressif/esp-idf.git +.. include:: /_build/inc/git-clone.inc -ESP-IDF will be downloaded into ``~/esp/esp-idf``. +Consult :doc:`/versions` for information about which version of ESP-IDF to use in a given situation. .. note:: Do not miss the ``--recursive`` option. If you have already cloned ESP-IDF without this option, run another command to get all the submodules:: cd ~/esp/esp-idf - git submodule update --init + git submodule update --init --recursive .. _get-started-setup-path: @@ -299,23 +299,9 @@ Updating ESP-IDF After some time of using ESP-IDF, you may want to update it to take advantage of new features or bug fixes. The simplest way to do so is by deleting existing ``esp-idf`` folder and cloning it again, exactly as when doing initial installation described in sections :ref:`get-started-get-esp-idf`. -Another solution is to update only what has changed. This method is useful if you have slow connection to the GiHub. To do the update run the following commands:: +If downloading to a new path, remember to :doc:`add-idf_path-to-profile` so that the toolchain scripts know where to find the ESP-IDF in its release specific location. - cd ~/esp/esp-idf - git pull - git submodule update --init --recursive - -The ``git pull`` command is fetching and merging changes from ESP-IDF repository on GitHub. Then ``git submodule update --init --recursive`` is updating existing submodules or getting a fresh copy of new ones. On GitHub the submodules are represented as links to other repositories and require this additional command to get them onto your PC. - -If you would like to use specific release of ESP-IDF, e.g. `v2.1`, run:: - - cd ~/esp - git clone https://github.com/espressif/esp-idf.git esp-idf-v2.1 - cd esp-idf-v2.1/ - git checkout v2.1 - git submodule update --init --recursive - -After that remember to :doc:`add-idf_path-to-profile`, so the toolchain scripts know where to find the ESP-IDF in it's release specific location. +Another solution is to update only what has changed. :ref:`The update procedure depends on the version of ESP-IDF you are using `. Related Documents @@ -330,3 +316,7 @@ Related Documents eclipse-setup idf-monitor toolchain-setup-scratch + +.. _Stable version: https://docs.espressif.com/projects/esp-idf/en/stable/ +.. _Releases page: https://github.com/espressif/esp-idf/releases + diff --git a/docs/index.rst b/docs/index.rst index e4ee3fe4d..fdb5869b4 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -41,6 +41,7 @@ This is the documentation for Espressif IoT Development Framework (`esp-idf API Guides Contribute + Versions Resources Copyrights About diff --git a/docs/versions.rst b/docs/versions.rst new file mode 100644 index 000000000..6b0a60df9 --- /dev/null +++ b/docs/versions.rst @@ -0,0 +1,178 @@ +ESP-IDF Versions +================ + +The ESP-IDF GitHub repository is updated regularly, especially on the "master branch" where new development happens. There are also stable releases which are recommended for production use. + +Releases +-------- + +Documentation for the current stable version can always be found at this URL: + +https://docs.espressif.com/projects/esp-idf/en/stable/ + +Documentation for the latest version ("master branch") can always be found at this URL: + +https://docs.espressif.com/projects/esp-idf/en/latest/ + +The full history of releases can be found on the GitHub repository `Releases page`_. There you can find release notes, links to each version of the documentation, and instructions for obtaining each version. + +Documentation for all releases can also be found in the HTML documentation by clicking the "versions" pop up in the bottom-left corner of the page. You can use this popup to switch between versions of the documentation. + +.. image:: _static/choose_version.png + +Which Version Should I Start With? +---------------------------------- + +- For production purposes, use the `current stable version`_. Stable versions have been manually tested, and are updated with "bugfix releases" which fix bugs without changing other functionality (see `Versioning Scheme`_ for more details). + +- For prototyping, experimentation or for developing new ESP-IDF features, use the `latest version (master branch in Git) `_. The latest version in the master branch has all the latest features and has passed automated testing, but has not been completely manually tested ("bleeding edge"). + +- If a required feature is not yet available in a stable release, but you don't want to use the master branch, it is possible to check out a pre-release version or a release branch. It is recommended to start from a stable version and then follow the instructions for :ref:`updating-pre-release` or :ref:`updating-release-branch`. + +See :ref:`updating` if you already have a local copy of ESP-IDF and wish to update it. + +Versioning Scheme +----------------- + +ESP-IDF uses `Semantic Versioning `_. This means: + +- Major Releases like ``v3.0`` add new functionality and may change functionality. This includes removing deprecated functionality. + + When updating to a new major release (for example, from ``v2.1`` to ``v3.0``), some of your project's code may need updating and functionality will need to be re-tested. The release notes on the `Releases page`_ include lists of Breaking Changes to refer to. +- Minor Releases like ``v3.1`` add new functionality and fix bugs but will not change or remove documented functionality, or make incompatible changes to public APIs. + + If updating to a new minor release (for example, from ``v3.0`` to ``v3.1``) then none of your project's code should need updating, but you should re-test your project. Pay particular attention to items mentioned in the release notes on the `Releases page`_. +- Bugfix Releases like ``v3.0.1`` only fix bugs and do not add new functionality. + + If updating to a new bugfix release (for example, from ``v3.0`` to ``v3.0.1``), you should not need to change any code in your project and should only need to re-test functionality relating directly to bugs listed in the release notes on the `Releases page`_. + +Checking The Current Version +---------------------------- + +The local ESP-IDF version can be checked using git:: + + cd $IDF_PATH + git describe --tags --dirty + +The version is also compiled into the firmware and can be accessed (as a string) via the macro ``IDF_VER``. The default ESP-IDF bootloader will print the version on boot (these versions in code will not always update, it only changes if that particular source file is recompiled). + +Examples of ESP-IDF versions: + +============================ ================================================== +Version String Meaning +============================ ================================================== +``v3.2-dev-306-gbeb3611ca`` Master branch pre-release, in development for + version 3.2. 306 commits after v3.2 development + started. Commit identifier ``beb3611ca``. +``v3.0.2`` Stable release, tagged ``v3.0.2``. +``v3.1-beta1-75-g346d6b0ea`` Beta version in development (on a + :ref:`release branch `). + 75 commits after ``v3.1-beta1`` pre-release tag. + Commit identifier ``346d6b0ea``. +``v3.0.1-dirty`` Stable release, tagged ``v3.0.1``. + There are modifications in the local ESP-IDF + directory ("``dirty``"). +============================ ================================================== + + + +Git Workflow +------------ + +The development (Git) workflow of the Espressif ESP-IDF team is: + +- New work is always added on the master branch (latest version) first. The ESP-IDF version on ``master`` is always tagged with ``-dev`` (for "in development"), for example ``v3.1-dev``. +- Changes are first added to an internal Git repository for code review and testing, but are pushed to GitHub after automated testing passes. +- When a new version (developed on ``master``) becomes feature complete and "beta" quality, a new branch is made for the release, for example ``release/v3.1``. A pre-release tag is also created, for example ``v3.1-beta1``. You can see a full `list of branches`_ and a `list of tags`_ on GitHub. Beta pre-releases have release notes which may include a significant number of Known Issues. +- As testing of the beta version progresses, bug fixes will be added to both the ``master`` branch and the release branch. New features (for the next release) may start being added to ``master`` at the same time. +- Once testing is nearly complete a new release candidate is tagged on the release branch, for example ``v3.1-rc1``. This is still a pre-release version. +- If no more significant bugs are found or reported then the final Major or Minor Version is tagged, for example ``v3.1``. This version appears on the `Releases page`_. +- As bugs are reported in released versions, the fixes will continue to be committed to the same release branch. +- Regular bugfix releases are made from the same release branch. After manual testing is complete, a bugfix release is tagged (i.e. ``v3.1.1``) and appears on the `Releases page`_. + +.. _updating: + +Updating ESP-IDF +---------------- + +Updating ESP-IDF depends on which version(s) you wish to follow: + +- :ref:`updating-stable-releases` is recommended for production use. +- :ref:`updating-master` is recommended for latest features, development use, and testing. +- :ref:`updating-release-branch` is a compromise between these two. + +.. note:: These guides assume you already have a local copy of ESP-IDF. To get one, follow the :doc:`Getting Started ` guide for any ESP-IDF version. + +.. _`updating-stable-releases`: + +Updating to Stable Release +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To update to new ESP-IDF releases (recommended for production use), this is the process to follow: + +- Check the `Releases page`_ regularly for new releases. +- When a bugfix release for a version you are using is released (for example if using ``v3.0.1`` and ``v3.0.2`` is available), check out the new bugfix version into the existing ESP-IDF directory:: + + cd $IDF_PATH + git fetch + git checkout vX.Y.Z + git submodule update --init --recursive +- When major or minor updates are released, check the Release Notes on the releases page and decide if you would like to update or to stay with your existing release. Updating is via the same Git commands shown above. + +.. note:: If you installed the stable release via zip file rather than using git, it may not be possible to change versions this way. In this case, update by downloading a new zip file and replacing the entire ``IDF_PATH`` directory with its contents. + + +.. _`updating-pre-release`: + +Updating to a Pre-Release Version +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +It is also possible to ``git checkout`` a tag corresponding to a pre-release version or release candidate, the process is the same as :ref:`updating-stable-releases`. + +Pre-release tags are not always found on the `Releases page`_. Consult the `list of tags`_ on GitHub for a full list. Caveats for using a pre-release are similar to :ref:`updating-release-branch`. + +.. _`updating-master`: + +Updating to Master Branch +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. note:: Using Master branch means living "on the bleeding edge" with the latest ESP-IDF code. + +To use the latest version on the ESP-IDF master branch, this is the process to follow: + +- Check out the master branch locally:: + + cd $IDF_PATH + git checkout master + git pull + git submodule update --init --recursive +- Periodically, re-run ``git pull`` to pull the latest version of master. Note that you may need to change your project or report bugs after updating master branch. +- To switch from ``master`` to a release branch or stable version, run ``git checkout`` as shown in the other sections. + +.. important:: It is strongly recommended to regularly run ``git pull`` and then ``git submodule update --init --recursive`` so a local copy of ``master`` does not get too old. Arbitrary old master branch revisions are effectively unsupportable "snapshots" that may have undocumented bugs. For a semi-stable version, try :ref:`updating-release-branch` instead. + +.. _`updating-release-branch`: + +Updating to a Release Branch +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In stability terms, using a release branch is part-way between using ``master`` branch and only using stable releases. A release branch is always beta quality or better, and receives bug fixes before they appear in each stable release. + +You can find a `list of branches`_ on GitHub. + +For example, to follow the branch for ESP-IDF v3.1, including any bugfixes for future releases like ``v3.1.1``, etc:: + + cd $IDF_PATH + git fetch + git checkout release/v3.1 + git pull + git submodule --update --init --recursive + +Each time you ``git pull`` this branch, ESP-IDF will be updated with fixes for this release. + +.. note:: The is no dedicated documentation for release branches. It is recommended to use the documentation for the closest version to the branch which is currently checked out. + +.. _`Releases page`: http://github.com/espressif/esp-idf/releases +.. _`list of branches`: https://github.com/espressif/esp-idf/branches +.. _`list of tags`: https://github.com/espressif/esp-idf/tags +.. _`current stable version`: https://docs.espressif.com/projects/esp-idf/en/stable/ From 998416c54b95eae35f07fa49841157fddf63d856 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 27 Jul 2018 17:21:38 +1000 Subject: [PATCH 2/3] README: Add version-specific links Make it clearer how the README fits in with the docs. --- README.md | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index e2bf85ea9..531113b34 100644 --- a/README.md +++ b/README.md @@ -4,22 +4,27 @@ ESP-IDF is the official development framework for the [ESP32](https://espressif.com/en/products/hardware/esp32/overview) chip. -# Developing With the ESP-IDF +# Developing With ESP-IDF ## Setting Up ESP-IDF See setup guides for detailed instructions to set up the ESP-IDF: -* [Windows Setup Guide](https://esp-idf.readthedocs.io/en/latest/get-started/windows-setup.html) -* [Mac OS Setup Guide](https://esp-idf.readthedocs.io/en/latest/get-started/macos-setup.html) -* [Linux Setup Guide](https://esp-idf.readthedocs.io/en/latest/get-started/linux-setup.html) +* [Getting Started Guide for the stable ESP-IDF version](https://docs.espressif.com/projects/esp-idf/en/stable/get-started/) +* [Getting Started Guide for the latest (master branch) ESP-IDF version](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/) ## Finding a Project -As well as the [esp-idf-template](https://github.com/espressif/esp-idf-template) project mentioned in the setup guide, ESP-IDF comes with some example projects in the [examples](examples) directory. +As well as the [esp-idf-template](https://github.com/espressif/esp-idf-template) project mentioned in Getting Started, ESP-IDF comes with some example projects in the [examples](examples) directory. Once you've found the project you want to work with, change to its directory and you can configure and build it. +To start your own project based on an example, copy the example project directory outside of the ESP-IDF directory. + +# Quick Reference + +See the Getting Started guide links above for a detailed setup guide. This is a quick reference for common commands when working with ESP-IDF projects: + ## Configuring the Project `make menuconfig` @@ -36,15 +41,17 @@ Once done configuring, press Escape multiple times to exit and say "Yes" to save ## Compiling the Project -`make all` +`make -j4 all` ... will compile app, bootloader and generate a partition table based on the config. +NOTE: The `-j4` option causes `make` to run 4 parallel jobs. This is much faster than the default single job. The recommended number to pass to this option is `-j(number of CPUs + 1)`. + ## Flashing the Project When `make all` finishes, it will print a command line to use esptool.py to flash the chip. However you can also do this from make by running: -`make flash` +`make -j4 flash` This will flash the entire project (app, bootloader and partition table) to a new chip. The settings for serial port flashing can be configured with `make menuconfig`. @@ -56,24 +63,24 @@ The `make monitor` target uses the [idf_monitor tool](https://esp-idf.readthedoc Exit the monitor by typing Ctrl-]. -To flash and monitor output in one pass, you can run: +To build, flash and monitor output in one pass, you can run: -`make flash monitor` +`make -j4 flash monitor` -## Compiling & Flashing Just the App +## Compiling & Flashing Only the App After the initial flash, you may just want to build and flash just your app, not the bootloader and partition table: * `make app` - build just the app. * `make app-flash` - flash just the app. -`make app-flash` will automatically rebuild the app if it needs it. +`make app-flash` will automatically rebuild the app if any source files have changed. (In normal development there's no downside to reflashing the bootloader and partition table each time, if they haven't changed.) ## Parallel Builds -ESP-IDF supports compiling multiple files in parallel, so all of the above commands can be run as `make -jN` where `N` is the number of parallel make processes to run (generally N should be equal to or one more than the number of CPU cores in your system.) +ESP-IDF supports compiling multiple files in parallel, so all of the above commands can be run as `make -jN` where `N` is the number of parallel make processes to run (generally N should be equal to the number of CPU cores in your system, plus one.) Multiple make functions can be combined into one. For example: to build the app & bootloader using 5 jobs in parallel, then flash everything, and then display serial output from the ESP32 run: From bb5789b6ee77b2bb6e45c51f7d3aa0c0bb2e0d97 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Mon, 13 Aug 2018 12:24:55 +1000 Subject: [PATCH 3/3] docs: Move version-related includes to run in sphinx-build not make Means they show up on ReadTheDocs(!) --- docs/Makefile | 61 ++++++++++++++------------- docs/conf.py | 15 +++++++ docs/gen-version-specific-includes.py | 4 +- 3 files changed, 48 insertions(+), 32 deletions(-) diff --git a/docs/Makefile b/docs/Makefile index 5cbe84797..9ea53a416 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -1,6 +1,14 @@ # Makefile for Sphinx documentation # +# ************ IMPORTANT ***************** +# +# ReadTheDocs DOES NOT USE THIS MAKEFILE, +# so any behaviour additions must be +# done via Sphinx Config not here +# +# **************************************** + # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build @@ -49,41 +57,38 @@ help: clean: rm -rf $(BUILDDIR)/* -# Add any dependencies for Sphinx code generation here -dependencies: version-specific-includes - -html: dependencies +html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." -dirhtml: dependencies +dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." -singlehtml: dependencies +singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." -pickle: dependencies +pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." -json: dependencies +json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." -htmlhelp: dependencies +htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." -qthelp: dependencies +qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ @@ -92,7 +97,7 @@ qthelp: dependencies @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/ReadtheDocsTemplate.qhc" -devhelp: dependencies +devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @@ -101,70 +106,70 @@ devhelp: dependencies @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/ReadtheDocsTemplate" @echo "# devhelp" -epub: dependencies +epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." -latex: dependencies +latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." -latexpdf: dependencies +latexpdf: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." $(MAKE) -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." -latexpdfja: dependencies +latexpdfja: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through platex and dvipdfmx..." $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." -text: dependencies +text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." -man: dependencies +man: $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." -texinfo: dependencies +texinfo: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." @echo "Run \`make' in that directory to run these through makeinfo" \ "(use \`make info' here to do that automatically)." -info: dependencies +info: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo "Running Texinfo files through makeinfo..." make -C $(BUILDDIR)/texinfo info @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." -gettext: dependencies +gettext: $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale @echo @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." -changes: dependencies +changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." -linkcheck: dependencies +linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." -gh-linkcheck: dependencies +gh-linkcheck: @echo "Checking for hardcoded GitHub links" @if (find ../ -name '*.rst' | xargs grep \ 'https://github.com/espressif/esp-idf/tree\|https://github.com/espressif/esp-idf/blob\|https://github.com/espressif/esp-idf/raw'\ @@ -188,21 +193,17 @@ gh-linkcheck: dependencies fi @echo "No hardcoded links found" -doctest: dependencies +doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." -xml: dependencies +xml: $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml @echo @echo "Build finished. The XML files are in $(BUILDDIR)/xml." -pseudoxml: dependencies +pseudoxml: $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml @echo @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." - -version-specific-includes: - mkdir -p $(BUILDDIR)/inc - ./gen-version-specific-includes.py en $(BUILDDIR)/inc diff --git a/docs/conf.py b/docs/conf.py index caa233c93..96ca4bd51 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -32,6 +32,15 @@ os.system("python gen-dxd.py") # Generate 'kconfig.inc' file from components' Kconfig files os.system("python gen-kconfig-doc.py > _build/inc/kconfig.inc") +# Generate version-related includes +# +# (Note: this is in a function as it needs to access configuration to get the language) +def generate_version_specific_includes(app): + print("Generating version-specific includes...") + if os.system('python gen-version-specific-includes.py en _build/inc'): + raise RuntimeError('gen-version-specific-includes.py failed') + + # http://stackoverflow.com/questions/12772927/specifying-an-online-image-in-sphinx-restructuredtext-format # suppress_warnings = ['image.nonlocal_uri'] @@ -314,3 +323,9 @@ if not on_rtd: # only import and set the theme if we're building docs locally # otherwise, readthedocs.org uses their theme by default, so no need to specify it +# Override RTD CSS theme to introduce the theme corrections +# https://github.com/rtfd/sphinx_rtd_theme/pull/432 +def setup(app): + app.add_stylesheet('theme_overrides.css') + generate_version_specific_includes(app) + diff --git a/docs/gen-version-specific-includes.py b/docs/gen-version-specific-includes.py index 313b15b6b..89b2dad38 100755 --- a/docs/gen-version-specific-includes.py +++ b/docs/gen-version-specific-includes.py @@ -60,8 +60,8 @@ def main(): language = sys.argv[1] out_dir = sys.argv[2] if not os.path.exists(out_dir): - print("Output directory %s not found" % out_dir) - sys.exit(1) + print("Creating directory %s" % out_dir) + os.mkdir(out_dir) template = TEMPLATES[language]