From 9e8c348ca2e34aa38f1bf867f4c8f44a1098cbde Mon Sep 17 00:00:00 2001
From: Maxim Prokhorov <prokhorov.max@outlook.com>
Date: Wed, 19 Jun 2024 23:54:08 +0300
Subject: [PATCH 1/3] tools: using .json tool name with git version

renamed tools/xtensa-lx106-elf -> tools/xtensa-lx106-elf-gcc
get.py can just use the top dir -> tool name translation, no need to ref
archive contents. just expect top dir to be there
---
 .gitignore                                    |  1 +
 bootloaders/eboot/Makefile                    |  2 +-
 cores/esp8266/esp8266_undocumented.h          |  2 +-
 doc/gdb.rst                                   |  8 +--
 .../BearSSL_CertStore/certs-from-mozilla.py   |  2 +-
 platform.txt                                  |  2 +-
 tests/ci/eboot_test.sh                        |  2 +-
 tests/common.sh                               |  4 +-
 tests/sanity_check.sh                         |  2 +-
 tools/get.py                                  | 62 +++++++++++--------
 tools/sdk/lib/compare/sdk-compare-libs        |  6 +-
 tools/sdk/lib/eval_fix_sdks.sh                |  6 +-
 tools/sdk/lib/fix_sdk_libs.sh                 |  6 +-
 tools/warnings/README.md                      |  2 +-
 14 files changed, 60 insertions(+), 47 deletions(-)

diff --git a/.gitignore b/.gitignore
index 6413393ea9..bd5ea83688 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
 .DS_Store
 tools/dist/
 tools/xtensa-lx106-elf/
+tools/xtensa-lx106-elf-gcc/
 tools/mkspiffs/
 tools/mklittlefs/
 tools/python3/
diff --git a/bootloaders/eboot/Makefile b/bootloaders/eboot/Makefile
index 3eb9fc58f4..f1ffa44244 100644
--- a/bootloaders/eboot/Makefile
+++ b/bootloaders/eboot/Makefile
@@ -1,4 +1,4 @@
-XTENSA_TOOLCHAIN ?= ../../tools/xtensa-lx106-elf/bin/
+XTENSA_TOOLCHAIN ?= ../../tools/xtensa-lx106-elf-gcc/bin/
 ESPTOOL ?= ../../tools/esptool/esptool
 
 BIN_DIR := ./
diff --git a/cores/esp8266/esp8266_undocumented.h b/cores/esp8266/esp8266_undocumented.h
index 5e68e53fa1..cbb9b0a7c2 100644
--- a/cores/esp8266/esp8266_undocumented.h
+++ b/cores/esp8266/esp8266_undocumented.h
@@ -23,7 +23,7 @@ extern "C" {
 extern void (*user_start_fptr)();
 
 #ifndef XCHAL_EXCCAUSE_NUM
-// from tools/xtensa-lx106-elf/include/xtensa/config/core.h:629:#define XCHAL_EXCCAUSE_NUM  		64
+// from xtensa hal header: xtensa/config/core.h:629:#define XCHAL_EXCCAUSE_NUM  		64
 #define XCHAL_EXCCAUSE_NUM  		64
 #endif
 
diff --git a/doc/gdb.rst b/doc/gdb.rst
index 79e221e844..6f9d736e75 100644
--- a/doc/gdb.rst
+++ b/doc/gdb.rst
@@ -96,23 +96,23 @@ Open a Command Prompt and Start GDB
 Open a terminal or ``CMD`` prompt and navigate to the proper ESP8266 toolchain
 directory.
 
-Linux
+Linux (Using Board Manager version)
 
 .. code:: bash
 
-    ~/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/2.5.0-4-b40a506/bin/xtensa-lx106-elf-gdb
+    ~/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.2.0-gcc10.3-c791b74/bin/xtensa-lx106-elf-gdb
 
 Windows (Using Board Manager version)
 
 .. code:: bash
 
-    %userprofile%\AppData\Local\Arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\2.5.0-3-20ed2b9\bin\xtensa-lx106-elf-gdb.exe
+    %userprofile%\AppData\Local\Arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\3.2.0-gcc10.3-c791b74\bin\xtensa-lx106-elf-gdb.exe
 
 Windows (Using Git version)
 
 .. code:: bash
 
-    %userprofile%\Documents\Arduino\hardware\esp8266com\esp8266\tools\xtensa-lx106-elf\bin\xtensa-lx106-elf-gdb.exe
+    %userprofile%\Documents\Arduino\hardware\esp8266com\esp8266\tools\xtensa-lx106-elf-gcc\bin\xtensa-lx106-elf-gdb.exe
 
 Please note the proper GDB name is "xtensa-lx106-elf-gdb".  If you accidentally
 run "gdb" you may start your own operating system's GDB, which will not know how
diff --git a/libraries/ESP8266WiFi/examples/BearSSL_CertStore/certs-from-mozilla.py b/libraries/ESP8266WiFi/examples/BearSSL_CertStore/certs-from-mozilla.py
index 80dbc48387..88dee40dcd 100755
--- a/libraries/ESP8266WiFi/examples/BearSSL_CertStore/certs-from-mozilla.py
+++ b/libraries/ESP8266WiFi/examples/BearSSL_CertStore/certs-from-mozilla.py
@@ -25,7 +25,7 @@
 
 # check if ar and openssl are available
 if which('ar') is None and not os.path.isfile('./ar') and not os.path.isfile('./ar.exe'):
-    raise Exception("You need the program 'ar' from xtensa-lx106-elf found here: (esp8266-arduino-core)/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/xtensa-lx106-elf/bin/ar")
+    raise Exception("You need the program 'ar' from xtensa-lx106-elf found here: (esp8266-arduino-core)/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf-gcc/xtensa-lx106-elf/bin/ar")
 if which('openssl') is None and not os.path.isfile('./openssl') and not os.path.isfile('./openssl.exe'):
     raise Exception("You need to have openssl in PATH, installable from https://www.openssl.org/")
     
diff --git a/platform.txt b/platform.txt
index 3ca4ffae29..fe9ea780c0 100644
--- a/platform.txt
+++ b/platform.txt
@@ -9,7 +9,7 @@ name=ESP8266 Boards (3.2.0-dev)
 version=3.2.0-dev
 
 # These will be removed by the packager script when doing a JSON release
-runtime.tools.xtensa-lx106-elf-gcc.path={runtime.platform.path}/tools/xtensa-lx106-elf
+runtime.tools.xtensa-lx106-elf-gcc.path={runtime.platform.path}/tools/xtensa-lx106-elf-gcc
 runtime.tools.python3.path={runtime.platform.path}/tools/python3
 
 runtime.tools.esptool.path={runtime.platform.path}/tools/esptool
diff --git a/tests/ci/eboot_test.sh b/tests/ci/eboot_test.sh
index 7efb6bbd60..e96a670353 100755
--- a/tests/ci/eboot_test.sh
+++ b/tests/ci/eboot_test.sh
@@ -3,7 +3,7 @@
 set -ev
 
 root=$(git rev-parse --show-toplevel)
-READELF="$root/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-readelf"
+READELF="$root/tools/xtensa-lx106-elf-gcc/bin/xtensa-lx106-elf-readelf"
 
 cd $root/tools
 python3 get.py -q
diff --git a/tests/common.sh b/tests/common.sh
index fc716abc66..423d30e5e4 100755
--- a/tests/common.sh
+++ b/tests/common.sh
@@ -224,7 +224,7 @@ function build_sketches()
                 && step_summary "$sketch warnings" "$cache_dir/build.log"
         fi
 
-        print_size_info "$core_path"/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-size \
+        print_size_info "$core_path"/tools/xtensa-lx106-elf-gcc/bin/xtensa-lx106-elf-size \
             $build_dir/*.elf >>$cache_dir/size.log
 
         echo ::endgroup::
@@ -442,7 +442,7 @@ function install_platformio()
     pio pkg install --global --skip-dependencies --platform "https://github.com/platformio/platform-espressif8266.git"
 
     local framework_symlink="framework-arduinoespressif8266 @ symlink://${ESP8266_ARDUINO_BUILD_DIR}"
-    local toolchain_symlink="toolchain-xtensa @ symlink://${ESP8266_ARDUINO_BUILD_DIR}/tools/xtensa-lx106-elf/"
+    local toolchain_symlink="toolchain-xtensa @ symlink://${ESP8266_ARDUINO_BUILD_DIR}/tools/xtensa-lx106-elf-gcc/"
 
     # pre-generate config; pio-ci with multiple '-O' replace each other instead of appending to the same named list
     # (and, it is much nicer to write this instead of a multi-line cmdline with several large strings)
diff --git a/tests/sanity_check.sh b/tests/sanity_check.sh
index a4754a0ed4..a75a65ca9a 100755
--- a/tests/sanity_check.sh
+++ b/tests/sanity_check.sh
@@ -9,7 +9,7 @@ python3 get.py -q
 popd
 pushd "$cache_dir"
 
-gcc="$root/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-gcc"\
+gcc="$root/tools/xtensa-lx106-elf-gcc/bin/xtensa-lx106-elf-gcc"\
 " -I$root/cores/esp8266"\
 " -I$root/tools/sdk/include"\
 " -I$root/variants/generic"\
diff --git a/tools/get.py b/tools/get.py
index 8276a46f21..2d7a6e59e3 100755
--- a/tools/get.py
+++ b/tools/get.py
@@ -14,7 +14,6 @@
 import sys
 import tarfile
 import zipfile
-import re
 
 verbose = True
 
@@ -48,29 +47,37 @@ def report_progress(count, blockSize, totalSize):
         sys.stdout.write("\r%d%%" % percent)
         sys.stdout.flush()
 
-def unpack(filename, destination):
+def unpack_impl(filename, destination):
+    file = None
     dirname = ''
-    print('Extracting {0}'.format(filename))
+
     if filename.endswith('tar.gz'):
-        tfile = tarfile.open(filename, 'r:gz')
-        tfile.extractall(destination)
-        dirname= tfile.getnames()[0]
+        file = tarfile.open(filename, 'r:gz')
+        file.extractall(destination)
+        dirname = tfile.getnames()[0]
     elif filename.endswith('zip'):
-        zfile = zipfile.ZipFile(filename)
-        zfile.extractall(destination)
+        file = zipfile.ZipFile(filename)
+        file.extractall(destination)
         dirname = zfile.namelist()[0]
     else:
         raise NotImplementedError('Unsupported archive type')
 
-    # a little trick to rename tool directories so they don't contain version number
-    rename_to = re.match(r'^([a-zA-Z_][^\-]*\-*)+', dirname).group(0).strip('-')
-    if rename_to != dirname:
-        print('Renaming {0} to {1}'.format(dirname, rename_to))
-        if os.path.isdir(rename_to):
-            shutil.rmtree(rename_to)
-        shutil.move(dirname, rename_to)
+    if file:
+        file.close()
+
+    return dirname
+
+def unpack(name, filename, destination):
+    print(f'Extracting {filename}')
+    dirname = unpack_impl(filename, destination)
+
+    if dirname != name:
+        print(f'Renaming {dirname} to {name}')
+        if os.path.isdir(name):
+            shutil.rmtree(name)
+        shutil.move(dirname, name)
 
-def get_tool(tool):
+def get_tool(name, tool):
     archive_name = tool['archiveFileName']
     local_path = dist_dir + archive_name
     url = tool['url']
@@ -81,21 +88,20 @@ def get_tool(tool):
         sys.stdout.write("\rDone\n")
         sys.stdout.flush()
     else:
-        print('Tool {0} already downloaded'.format(archive_name))
+        print(f'Tool "{name}" already downloaded as "{archive_name}"')
     local_hash = sha256sum(local_path)
     if local_hash != real_hash:
-        print('Hash mismatch for {0}, delete the file and try again'.format(local_path))
-        raise RuntimeError()
-    unpack(local_path, '.')
+        raise RuntimeError(f'Hash mismatch for tool {name} "{local_path}", delete the file and try again')
+    unpack(name, local_path, '.')
 
-def load_tools_list(filename, platform):
+def load_tools(filename, platform):
     tools_info = json.load(open(filename))['packages'][0]['tools']
-    tools_to_download = []
+    tools_to_download = {}
     for t in tools_info:
         tool_platform = [p for p in t['systems'] if p['host'] == platform]
-        if len(tool_platform) == 0:
+        if not tool_platform:
             continue
-        tools_to_download.append(tool_platform[0])
+        tools_to_download[t['name']] = tool_platform[0]
     return tools_to_download
 
 def identify_platform():
@@ -127,10 +133,12 @@ def main():
     if (os.path.exists('python3/python3')):
         os.unlink('python3/python3')
     print('Platform: {0}'.format(identify_platform()))
-    tools_to_download = load_tools_list('../package/package_esp8266com_index.template.json', identify_platform())
+    tools_to_download = load_tools(
+        '../package/package_esp8266com_index.template.json',
+        identify_platform())
     mkdir_p(dist_dir)
-    for tool in tools_to_download:
-        get_tool(tool)
+    for name, tool in tools_to_download.items():
+        get_tool(name, tool)
 
 if __name__ == '__main__':
     main()
diff --git a/tools/sdk/lib/compare/sdk-compare-libs b/tools/sdk/lib/compare/sdk-compare-libs
index 8b083c3550..61b9e7bcf5 100755
--- a/tools/sdk/lib/compare/sdk-compare-libs
+++ b/tools/sdk/lib/compare/sdk-compare-libs
@@ -32,10 +32,10 @@ verbose=false
 sdk="$1"
 me="$0"
 core=$(cd ${me%/*}/../../../..; pwd)
-
+tool="$core/tools/xtensa-lx106-elf-gcc/bin"
 
 [ -r "$sdk/lib/libnet80211.a" ] || help "$0"
-[ -r "$core/tools/xtensa-lx106-elf/bin" ] || help "$0"
+[ -r "$tool" ] || help "$0"
 
 tmp=$(pwd)/NONOSDK.deleteme
 
@@ -53,7 +53,7 @@ md5()
 {
 	mkdir temp
 	cd temp
-	PATH="$core/tools/xtensa-lx106-elf/bin:$PATH" xtensa-lx106-elf-ar x "$1"
+	PATH="$tool:$PATH" xtensa-lx106-elf-ar x "$1"
 	rm -f mem_manager.o time.o user_interface.o eagle_lwip_if.o
 	cat *.o | md5sum
 	cd ..
diff --git a/tools/sdk/lib/eval_fix_sdks.sh b/tools/sdk/lib/eval_fix_sdks.sh
index 389ee31650..3f94ffda54 100755
--- a/tools/sdk/lib/eval_fix_sdks.sh
+++ b/tools/sdk/lib/eval_fix_sdks.sh
@@ -1,6 +1,8 @@
 #!/bin/bash
 # set -e
 
+root=$(git rev-parse --show-toplevel)
+
 single_sdk="${2}"
 if [[ -n "$single_sdk" ]]; then
   if [[ "NONOSDK" != "${single_sdk:0:7}" ]]; then
@@ -16,8 +18,8 @@ add_path_ifexist() {
   return 1
 }
 
-if ! which xtensa-lx106-elf-ar | grep "tools/xtensa-lx106-elf/bin" >>/dev/null; then
-  add_path_ifexist "../../../xtensa-lx106-elf/bin" || add_path_ifexist "../../xtensa-lx106-elf/bin"
+if ! which xtensa-lx106-elf-ar >>/dev/null; then
+  add_path_ifexist "$root/tools/xtensa-lx106-elf-gcc/bin"
 fi
 
 help_msg() {
diff --git a/tools/sdk/lib/fix_sdk_libs.sh b/tools/sdk/lib/fix_sdk_libs.sh
index d024b46a08..b6e8981970 100755
--- a/tools/sdk/lib/fix_sdk_libs.sh
+++ b/tools/sdk/lib/fix_sdk_libs.sh
@@ -1,6 +1,8 @@
 #!/bin/bash
 set -e
 
+root=$(git rev-parse --show-toplevel)
+
 add_path_ifexist() {
 	if [[ -d $1 ]]; then
 		export PATH=$( realpath $1 ):$PATH
@@ -9,8 +11,8 @@ add_path_ifexist() {
 	return 1
 }
 
-if ! which xtensa-lx106-elf-ar | grep "tools/xtensa-lx106-elf/bin" >>/dev/null; then
-	add_path_ifexist "../../../xtensa-lx106-elf/bin" || add_path_ifexist "../../xtensa-lx106-elf/bin"
+if ! which xtensa-lx106-elf-ar >>/dev/null; then
+  add_path_ifexist "$root/tools/xtensa-lx106-elf-gcc/bin"
 fi
 WORK_SPACE=${PWD}
 
diff --git a/tools/warnings/README.md b/tools/warnings/README.md
index 5fb33f2bd7..eea391c847 100644
--- a/tools/warnings/README.md
+++ b/tools/warnings/README.md
@@ -8,5 +8,5 @@ to delete every warning but "-Wreturn-type"
 
 Generate the "none-g++" file with the following command:
 ````
-./tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-gcc --help=warnings -Q | grep '\[enabled\]' | grep -v 'return-type' | awk '{print $1}' | sed 's/-W/-Wno-/' | grep -v = | grep -v -- -f | egrep -v '(c11-c2x-compat|c90-c99-compat|c99-c11-compat|declaration-after-statement|designated-init|discarded-array-qualifiers|discarded-qualifiers|implicit-int|incompatible-pointer-types|int-conversion|old-style-definition|override-init-side-effects|pointer-to-int-cast)' > tools/warnings/none-g++
+./tools/xtensa-lx106-elf-gcc/bin/xtensa-lx106-elf-gcc --help=warnings -Q | grep '\[enabled\]' | grep -v 'return-type' | awk '{print $1}' | sed 's/-W/-Wno-/' | grep -v = | grep -v -- -f | egrep -v '(c11-c2x-compat|c90-c99-compat|c99-c11-compat|declaration-after-statement|designated-init|discarded-array-qualifiers|discarded-qualifiers|implicit-int|incompatible-pointer-types|int-conversion|old-style-definition|override-init-side-effects|pointer-to-int-cast)' > tools/warnings/none-g++
 ````

From cc5d5c14305f3296e061d5f0976049726dbe2f62 Mon Sep 17 00:00:00 2001
From: Maxim Prokhorov <prokhorov.max@outlook.com>
Date: Thu, 20 Jun 2024 00:08:17 +0300
Subject: [PATCH 2/3] typo

---
 tools/get.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/get.py b/tools/get.py
index 2d7a6e59e3..5e7473dd2a 100755
--- a/tools/get.py
+++ b/tools/get.py
@@ -54,11 +54,11 @@ def unpack_impl(filename, destination):
     if filename.endswith('tar.gz'):
         file = tarfile.open(filename, 'r:gz')
         file.extractall(destination)
-        dirname = tfile.getnames()[0]
+        dirname = file.getnames()[0]
     elif filename.endswith('zip'):
         file = zipfile.ZipFile(filename)
         file.extractall(destination)
-        dirname = zfile.namelist()[0]
+        dirname = file.namelist()[0]
     else:
         raise NotImplementedError('Unsupported archive type')
 

From 632d985353cd527c214053a2bb206a5d7637a9e8 Mon Sep 17 00:00:00 2001
From: Maxim Prokhorov <prokhorov.max@outlook.com>
Date: Thu, 20 Jun 2024 00:22:46 +0300
Subject: [PATCH 3/3] paths arent strings

---
 tools/get.py | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/tools/get.py b/tools/get.py
index 5e7473dd2a..446b72e318 100755
--- a/tools/get.py
+++ b/tools/get.py
@@ -8,6 +8,7 @@
 import shutil
 import errno
 import os.path
+import pathlib
 import hashlib
 import json
 import platform
@@ -65,17 +66,19 @@ def unpack_impl(filename, destination):
     if file:
         file.close()
 
-    return dirname
+    return pathlib.Path(destination) / dirname
 
 def unpack(name, filename, destination):
+    expected = pathlib.Path(destination) / name
+
     print(f'Extracting {filename}')
-    dirname = unpack_impl(filename, destination)
+    output = unpack_impl(filename, destination)
 
-    if dirname != name:
-        print(f'Renaming {dirname} to {name}')
-        if os.path.isdir(name):
-            shutil.rmtree(name)
-        shutil.move(dirname, name)
+    if expected != output:
+        print(f'Renaming {output} to {expected}')
+        if expected.is_dir():
+            shutil.rmtree(expected)
+        output.rename(expected)
 
 def get_tool(name, tool):
     archive_name = tool['archiveFileName']