tools: Windows Installer project moved to github.com/espressif/idf-installer

This commit is contained in:
Juraj Michálek 2021-06-23 12:35:25 +02:00 committed by Juraj Michalek
parent ead49c7acf
commit 76544b053a
43 changed files with 0 additions and 5514 deletions

View File

@ -385,28 +385,6 @@ build_idf_exe:
variables:
TEST_DIR: tools/windows/idf_exe
build_cmdlinerunner:
extends: .test-on-windows
stage: host_test
artifacts:
paths:
- tools/windows/tool_setup/cmdlinerunner/build/cmdlinerunner.dll
expire_in: 4 days
variables:
TEST_DIR: tools/windows/tool_setup/cmdlinerunner
build_installer:
extends: .test-on-windows
# using a different stage here to be able to use artifacts from build_cmdlinerunner job
stage: test_deploy # need to be after host_test since depends on `build_cmdlinerunner`
image: $CI_DOCKER_REGISTRY/wine-innosetup:2
dependencies: # set dependencies to null to avoid missing artifacts issue
needs:
- build_cmdlinerunner
script:
- cd tools/windows/tool_setup/
- ./build_installer.sh
# This job builds template app with permutations of targets and optimization levels
build_template_app:
extends:

View File

@ -113,5 +113,3 @@ tools/test_mkuf2/test_mkuf2.py
tools/unit-test-app/tools/get_available_configs.sh
tools/unit-test-app/unit_test.py
tools/windows/eclipse_make.sh
tools/windows/tool_setup/build_installer.sh
tools/windows/tool_setup/sign_installer.sh

View File

@ -281,6 +281,3 @@ tools/unit-test-app/tools/CreateSectionTable.py
tools/unit-test-app/tools/UnitTestParser.py
tools/unit-test-app/unit_test.py
tools/windows/eclipse_make.py
tools/windows/tool_setup/system_check/system_check_download.py
tools/windows/tool_setup/system_check/system_check_subprocess.py
tools/windows/tool_setup/system_check/system_check_virtualenv.py

View File

@ -1,8 +0,0 @@
Output
cmdlinerunner/build
dist
unzip
keys
idf_versions.txt
releases
tools

View File

@ -1,47 +0,0 @@
; Copyright 2019-2020 Espressif Systems (Shanghai) CO LTD
; SPDX-License-Identifier: Apache-2.0
[LangOptions]
LanguageName=English
LanguageID=$0409
[CustomMessages]
PreInstallationCheckTitle=Pre-installation system check
PreInstallationCheckSubtitle=Verification of environment
SystemCheckStart=Starting system check ...
SystemCheckForDefender=Checking Windows Defender
SystemCheckHint=Hint
SystemCheckResultFound=FOUND
SystemCheckResultNotFound=NOT FOUND
SystemCheckResultOk=OK
SystemCheckResultFail=FAIL
SystemCheckResultError=ERR
SystemCheckResultWarn=WARN
SystemCheckStopped=Check stopped.
SystemCheckStopButtonCaption=Stop
SystemCheckComplete=Check complete.
SystemCheckForComponent=Checking installed
SystemCheckUnableToExecute=Unable to execute
SystemCheckUnableToFindFile=Unable to find file
SystemCheckRemedyMissingPip=Please use a supported version of Python available on the next screen.
SystemCheckRemedyMissingVirtualenv=Please install virtualenv and retry the installation. Suggested commands:
SystemCheckRemedyCreateVirtualenv=Please use the supported Python version that is available on the next screen.
SystemCheckRemedyPythonInVirtualenv=Please use the supported Python version that is available on the next screen.
SystemCheckRemedyBinaryPythonWheel=Please use the supported Python version that is available on the next screen.
SystemCheckRemedyFailedHttpsDownload=Please use the supported Python version that is available on the next screen.
SystemCheckRemedyFailedSubmoduleRun=Python contains a subprocess.run module intended for Python 2. Please uninstall the module. Suggested command:
SystemCheckApplyFixesButtonCaption=Apply Fixes
SystemCheckFullLogButtonCaption=Full log
SystemCheckApplyFixesConsent=Do you want to apply the commands with the suggested fixes to update your Windows environment and start a new System Check?
SystemCheckFixesSuccessful=Successful application of Fixes.
SystemCheckFixesFailed=Failed application of Fixes. Please refer to the Full log.
SystemCheckNotCompleteConsent=System check is not complete. Do you want to proceed by skipping checks?
SystemCheckRootCertificates=Checking certificates
SystemCheckRootCertificateWarning=Unable to load data from server dl.espressif.com.
CreateShortcutStartMenu=Start Menu
CreateShortcutDesktop=Desktop
CreateShortcutPowerShell=PowerShell - Create shortcut for the ESP-IDF Tools:
CreateShortcutCMD=CMD - Create shortcut for the ESP-IDF Tools:
OptimizationTitle=Optimization:
OptimizationWindowsDefender=Register the ESP-IDF Tools executables as Windows Defender exclusions. The registration might improve compilation speed. The registration of exclusions requires elevation of privileges.
OptimizationDownloadMirror=Use Espressif download server instead of downloading tool packages from GitHub.

View File

@ -1,185 +0,0 @@
# ESP-IDF Tools Installer for Windows
This directory contains source files required to build the tools installer for Windows.
The installer is built using [Inno Setup](http://www.jrsoftware.org/isinfo.php). At the time of writing, the installer can be built with Inno Setup version 6.0.2.
The main source file of the installer is `idf_tools_setup.iss`. PascalScript code is split into multiple `*.iss.inc` files.
Some functionality of the installer depends on additional programs:
* [Inno Download Plugin](https://bitbucket.org/mitrich_k/inno-download-plugin) — used to download additional files during the installation.
* [7-zip](https://www.7-zip.org) — used to extract downloaded IDF archives.
* [cmdlinerunner](cmdlinerunner/cmdlinerunner.c) — a helper DLL used to run external command-line programs from the installer, capture live console output, and get the exit code.
## Installation of dependencies via Chocolatey
Run with Administrator privileges:
```
choco install inno-download-plugin
```
## Building the installer
### In Docker
This uses `wine-innosetup` Docker image and `build_installer.sh` script. This is how the installer is built in CI.
```
docker run --rm -v $IDF_PATH:/idf -w /idf/tools/windows/tool_setup -it $CI_DOCKER_REGISTRY/wine-innosetup:1 /bin/bash build_installer.sh
```
### Windows development env with WSL2 and Windows Docker Containers
The best approach to quickly develop and test all aspects of the build process is to use Windows with WSL2.
Requirements:
* WSL2 and Ubuntu distribution via Microsoft Store
* Install Windows Terminal - https://github.com/microsoft/terminal
* Install Docker and switch container runner to Windows
* Install Visual Studio Code - install plugin for Inno Setup and Docker
* Install Inno Setup - `choco install innnosetup`
#### The first build of the installer
This step is bootstrapping the whole process. Open Windows Terminal, click + sign and select Ubuntu.
```
cd tools/windows/tools_setup/
./build_installer.sh online
```
The setup will download the necessary dependencies and it will build the installer.
#### Build of offline version of the installer
The offline version is built by setting /DOFFLINE=yes to ISCC on the command-line. To speed up build, it's possible to redirect stdout of ISCC to the file.
```
./build_installer.sh offline >out.txt
```
To speed up development build it's possible to disable compression which is set by default to lzma.
```
./build_installer.sh offline none >out.txt
```
#### Development work in idf_tool_setup.iss
Open Inno Setup and open file idf_tool_setup.iss. This is the main file of the installer
Press CTRL+F9 to rebuild the whole installer. Inno Setup detects changes only in the main file. If you change anything in include files, you need to explicitly press CTRL+F9 to build and Run.
Press F9 to run the installer.
Additional parameters to speed up development could be passed via Run - Parameters
#### Development work in iss.inc files
The majority of code is store in iss.inc files. The best way to develop it is to open a whole esp-idf directory in Visual Studio Code.
To configure syntax highlight for inc files, open Settings CTRL+, search for `Associations`. In section TextEditor - Files find `File: Associations`. Click `Add Item`, set `item` to `*.inc`, set `value` to `innnosetup`.
#### Manually, step by step
* Build cmdlinerunner DLL.
- On Linux/Mac, install mingw-w64 toolchain (`i686-w64-mingw32-gcc`). Then build the DLL using CMake:
```
mkdir -p cmdlinerunner/build
cd cmdlinerunner/build
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchain-i686-w64-mingw32.cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build .
```
This will produce `cmdlinerunner.dll` in the build directory.
- On Windows, it is possible to build using Visual Studio, with CMake support installed. By default, VS produces build artifacts in some hard to find directory. You can adjust this in CmakeSettings.json file generated by VS.
* Download 7zip.exe [("standalone console version")](https://www.7-zip.org/download.html) and put it into `unzip` directory (to get `unzip/7za.exe`).
* Download [idf_versions.txt](https://dl.espressif.com/dl/esp-idf/idf_versions.txt) and place it into the current directory. The installer will use it as a fallback, if it can not download idf_versions.txt at run time.
* Create the `dist` directory and populate it with the tools which should be bundled with the installer. At the moment the easiest way to obtain it is to use `install.sh`/`install.bat` in IDF, and then copy the contents of `$HOME/.espressif/dist` directory. If the directory is empty, the installer should still work, and the tools will be downloaded during the installation.
* Build the installer using Inno Setup Compiler: `ISCC.exe idf_tools_setup.iss`.
### Testing of the installer
Development and testing of the installer can be simplified by using command line parameters which can be passed to the installer.
Select Run - Parameters in Inno Setup and add parameters.
Example of parameters:
```
/SKIPSYSTEMCHECK=yes /IDFVERSIONSURL=http://localhost:8000/idf_versions.txt /GITRESET=no /GITREPO=C:/projects/esp-idf /GITRECURSIVE=no
```
These combinations of parameters will result:
* ``SKIPSYSTEMCHECK=yes`` - The screen with System Check will be skipped.
* ``IDFVERSIONURL`` - idf_versions.txt will be downloaded from localhost:8000
- it's possible to add branch name into idf_versions.txt, e.g. feature/win_inst
* ``GITRESET=no`` - Git repository won't be reset after clone, it can save time and add custom changes in case of the zip archive with repository
* ``GITREPO`` - The version will be cloned from the specific location, e.g. from a local directory
* ``GITRECURSIVE=no`` - The clone of the repo won't contain modules, it speeds up the cloning process. Use when modules are not necessary.
Documentation of parameters is available in api-guides/tools/idf-windows-installer.rst
### Testing installation in Docker with Windows containers
The testing script is stored in docker-compose.yml. The test performs full silent installation and executes the build of get-started example.
Commands for testing of `online` and `offline` installer with support for cache of dist and releases:
```
$env:IDF_VERSION="v4.1"; docker-compose.exe run idf-setup-test
$env:IDF_VERSION="v4.0.2"; docker-compose.exe run idf-setup-test
$env:IDF_VERSION="v3.3.4"; docker-compose.exe run idf-setup-test
$env:IDF_VERSION="release/v4.2"; docker-compose.exe run idf-setup-test
$env:IDF_VERSION="release/v4.1"; docker-compose.exe run idf-setup-test
$env:IDF_VERSION="release/v4.0"; docker-compose.exe run idf-setup-test
$env:IDF_VERSION="release/v3.3"; docker-compose.exe run idf-setup-test
$env:IDF_VERSION="master"; docker-compose.exe run idf-setup-test
```
Command for testing `offline` type of installer which contains everything but kitchen sink.:
```
$env:IDF_VERSION="v4.2"; docker-compose.exe run idf-setup-offline-test
$env:IDF_VERSION="release/v4.2"; docker-compose.exe run idf-setup-offline-test
```
The installation log is not displayed immediately on the screen. It's stored in the file and it's displayed when the installation finishes. The glitch of Inno Setup is that in case of failed installation it won't terminate and it keeps hanging.
Recommendation: Use Visual Studio Code with Docker plugin to work with container.
The log file is then accessible under Docker - Containers - Container - Files - Temp - install.txt - right click - Open.
### Testing multiple installations at once
Docker compose contains definition of multiple scenarios. The test can be launched by command:
```
$env:IDF_VERSION="v4.2"; docker-compose up --force-recreate
```
Note: `--force-recreate` is necessary otherwise the container will be just resumed from previous state.
### Testing the installation in Hyper-V
Docker does not support the test of installation with GUI and enabled Windows Defender. These tests can be executed in Hyper-V available on Windows. Launch `Hyper-V Manager`, create VM, and connect to it.
Use the following command to copy the installer to Hyper-V machine with the name "win10":
```
Copy-VMFile "win10" -SourcePath C:\projects\esp-idf\tools\windows\tool_setup\Output\esp-idf-tools-setup-unsigned.exe -DestinationPath "C:\Users\Tester\Desktop\esp-idf-tools-setup-unsigned.exe" -CreateFullPath -FileSource Host -Force
```
## Signing the installer
* Obtain the signing key (e.g `key.pem`) and the certificate chain (e.g. `certchain.pem`). Set the environment variables to point to these files:
- `export KEYFILE=key.pem`
- `export CERTCHAIN=certchain.pem`
* Run `sign_installer.sh` script. This will ask for the `key.pem` password and produce the signed installer in the Output directory. If you plan to run the script multiple times, you may also set `KEYPASSWORD` environment variable to the `key.pem` password, to avoid the prompt.

View File

@ -1,24 +0,0 @@
param (
[string]$Installer="C:\Output\esp-idf-tools-setup-unsigned.exe",
[string]$IdfPath = "C:\Users\ContainerAdministrator\Desktop\esp-idf",
[string]$IdfVersion = "v4.1"
)
"Configuration:"
"* Installer = $Installer"
"* IdfPath = $IdfPath"
"* IdfVersion = $IdfVersion"
$ProcessName = (Get-Item $Installer).Basename
"Waiting for process: $ProcessName"
# Set PYTHONHOME and PYTHONPATH to some directory which is not on the system to test process of creating venv
# The Installer and IDF shell wrappers contains clearing of variables
$env:PYTHONPATH="C:\Hvannadalshnúkur"
$env:PYTHONHOME="C:\Hvannadalshnúkur"
mkdir C:\Temp
&$Installer /VERYSILENT /LOG=C:\Temp\install.txt /SUPPRESSMSGBOXES /SP- /NOCANCEL /NORESTART /IDFVERSION=${IdfVersion}
$InstallerProcess = Get-Process $ProcessName
Wait-Process -Id $InstallerProcess.id
Get-Content -Tail 80 C:\Temp\install.txt

View File

@ -1,8 +0,0 @@
param (
[string]$IdfVersion = "v4.1"
)
$ErrorActionPreference = "Stop"
New-Item -Path C:\Users\ContainerAdministrator\ -Name .espressif -ItemType "directory"
New-Item -Path C:\Users\ContainerAdministrator\.espressif -Name releases -ItemType "directory"
Copy-Item -Recurse -Verbose -Path C:\Cache\dist -Destination C:\Users\ContainerAdministrator\.espressif\dist
Copy-Item -Verbose -Path C:\Cache\releases\esp-idf-${IdfVersion}.zip -Destination C:\Users\ContainerAdministrator\.espressif\releases

View File

@ -1,19 +0,0 @@
param (
[string]$PythonPath = "C:\Python38\",
[string]$IdfPath = "C:\Users\ContainerAdministrator\Desktop\esp-idf"
)
$env:PATH+=";${PythonPath}"
Set-Location "${IdfPath}"
$env:PYTHONPATH="C:\Users\ContainerAdministrator\Desktop\esp-idf\tools\"
# Timeout is necessary to fix the problem when installer is writing some final files
# it seems that installer exits, but locks were not released yet
Start-Sleep -s 5
$WSShell = New-Object -comObject WScript.Shell
$Shortcut = $WSShell.CreateShortcut('C:\Users\ContainerAdministrator\Desktop\ESP-IDF Command Prompt (cmd.exe).lnk')
$Arguments = $Shortcut.Arguments -replace "/k ", "/c '"
$Command = $Shortcut.TargetPath + ' ' + $Arguments -replace '""', '"'
$Command += " && cd examples\get-started\blink\ && idf.py build'"
Invoke-Expression -Command $Command

View File

@ -1,31 +0,0 @@
param (
[string]$PythonPath = "C:\Python38\",
[string]$IdfPath = "C:\Users\ContainerAdministrator\Desktop\esp-idf"
)
$env:PATH+=";${PythonPath}"
Set-Location "${IdfPath}"
$env:PYTHONPATH="C:\Users\ContainerAdministrator\Desktop\esp-idf\tools\"
# Timeout is necessary to fix the problem when installer is writing some final files
# it seems that installer exits, but locks were not released yet
Start-Sleep -s 5
$WSShell = New-Object -comObject WScript.Shell
$Shortcut = $WSShell.CreateShortcut('C:\Users\ContainerAdministrator\Desktop\ESP-IDF PowerShell.lnk')
$Command = '. ' + $Shortcut.Arguments -replace '""', '"'
$Command = $Command -replace " -ExecutionPolicy Bypass -NoExit -File", ""
$Command
Invoke-Expression -Command $Command
cd examples\get-started\blink\
idf.py build
# Check whether the repository is clean
$GitChanges=(git status -s).Lenght
if ($GitChanges -gt 0) {
"* Warning! Git repository dirty."
$GitChanges
} else {
"Git repository clean."
}

View File

@ -1,234 +0,0 @@
#!/usr/bin/env bash
#
# Script to build the IDF Tools installer for Windows with Inno Setup.
# This script should be executed inside wine-innosetup docker image.
#
# - Downloads all tools to install into the "dist/" directory
# - Downloads 7z and idf_versions.txt
# - Runs ISCC under wine to compile the installer itself
set -x
set -e
set -u
INSTALLER_TYPE="${1-online}"
COMPRESSION="${2-lzma}"
# Default values for IDF installer passed in 'offline' version of build
IDF_GIT_VERSION="2.30.0.2"
IDF_GIT_VERSION_DIR="v2.30.0.windows.2"
IDF_PYTHON_VERSION="3.8.7"
IDF_PYTHON_WHEELS_VERSION="3.8-2021-01-21"
echo "Selected installer type: $INSTALLER_TYPE"
echo "Selected compresion: $COMPRESSION"
echo "Available installer types: online, offline, precached, draft"
echo "Available compressions: lzma, none"
# Configuration options passed to ISCC compiler
# OFFLINE [yes|no] - set installer to offline mode, nothing will be retrieved from
# internet during installation
ISCC_PARAMS=""
function prepare_offline_branches()
{
BUNDLE_DIR="releases/esp-idf-bundle"
if [[ ! -d "$BUNDLE_DIR" ]]; then
echo "Performing full clone."
git clone --shallow-since=2020-01-01 --jobs 8 --recursive https://github.com/espressif/esp-idf.git "$BUNDLE_DIR"
# Fix repo mode
git -C "$BUNDLE_DIR" config --local core.fileMode false
git -C "$BUNDLE_DIR" submodule foreach --recursive git config --local core.fileMode false
# Allow deleting directories by git clean --force
# Required when switching between versions which does not have a module present in current branch
git -C "$BUNDLE_DIR" config --local clean.requireForce false
git -C "$BUNDLE_DIR" reset --hard
git -C "$BUNDLE_DIR" submodule foreach git reset --hard
else
git -C "$BUNDLE_DIR" fetch
fi
VERSIONS="idf_versions.txt"
tac "$VERSIONS" | while read BRANCH; do
pushd "$BUNDLE_DIR"
if [[ -z "$BRANCH" ]]; then
continue
fi
echo "processing branch: ($BRANCH)"
git fetch origin tag "$BRANCH"
git checkout "$BRANCH"
# Pull changes only for branches, tags does not support pull
#https://stackoverflow.com/questions/1593188/how-to-programmatically-determine-whether-the-git-checkout-is-a-tag-and-if-so-w
git describe --exact-match HEAD || git pull
git submodule update --init --recursive
# Clean up left over submodule directories after switching to other branch
git clean --force -d
# Some modules are very persistent like cmok and needs 2nd round of cleaning
git clean --force -d
git reset --hard
git submodule foreach git reset --hard
if [[ $(git status -s | wc -l ) -ne 0 ]]; then
echo "git status not empty. Repository is dirty. Aborting."
git status
exit 1
fi
$IDF_PATH/tools/idf_tools.py --tools-json tools/tools.json --non-interactive download --platform Windows-x86_64 all
popd
done
# Remove symlinks which are not supported on Windws, unfortunatelly -c core.symlinks=false does not work
find "$BUNDLE_DIR" -type l -print -delete;
}
function install_idf_package()
{
TOOL_URL="$1"
TOOL_FILE="$2"
TOOL_VERSION="$3"
if [[ ! -f "${TOOL_FILE}" ]]; then
wget --no-verbose -O "${TOOL_FILE}" "${TOOL_URL}"
fi
if [[ ! -d "${TOOL_VERSION}" ]]; then
mkdir -p "${TOOL_VERSION}"
unzip -q "${TOOL_FILE}" -d "${TOOL_VERSION}"
fi
}
function install_idf_python()
{
install_idf_package \
"https://dl.espressif.com/dl/idf-python/idf-python-$IDF_PYTHON_VERSION-embed-win64.zip" \
"${IDF_TOOLS_PATH}/idf-python-${IDF_PYTHON_VERSION}-embed-win64.zip" \
"tools/idf-python/${IDF_PYTHON_VERSION}"
}
function install_idf_python_wheels()
{
install_idf_package \
"https://dl.espressif.com/dl/idf-python-wheels/idf-python-wheels-$IDF_PYTHON_WHEELS_VERSION-win64.zip" \
"${IDF_TOOLS_PATH}/idf-python-wheels-${IDF_PYTHON_WHEELS_VERSION}-win64.zip" \
"tools/idf-python-wheels/${IDF_PYTHON_WHEELS_VERSION}"
}
function install_idf_git()
{
IDF_FILE="Git-${IDF_GIT_VERSION}-64-bit.exe"
if [[ -f "${IDF_FILE}" ]]; then
return
fi
mkdir -p "${IDF_TOOLS_PATH}/dist/"
wget -nc --no-verbose -O "${IDF_TOOLS_PATH}/dist/${IDF_FILE}" "https://github.com/git-for-windows/git/releases/download/${IDF_GIT_VERSION_DIR}/${IDF_FILE}" || echo "exists"
if [[ `file -b "${IDF_TOOLS_PATH}/dist/${IDF_FILE}"` != "PE32 executable (GUI) Intel 80386, for MS Windows" ]]; then
echo "Git installer is not valid Windows Executable"
exit 1
fi
}
function download_idf_versions()
{
echo "Downloading idf_versions.txt..."
wget --no-verbose -O idf_versions.txt https://dl.espressif.com/dl/esp-idf/idf_versions.txt
}
function build_with_wine()
{
xvfb-run-wine /opt/wine/drive_c/Program\ Files\ \(x86\)/Inno\ Setup\ 6/ISCC.exe $ISCC_PARAMS idf_tool_setup.iss
}
# Check for ISCC on Windows WSL2
iscc_path=$(which ISCC.exe) || echo "ISCC.exe not found. If running in WSL2, install ISCC by following command: choco install innosetup"
if [[ -z "$iscc_path" ]]; then
echo "Searching for iscc"
iscc_path=$(which iscc)
if [[ -z "$iscc_path" ]]; then
echo "Inno setup compiler (iscc) not found. Are you running wine-innosetup Docker image?"
exit 1
fi
fi
if [ ! -d "unzip" ]; then
echo "Downloading 7z..."
mkdir -p unzip
pushd unzip
wget --no-verbose -O 7z1900-extra.7z https://www.7-zip.org/a/7z1900-extra.7z
7zr e -y 7z1900-extra.7z
popd
fi
if [[ -z "${IDF_PATH:-}" ]]; then
export IDF_PATH=$(cd ../../../; pwd)
echo "Assuming IDF_PATH: ${IDF_PATH}"
fi
export IDF_TOOLS_PATH="${PWD}/idf_tools_tmp_${INSTALLER_TYPE}"
mkdir -p "${IDF_TOOLS_PATH}"
echo "Using IDF_TOOLS_PATH specific for installer type: ${IDF_TOOLS_PATH}"
# Clean up production dist, data will be transferred from helper dist specific for installer type
if [[ -d "dist" ]]; then
rm -rf dist
fi
mkdir -p dist
if [[ "$INSTALLER_TYPE" == "precached" ]]; then
ISCC_PARAMS="/DOFFLINE=no /DCOMPRESSION=$COMPRESSION /DSOLIDCOMPRESSION=no /DPYTHONWHEELSVERSION= /DGITVERSION=${IDF_GIT_VERSION} /DGITVERSIONDIR=${IDF_GIT_VERSION_DIR}"
download_idf_versions
$IDF_PATH/tools/idf_tools.py --non-interactive download --platform Windows-x86_64 all
$IDF_PATH/tools/idf_tools.py --tools-json tools_fallback.json --non-interactive download --platform Windows-x86_64 all
cp $IDF_TOOLS_PATH/dist/* dist/
elif [[ "$INSTALLER_TYPE" == "online" ]]; then
ISCC_PARAMS="/DOFFLINE=no /DCOMPRESSION=$COMPRESSION /DSOLIDCOMPRESSION=no /DPYTHONWHEELSVERSION= /DGITVERSION=${IDF_GIT_VERSION} /DGITVERSIONDIR=${IDF_GIT_VERSION_DIR}"
download_idf_versions
install_idf_python
rm -rf tools/idf-python-wheels
elif [[ "$INSTALLER_TYPE" == "offline" ]]; then
# Turn off also solid compression - it causes delay in start time of installer.
ISCC_PARAMS="/DOFFLINE=yes /DCOMPRESSION=$COMPRESSION /DSOLIDCOMPRESSION=no /DPYTHONWHEELSVERSION=$IDF_PYTHON_WHEELS_VERSION /DGITVERSION=${IDF_GIT_VERSION} /DGITVERSIONDIR=${IDF_GIT_VERSION_DIR}"
install_idf_git
install_idf_python
install_idf_python_wheels
cp idf_versions_offline.txt idf_versions.txt
prepare_offline_branches
cp $IDF_TOOLS_PATH/dist/* dist/
elif [[ "$INSTALLER_TYPE" == "draft" ]]; then
ISCC_PARAMS="/DOFFLINE=yes /DCOMPRESSION=$COMPRESSION /DSOLIDCOMPRESSION=no /DPYTHONWHEELSVERSION=$IDF_PYTHON_WHEELS_VERSION /DGITVERSION=${IDF_GIT_VERSION} /DGITVERSIONDIR=${IDF_GIT_VERSION_DIR}"
else
echo "Uknown type of installer: $INSTALLER_TYPE"
exit 1
fi
# Check for cmdlinerunner
if [[ ! -f "cmdlinerunner/build/cmdlinerunner.dll" ]]; then
echo "cmdlinerunner not found, downloading"
wget --no-verbose -O $IDF_TOOLS_PATH/idf-cmdlinerunner-1.0.zip https://dl.espressif.com/dl/idf-cmdlinerunner/idf-cmdlinerunner-1.0.zip
mkdir -p cmdlinerunner/build
unzip -q $IDF_TOOLS_PATH/idf-cmdlinerunner-1.0.zip -d cmdlinerunner/build/
rm $IDF_TOOLS_PATH/idf-cmdlinerunner-1.0.zip
fi
echo "Running ISCC..."
# https://jrsoftware.org/ishelp/index.php?topic=compilercmdline
echo "iscc $ISCC_PARAMS idf_tool_setup.iss"
# Check whether we should run wine in case of docker image
which xvfb-run-wine && \
build_with_wine ||
iscc $ISCC_PARAMS idf_tool_setup.iss
mv "Output/esp-idf-tools-setup-unsigned.exe" "Output/esp-idf-tools-setup-${INSTALLER_TYPE}-unsigned.exe"

View File

@ -1,250 +0,0 @@
{ Copyright 2019-2021 Espressif Systems (Shanghai) CO LTD
SPDX-License-Identifier: Apache-2.0 }
var
ChoicePagePrepare: array of TNotifyEvent;
ChoicePageSelectionChange: array of TNotifyEvent;
ChoicePageValidate: array of TWizardPageButtonEvent;
ChoicePageMaxTag: Integer;
ChoicePages: array of TWizardPage;
procedure ChoicePageOnClickCheck(Sender: TObject);
var
ListBox: TNewCheckListBox;
Id: Integer;
begin
ListBox := TNewCheckListBox(Sender);
Id := Integer(ListBox.Tag);
ChoicePageSelectionChange[Id](ChoicePages[Id]);
end;
function ChoicePageGetInput(Page: TInputOptionWizardPage): TNewEdit;
begin
Result := TNewEdit(Page.FindComponent('ChoicePageInput'));
end;
function ChoicePageGetLabel(Page: TInputOptionWizardPage): TNewStaticText;
begin
Result := TNewStaticText(Page.FindComponent('ChoicePageLabel'));
end;
function ChoicePageGetButton(Page: TInputOptionWizardPage): TNewButton;
begin
Result := TNewButton(Page.FindComponent('ChoicePageBrowseButton'));
end;
procedure ChoicePageSetEditLabel(Page: TInputOptionWizardPage; Caption: String);
var
InputLabel: TNewStaticText;
begin
InputLabel := ChoicePageGetLabel(Page);
InputLabel.Caption := Caption;
end;
function ChoicePageGetInputText(Page: TInputOptionWizardPage): String;
begin
Result := ChoicePageGetInput(Page).Text;
end;
procedure ChoicePageSetInputText(Page: TInputOptionWizardPage; Text: String);
begin
ChoicePageGetInput(Page).Text := Text;
end;
procedure ChoicePageSetInputEnabled(Page: TInputOptionWizardPage; Enabled: Boolean);
begin
ChoicePageGetLabel(Page).Enabled := Enabled;
ChoicePageGetInput(Page).Enabled := Enabled;
ChoicePageGetButton(Page).Enabled := Enabled;
end;
procedure ChoicePageOnBrowseButtonClick(Sender: TObject);
var
Button: TNewButton;
Page: TInputOptionWizardPage;
InputLabel: TNewStaticText;
Input: TNewEdit;
Dir: String;
begin
Button := TNewButton(Sender);
Page := TInputOptionWizardPage(Button.Owner);
Input := ChoicePageGetInput(Page);
InputLabel := ChoicePageGetLabel(Page);
Dir := Input.Text;
if BrowseForFolder(InputLabel.Caption, Dir, True) then
begin
Input.Text := Dir;
end;
end;
<event('CurPageChanged')>
procedure ChoicePageOnCurPageChanged(CurPageID: Integer);
var
i: Integer;
begin
for i := 1 to ChoicePageMaxTag do
begin
if ChoicePages[i].ID = CurPageID then
begin
ChoicePagePrepare[i](ChoicePages[i]);
break;
end;
end;
end;
<event('NextButtonClick')>
function ChoicePageOnNextButtonClick(CurPageID: Integer): Boolean;
var
i: Integer;
begin
Result := True;
for i := 1 to ChoicePageMaxTag do
begin
if ChoicePages[i].ID = CurPageID then
begin
Result := ChoicePageValidate[i](ChoicePages[i]);
break;
end;
end;
end;
<event('InitializeWizard')>
procedure InitChoicePages();
begin
ChoicePages := [ ];
ChoicePagePrepare := [ ];
ChoicePageSelectionChange := [ ];
ChoicePageValidate := [ ];
end;
function FindLinkInText(Text: String): String;
var
Tmp: String;
LinkStartPos, LinkEndPos: Integer;
begin
Result := '';
Tmp := Text;
LinkStartPos := Pos('https://', Tmp);
if LinkStartPos = 0 then exit;
Delete(Tmp, 1, LinkStartPos - 1);
{ Try to find the end of the link }
LinkEndPos := 0
if LinkEndPos = 0 then LinkEndPos := Pos(' ', Tmp);
if LinkEndPos = 0 then LinkEndPos := Pos(',', Tmp);
if LinkEndPos = 0 then LinkEndPos := Pos('.', Tmp);
if LinkEndPos = 0 then LinkEndPos := Length(Tmp);
Delete(Text, LinkEndPos, Length(Tmp));
Log('Found link in "' + Text + '": "' + Tmp + '"');
Result := Tmp;
end;
procedure OnStaticTextClick(Sender: TObject);
var
StaticText: TNewStaticText;
Link: String;
Err: Integer;
begin
StaticText := TNewStaticText(Sender);
Link := FindLinkInText(StaticText.Caption);
if Link = '' then
exit;
ShellExec('open', Link, '', '', SW_SHOWNORMAL, ewNoWait, Err);
end;
procedure MakeStaticTextClickable(StaticText: TNewStaticText);
begin
if FindLinkInText(StaticText.Caption) = '' then
exit;
StaticText.OnClick := @OnStaticTextClick;
StaticText.Cursor := crHand;
end;
function ChoicePageCreate(
const AfterID: Integer;
const Caption, Description, SubCaption, EditCaption: String;
HasDirectoryChooser: Boolean;
Prepare: TNotifyEvent;
SelectionChange: TNotifyEvent;
Validate: TWizardPageButtonEvent): TInputOptionWizardPage;
var
VSpace, Y : Integer;
ChoicePage: TInputOptionWizardPage;
InputLabel: TNewStaticText;
Input: TNewEdit;
Button: TNewButton;
begin
ChoicePageMaxTag := ChoicePageMaxTag + 1;
VSpace := ScaleY(8);
ChoicePage := CreateInputOptionPage(AfterID, Caption,
Description, SubCaption, True, True);
MakeStaticTextClickable(ChoicePage.SubCaptionLabel);
ChoicePage.Tag := ChoicePageMaxTag;
ChoicePage.CheckListBox.OnClickCheck := @ChoicePageOnClickCheck;
ChoicePage.CheckListBox.Tag := ChoicePageMaxTag;
if HasDirectoryChooser then
begin
ChoicePage.CheckListBox.Anchors := [ akLeft, akTop, akRight ];
ChoicePage.CheckListBox.Height := ChoicePage.CheckListBox.Height - ScaleY(60);
Y := ChoicePage.CheckListBox.Top + ChoicePage.CheckListBox.Height + VSpace;
InputLabel := TNewStaticText.Create(ChoicePage);
with InputLabel do
begin
Top := Y;
Anchors := [akTop, akLeft, akRight];
Caption := EditCaption;
AutoSize := True;
Parent := ChoicePage.Surface;
Name := 'ChoicePageLabel';
end;
MakeStaticTextClickable(InputLabel);
Y := Y + InputLabel.Height + VSpace;
Input := TNewEdit.Create(ChoicePage);
with Input do
begin
Top := Y;
Anchors := [akTop, akLeft, akRight];
Parent := ChoicePage.Surface;
Name := 'ChoicePageInput';
Text := '';
end;
Button := TNewButton.Create(ChoicePage);
with Button do
begin
Anchors := [akTop, akRight];
Parent := ChoicePage.Surface;
Width := WizardForm.NextButton.Width;
Height := WizardForm.NextButton.Height;
Top := Y - (Height - Input.Height) / 2;
Left := ChoicePage.SurfaceWidth - Button.Width;
Name := 'ChoicePageBrowseButton';
Caption := SetupMessage(msgButtonWizardBrowse);
OnClick := @ChoicePageOnBrowseButtonClick;
end;
Input.Width := Button.Left - ScaleX(8);
end;
SetArrayLength(ChoicePages, ChoicePageMaxTag+1);
SetArrayLength(ChoicePagePrepare, ChoicePageMaxTag+1);
SetArrayLength(ChoicePageSelectionChange, ChoicePageMaxTag+1);
SetArrayLength(ChoicePageValidate, ChoicePageMaxTag+1);
ChoicePages[ChoicePageMaxTag] := ChoicePage;
ChoicePagePrepare[ChoicePageMaxTag] := Prepare;
ChoicePageSelectionChange[ChoicePageMaxTag] := SelectionChange;
ChoicePageValidate[ChoicePageMaxTag] := Validate;
Result := ChoicePage;
end;

View File

@ -1,153 +0,0 @@
{ Copyright 2019-2021 Espressif Systems (Shanghai) CO LTD
SPDX-License-Identifier: Apache-2.0 }
{ ------------------------------ Progress & log page for command line tools ------------------------------ }
var
CmdlineInstallCancel: Boolean;
{ ------------------------------ Splitting strings into lines and adding them to TStrings ------------------------------ }
procedure StringsAddLine(Dest: TStrings; Line: String; var ReplaceLastLine: Boolean);
begin
if ReplaceLastLine then
begin
Dest.Strings[Dest.Count - 1] := Line;
ReplaceLastLine := False;
end else begin
Dest.Add(Line);
end;
end;
procedure StrSplitAppendToList(Text: String; Dest: TStrings; var LastLine: String);
var
pCR, pLF, Len: Integer;
Tmp: String;
ReplaceLastLine: Boolean;
begin
if Length(LastLine) > 0 then
begin
ReplaceLastLine := True;
Text := LastLine + Text;
end;
repeat
Len := Length(Text);
pLF := Pos(#10, Text);
pCR := Pos(#13, Text);
if (pLF > 0) and ((pCR = 0) or (pLF < pCR) or (pLF = pCR + 1)) then
begin
if pLF < pCR then
Tmp := Copy(Text, 1, pLF - 1)
else
Tmp := Copy(Text, 1, pLF - 2);
StringsAddLine(Dest, Tmp, ReplaceLastLine);
Text := Copy(Text, pLF + 1, Len)
end else begin
if (pCR = Len) or (pCR = 0) then
begin
break;
end;
Text := Copy(Text, pCR + 1, Len)
end;
until (pLF = 0) and (pCR = 0);
LastLine := Text;
if pCR = Len then
begin
Text := Copy(Text, 1, pCR - 1);
end;
if Length(LastLine) > 0 then
begin
StringsAddLine(Dest, Text, ReplaceLastLine);
end;
end;
{ ------------------------------ The actual command line install page ------------------------------ }
procedure OnCmdlineInstallCancel(Sender: TObject);
begin
CmdlineInstallCancel := True;
end;
function DoCmdlineInstall(caption, description, command: String): Boolean;
var
CmdlineInstallPage: TOutputProgressWizardPage;
Res: Integer;
Handle: Longword;
ExitCode: Integer;
LogTextAnsi: AnsiString;
LogText, LeftOver: String;
Memo: TNewMemo;
PrevCancelButtonOnClick: TNotifyEvent;
begin
CmdlineInstallPage := CreateOutputProgressPage('', '')
CmdlineInstallPage.Caption := caption;
CmdlineInstallPage.Description := description;
Memo := TNewMemo.Create(CmdlineInstallPage);
Memo.Top := CmdlineInstallPage.ProgressBar.Top + CmdlineInstallPage.ProgressBar.Height + ScaleY(8);
Memo.Width := CmdlineInstallPage.SurfaceWidth;
Memo.Height := ScaleY(120);
Memo.ScrollBars := ssVertical;
Memo.Parent := CmdlineInstallPage.Surface;
Memo.Lines.Clear();
CmdlineInstallPage.Show();
try
WizardForm.CancelButton.Visible := True;
WizardForm.CancelButton.Enabled := True;
PrevCancelButtonOnClick := WizardForm.CancelButton.OnClick;
WizardForm.CancelButton.OnClick := @OnCmdlineInstallCancel;
CmdlineInstallPage.SetProgress(0, 100);
CmdlineInstallPage.ProgressBar.Style := npbstMarquee;
ExitCode := -1;
Memo.Lines.Append('Running command: ' + command);
Handle := ProcStart(command, ExpandConstant('{tmp}'))
if Handle = 0 then
begin
Log('ProcStart failed');
ExitCode := -2;
end;
while (ExitCode = -1) and not CmdlineInstallCancel do
begin
ExitCode := ProcGetExitCode(Handle);
SetLength(LogTextAnsi, 4096);
Res := ProcGetOutput(Handle, LogTextAnsi, 4096)
if Res > 0 then
begin
SetLength(LogTextAnsi, Res);
LogText := LeftOver + String(LogTextAnsi);
StrSplitAppendToList(LogText, Memo.Lines, LeftOver);
end;
CmdlineInstallPage.SetProgress(0, 100);
Sleep(10);
end;
ProcEnd(Handle);
finally
Log('Done, exit code=' + IntToStr(ExitCode));
Log('--------');
Log(Memo.Lines.Text);
Log('--------');
if CmdlineInstallCancel then
begin
MsgBox('Installation has been cancelled.', mbError, MB_OK);
Result := False;
end else if ExitCode <> 0 then
begin
MsgBox('Installation has failed with exit code ' + IntToStr(ExitCode), mbError, MB_OK);
Result := False;
end else begin
Result := True;
end;
CmdlineInstallPage.Hide;
CmdlineInstallPage.Free;
WizardForm.CancelButton.OnClick := PrevCancelButtonOnClick;
end;
if not Result then
RaiseException('Installation has failed at step: ' + caption);
end;

View File

@ -1,8 +0,0 @@
cmake_minimum_required(VERSION 3.5)
project(cmdlinerunner)
set(CMAKE_EXE_LINKER_FLAGS " -static")
add_library(cmdlinerunner SHARED cmdlinerunner.c)
target_compile_definitions(cmdlinerunner PUBLIC UNICODE _UNICODE)
set_target_properties(cmdlinerunner PROPERTIES PREFIX "")
set_target_properties(cmdlinerunner PROPERTIES C_STANDARD 99)
target_link_libraries(cmdlinerunner "-static-libgcc")

View File

@ -1,193 +0,0 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at",
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License
#define CMDLINERUNNER_EXPORTS
#include <windows.h>
#include <tchar.h>
#include <strsafe.h>
#include "cmdlinerunner.h"
#define LINESIZE 1024
#ifdef WITH_DEBUG
#include <stdio.h>
#define DEBUGV(...) do { fprintf(stderr, __VA_ARG__); } while(0)
#else
#define DEBUGV(...)
#endif
struct proc_instance_s {
PROCESS_INFORMATION child_process;
HANDLE pipe_server_handle;
HANDLE pipe_client_handle;
};
#ifdef WITH_DEBUG
static void print_last_error(void)
{
DWORD dw;
TCHAR errmsg[LINESIZE];
dw = GetLastError();
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
errmsg, sizeof(errmsg) - 1, NULL );
DEBUGV("error %d: %s\n", dw, errmsg);
}
#define PRINT_LAST_ERROR() print_last_error()
#else
#define PRINT_LAST_ERROR()
#endif
static proc_instance_t *proc_instance_allocate(void)
{
return (proc_instance_t*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(proc_instance_t));
}
static void proc_instance_free(proc_instance_t *instance)
{
if (instance->pipe_server_handle) {
CloseHandle(instance->pipe_server_handle);
}
if (instance->pipe_client_handle) {
CloseHandle(instance->pipe_client_handle);
}
if (instance->child_process.hProcess) {
TerminateProcess(instance->child_process.hProcess, 1);
CloseHandle(instance->child_process.hProcess);
CloseHandle(instance->child_process.hThread);
}
HeapFree(GetProcessHeap(), 0, instance);
}
void proc_end(proc_instance_t *inst)
{
if (inst == NULL) {
return;
}
proc_instance_free(inst);
}
CMDLINERUNNER_API proc_instance_t * proc_start(LPCTSTR cmdline, LPCTSTR workdir)
{
proc_instance_t *inst = proc_instance_allocate();
if (inst == NULL) {
return NULL;
}
SECURITY_ATTRIBUTES sec_attr = {
.nLength = sizeof(SECURITY_ATTRIBUTES),
.bInheritHandle = TRUE,
.lpSecurityDescriptor = NULL
};
LPCTSTR pipename = TEXT("\\\\.\\pipe\\cmdlinerunner_pipe");
inst->pipe_server_handle = CreateNamedPipe(pipename, PIPE_ACCESS_DUPLEX,
PIPE_TYPE_BYTE | PIPE_WAIT, 1, 1024 * 16, 1024 * 16,
NMPWAIT_WAIT_FOREVER, &sec_attr);
if (inst->pipe_server_handle == INVALID_HANDLE_VALUE) {
DEBUGV("inst->pipe_server_handle == INVALID_HANDLE_VALUE\n");
goto error;
}
inst->pipe_client_handle = CreateFile(pipename, GENERIC_WRITE | GENERIC_READ,
0, &sec_attr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (inst->pipe_client_handle == INVALID_HANDLE_VALUE) {
DEBUGV("inst->pipe_client_handle == INVALID_HANDLE_VALUE\n");
goto error;
}
DWORD new_mode = PIPE_READMODE_BYTE | PIPE_NOWAIT;
if (!SetNamedPipeHandleState(inst->pipe_server_handle, &new_mode, NULL,
NULL)) {
DEBUGV("SetNamedPipeHandleState failed\n");
goto error;
}
if (!SetHandleInformation(inst->pipe_server_handle, HANDLE_FLAG_INHERIT, 0)) {
DEBUGV("SetHandleInformation failed\n");
goto error;
}
if (!SetHandleInformation(inst->pipe_client_handle, HANDLE_FLAG_INHERIT,
HANDLE_FLAG_INHERIT)) {
DEBUGV("SetHandleInformation failed\n");
goto error;
}
STARTUPINFO siStartInfo = {
.cb = sizeof(STARTUPINFO),
.hStdError = inst->pipe_client_handle,
.hStdOutput = inst->pipe_client_handle,
.hStdInput = inst->pipe_client_handle,
.dwFlags = STARTF_USESTDHANDLES
};
size_t workdir_len = 0;
StringCbLength(workdir, STRSAFE_MAX_CCH * sizeof(TCHAR), &workdir_len);
if (workdir_len == 0) {
workdir = NULL;
}
TCHAR cmdline_tmp[LINESIZE];
StringCbCopy(cmdline_tmp, sizeof(cmdline_tmp), cmdline);
if (!CreateProcess(NULL, cmdline_tmp,
NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, workdir, &siStartInfo,
&inst->child_process)) {
DEBUGV("CreateProcess failed\n");
goto error;
}
return inst;
error:
PRINT_LAST_ERROR();
proc_instance_free(inst);
return NULL;
}
int proc_get_exit_code(proc_instance_t *inst)
{
DWORD result;
if (!GetExitCodeProcess(inst->child_process.hProcess, &result)) {
return -2;
}
if (result == STILL_ACTIVE) {
return -1;
}
return (int) result;
}
DWORD proc_get_output(proc_instance_t *inst, LPSTR dest, DWORD sz)
{
DWORD read_bytes;
BOOL res = ReadFile(inst->pipe_server_handle, dest,
sz - 1, &read_bytes, NULL);
if (!res) {
if (GetLastError() == ERROR_NO_DATA) {
return 0;
} else {
PRINT_LAST_ERROR();
return 0;
}
}
dest[read_bytes] = 0;
return read_bytes;
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved )
{
return TRUE;
}

View File

@ -1,32 +0,0 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at",
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License
#pragma once
#include <windows.h>
struct proc_instance_s;
typedef struct proc_instance_s proc_instance_t;
#ifdef CMDLINERUNNER_EXPORTS
#define CMDLINERUNNER_API __declspec(dllexport)
#else
#define CMDLINERUNNER_API __declspec(dllimport)
#endif
CMDLINERUNNER_API proc_instance_t * proc_start(LPCTSTR cmdline, LPCTSTR workdir);
CMDLINERUNNER_API int proc_get_exit_code(proc_instance_t *inst);
CMDLINERUNNER_API DWORD proc_get_output(proc_instance_t *inst, LPSTR dest, DWORD sz);
CMDLINERUNNER_API void proc_end(proc_instance_t *inst);
CMDLINERUNNER_API BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved );

View File

@ -1,7 +0,0 @@
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_PROCESSOR x86)
set(CMAKE_C_COMPILER i686-w64-mingw32-gcc)
set(CMAKE_CXX_COMPILER i686-w64-mingw32-g++)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

View File

@ -1,18 +0,0 @@
[DEFAULT]
GITRECURSIVE=yes
GITRESET=yes
GITREPO=https://github.com/espressif/esp-idf.git
; In case of password protected keychain you can use ssh-agent
; Make sure that the 'Open SSH Agent' service is not Disabled in services list.
; Add kyes: ssh-add
; Tell git which ssh command to use, otherwise it might still prompt you for password
; [Environment]::SetEnvironmentVariable("GIT_SSH", "$((Get-Command ssh).Source)", [System.EnvironmentVariableTarget]::User)
; Start new process/terminal to load env variable
; Note: OpenSSH is part of Windows 1803 - https://poshsecurity.com/blog/using-the-openssh-client-included-in-windows-10-1809-as-your-gits-ssh-client
IDFDIR=
IDFVERSION=
IDFVERSIONSURL=https://dl.espressif.com/dl/esp-idf/idf_versions.txt
OFFLINE=yes
PYTHONWHEELSURL=https://dl.espressif.com/pypi
SKIPSYSTEMCHECK=no
USEEMBEDDEDPYTHON=yes

View File

@ -1,73 +0,0 @@
{ Copyright 2019-2021 Espressif Systems (Shanghai) CO LTD
SPDX-License-Identifier: Apache-2.0 }
{ ------------------------------ Load configuration of the installer ------------------------------ }
var
ConfigurationFile: String;
GitRepository: String;
IsGitRecursive: Boolean;
IsGitResetAllowed: Boolean;
IsGitCleanAllowed: Boolean;
IsPythonNoUserSite: Boolean;
IsOfflineMode: Boolean;
IDFDirectory: String;
IDFVersion: String;
IDFVersionUrl: String;
PythonWheelsUrl: String;
PythonWheelsVersion: String;
SkipSystemCheck: Boolean;
UseEmbeddedPython: Boolean;
function GetConfigurationString(Key: String; Default: String):String;
var Value: String;
begin
Value := GetIniString('DEFAULT', Key, Default, ConfigurationFile);
Value := ExpandConstant('{param:' + Key + '|' + Value + '}');
Log('Configuration /' + Key + '=' + Value);
Result := Value;
end;
function GetConfigurationBoolean(Key: String; DefaultString: String):Boolean;
begin
Result := (GetConfigurationString(Key, DefaultString) = 'yes');
end;
{ Initialize configuration of the installer. }
{ Default configuration is encoded in installer. }
{ The configuration can be changed by configuration.ini file. }
{ The configuration can be changed by command line options which have highest priority. }
<event('InitializeWizard')>
procedure InitializeConfiguration();
begin
ConfigurationFile := ExpandConstant('{param:CONFIG|}');
if (ConfigurationFile <> '') then begin
if (not FileExists(ConfigurationFile)) then begin
Log('Configuration file does not exist, using default values.');
end;
end;
Log('Configuration /CONFIG=' + ConfigurationFile);
IsGitCleanAllowed := GetConfigurationBoolean('GITCLEAN', 'yes');
IsGitRecursive := GetConfigurationBoolean('GITRECURSIVE', 'yes');
IsGitResetAllowed := GetConfigurationBoolean('GITRESET', 'yes');
GitRepository := GetConfigurationString('GITREPO', 'https://github.com/espressif/esp-idf.git');
IDFDirectory := GetConfigurationString('IDFDIR', '');
IDFVersion := GetConfigurationString('IDFVERSION', '');
IDFVersionUrl := GetConfigurationString('IDFVERSIONSURL', 'https://dl.espressif.com/dl/esp-idf/idf_versions.txt');
IsOfflineMode := GetConfigurationBoolean('OFFLINE', '{#OFFLINE}');
IsPythonNoUserSite := GetConfigurationBoolean('PYTHONNOUSERSITE', 'yes');
PythonWheelsUrl := GetConfigurationString('PYTHONWHEELSURL', 'https://dl.espressif.com/pypi');
PythonWheelsVersion := GetConfigurationString('PYTHONWHEELSVERSION', '{#PYTHONWHEELSVERSION}');
SkipSystemCheck := GetConfigurationBoolean('SKIPSYSTEMCHECK', 'no');
UseEmbeddedPython := GetConfigurationBoolean('USEEMBEDDEDPYTHON', 'yes');
end;
{ Required to display option for installation configuration. }
function IsOnlineMode():Boolean;
begin
Result := not IsOfflineMode;
end;

View File

@ -1,54 +0,0 @@
version: "3"
# This docker-compose is for testing the installation process.
# In starts the installation and executes also build of get-started example.
services:
idf-setup-online-test:
image: mcr.microsoft.com/windows/servercore:1809
command: powershell -c "C:/Scripts/Install-Idf.ps1 -Installer 'c:/Output/esp-idf-tools-setup-online-unsigned.exe' -IdfVersion ${IDF_VERSION}; C:/Scripts/Test-IdfCmd.ps1; C:/Scripts/Test-IdfPowerShell.ps1;; powershell ;exit $$LASTEXITCODE"
tmpfs:
- C:\Users\ContainerAdministrator\.espressif
volumes:
- type: bind
source: C:\projects\esp-idf\tools\windows\tool_setup\Output
target: C:\Output
read_only: true
- type: bind
source: C:\projects\esp-idf\tools\windows\tool_setup\Scripts
target: C:\Scripts
read_only: true
idf-setup-offline-test:
image: mcr.microsoft.com/windows/servercore:1809
command: powershell -c "C:/Scripts/Install-Idf.ps1 -Installer 'c:/Output/esp-idf-tools-setup-offline-unsigned.exe' -IdfVersion ${IDF_VERSION}; C:/Scripts/Test-IdfCmd.ps1; C:/Scripts/Test-IdfPowerShell.ps1; powershell ;exit $$LASTEXITCODE"
tmpfs:
- C:\Users\ContainerAdministrator\.espressif
volumes:
- type: bind
source: C:\projects\esp-idf\tools\windows\tool_setup\Output
target: C:\Output
read_only: true
- type: bind
source: C:\projects\esp-idf\tools\windows\tool_setup\Scripts
target: C:\Scripts
read_only: true
idf-setup-precached-test:
image: mcr.microsoft.com/windows/servercore:1809
command: powershell -c "C:/Scripts/Prepare-Cache.ps1 -IdfVersion ${IDF_VERSION}; C:/Scripts/Install-Idf.ps1 -Installer 'c:/Output/esp-idf-tools-setup-online-unsigned.exe' -IdfVersion ${IDF_VERSION}; C:/Scripts/Test-IdfCmd.ps1; C:/Scripts/Test-IdfPowerShell.ps1; powershell ;exit $$LASTEXITCODE"
tmpfs:
- C:\Users\ContainerAdministrator\.espressif
volumes:
- type: bind
source: C:\projects\esp-idf\tools\windows\tool_setup\Output
target: C:\Output
read_only: true
- type: bind
source: C:\projects\esp-idf\tools\windows\tool_setup\Scripts
target: C:\Scripts
read_only: true
# releases volume to speed up installation and avoid downloading of files
- type: bind
source: C:\projects\esp-tests\installer-docker-runner\.espressif\
target: C:\Cache
read_only: true

View File

@ -1,98 +0,0 @@
{ Copyright 2019-2021 Espressif Systems (Shanghai) CO LTD
SPDX-License-Identifier: Apache-2.0 }
{ ------------------------------ Find installed copies of Git ------------------------------ }
var
InstalledGitVersions: TStringList;
InstalledGitDisplayNames: TStringList;
InstalledGitExecutables: TStringList;
procedure GitVersionAdd(Version, DisplayName, Executable: String);
begin
Log('Adding Git version=' + Version + ' name='+DisplayName+' executable='+Executable);
InstalledGitVersions.Append(Version);
InstalledGitDisplayNames.Append(DisplayName);
InstalledGitExecutables.Append(Executable);
end;
function GetVersionOfGitExe(Path: String; var Version: String; var ErrStr: String): Boolean;
var
VersionOutputFile: String;
Args: String;
GitVersionAnsi: AnsiString;
GitVersion: String;
GitVersionPrefix: String;
Err: Integer;
begin
VersionOutputFile := ExpandConstant('{tmp}\gitver.txt');
DeleteFile(VersionOutputFile);
Args := '/C "' + Path + '" --version >gitver.txt';
Log('Running ' + Args);
if not ShellExec('', 'cmd.exe', Args,
ExpandConstant('{tmp}'), SW_HIDE, ewWaitUntilTerminated, Err) then
begin
ErrStr := 'Failed to get git version, error=' + IntToStr(err);
Log(ErrStr);
Result := False;
exit;
end;
LoadStringFromFile(VersionOutputFile, GitVersionAnsi);
GitVersion := Trim(String(GitVersionAnsi));
GitVersionPrefix := 'git version ';
if Pos(GitVersionPrefix, GitVersion) <> 1 then
begin
ErrStr := 'Unexpected git version format: ' + GitVersion;
Log(ErrStr);
Result := False;
exit;
end;
Delete(GitVersion, 1, Length(GitVersionPrefix));
Version := GitVersion;
Result := True;
end;
procedure FindGitInPath();
var
Args: String;
GitListFile: String;
GitPaths: TArrayOfString;
GitVersion: String;
ErrStr: String;
Err: Integer;
i: Integer;
begin
GitListFile := ExpandConstant('{tmp}\gitlist.txt');
Args := '/C where git.exe >"' + GitListFile + '"';
if not ShellExec('', 'cmd.exe', Args,
'', SW_HIDE, ewWaitUntilTerminated, Err) then
begin
Log('Failed to find git using "where", error='+IntToStr(Err));
exit;
end;
LoadStringsFromFile(GitListFile, GitPaths);
for i:= 0 to GetArrayLength(GitPaths) - 1 do
begin
Log('Git path: ' + GitPaths[i]);
if not GetVersionOfGitExe(GitPaths[i], GitVersion, ErrStr) then
continue;
Log('Git version: ' + GitVersion);
GitVersionAdd(GitVersion, GitVersion, GitPaths[i]);
end;
end;
procedure FindInstalledGitVersions();
begin
InstalledGitVersions := TStringList.Create();
InstalledGitDisplayNames := TStringList.Create();
InstalledGitExecutables := TStringList.Create();
FindGitInPath();
end;

View File

@ -1,194 +0,0 @@
{ Copyright 2019-2021 Espressif Systems (Shanghai) CO LTD
SPDX-License-Identifier: Apache-2.0 }
{ ------------------------------ Page to select Git ------------------------------ }
#include "git_find_installed.iss.inc"
var
GitPage: TInputOptionWizardPage;
GitPath, GitExecutablePath, GitVersion: String;
GitUseExisting: Boolean;
GitSelectionInstallIndex: Integer;
GitSelectionCustomPathIndex: Integer;
function GetGitPath(Unused: String): String;
begin
Result := GitPath;
end;
function GitInstallRequired(): Boolean;
begin
Result := not GitUseExisting;
end;
function GitVersionSupported(Version: String): Boolean;
var
Major, Minor: Integer;
begin
Result := False;
if not VersionExtractMajorMinor(Version, Major, Minor) then
begin
Log('GitVersionSupported: Could not parse version=' + Version);
exit;
end;
{ Need at least git 2.12 for 'git clone --reference' to work with submodules }
if (Major = 2) and (Minor >= 12) then Result := True;
if (Major > 2) then Result := True;
end;
procedure GitCustomPathUpdateEnabled();
var
Enable: Boolean;
begin
if GitPage.SelectedValueIndex = GitSelectionCustomPathIndex then
Enable := True;
ChoicePageSetInputEnabled(GitPage, Enable);
end;
procedure OnGitPagePrepare(Sender: TObject);
var
Page: TInputOptionWizardPage;
FullName: String;
i, Index, FirstEnabledIndex: Integer;
OfferToInstall: Boolean;
VersionToInstall: String;
VersionSupported: Boolean;
begin
Page := TInputOptionWizardPage(Sender);
Log('OnGitPagePrepare');
if Page.CheckListBox.Items.Count > 0 then
exit;
FindInstalledGitVersions();
VersionToInstall := '{#GitVersion}';
OfferToInstall := True;
FirstEnabledIndex := -1;
for i := 0 to InstalledGitVersions.Count - 1 do
begin
VersionSupported := GitVersionSupported(InstalledGitVersions[i]);
FullName := InstalledGitDisplayNames.Strings[i];
if not VersionSupported then
begin
FullName := FullName + ' (unsupported)';
end;
FullName := FullName + #13#10 + InstalledGitExecutables.Strings[i];
Index := Page.Add(FullName);
if not VersionSupported then
begin
Page.CheckListBox.ItemEnabled[Index] := False;
end else begin
if FirstEnabledIndex < 0 then FirstEnabledIndex := Index;
end;
if InstalledGitVersions[i] = VersionToInstall then
begin
OfferToInstall := False;
end;
end;
if OfferToInstall then
begin
Index := Page.Add('Install Git ' + VersionToInstall);
if FirstEnabledIndex < 0 then FirstEnabledIndex := Index;
GitSelectionInstallIndex := Index;
end;
Index := Page.Add('Custom git.exe location');
if FirstEnabledIndex < 0 then FirstEnabledIndex := Index;
GitSelectionCustomPathIndex := Index;
Page.SelectedValueIndex := FirstEnabledIndex;
GitCustomPathUpdateEnabled();
end;
procedure OnGitSelectionChange(Sender: TObject);
var
Page: TInputOptionWizardPage;
begin
Page := TInputOptionWizardPage(Sender);
Log('OnGitSelectionChange index=' + IntToStr(Page.SelectedValueIndex));
GitCustomPathUpdateEnabled();
end;
function OnGitPageValidate(Sender: TWizardPage): Boolean;
var
Page: TInputOptionWizardPage;
Version, ErrStr: String;
begin
Page := TInputOptionWizardPage(Sender);
Log('OnGitPageValidate index=' + IntToStr(Page.SelectedValueIndex));
if Page.SelectedValueIndex = GitSelectionInstallIndex then
begin
GitUseExisting := False;
GitExecutablePath := '';
GitPath := '';
GitVersion := '{#GitVersion}';
Result := True;
end else if Page.SelectedValueIndex = GitSelectionCustomPathIndex then
begin
GitPath := ChoicePageGetInputText(Page);
GitExecutablePath := GitPath + '\git.exe';
if not FileExists(GitExecutablePath) then
begin
MsgBox('Can not find git.exe in ' + GitPath, mbError, MB_OK);
Result := False;
exit;
end;
if not GetVersionOfGitExe(GitExecutablePath, Version, ErrStr) then
begin
MsgBox('Can not determine version of git.exe.' + #13#10
+ 'Please check that this copy of git works from cmd.exe.', mbError, MB_OK);
Result := False;
exit;
end;
Log('Version of ' + GitExecutablePath + ' is ' + Version);
if not GitVersionSupported(Version) then
begin
MsgBox('Selected git version (' + Version + ') is not supported.', mbError, MB_OK);
Result := False;
exit;
end;
Log('Version of git is supported');
GitUseExisting := True;
GitVersion := Version;
end else begin
GitUseExisting := True;
GitExecutablePath := InstalledGitExecutables[Page.SelectedValueIndex];
GitPath := ExtractFilePath(GitExecutablePath);
GitVersion := InstalledGitVersions[Page.SelectedValueIndex];
Result := True;
end;
end;
procedure GitExecutablePathUpdateAfterInstall();
var
GitInstallPath: String;
begin
GitInstallPath := GetInstallPath('SOFTWARE\GitForWindows', 'InstallPath');
if GitInstallPath = '' then
begin
Log('Failed to find Git install path');
exit;
end;
GitPath := GitInstallPath + '\cmd';
GitExecutablePath := GitPath + '\git.exe';
end;
<event('InitializeWizard')>
procedure CreateGitPage();
begin
GitPage := ChoicePageCreate(
wpLicense,
'Git choice', 'Please choose Git version',
'Available Git versions',
'Enter custom location of git.exe',
True,
@OnGitPagePrepare,
@OnGitSelectionChange,
@OnGitPageValidate);
end;

View File

@ -1,129 +0,0 @@
@echo off
:: This script is called from a shortcut (cmd.exe /k export_fallback.bat), with
:: the working directory set to an ESP-IDF directory.
:: Its purpose is to support using the "IDF Tools Directory" method of
:: installation for ESP-IDF versions older than IDF v4.0.
:: It does the same thing as "export.bat" in IDF v4.0.
set IDF_PATH=%CD%
if not exist "%IDF_PATH%\tools\idf.py" (
echo This script must be invoked from ESP-IDF directory.
goto :end
)
if "%~2"=="" (
echo Usage: idf_cmd_init.bat ^<Python directory^> ^<Git directory^>
echo This script must be invoked from ESP-IDF directory.
goto :end
)
set "IDF_PYTHON_DIR=%1"
set "IDF_GIT_DIR=%2"
:: Strip quoutes
set "IDF_PYTHON_DIR=%IDF_PYTHON_DIR:"=%"
set "IDF_GIT_DIR=%IDF_GIT_DIR:"=%"
:: Clear PYTHONPATH as it may contain libraries of other Python versions
if not "%PYTHONPATH%"=="" (
echo Clearing PYTHONPATH, was set to %PYTHONPATH%
set PYTHONPATH=
)
:: Clear PYTHONHOME as it may contain path to other Python versions which can cause crash of Python using virtualenv
if not "%PYTHONHOME%"=="" (
echo Clearing PYTHONHOME, was set to %PYTHONHOME%
set PYTHONHOME=
)
:: Set PYTHONNOUSERSITE to avoid loading of Python packages from AppData\Roaming profile
if "%PYTHONNOUSERSITE%"=="" (
echo Setting PYTHONNOUSERSITE, was not set
set PYTHONNOUSERSITE=True
)
:: Add Python and Git paths to PATH
set "PATH=%IDF_PYTHON_DIR%;%IDF_GIT_DIR%;%PATH%"
echo Using Python in %IDF_PYTHON_DIR%
python.exe --version
echo Using Git in %IDF_GIT_DIR%
git.exe --version
:: Check if this is a recent enough copy of ESP-IDF.
:: If so, use export.bat provided there.
:: Note: no "call", will not return into this batch file.
if exist "%IDF_PATH%\export.bat" %IDF_PATH%\export.bat
echo IDF version does not include export.bat. Using the fallback version.
if exist "%IDF_PATH%\tools\tools.json" (
set "IDF_TOOLS_JSON_PATH=%IDF_PATH%\tools\tools.json"
) else (
echo IDF version does not include tools\tools.json. Using the fallback version.
set "IDF_TOOLS_JSON_PATH=%~dp0%tools_fallback.json"
)
if exist "%IDF_PATH%\tools\idf_tools.py" (
set "IDF_TOOLS_PY_PATH=%IDF_PATH%\tools\idf_tools.py"
) else (
echo IDF version does not include tools\idf_tools.py. Using the fallback version.
set "IDF_TOOLS_PY_PATH=%~dp0%idf_tools_fallback.py"
)
echo.
echo Setting IDF_PATH: %IDF_PATH%
echo.
set "OLD_PATH=%PATH%"
echo Adding ESP-IDF tools to PATH...
:: Export tool paths and environment variables.
:: It is possible to do this without a temporary file (running idf_tools.py from for /r command),
:: but that way it is impossible to get the exit code of idf_tools.py.
set "IDF_TOOLS_EXPORTS_FILE=%TEMP%\idf_export_vars.tmp"
python.exe "%IDF_TOOLS_PY_PATH%" --tools-json "%IDF_TOOLS_JSON_PATH%" export --format key-value >"%IDF_TOOLS_EXPORTS_FILE%"
if %errorlevel% neq 0 goto :end
for /f "usebackq tokens=1,2 eol=# delims==" %%a in ("%IDF_TOOLS_EXPORTS_FILE%") do (
call set "%%a=%%b"
)
:: This removes OLD_PATH substring from PATH, leaving only the paths which have been added,
:: and prints semicolon-delimited components of the path on separate lines
call set PATH_ADDITIONS=%%PATH:%OLD_PATH%=%%
if "%PATH_ADDITIONS%"=="" call :print_nothing_added
if not "%PATH_ADDITIONS%"=="" echo %PATH_ADDITIONS:;=&echo. %
echo Checking if Python packages are up to date...
python.exe %IDF_PATH%\tools\check_python_dependencies.py
if %errorlevel% neq 0 goto :end
echo.
echo Done! You can now compile ESP-IDF projects.
echo Go to the project directory and run:
echo.
echo idf.py build
echo.
goto :end
:print_nothing_added
echo No directories added to PATH:
echo.
echo %PATH%
echo.
goto :eof
:end
:: Clean up
if not "%IDF_TOOLS_EXPORTS_FILE%"=="" (
del "%IDF_TOOLS_EXPORTS_FILE%" 1>nul 2>nul
)
set IDF_TOOLS_EXPORTS_FILE=
set IDF_PYTHON_DIR=
set IDF_GIT_DIR=
set IDF_TOOLS_PY_PATH=
set IDF_TOOLS_JSON_PATH=
set OLD_PATH=
set PATH_ADDITIONS=

View File

@ -1,126 +0,0 @@
# This script is called from a Windows shortcut, with
# the working directory set to an ESP-IDF directory.
# Its purpose is to support using the "IDF Tools Directory" method of
# installation for ESP-IDF versions older than IDF v4.1.
# It does the same thing as "export.ps1" in IDF v4.1.
Param
(
[String]$IdfGitDir,
[String]$IdfPythonDir
)
$IDF_PATH = "."
$isEspIdfRoot = (Test-Path "$IDF_PATH/tools/idf.py")
if (-not $isEspIdfRoot) {
Write-Output "Usage: idf_cmd_init.ps1 ^<Python directory^> ^<Git directory^>"
Write-Output "This script must be invoked from ESP-IDF directory."
}
# Clear PYTHONPATH as it may contain libraries of other Python versions
if ($null -ne $env:PYTHONPATH) {
"Clearing PYTHONPATH, was set to $env:PYTHONPATH"
$env:PYTHONPATH=$null
}
# Clear PYTHONHOME as it may contain path to other Python versions which can cause crash of Python using virtualenv
if ($null -ne $env:PYTHONHOME) {
"Clearing PYTHONHOME, was set to $env:PYTHONHOME"
$env:PYTHONHOME=$null
}
# Set PYTHONNOUSERSITE to avoid loading of Python packages from AppData\Roaming profile
if ($null -eq $env:PYTHONNOUSERSITE) {
"Setting PYTHONNOUSERSITE, was not set"
$env:PYTHONNOUSERSITE="True"
}
# Strip quotes
$IdfGitDir = $IdfGitDir.Trim("`"")
$IdfPythonDir = $IdfPythonDir.Trim("`"")
# Add Python and Git paths to PATH
$env:PATH = "$IdfGitDir;$IdfPythonDir;$env:PATH"
Write-Output "Using Python in $IdfPythonDir"
python.exe --version
Write-Output "Using Git in $IdfGitDir"
git.exe --version
# Check if this is a recent enough copy of ESP-IDF.
# If so, use export.ps1 provided there.
$isExport = (Test-Path "$IDF_PATH/export.ps1")
if ($isExport){
. $IDF_PATH/export.ps1
}
else {
Write-Output "IDF version does not include export.ps1. Using the fallback version."
if ((Test-Path "$IDF_PATH/tools/tools.json")){
$IDF_TOOLS_JSON_PATH = "$IDF_PATH/tools/tools.json"
}
else{
Write-Output "IDF version does not include tools/tools.json. Using the fallback version."
$IDF_TOOLS_JSON_PATH = "$PSScriptRoot/tools_fallback.json"
}
if ((Test-Path "$IDF_PATH/tools/idf_tools.py")){
$IDF_TOOLS_PY_PATH = "$IDF_PATH/tools/idf_tools.py"
}
else{
Write-Output "IDF version does not include tools/idf_tools.py. Using the fallback version."
$IDF_TOOLS_PY_PATH = "$PSScriptRoot/idf_tools_fallback.py"
}
Write-Output "Setting IDF_PATH: $IDF_PATH"
$env:IDF_PATH = $IDF_PATH
Write-Output "Adding ESP-IDF tools to PATH..."
$OLD_PATH = $env:Path.split(";") | Select-Object -Unique # array without duplicates
# using idf_tools.py to get $envars_array to set
$envars_raw = (python.exe "$IDF_TOOLS_PY_PATH" --tools-json "$IDF_TOOLS_JSON_PATH" export --format key-value)
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } # if error
$envars_array # will be filled like:
# [
# [vname1, vval1], [vname2, vval2], ...
# ]
foreach ($line in $envars_raw) {
$pair = $line.split("=") # split in name, val
$var_name = $pair[0].Trim() # trim spaces on the ends of the name
$var_val = $pair[1].Trim() # trim spaces on the ends of the val
$var_val = $var_val -replace "%(.+)%", "`$env:`$1" # convert var syntax to PS using RegEx
$var_val = $ExecutionContext.InvokeCommand.ExpandString($var_val) # expand variables to values
$envars_array += (, ($var_name, $var_val))
}
foreach ($pair in $envars_array) {
# setting the values
$var_name = $pair[0].Trim() # trim spaces on the ends of the name
$var_val = $pair[1].Trim() # trim spaces on the ends of the val
Set-Item -Path "Env:$var_name" -Value "$var_val"
}
#Compare Path's OLD vs. NEW
$NEW_PATH = $env:Path.split(";") | Select-Object -Unique # array without duplicates
$dif_Path = Compare-Object -ReferenceObject $OLD_PATH -DifferenceObject $NEW_PATH -PassThru
if ($dif_Path -ne $null) {
Write-Output $dif_Path
}
else {
Write-Output "No directories added to PATH:"
Write-Output $OLD_PATH
}
Write-Output "Checking if Python packages are up to date..."
Start-Process -Wait -NoNewWindow -FilePath "python" -Args "`"$IDF_PATH/tools/check_python_dependencies.py`""
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } # if error
Write-Output "
Done! You can now compile ESP-IDF projects.
Go to the project directory and run:
idf.py build
"
}

View File

@ -1,197 +0,0 @@
{ Copyright 2019-2021 Espressif Systems (Shanghai) CO LTD
SPDX-License-Identifier: Apache-2.0 }
{ ------------------------------ Page to select the version of ESP-IDF to download ------------------------------ }
var
IDFDownloadPage: TInputOptionWizardPage;
IDFDownloadAvailableVersions: TArrayOfString;
IDFDownloadPath, IDFDownloadVersion: String;
function GetSuggestedIDFDirectory(): String;
var
BaseName: String;
RepeatIndex: Integer;
begin
if (IDFDirectory <> '') then begin
Result := IDFDirectory
Exit;
end;
{ Start with Desktop\esp-idf name and if it already exists,
keep trying with Desktop\esp-idf-N for N=2 and above. }
BaseName := ExpandConstant('{userdesktop}\esp-idf');
Result := BaseName;
RepeatIndex := 1;
while DirExists(Result) do
begin
RepeatIndex := RepeatIndex + 1;
Result := BaseName + '-' + IntToStr(RepeatIndex);
end;
end;
function GetIDFVersionDescription(Version: String): String;
begin
if WildCardMatch(Version, 'v*-beta*') then
Result := 'beta version'
else if WildCardMatch(Version, 'v*-rc*') then
Result := 'pre-release version'
else if WildCardMatch(Version, 'v*') then
Result := 'release version'
else if WildCardMatch(Version, 'release/v*') then
Result := 'release branch'
else if WildCardMatch(Version, 'master') then
Result := 'development branch'
else
Result := '';
end;
procedure ExtractIDFVersionList();
begin
ExtractTemporaryFile('idf_versions.txt');
end;
procedure DownloadIDFVersionsList();
var
VersionFile: String;
begin
VersionFile := ExpandConstant('{tmp}\idf_versions.txt');
if idpDownloadFile(IDFVersionUrl, VersionFile) then
begin
Log('Downloaded ' + IDFVersionUrl + ' to ' + VersionFile);
end else begin
Log('Download of ' + IDFVersionUrl + ' failed, using a fallback versions list');
ExtractIDFVersionList();
end;
end;
procedure OnIDFDownloadPagePrepare(Sender: TObject);
var
Page: TInputOptionWizardPage;
VersionFile: String;
i: Integer;
begin
Page := TInputOptionWizardPage(Sender);
Log('OnIDFDownloadPagePrepare');
if Page.CheckListBox.Items.Count > 0 then
exit;
if (IsOfflineMode) then begin
Log('Offline Mode: using embedded idf_versions.txt')
ExtractIDFVersionList();
end else begin
DownloadIDFVersionsList();
end;
VersionFile := ExpandConstant('{tmp}\idf_versions.txt');
if not LoadStringsFromFile(VersionFile, IDFDownloadAvailableVersions) then
begin
Log('Failed to load versions from ' + VersionFile);
exit;
end;
Log('Versions count: ' + IntToStr(GetArrayLength(IDFDownloadAvailableVersions)))
for i := 0 to GetArrayLength(IDFDownloadAvailableVersions) - 1 do
begin
Log('Version ' + IntToStr(i) + ': ' + IDFDownloadAvailableVersions[i]);
Page.Add(IDFDownloadAvailableVersions[i] + ' ('
+ GetIDFVersionDescription(IDFDownloadAvailableVersions[i]) + ')');
end;
Page.SelectedValueIndex := 0;
ChoicePageSetInputText(Page, GetSuggestedIDFDirectory());
end;
{ Validation of PATH for IDF releases which does not support special characters. }
{ Source: https://stackoverflow.com/questions/21623515/is-it-possible-to-filter-require-installation-path-to-be-ascii-in-innosetup }
function IsCharValid(Value: Char): Boolean;
begin
Result := Ord(Value) <= $007F;
end;
function IsDirNameValid(const Value: string): Boolean;
var
I: Integer;
begin
Result := False;
for I := 1 to Length(Value) do
if not IsCharValid(Value[I]) then
Exit;
Result := True;
end;
procedure OnIDFDownloadSelectionChange(Sender: TObject);
var
Page: TInputOptionWizardPage;
begin
Page := TInputOptionWizardPage(Sender);
Log('OnIDFDownloadSelectionChange index=' + IntToStr(Page.SelectedValueIndex));
end;
function OnIDFDownloadPageValidate(Sender: TWizardPage): Boolean;
var
Page: TInputOptionWizardPage;
IDFPath: String;
begin
Result := False;
Page := TInputOptionWizardPage(Sender);
Log('OnIDFDownloadPageValidate index=' + IntToStr(Page.SelectedValueIndex));
IDFPath := ChoicePageGetInputText(Page);
if DirExists(IDFPath) and not DirIsEmpty(IDFPath) then
begin
MsgBox('Directory already exists and is not empty:' + #13#10 +
IDFPath + #13#10 + 'Please choose a different directory.', mbError, MB_OK);
exit;
end;
if Pos(' ', IDFPath) <> 0 then
begin
MsgBox('ESP-IDF build system does not support spaces in paths.' + #13#10
'Please choose a different directory.', mbError, MB_OK);
exit;
end;
IDFDownloadPath := IDFPath;
{ Use parameter /IDFVERSION=x to override selection in the box. }
IDFDownloadVersion := IDFVersion;
if (IDFDownloadVersion = '') then begin
IDFDownloadVersion := IDFDownloadAvailableVersions[Page.SelectedValueIndex];
end;
{ Following ZIP versions of IDF does not support installation on path with special characters. }
{ Issue: https://github.com/espressif/esp-idf/issues/5996 }
if ((IDFDownloadVersion = 'v4.2') or (IDFDownloadVersion = 'v4.0.2') or
(IDFDownloadVersion = 'v3.3.4')) then begin
if (not IsDirNameValid(IDFPath)) then begin
MsgBox('The installation of selected version of IDF is not supported on path with special characters.' + #13#10
'Please choose a different directory.', mbError, MB_OK);
exit;
end;
end;
Result := True;
end;
<event('ShouldSkipPage')>
function ShouldSkipIDFDownloadPage(PageID: Integer): Boolean;
begin
if (PageID = IDFDownloadPage.ID) and not IDFDownloadRequired() then
Result := True;
end;
<event('InitializeWizard')>
procedure CreateIDFDownloadPage();
begin
IDFDownloadPage := ChoicePageCreate(
IDFPage.ID,
'Version of ESP-IDF', 'Please choose ESP-IDF version to install',
'For more information about ESP-IDF versions, see' + #13#10 +
'https://docs.espressif.com/projects/esp-idf/en/latest/versions.html',
'Choose a directory to install ESP-IDF to',
True,
@OnIDFDownloadPagePrepare,
@OnIDFDownloadSelectionChange,
@OnIDFDownloadPageValidate);
end;

View File

@ -1,128 +0,0 @@
{ Copyright 2019-2021 Espressif Systems (Shanghai) CO LTD
SPDX-License-Identifier: Apache-2.0 }
{ ------------------------------ Page to select whether to download ESP-IDF, or use an existing copy ------------------------------ }
var
IDFPage: TInputOptionWizardPage;
IDFSelectionDownloadIndex: Integer;
IDFSelectionCustomPathIndex: Integer;
IDFUseExisting: Boolean;
IDFExistingPath: String;
function IDFDownloadRequired(): Boolean;
begin
Result := not IDFUseExisting;
end;
procedure IDFPageUpdateInput();
var
Enable: Boolean;
begin
if IDFPage.SelectedValueIndex = IDFSelectionCustomPathIndex then
Enable := True;
ChoicePageSetInputEnabled(IDFPage, Enable);
end;
procedure OnIDFPagePrepare(Sender: TObject);
var
Page: TInputOptionWizardPage;
begin
Page := TInputOptionWizardPage(Sender);
Log('OnIDFPagePrepare');
if Page.CheckListBox.Items.Count > 0 then
exit;
IDFSelectionDownloadIndex := Page.Add('Download ESP-IDF')
IDFSelectionCustomPathIndex := Page.Add('Use an existing ESP-IDF directory');
Page.SelectedValueIndex := 0;
IDFPageUpdateInput();
end;
procedure OnIDFSelectionChange(Sender: TObject);
var
Page: TInputOptionWizardPage;
begin
Page := TInputOptionWizardPage(Sender);
Log('OnIDFSelectionChange index=' + IntToStr(Page.SelectedValueIndex));
IDFPageUpdateInput();
end;
function OnIDFPageValidate(Sender: TWizardPage): Boolean;
var
Page: TInputOptionWizardPage;
NotSupportedMsg, IDFPath, IDFPyPath, RequirementsPath: String;
begin
Page := TInputOptionWizardPage(Sender);
Log('OnIDFPageValidate index=' + IntToStr(Page.SelectedValueIndex));
if Page.SelectedValueIndex = IDFSelectionDownloadIndex then
begin
IDFUseExisting := False;
Result := True;
end else begin
IDFUseExisting := True;
Result := False;
NotSupportedMsg := 'The selected version of ESP-IDF is not supported:' + #13#10;
IDFPath := ChoicePageGetInputText(Page);
if not DirExists(IDFPath) then
begin
MsgBox('Directory doesn''t exist: ' + IDFPath + #13#10 +
'Please choose an existing ESP-IDF directory', mbError, MB_OK);
exit;
end;
if Pos(' ', IDFPath) <> 0 then
begin
MsgBox('ESP-IDF build system does not support spaces in paths.' + #13#10
'Please choose a different directory.', mbError, MB_OK);
exit;
end;
IDFPyPath := IDFPath + '\tools\idf.py';
if not FileExists(IDFPyPath) then
begin
MsgBox(NotSupportedMsg +
'Can not find idf.py in ' + IDFPath + '\tools', mbError, MB_OK);
exit;
end;
RequirementsPath := IDFPath + '\requirements.txt';
if not FileExists(RequirementsPath) then
begin
MsgBox(NotSupportedMsg +
'Can not find requirements.txt in ' + IDFPath, mbError, MB_OK);
exit;
end;
IDFExistingPath := IDFPath;
Result := True;
end;
end;
<event('ShouldSkipPage')>
function ShouldSkipIDFPage(PageID: Integer): Boolean;
begin
{ The page does not make sense in offline mode }
if (PageID = IDFPage.ID) and IsOfflineMode then begin
Result := True;
end;
end;
<event('InitializeWizard')>
procedure CreateIDFPage();
begin
IDFPage := ChoicePageCreate(
wpLicense,
'Download or use ESP-IDF', 'Please choose ESP-IDF version to download, or use an existing ESP-IDF copy',
'Available ESP-IDF versions',
'Choose existing ESP-IDF directory',
True,
@OnIDFPagePrepare,
@OnIDFSelectionChange,
@OnIDFPageValidate);
end;

View File

@ -1,527 +0,0 @@
{ Copyright 2019-2021 Espressif Systems (Shanghai) CO LTD
SPDX-License-Identifier: Apache-2.0 }
{ ------------------------------ Downloading ESP-IDF ------------------------------ }
var
IDFZIPFileVersion, IDFZIPFileName: String;
function GetIDFPath(Unused: String): String;
begin
if IDFUseExisting then
Result := IDFExistingPath
else
Result := IDFDownloadPath;
end;
function GetIDFZIPFileVersion(Version: String): String;
var
ReleaseVerPart: String;
i: Integer;
Found: Boolean;
begin
if WildCardMatch(Version, 'v*') or WildCardMatch(Version, 'v*-rc*') then
Result := Version
else if Version = 'master' then
Result := ''
else if WildCardMatch(Version, 'release/v*') then
begin
ReleaseVerPart := Version;
Log('ReleaseVerPart=' + ReleaseVerPart)
Delete(ReleaseVerPart, 1, Length('release/'));
Log('ReleaseVerPart=' + ReleaseVerPart)
Found := False;
for i := 0 to GetArrayLength(IDFDownloadAvailableVersions) - 1 do
begin
if Pos(ReleaseVerPart, IDFDownloadAvailableVersions[i]) = 1 then
begin
Result := IDFDownloadAvailableVersions[i];
Found := True;
break;
end;
end;
if not Found then
Result := '';
end;
Log('GetIDFZIPFileVersion(' + Version + ')=' + Result);
end;
procedure IDFAddDownload();
var
Url, MirrorUrl: String;
begin
IDFZIPFileVersion := GetIDFZIPFileVersion(IDFDownloadVersion);
Log('IDFZIPFileVersion: ' + IDFZIPFileVersion);
if IDFZIPFileVersion <> '' then
begin
Url := 'https://github.com/espressif/esp-idf/releases/download/' + IDFZIPFileVersion + '/esp-idf-' + IDFZIPFileVersion + '.zip';
MirrorUrl := 'https://dl.espressif.com/github_assets/espressif/esp-idf/releases/download/' + IDFZIPFileVersion + '/esp-idf-' + IDFZIPFileVersion + '.zip';
IDFZIPFileName := ExpandConstant('{app}\releases\esp-idf-' + IDFZIPFileVersion + '.zip');
if not FileExists(IDFZIPFileName) then
begin
Log('IDFZIPFileName: ' + IDFZIPFileName + ' exists');
ForceDirectories(ExpandConstant('{app}\releases'))
Log('Adding download: ' + Url + ', mirror: ' + MirrorUrl + ', destination: ' + IDFZIPFileName);
idpAddFile(Url, IDFZIPFileName);
idpAddMirror(Url, MirrorUrl);
end else begin
Log('IDFZIPFileName: ' + IDFZIPFileName + ' does not exist');
end;
end;
end;
procedure RemoveAlternatesFile(Path: String);
begin
Log('Removing ' + Path);
DeleteFile(Path);
end;
{
Replacement of the '--dissociate' flag of 'git clone', to support older versions of Git.
'--reference' is supported for submodules since git 2.12, but '--dissociate' only from 2.18.
}
procedure GitRepoDissociate(Path: String);
var
CmdLine: String;
begin
CmdLine := GitExecutablePath + ' -C ' + Path + ' repack -d -a'
DoCmdlineInstall('Finishing ESP-IDF installation', 'Re-packing the repository', CmdLine);
CmdLine := GitExecutablePath + ' -C ' + Path + ' submodule foreach git repack -d -a'
DoCmdlineInstall('Finishing ESP-IDF installation', 'Re-packing the submodules', CmdLine);
FindFileRecursive(Path + '\.git', 'alternates', @RemoveAlternatesFile);
end;
{
Initialize submodules - required to call when switching branches in existing repo.
E.g. created by offline installer
}
procedure GitUpdateSubmodules(Path: String);
var
CmdLine: String;
begin
CmdLine := GitExecutablePath + ' -C ' + Path + ' submodule update --init --recursive';
Log('Updating submodules: ' + CmdLine);
DoCmdlineInstall('Finishing ESP-IDF installation', 'Updating submodules', CmdLine);
end;
{
Run git config fileMode is repairing problem when git repo was zipped on Linux and extracted on Windows.
The repo and submodules are marked as dirty which confuses users that fresh installation already contains changes.
More information: https://mirrors.edge.kernel.org/pub/software/scm/git/docs/git-config.html
}
procedure GitRepoFixFileMode(Path: String);
var
CmdLine: String;
begin
CmdLine := GitExecutablePath + ' -C ' + Path + ' config --local core.fileMode false';
Log('Setting core.fileMode on repository: ' + CmdLine);
DoCmdlineInstall('Finishing ESP-IDF installation', 'Updating fileMode', CmdLine);
Log('Setting core.fileMode on repository for submodules: ' + CmdLine);
CmdLine := GitExecutablePath + ' -C ' + Path + ' submodule foreach --recursive git config --local core.fileMode false';
DoCmdlineInstall('Finishing ESP-IDF installation', 'Updating fileMode in submodules', CmdLine);
end;
{ Run git reset --hard in the repo and in the submodules, to fix the newlines. }
procedure GitResetHard(Path: String);
var
CmdLine: String;
begin
if (not IsGitResetAllowed) then begin
Log('Git reset disabled by command line option /GITRESET=no.');
Exit;
end;
CmdLine := GitExecutablePath + ' -C ' + Path + ' reset --hard';
Log('Resetting the repository: ' + CmdLine);
DoCmdlineInstall('Finishing ESP-IDF installation', 'Updating newlines', CmdLine);
Log('Resetting the submodules: ' + CmdLine);
CmdLine := GitExecutablePath + ' -C ' + Path + ' submodule foreach git reset --hard';
DoCmdlineInstall('Finishing ESP-IDF installation', 'Updating newlines in submodules', CmdLine);
end;
{ Run git clean - clean leftovers after switching between tags }
{ The repo should be created with: git config --local clean.requireForce false}
procedure GitCleanForceDirectory(Path: String);
var
CmdLine: String;
begin
if (not IsGitCleanAllowed) then begin
Log('Git clean disabled by command line option /GITCLEAN=no.');
Exit;
end;
CmdLine := GitExecutablePath + ' -C ' + Path + ' clean --force -d';
Log('Resetting the repository: ' + CmdLine);
DoCmdlineInstall('Finishing ESP-IDF installation', 'Cleaning untracked directories', CmdLine);
end;
{
Switch to different branch. Used in offline installation.
}
procedure GitSwitchBranch(Path: String; BranchName: String);
var
CmdLine: String;
begin
CmdLine := GitExecutablePath + ' -C ' + Path + ' checkout ' + BranchName;
Log('Updating submodules: ' + CmdLine);
DoCmdlineInstall('Switching branch', 'Switching to branch', CmdLine);
GitUpdateSubmodules(Path);
GitResetHard(Path);
GitCleanForceDirectory(Path);
end;
{
There are 3 possible ways how an ESP-IDF copy can be obtained:
- Download the .zip archive with submodules included, extract to destination directory,
then do 'git reset --hard' and 'git submodule foreach git reset --hard' to correct for
possibly different newlines. This is done for release versions.
- Do a git clone of the Github repository into the destination directory.
This is done for the master branch.
- Download the .zip archive of a "close enough" release version, extract into a temporary
directory. Then do a git clone of the Github repository, using the temporary directory
as a '--reference'. This is done for other versions (such as release branches).
}
procedure IDFOfflineInstall();
var
IDFTempPath: String;
IDFPath: String;
begin
IDFPath := IDFDownloadPath;
IDFTempPath := ExpandConstant('{app}\releases\esp-idf-bundle');
Log('IDFTempPath - location of bundle: ' + IDFTempPath);
GitSwitchBranch(IDFPath, IDFDownloadVersion);
end;
procedure IDFDownloadInstall();
var
CmdLine: String;
IDFTempPath: String;
IDFPath: String;
NeedToClone: Boolean;
begin
IDFPath := IDFDownloadPath;
{ If there is a release archive to download, IDFZIPFileName and IDFZIPFileVersion will be set.
See GetIDFZIPFileVersion function.
}
if IDFZIPFileName <> '' then
begin
if IDFZIPFileVersion <> IDFDownloadVersion then
begin
{ The version of .zip file downloaded is not the same as the version the user has requested.
Will use 'git clone --reference' to obtain the correct version, using the contents
of the .zip file as reference.
}
NeedToClone := True;
end;
CmdLine := ExpandConstant('{tmp}\7za.exe x -o' + ExpandConstant('{tmp}') + ' -r -aoa "' + IDFZIPFileName + '"');
IDFTempPath := ExpandConstant('{tmp}\esp-idf-') + IDFZIPFileVersion;
Log('Extracting ESP-IDF reference repository: ' + CmdLine);
Log('Reference repository path: ' + IDFTempPath);
DoCmdlineInstall('Extracting ESP-IDF', 'Setting up reference repository', CmdLine);
end else begin
{ IDFZIPFileName is not set, meaning that we will rely on 'git clone'. }
NeedToClone := True;
Log('Not .zip release archive. Will do full clone.');
end;
if NeedToClone then
begin
CmdLine := GitExecutablePath + ' clone --progress -b ' + IDFDownloadVersion;
if (IsGitRecursive) then begin
CmdLine := CmdLine + ' --recursive ';
end;
if IDFTempPath <> '' then
CmdLine := CmdLine + ' --reference ' + IDFTempPath;
CmdLine := CmdLine + ' ' + GitRepository +' ' + IDFPath;
Log('Cloning IDF: ' + CmdLine);
DoCmdlineInstall('Downloading ESP-IDF', 'Using git to clone ESP-IDF repository', CmdLine);
if IDFTempPath <> '' then
GitRepoDissociate(IDFPath);
end else begin
Log('Copying ' + IDFTempPath + ' to ' + IDFPath);
if DirExists(IDFPath) then
begin
if not DirIsEmpty(IDFPath) then
begin
MsgBox('Destination directory exists and is not empty: ' + IDFPath, mbError, MB_OK);
RaiseException('Failed to copy ESP-IDF')
end;
end;
{ If cmd.exe command argument starts with a quote, the first and last quote chars in the command
will be removed by cmd.exe.
Keys explanation: /s+/e includes all subdirectories, /i assumes that destination is a directory,
/h copies hidden files, /q disables file name logging (making copying faster!)
}
CmdLine := ExpandConstant('cmd.exe /c ""xcopy" /s /e /i /h /q "' + IDFTempPath + '" "' + IDFPath + '""');
DoCmdlineInstall('Extracting ESP-IDF', 'Copying ESP-IDF into the destination directory', CmdLine);
GitRepoFixFileMode(IDFPath);
GitResetHard(IDFPath);
DelTree(IDFTempPath, True, True, True);
end;
end;
{ ------------------------------ IDF Tools setup, Python environment setup ------------------------------ }
function UseBundledIDFToolsPy(Version: String) : Boolean;
begin
Result := False;
{ Use bundled copy of idf_tools.py, as the copy shipped with these IDF versions can not work due to
the --no-site-packages bug.
}
if (Version = 'v4.0') or (Version = 'v3.3.1') then
begin
Log('UseBundledIDFToolsPy: version=' + Version + ', using bundled idf_tools.py');
Result := True;
end;
end;
{ Find Major and Minor version in esp_idf_version.h file. }
function GetIDFVersionFromHeaderFile():String;
var
HeaderFileName: String;
HeaderLines: TArrayOfString;
LineIndex: Integer;
LineCount: Longint;
Line: String;
MajorVersion: String;
MinorVersion: String;
begin
HeaderFileName := GetIDFPath('') + '\components\esp_common\include\esp_idf_version.h';
if (not FileExists(HeaderFileName)) then begin
Result := '';
Exit;
end;
LoadStringsFromFile(HeaderFileName, HeaderLines);
LineCount := GetArrayLength(HeaderLines);
for LineIndex := 0 to LineCount - 1 do begin
Line := HeaderLines[LineIndex];
if (pos('define ESP_IDF_VERSION_MAJOR', Line) > 0) then begin
Delete(Line, 1, 29);
MajorVersion := Trim(Line);
end else if (pos('define ESP_IDF_VERSION_MINOR', Line) > 0) then begin
Delete(Line, 1, 29);
MinorVersion := Trim(Line);
Result := MajorVersion + '.' + MinorVersion;
Exit;
end
end;
end;
{ Get short version from long version e.g. 3.7.9 -> 3.7 }
function GetShortVersion(VersionString:String):String;
var
VersionIndex: Integer;
MajorString: String;
MinorString: String;
DotIndex: Integer;
begin
{ Transform version vx.y or release/vx.y to x.y }
VersionIndex := pos('v', VersionString);
if (VersionIndex > 0) then begin
Delete(VersionString, 1, VersionIndex);
end;
{ Transform version x.y.z to x.y }
DotIndex := pos('.', VersionString);
if (DotIndex > 0) then begin
MajorString := Copy(VersionString, 1, DotIndex - 1);
Delete(VersionString, 1, DotIndex);
{ Trim trailing version numbers. }
DotIndex := pos('.', VersionString);
if (DotIndex > 0) then begin
MinorString := Copy(VersionString, 1, DotIndex - 1);
VersionString := MajorString + '.' + MinorString;
end else begin
VersionString := MajorString + '.' + VersionString;
end;
end;
Result := VersionString;
end;
{ Get IDF version string in combination with Python version. }
{ Result e.g.: idf4.1_py38 }
function GetIDFPythonEnvironmentVersion():String;
var
IDFVersionString: String;
begin
{ Transform main or master to x.y }
if (Pos('main', IDFDownloadVersion) > 0) or (Pos('master', IDFDownloadVersion) > 0) then begin
IDFVersionString := GetIDFVersionFromHeaderFile();
end else begin
IDFVersionString := GetShortVersion(IDFDownloadVersion);
end;
Result := 'idf' + IDFVersionString + '_py' + GetShortVersion(PythonVersion);
end;
function GetPythonVirtualEnvPath(): String;
var
PythonVirtualEnvPath: String;
begin
{ The links should contain reference to Python vitual env }
PythonVirtualEnvPath := ExpandConstant('{app}\python_env\') + GetIDFPythonEnvironmentVersion() + '_env\Scripts';
Log('Path to Python in virtual env: ' + PythonVirtualEnvPath);
{ Fallback in case of not existing environment. }
if (not FileExists(PythonVirtualEnvPath + '\python.exe')) then begin
PythonVirtualEnvPath := PythonPath;
Log('python.exe not found, reverting to:' + PythonPath);
end;
Result := PythonVirtualEnvPath;
end;
procedure IDFToolsSetup();
var
CmdLine: String;
IDFPath: String;
IDFToolsPyPath: String;
IDFToolsPyCmd: String;
BundledIDFToolsPyPath: String;
JSONArg: String;
PythonVirtualEnvPath: String;
begin
IDFPath := GetIDFPath('');
IDFToolsPyPath := IDFPath + '\tools\idf_tools.py';
BundledIDFToolsPyPath := ExpandConstant('{app}\idf_tools_fallback.py');
JSONArg := '';
if FileExists(IDFToolsPyPath) then
begin
Log('idf_tools.py exists in IDF directory');
if UseBundledIDFToolsPy(IDFDownloadVersion) then
begin
Log('Using the bundled idf_tools.py copy');
IDFToolsPyCmd := BundledIDFToolsPyPath;
end else begin
IDFToolsPyCmd := IDFToolsPyPath;
end;
end else begin
Log('idf_tools.py does not exist in IDF directory, using a fallback version');
IDFToolsPyCmd := BundledIDFToolsPyPath;
JSONArg := ExpandConstant('--tools "{app}\tools_fallback.json"');
end;
{ IDFPath not quoted, as it can not contain spaces }
IDFToolsPyCmd := PythonExecutablePath + ' "' + IDFToolsPyCmd + '" --idf-path ' + IDFPath + JSONArg;
SetEnvironmentVariable('PYTHONUNBUFFERED', '1');
if (IsOfflineMode) then begin
SetEnvironmentVariable('PIP_NO_INDEX', 'true');
Log('Offline installation selected. Setting environment variable PIP_NO_INDEX=1');
SetEnvironmentVariable('PIP_FIND_LINKS', ExpandConstant('{app}\tools\idf-python-wheels\' + PythonWheelsVersion));
end else begin
SetEnvironmentVariable('PIP_EXTRA_INDEX_URL', PythonWheelsUrl);
Log('Adding extra Python wheels location. Setting environment variable PIP_EXTRA_INDEX_URL=' + PythonWheelsUrl);
end;
Log('idf_tools.py command: ' + IDFToolsPyCmd);
CmdLine := IDFToolsPyCmd + ' install';
Log('Installing tools:' + CmdLine);
DoCmdlineInstall('Installing ESP-IDF tools', '', CmdLine);
CmdLine := PythonExecutablePath + ' -m virtualenv --version';
Log('Checking Python virtualenv support:' + CmdLine)
DoCmdlineInstall('Checking Python virtualenv support', '', CmdLine);
PythonVirtualEnvPath := ExpandConstant('{app}\python_env\') + GetIDFPythonEnvironmentVersion() + '_env';
CmdLine := PythonExecutablePath + ' -m virtualenv "' + PythonVirtualEnvPath + '" -p ' + '"' + PythonExecutablePath + '"';
if (DirExists(PythonVirtualEnvPath)) then begin
Log('ESP-IDF Python Virtual environment exists, refreshing the environment: ' + CmdLine);
end else begin
Log('ESP-IDF Python Virtual environment does not exist, creating the environment: ' + CmdLine);
end;
DoCmdlineInstall('Creating Python environment', '', CmdLine);
CmdLine := IDFToolsPyCmd + ' install-python-env';
Log('Installing Python environment:' + CmdLine);
DoCmdlineInstall('Installing Python environment', '', CmdLine);
end;
{ ------------------------------ Start menu shortcut ------------------------------ }
procedure CreateIDFCommandPromptShortcut(LnkString: String);
var
Destination: String;
Description: String;
Command: String;
begin
ForceDirectories(ExpandConstant(LnkString));
Destination := ExpandConstant(LnkString + '\{#IDFCmdExeShortcutFile}');
Description := '{#IDFCmdExeShortcutDescription}';
{ If cmd.exe command argument starts with a quote, the first and last quote chars in the command
will be removed by cmd.exe; each argument needs to be surrounded by quotes as well. }
Command := ExpandConstant('/k ""{app}\idf_cmd_init.bat" "') + GetPythonVirtualEnvPath() + '" "' + GitPath + '""';
Log('CreateShellLink Destination=' + Destination + ' Description=' + Description + ' Command=' + Command)
try
CreateShellLink(
Destination,
Description,
'cmd.exe',
Command,
GetIDFPath(''),
'', 0, SW_SHOWNORMAL);
except
MsgBox('Failed to create the shortcut: ' + Destination, mbError, MB_OK);
RaiseException('Failed to create the shortcut');
end;
end;
procedure CreateIDFPowershellShortcut(LnkString: String);
var
Destination: String;
Description: String;
Command: String;
GitPathWithForwardSlashes: String;
PythonPathWithForwardSlashes: String;
begin
ForceDirectories(ExpandConstant(LnkString));
Destination := ExpandConstant(LnkString + '\{#IDFPsShortcutFile}');
Description := '{#IDFPsShortcutDescription}';
GitPathWithForwardSlashes := GitPath;
PythonPathWithForwardSlashes := GetPythonVirtualEnvPath();
StringChangeEx(GitPathWithForwardSlashes, '\', '/', True);
StringChangeEx(PythonPathWithForwardSlashes, '\', '/', True);
Command := ExpandConstant('-ExecutionPolicy Bypass -NoExit -File ""{app}\idf_cmd_init.ps1"" ') + '"' + GitPathWithForwardSlashes + '" "' + PythonPathWithForwardSlashes + '"'
Log('CreateShellLink Destination=' + Destination + ' Description=' + Description + ' Command=' + Command)
try
CreateShellLink(
Destination,
Description,
'powershell.exe',
Command,
GetIDFPath(''),
'', 0, SW_SHOWNORMAL);
except
MsgBox('Failed to create the shortcut: ' + Destination, mbError, MB_OK);
RaiseException('Failed to create the shortcut');
end;
end;

View File

@ -1,172 +0,0 @@
; Copyright 2019-2021 Espressif Systems (Shanghai) CO LTD
; SPDX-License-Identifier: Apache-2.0
#pragma include __INCLUDE__ + ";" + ReadReg(HKLM, "Software\Mitrich Software\Inno Download Plugin", "InstallDir")
#include <idp.iss>
#define MyAppName "ESP-IDF Tools"
#define MyAppVersion "2.5"
#define MyAppPublisher "Espressif Systems (Shanghai) Co. Ltd."
#define MyAppURL "https://github.com/espressif/esp-idf"
#ifndef PYTHONVERSION
#define PYTHONVERSION "3.8.7"
#endif
#define PythonInstallerName "idf-python-" + PYTHONVERSION + "-embed-win64.zip"
#define PythonInstallerDownloadURL "https://dl.espressif.com/dl/idf-python/idf-python-" + PYTHONVERSION + "-embed-win64.zip"
#ifndef GITVERSION
#define GITVERSION "2.30.0.2"
#endif
; The URL where git is stored is not equal to it's version. Minor build has prefixes with windows
#ifndef GITVERSIONDIR
#define GITVERSIONDIR "v2.30.0.windows.2"
#endif
#define GitInstallerName "Git-" + GITVERSION + "-64-bit.exe"
#define GitInstallerDownloadURL "https://github.com/git-for-windows/git/releases/download/" + GITVERSIONDIR + "/Git-" + GITVERSION + "-64-bit.exe"
#define IDFVersionsURL "https://dl.espressif.com/dl/esp-idf/idf_versions.txt"
#define IDFCmdExeShortcutDescription "Open ESP-IDF Command Prompt (cmd.exe) Environment"
#define IDFCmdExeShortcutFile "ESP-IDF Command Prompt (cmd.exe).lnk"
#define IDFPsShortcutDescription "Open ESP-IDF PowerShell Environment"
#define IDFPsShortcutFile "ESP-IDF PowerShell.lnk"
; List of default values
; Default values can be set by command-line option when startig installer
; or it can be stored in .INI file which can be passed to installer by /CONFIG=[PATH].
; Code for evaluating configuration is in the file configuration.inc.iss.
#ifndef COMPRESSION
#define COMPRESSION = 'lzma';
#endif
; In case of large installer set it to 'no' to avoid problem delay during starting installer
; In case of 1 GB installer it could be 30+ seconds just to start installer.
#ifndef SOLIDCOMPRESSION
#define SOLIDCOMPRESSION = 'yes';
#endif
; Offline installation specific options
#ifndef OFFLINE
#define OFFLINE = 'no';
#endif
#ifndef PYTHONWHEELSVERSION
#define PYTHONWHEELSVERSION = '3.8-2021-01-21'
#endif
[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{9E068D99-5C4B-4E5F-96A3-B17CF291E6BD}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={%USERPROFILE}\.espressif
UsePreviousAppDir=no
DirExistsWarning=no
DefaultGroupName=ESP-IDF
DisableProgramGroupPage=yes
OutputBaseFilename=esp-idf-tools-setup-unsigned
Compression={#COMPRESSION}
SolidCompression={#SOLIDCOMPRESSION}
ArchitecturesAllowed=x64
ArchitecturesInstallIn64BitMode=x64
LicenseFile=license.txt
PrivilegesRequired=lowest
SetupLogging=yes
ChangesEnvironment=yes
WizardStyle=modern
; https://jrsoftware.org/ishelp/index.php?topic=setup_touchdate
; Default values are set to 'no' which might result in files that are installed on the machine
; in the 'future'. This creates a problem for Ninja/CMake which may end up in a neverending loop.
; Setting this flag to 'yes' should avoid the problem.
TimeStampsInUTC=yes
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl,Languages/idf_tool_en-US.islu"
[Dirs]
Name: "{app}\dist"
[Files]
Source: "configuration.ini"; Flags: dontcopy noencryption
Source: "cmdlinerunner\build\cmdlinerunner.dll"; Flags: dontcopy
Source: "unzip\7za.exe"; Flags: dontcopy
Source: "idf_versions.txt"; Flags: dontcopy
Source: "..\..\idf_tools.py"; DestDir: "{app}"; DestName: "idf_tools_fallback.py"
; Note: this tools.json matches the requirements of IDF v3.x versions.
Source: "tools_fallback.json"; DestDir: "{app}"; DestName: "tools_fallback.json"
Source: "idf_cmd_init.bat"; DestDir: "{app}"
Source: "idf_cmd_init.ps1"; DestDir: "{app}"
Source: "dist\*"; DestDir: "{app}\dist"; Flags: skipifsourcedoesntexist;
; esp-idf-bundle - bundle only in case it exists, it's used only in offline installer
Source: "releases\esp-idf-bundle\*"; DestDir: "{code:GetIDFPath}"; Flags: recursesubdirs skipifsourcedoesntexist;
Source: "tools\idf-python\*"; DestDir: "{app}\tools\idf-python\"; Flags: recursesubdirs;
Source: "tools\idf-python-wheels\*"; DestDir: "{app}\tools\idf-python-wheels\"; Flags: recursesubdirs skipifsourcedoesntexist;
; Helper Python files for sanity check of Python environment - used by system_check_page
Source: "system_check\system_check_download.py"; Flags: dontcopy
Source: "system_check\system_check_subprocess.py"; Flags: dontcopy
Source: "system_check\system_check_virtualenv.py"; Flags: dontcopy
; Helper PowerShell scripts for managing exceptions in Windows Defender
Source: "tools_WD_excl.ps1"; DestDir: "{app}\dist"
Source: "tools_WD_clean.ps1"; DestDir: "{app}\dist"
[UninstallDelete]
Type: filesandordirs; Name: "{app}\dist"
Type: filesandordirs; Name: "{app}\releases"
Type: filesandordirs; Name: "{app}\tools"
Type: filesandordirs; Name: "{app}\python_env"
Type: files; Name: "{group}\{#IDFCmdExeShortcutFile}"
Type: files; Name: "{group}\{#IDFPsShortcutFile}"
Type: files; Name: "{autodesktop}\{#IDFCmdExeShortcutFile}"
Type: files; Name: "{autodesktop}\{#IDFPsShortcutFile}"
[Tasks]
Name: CreateLinkStartPowerShell; GroupDescription: "{cm:CreateShortcutPowerShell}"; Description: "{cm:CreateShortcutStartMenu}";
Name: CreateLinkDeskPowerShell; GroupDescription: "{cm:CreateShortcutPowerShell}"; Description: "{cm:CreateShortcutDesktop}";
Name: CreateLinkStartCmd; GroupDescription: "{cm:CreateShortcutCMD}"; Description: "{cm:CreateShortcutStartMenu}";
Name: CreateLinkDeskCmd; GroupDescription: "{cm:CreateShortcutCMD}"; Description: "{cm:CreateShortcutDesktop}";
; Optimization for Online mode
Name: UseMirror; GroupDescription:"{cm:OptimizationTitle}"; Description: "{cm:OptimizationDownloadMirror}"; Flags: unchecked; Check: IsOnlineMode
[Run]
Filename: "{app}\dist\{#GitInstallerName}"; Parameters: "/silent /tasks="""" /norestart"; Description: "Installing Git"; Check: GitInstallRequired
Filename: "{group}\{#IDFPsShortcutFile}"; Flags: postinstall shellexec unchecked; Description: "Run ESP-IDF PowerShell Environment"; Check: IsPowerShellInstalled
Filename: "{group}\{#IDFCmdExeShortcutFile}"; Flags: postinstall shellexec unchecked; Description: "Run ESP-IDF Command Prompt Environment"; Check: IsCmdInstalled
; WD registration checkbox is identified by 'Windows Defender' substring anywhere in its caption, not by the position index in WizardForm.TasksList.Items
; Please, keep this in mind when making changes to the item's description - WD checkbox is to be disabled on systems without the Windows Defender installed
Filename: "powershell"; Parameters: "-ExecutionPolicy ByPass -File ""{app}\dist\tools_WD_excl.ps1"" -AddExclPath ""{app}\*.exe"""; Flags: postinstall shellexec runhidden; Description: "{cm:OptimizationWindowsDefender}"; Check: GetIsWindowsDefenderEnabled
[UninstallRun]
Filename: "powershell.exe"; \
Parameters: "-ExecutionPolicy Bypass -File ""{app}\dist\tools_WD_clean.ps1"" -RmExclPath ""{app}"""; \
WorkingDir: {app}; Flags: runhidden
[Registry]
Root: HKCU; Subkey: "Environment"; ValueType: string; ValueName: "IDF_TOOLS_PATH"; \
ValueData: "{app}"; Flags: preservestringtype createvalueifdoesntexist uninsdeletevalue deletevalue;
[Code]
#include "configuration.iss.inc"
#include "utils.iss.inc"
#include "choice_page.iss.inc"
#include "cmdline_page.iss.inc"
#include "idf_page.iss.inc"
#include "git_page.iss.inc"
#include "python_page.iss.inc"
#include "system_check_page.iss.inc"
#include "idf_download_page.iss.inc"
#include "idf_setup.iss.inc"
#include "summary.iss.inc"
#include "main.iss.inc"

View File

@ -1,2 +0,0 @@
v4.2
v4.1.1

View File

@ -1,357 +0,0 @@
This installer incorporates the following software programs licensed under the terms of GNU General Public License Version 2
- GNU Compiler Collection (GCC)
- GNU development tools ("binutils")
- GNU Debugger ("gdb")
- OpenOCD
- KConfig Frontends
Text of this license is included below.
Source code for these programs can be obtained from the following URLs:
- https://github.com/espressif/crosstool-NG
- https://github.com/espressif/binutils-esp32ulp
- https://github.com/espressif/openocd-esp32
- https://github.com/espressif/kconfig-frontends
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View File

@ -1,223 +0,0 @@
{ Copyright 2019-2021 Espressif Systems (Shanghai) CO LTD
SPDX-License-Identifier: Apache-2.0 }
{ ------------------------------ Custom steps before the main installation flow ------------------------------ }
var
SetupAborted: Boolean;
function InstallationSuccessful(): Boolean;
begin
Result := not SetupAborted;
end;
<event('InitializeWizard')>
procedure InitializeDownloader();
begin
idpDownloadAfter(wpReady);
end;
{ If IDF_TOOLS_PATH is set in the environment,
set the default installation directory accordingly.
Note: here we read IDF_TOOLS_PATH using GetEnv rather than
by getting it from registry, in case the user has set
IDF_TOOLS_PATH as a system environment variable manually. }
<event('InitializeWizard')>
procedure UpdateInstallDir();
var
EnvToolsPath: String;
begin
EnvToolsPath := GetEnv('IDF_TOOLS_PATH');
if EnvToolsPath <> '' then
begin
WizardForm.DirEdit.Text := EnvToolsPath;
end;
end;
<event('NextButtonClick')>
function PreInstallSteps(CurPageID: Integer): Boolean;
var
DestPath: String;
begin
Result := True;
if CurPageID <> wpReady then begin
Exit;
end;
ForceDirectories(ExpandConstant('{app}\dist'));
if (IsOfflineMode) then begin
ForceDirectories(ExpandConstant('{app}\releases'));
IDFZIPFileVersion := IDFDownloadVersion;
IDFZIPFileName := ExpandConstant('{app}\releases\esp-idf-bundle.zip');
Exit;
end;
if not GitUseExisting then
begin
DestPath := ExpandConstant('{app}\dist\{#GitInstallerName}');
if FileExists(DestPath) then
begin
Log('Git installer already downloaded: ' + DestPath);
end else begin
idpAddFile('{#GitInstallerDownloadURL}', DestPath);
end;
end;
if not IDFUseExisting then
begin
IDFAddDownload();
end;
end;
{ ------------------------------ Custom steps after the main installation flow ------------------------------ }
procedure AddPythonGitToPath();
var
EnvPath: String;
PythonLibPath: String;
EnvPythonHome: String;
PythonNoUserSite: String;
begin
EnvPath := GetEnv('PATH');
if not GitUseExisting then
GitExecutablePathUpdateAfterInstall();
EnvPath := PythonPath + ';' + GitPath + ';' + EnvPath;
Log('Setting PATH for this process: ' + EnvPath);
SetEnvironmentVariable('PATH', EnvPath);
{ Set IDF_TOOLS_PATH variable, in case it was set to a different value in the environment.
The installer will set the variable to the new value in the registry, but we also need the
new value to be visible to this process. }
SetEnvironmentVariable('IDF_TOOLS_PATH', ExpandConstant('{app}'))
{ Set PYTHONNOUSERSITE variable True to avoid loading packages from AppData\Roaming. }
{ https://doc.pypy.org/en/latest/man/pypy.1.html#environment }
{ If set to a non-empty value, equivalent to the -s option. Dont add the user site directory to sys.path. }
if (IsPythonNoUserSite) then begin
PythonNoUserSite := 'True';
end else begin
PythonNoUserSite := '';
end;
Log('PYTHONNOUSERSITE=' + PythonNoUserSite);
SetEnvironmentVariable('PYTHONNOUSERSITE', PythonNoUserSite);
{ Log and clear PYTHONPATH variable, as it might point to libraries of another Python version}
PythonLibPath := GetEnv('PYTHONPATH')
Log('PYTHONPATH=' + PythonLibPath)
SetEnvironmentVariable('PYTHONPATH', '')
{ Log and clear PYTHONHOME, the existence of PYTHONHOME might cause trouble when creating virtualenv. }
{ The error message when creating virtualenv: }
{ Fatal Python error: init_fs_encoding: failed to get the Python codec of the filesystem encoding. }
EnvPythonHome := GetEnv('PYTHONHOME')
Log('PYTHONHOME=' + EnvPythonHome)
SetEnvironmentVariable('PYTHONHOME', '')
end;
procedure InstallEmbeddedPython();
var
EmbeddedPythonPath: String;
CmdLine: String;
begin
if (Pos('tools', PythonPath) <> 1) then begin
Exit;
end;
EmbeddedPythonPath := ExpandConstant('{app}\') + PythonExecutablePath;
UpdatePythonVariables(EmbeddedPythonPath);
Log('Checking existence of Embedded Python: ' + EmbeddedPythonPath);
if (FileExists(EmbeddedPythonPath)) then begin
Log('Embedded Python found.');
Exit;
end;
CmdLine := ExpandConstant('{tmp}\7za.exe x -o{app}\tools\idf-python\' + PythonVersion + '\ -r -aoa "{app}\dist\idf-python-' + PythonVersion + '-embed-win64.zip"');
DoCmdlineInstall('Extracting Python Interpreter', 'Using Embedded Python', CmdLine);
end;
<event('CurStepChanged')>
procedure PostInstallSteps(CurStep: TSetupStep);
var
Err: Integer;
begin
if CurStep <> ssPostInstall then
exit;
ExtractTemporaryFile('7za.exe');
InstallEmbeddedPython();
try
AddPythonGitToPath();
if not IDFUseExisting then begin
if (IsOfflineMode) then begin
IDFOfflineInstall();
end else begin
IDFDownloadInstall();
end;
end;
if WizardIsTaskSelected('UseMirror') then
begin
SetEnvironmentVariable('IDF_GITHUB_ASSETS', 'dl.espressif.com/github_assets')
end;
IDFToolsSetup();
if WizardIsTaskSelected('CreateLinkStartCmd') then
begin
CreateIDFCommandPromptShortcut('{autostartmenu}\Programs\ESP-IDF');
end;
if WizardIsTaskSelected('CreateLinkStartPowerShell') then
begin
CreateIDFPowershellShortcut('{autostartmenu}\Programs\ESP-IDF' );
end;
if WizardIsTaskSelected('CreateLinkDeskCmd') then
begin
CreateIDFCommandPromptShortcut('{autodesktop}');
end;
if WizardIsTaskSelected('CreateLinkDeskPowerShell') then
begin
CreateIDFPowershellShortcut('{autodesktop}');
end;
except
SetupAborted := True;
if MsgBox('Installation log has been created, it may contain more information about the problem.' + #13#10
+ 'Display the installation log now?', mbConfirmation, MB_YESNO or MB_DEFBUTTON1) = IDYES then
begin
ShellExec('', 'notepad.exe', ExpandConstant('{log}'), ExpandConstant('{tmp}'), SW_SHOW, ewNoWait, Err);
end;
Abort();
end;
end;
<event('ShouldSkipPage')>
function SkipFinishedPage(PageID: Integer): Boolean;
begin
Result := False;
if PageID = wpFinished then
begin
Result := SetupAborted;
end;
end;
function IsPowerShellInstalled(): Boolean;
begin
Result := ((not SetupAborted) and (WizardIsTaskSelected('CreateLinkDeskPowerShell') or WizardIsTaskSelected('CreateLinkStartPowerShell')));
end;
function IsCmdInstalled(): Boolean;
begin
Result := ((not SetupAborted) and (WizardIsTaskSelected('CreateLinkDeskCmd') or WizardIsTaskSelected('CreateLinkStartCmd')));
end;

View File

@ -1,64 +0,0 @@
{ Copyright 2019-2021 Espressif Systems (Shanghai) CO LTD
SPDX-License-Identifier: Apache-2.0 }
{ ------------------------------ Find installed Python interpreters in Windows Registry (see PEP 514) ------------------------------ }
var
InstalledPythonVersions: TStringList;
InstalledPythonDisplayNames: TStringList;
InstalledPythonExecutables: TStringList;
procedure PythonVersionAdd(Version, DisplayName, Executable: String);
begin
Log('Adding Python version=' + Version + ' name='+DisplayName+' executable='+Executable);
InstalledPythonVersions.Append(Version);
InstalledPythonDisplayNames.Append(DisplayName);
InstalledPythonExecutables.Append(Executable);
end;
function GetPythonVersionInfoFromKey(RootKey: Integer; SubKeyName, CompanyName, TagName: String;
var Version: String;
var DisplayName: String;
var ExecutablePath: String;
var BaseDir: String): Boolean;
var
TagKey, InstallPathKey, DefaultPath: String;
begin
TagKey := SubKeyName + '\' + CompanyName + '\' + TagName;
InstallPathKey := TagKey + '\InstallPath';
if not RegQueryStringValue(RootKey, InstallPathKey, '', DefaultPath) then
begin
Log('No (Default) key, skipping');
Result := False;
exit;
end;
if not RegQueryStringValue(RootKey, InstallPathKey, 'ExecutablePath', ExecutablePath) then
begin
Log('No ExecutablePath, using the default');
ExecutablePath := DefaultPath + '\python.exe';
end;
BaseDir := DefaultPath;
if not RegQueryStringValue(RootKey, TagKey, 'SysVersion', Version) then
begin
if CompanyName = 'PythonCore' then
begin
Version := TagName;
Delete(Version, 4, Length(Version));
end else begin
Log('Can not determine SysVersion');
Result := False;
exit;
end;
end;
if not RegQueryStringValue(RootKey, TagKey, 'DisplayName', DisplayName) then
begin
DisplayName := 'Python ' + Version;
end;
Result := True;
end;

View File

@ -1,139 +0,0 @@
{ Copyright 2019-2021 Espressif Systems (Shanghai) CO LTD
SPDX-License-Identifier: Apache-2.0 }
{ ------------------------------ Page to select Python interpreter ------------------------------ }
#include "python_find_installed.iss.inc"
var
PythonPage: TInputOptionWizardPage;
PythonVersion, PythonPath, PythonExecutablePath: String;
function GetPythonPath(Unused: String): String;
begin
Result := PythonPath;
end;
function PythonVersionSupported(Version: String): Boolean;
var
Major, Minor: Integer;
begin
Result := False;
if not VersionExtractMajorMinor(Version, Major, Minor) then
begin
Log('PythonVersionSupported: Could not parse version=' + Version);
exit;
end;
if (Major = 2) and (Minor = 7) then Result := True;
if (Major = 3) and (Minor >= 5) then Result := True;
end;
procedure OnPythonPagePrepare(Sender: TObject);
var
Page: TInputOptionWizardPage;
FullName: String;
i, Index, FirstEnabledIndex: Integer;
OfferToInstall: Boolean;
VersionToInstall: String;
VersionSupported: Boolean;
begin
Page := TInputOptionWizardPage(Sender);
Log('OnPythonPagePrepare');
if Page.CheckListBox.Items.Count > 0 then
exit;
VersionToInstall := '{#PythonVersion}';
OfferToInstall := True;
FirstEnabledIndex := -1;
for i := 0 to InstalledPythonVersions.Count - 1 do
begin
VersionSupported := PythonVersionSupported(InstalledPythonVersions[i]);
FullName := InstalledPythonDisplayNames.Strings[i];
if not VersionSupported then
begin
FullName := FullName + ' (unsupported)';
end;
FullName := FullName + #13#10 + InstalledPythonExecutables.Strings[i];
Index := Page.Add(FullName);
if not VersionSupported then
begin
Page.CheckListBox.ItemEnabled[Index] := False;
end else begin
if FirstEnabledIndex < 0 then FirstEnabledIndex := Index;
end;
if InstalledPythonVersions[i] = VersionToInstall then
begin
OfferToInstall := False;
end;
end;
if OfferToInstall then
begin
Index := Page.Add('Install Python ' + VersionToInstall);
if FirstEnabledIndex < 0 then FirstEnabledIndex := Index;
end;
Page.SelectedValueIndex := FirstEnabledIndex;
end;
procedure OnPythonSelectionChange(Sender: TObject);
var
Page: TInputOptionWizardPage;
begin
Page := TInputOptionWizardPage(Sender);
Log('OnPythonSelectionChange index=' + IntToStr(Page.SelectedValueIndex));
end;
procedure ApplyPythonConfigurationByIndex(Index:Integer);
begin
Log('ApplyPythonConfigurationByIndex index=' + IntToStr(Index));
PythonExecutablePath := InstalledPythonExecutables[Index];
PythonPath := ExtractFilePath(PythonExecutablePath);
PythonVersion := InstalledPythonVersions[Index];
Log('ApplyPythonConfigurationByIndex: PythonPath='+PythonPath+' PythonExecutablePath='+PythonExecutablePath);
end;
function OnPythonPageValidate(Sender: TWizardPage): Boolean;
var
Page: TInputOptionWizardPage;
begin
Page := TInputOptionWizardPage(Sender);
ApplyPythonConfigurationByIndex(Page.SelectedValueIndex);
Result := True;
end;
procedure UpdatePythonVariables(ExecutablePath: String);
begin
PythonExecutablePath := ExecutablePath;
PythonPath := ExtractFilePath(PythonExecutablePath);
Log('PythonExecutablePathUpdateAfterInstall: PythonPath='+PythonPath+' PythonExecutablePath='+PythonExecutablePath);
end;
<event('InitializeWizard')>
procedure CreatePythonPage();
begin
PythonPage := ChoicePageCreate(
wpLicense,
'Python choice', 'Please choose Python version',
'Available Python versions',
'',
False,
@OnPythonPagePrepare,
@OnPythonSelectionChange,
@OnPythonPageValidate);
end;
<event('ShouldSkipPage')>
function ShouldSkipPythonPage(PageID: Integer): Boolean;
begin
if (PageID = PythonPage.ID) then begin
{ Skip in case of embedded Python. }
if (UseEmbeddedPython) then begin
ApplyPythonConfigurationByIndex(0);
Result := True;
end;
end;
end;

View File

@ -1,51 +0,0 @@
#!/usr/bin/env bash
#
# Script to sign the IDF Tools installer for Windows, built with build_installer.sh.
#
set -e
set -u
INSTALLER_TYPE="${1-online}"
if [[ -z "${KEYFILE:-}" || -z "${CERTCHAIN:-}" ]]; then
echo "To sign the installer, set the following environment variables:"
echo " KEYFILE - private key file"
echo " KEYPASSWORD - password for the private key file (optional, will prompt for password if not set)"
echo " CERTCHAIN - certificate chain file"
exit 1
fi
umask 770 # for the process substitution FIFO
VERSION=`grep "#define MyAppVersion " idf_tool_setup.iss | cut -d ' ' -f3 | tr -d '"'`
echo "Installer version ${VERSION}"
IN_FILE="Output/esp-idf-tools-setup-${INSTALLER_TYPE}-unsigned.exe"
OUT_FILE="Output/esp-idf-tools-setup-${INSTALLER_TYPE}-${VERSION}.exe"
if [[ -n "${KEYPASSWORD:-}" ]]; then
PASSARG="-readpass <(echo \"$KEYPASSWORD\")"
else
PASSARG="-askpass"
fi
echo "Signing the installer (${IN_FILE})..."
# Note: The cert chain passed to -certs needs to contain the intermediate
# cert(s) as well, appended after the code signing cert, or Windows may see
# it as "Unknown Publisher"
#
# See https://stackoverflow.com/a/52637050 for full details
#
osslsigncode -certs ${CERTCHAIN} -key ${KEYFILE} \
${PASSARG} \
-in ${IN_FILE} \
-out ${OUT_FILE} \
-h sha256 \
-n "Espressif Systems (Shanghai) Co., Ltd." \
-i "https://www.espressif.com/" \
-ts http://timestamp.digicert.com
chmod 644 ${OUT_FILE} # make up for the umask
echo "Generated ${OUT_FILE}"

View File

@ -1,40 +0,0 @@
{ Copyright 2019-2021 Espressif Systems (Shanghai) CO LTD
SPDX-License-Identifier: Apache-2.0 }
{ ------------------------------ Installation summary page ------------------------------ }
function UpdateReadyMemo(Space, NewLine, MemoUserInfoInfo, MemoDirInfo,
MemoTypeInfo, MemoComponentsInfo, MemoGroupInfo, MemoTasksInfo: String): String;
begin
Result := ''
if (FileExists(PythonExecutablePath)) then
begin
Result := Result + 'Using Python ' + PythonVersion + ':' + NewLine
+ Space + PythonExecutablePath + NewLine + NewLine;
end else begin
Result := Result + 'Using embedded Python ' + PythonVersion + NewLine + NewLine;
end;
if GitUseExisting then
begin
Result := Result + 'Using Git ' + GitVersion + ':' + NewLine
+ Space + GitExecutablePath + NewLine + NewLine;
end else begin
Result := Result + 'Will download and install Git for Windows ' + GitVersion + NewLine + NewLine;
end;
if IDFUseExisting then
begin
Result := Result + 'Using existing ESP-IDF copy: ' + NewLine
+ Space + IDFExistingPath + NewLine + NewLine;
end else begin
Result := Result + 'Will install ESP-IDF ' + IDFDownloadVersion + ' into:' + NewLine
+ Space + IDFDownloadPath + NewLine + NewLine;
end;
Result := Result + 'IDF tools directory (IDF_TOOLS_PATH):' + NewLine +
Space + ExpandConstant('{app}') + NewLine + NewLine;
Log('Summary message: ' + NewLine + Result);
end;

View File

@ -1,13 +0,0 @@
#!/usr/bin/env python
import sys
download_url = sys.argv[1]
output_filename = sys.argv[2]
if (sys.version_info > (3, 0)):
import urllib.request
urllib.request.urlretrieve(download_url, output_filename)
else:
import urllib2
response = urllib2.urlopen(download_url)
with open(output_filename, 'w') as output_file:
output_file.write(response.read())

View File

@ -1,6 +0,0 @@
#!/usr/bin/env python
import sys
if (sys.version_info > (3, 0)):
import subprocess
subprocess.run('cmd /c echo hello')

View File

@ -1,11 +0,0 @@
#!/usr/bin/env python
import sys
expected_executable = sys.argv[1]
active_executable = sys.executable
if expected_executable != active_executable:
print('Failure. Expected executable does not match current executable.')
print('Expected:', expected_executable)
print('Active: ', active_executable)
sys.exit(1)

View File

@ -1,705 +0,0 @@
{ Copyright 2019-2021 Espressif Systems (Shanghai) CO LTD
SPDX-License-Identifier: Apache-2.0 }
{ SystemCheck states }
const
SYSTEM_CHECK_STATE_INIT = 0; { No check was executed yet. }
SYSTEM_CHECK_STATE_RUNNING = 1; { Check is in progress and can be cancelled. }
SYSTEM_CHECK_STATE_COMPLETE = 2; { Check is complete. }
SYSTEM_CHECK_STATE_STOPPED = 3; { User stopped the check. }
var
{ RTF View to display content of system check. }
SystemCheckViewer: TNewMemo;
{ Indicate state of System Check. }
SystemCheckState:Integer;
{ Text representation of log messages which are then converte to RTF. }
SystemLogText: TStringList;
{ Message for user which gives a hint how to correct the problem. }
SystemCheckHint: String;
{ Setup Page which displays progress/result of system check. }
SystemCheckPage: TOutputMsgWizardPage;
{ TimeCounter for Spinner animation invoked during command execution. }
TimeCounter:Integer;
{ Spinner is TStringList, because characters like backslash must be escaped and stored on two bytes. }
Spinner: TStringList;
{ Button to request display of full log of system check/installation. }
FullLogButton: TNewButton;
{ Button to request application of available fixtures. }
ApplyFixesButton: TNewButton;
{ Commands which should be executed to fix problems discovered during system check. }
Fixes: TStringList;
{ Button to request Stop of System Checks manually. }
StopSystemCheckButton: TNewButton;
{ Count number of createde virtualenv to avoid collision with previous runs. }
VirtualEnvCounter: Integer;
{ Indicates whether system check was able to find running Windows Defender. }
var IsWindowsDefenderEnabled: Boolean;
{ Const values for user32.dll which allows scrolling of the text view. }
const
WM_VSCROLL = $0115;
SB_BOTTOM = 7;
type
TMsg = record
hwnd: HWND;
message: UINT;
wParam: Longint;
lParam: Longint;
time: DWORD;
pt: TPoint;
end;
const
PM_REMOVE = 1;
{ Functions to communicate via Windows API. }
function PeekMessage(var lpMsg: TMsg; hWnd: HWND; wMsgFilterMin, wMsgFilterMax, wRemoveMsg: UINT): BOOL; external 'PeekMessageW@user32.dll stdcall';
function TranslateMessage(const lpMsg: TMsg): BOOL; external 'TranslateMessage@user32.dll stdcall';
function DispatchMessage(const lpMsg: TMsg): Longint; external 'DispatchMessageW@user32.dll stdcall';
procedure AppProcessMessage;
var
Msg: TMsg;
begin
while PeekMessage(Msg, WizardForm.Handle, 0, 0, PM_REMOVE) do begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end;
{ Render text message for view, add spinner if necessary and scroll the window. }
procedure SystemLogRefresh();
begin
SystemCheckViewer.Lines := SystemLogText;
{ Add Spinner to message. }
if ((TimeCounter > 0) and (TimeCounter < 6)) then begin
SystemCheckViewer.Lines[SystemCheckViewer.Lines.Count - 1] := SystemCheckViewer.Lines[SystemCheckViewer.Lines.Count - 1] + ' [' + Spinner[TimeCounter - 1] + ']';
end;
{ Scroll window to the bottom of the log - https://stackoverflow.com/questions/64587596/is-it-possible-to-display-the-install-actions-in-a-list-in-inno-setup }
SendMessage(SystemCheckViewer.Handle, WM_VSCROLL, SB_BOTTOM, 0);
end;
{ Log message to file and display just a '.' to user so that user is not overloaded by details. }
procedure SystemLogProgress(message:String);
begin
Log(message);
if (SystemLogText.Count = 0) then begin
SystemLogText.Append('');
end;
SystemLogText[SystemLogText.Count - 1] := SystemLogText[SystemLogText.Count - 1] + '.';
SystemLogRefresh();
end;
{ Log message to file and display it to user as title message with asterisk prefix. }
procedure SystemLogTitle(message:String);
begin
message := '* ' + message;
Log(message);
SystemLogText.Append(message);
SystemLogRefresh();
end;
{ Log message to file and display it to user. }
procedure SystemLog(message:String);
begin
Log(message);
if (SystemLogText.Count = 0) then begin
SystemLogText.Append('');
end;
SystemLogText[SystemLogText.Count - 1] := SystemLogText[SystemLogText.Count - 1] + message;
SystemLogRefresh();
end;
{ Process timer tick during command execution so that the app keeps communicating with user. }
procedure TimerTick();
begin
{ TimeCounter for animating Spinner. }
TimeCounter:=TimeCounter+1;
if (TimeCounter = 5) then begin
TimeCounter := 1;
end;
{ Redraw Log with Spinner animation. }
SystemLogRefresh();
{ Give control back to UI so that it can be updated. https://gist.github.com/jakoch/33ac13800c17eddb2dd4 }
AppProcessMessage;
end;
{ --- Command line nonblocking exec --- }
function NonBlockingExec(command, workdir: String): Integer;
var
Res: Integer;
Handle: Longword;
ExitCode: Integer;
LogTextAnsi: AnsiString;
LogText, LeftOver: String;
begin
if (SystemCheckState = SYSTEM_CHECK_STATE_STOPPED) then begin
ExitCode := -3;
Exit;
end;
try
ExitCode := -1;
{ SystemLog('Workdir: ' + workdir); }
SystemLogProgress(' $ ' + command);
Handle := ProcStart(command, workdir)
if Handle = 0 then
begin
SystemLog('[' + CustomMessage('SystemCheckResultError') + ']');
Result := -2;
Exit;
end;
while (ExitCode = -1) and (SystemCheckState <> SYSTEM_CHECK_STATE_STOPPED) do
begin
ExitCode := ProcGetExitCode(Handle);
SetLength(LogTextAnsi, 4096);
Res := ProcGetOutput(Handle, LogTextAnsi, 4096)
if Res > 0 then
begin
SetLength(LogTextAnsi, Res);
LogText := LeftOver + String(LogTextAnsi);
SystemLogProgress(LogText);
end;
TimerTick();
Sleep(200);
end;
ProcEnd(Handle);
finally
if (SystemCheckState = SYSTEM_CHECK_STATE_STOPPED) then
begin
Result := -1;
end else begin
Result := ExitCode;
end;
end;
end;
{ Execute command for SystemCheck and reset timer so that Spinner will disappear after end of execution. }
function SystemCheckExec(command, workdir: String): Integer;
begin
TimeCounter := 0;
Result := NonBlockingExec(command, workdir);
TimeCounter := 0;
end;
{ Get formated line from SystemCheck for user. }
function GetSystemCheckHint(Command: String; CustomCheckMessageKey:String):String;
begin
Result := CustomMessage('SystemCheckUnableToExecute') + ' ' + Command + #13#10 + CustomMessage(CustomCheckMessageKey);
end;
{ Add command to list of fixes which can be executed by installer. }
procedure AddFix(Command:String);
begin
{ Do not add possible fix command when check command was stopped by user. }
if (SystemCheckState = SYSTEM_CHECK_STATE_STOPPED) then begin
Exit;
end;
Fixes.Append(Command);
end;
{ Execute checks to determine whether Python installation is valid so thet user can choose it to install IDF. }
function IsPythonInstallationValid(displayName: String; pythonPath:String): Boolean;
var
ResultCode: Integer;
ScriptFile: String;
TempDownloadFile: String;
Command: String;
VirtualEvnPath: String;
VirtualEnvPython: String;
RemedyCommand: String;
begin
SystemLogTitle(CustomMessage('SystemCheckForComponent') + ' ' + displayName + ' ');
SystemCheckHint := '';
pythonPath := pythonPath + ' ';
Command := pythonPath + '-m pip --version';
ResultCode := SystemCheckExec(Command, ExpandConstant('{tmp}'));
if (ResultCode <> 0) then begin
SystemCheckHint := GetSystemCheckHint(Command, 'SystemCheckRemedyMissingPip');
Result := False;
Exit;
end;
Command := pythonPath + '-m virtualenv --version';
ResultCode := SystemCheckExec(Command, ExpandConstant('{tmp}'));
if (ResultCode <> 0) then begin
SystemCheckHint := GetSystemCheckHint(Command, 'SystemCheckRemedyMissingVirtualenv') + #13#10 + pythonPath + '-m pip install --upgrade pip' + #13#10 + pythonPath + '-m pip install virtualenv';
AddFix(pythonPath + '-m pip install --upgrade pip');
AddFix(pythonPath + '-m pip install virtualenv');
Result := False;
Exit;
end;
VirtualEnvCounter := VirtualEnvCounter + 1;
VirtualEvnPath := ExpandConstant('{tmp}\') + IntToStr(VirtualEnvCounter) + '-idf-test-venv\';
VirtualEnvPython := VirtualEvnPath + 'Scripts\python.exe ';
Command := pythonPath + '-m virtualenv ' + VirtualEvnPath;
ResultCode := SystemCheckExec(Command, ExpandConstant('{tmp}'));
if (ResultCode <> 0) then begin
SystemCheckHint := GetSystemCheckHint(Command, 'SystemCheckRemedyCreateVirtualenv');
Result := False;
Exit;
end;
ScriptFile := ExpandConstant('{tmp}\system_check_virtualenv.py')
Command := VirtualEnvPython + ScriptFile + ' ' + VirtualEnvPython;
ResultCode := SystemCheckExec(Command, ExpandConstant('{tmp}'));
if (ResultCode <> 0) then begin
SystemCheckHint := GetSystemCheckHint(Command, 'SystemCheckRemedyPythonInVirtualenv');
Result := False;
Exit;
end;
Command := VirtualEnvPython + '-m pip install --only-binary ":all:" "cryptography>=2.1.4" --no-binary future';
ResultCode := SystemCheckExec(Command, ExpandConstant('{tmp}'));
if (ResultCode <> 0) then begin
SystemCheckHint := GetSystemCheckHint(Command, 'SystemCheckRemedyBinaryPythonWheel');
Result := False;
Exit;
end;
TempDownloadFile := IntToStr(VirtualEnvCounter) + '-idf-exe-v1.0.1.zip';
ScriptFile := ExpandConstant('{tmp}\system_check_download.py');
Command := VirtualEnvPython + ScriptFile + ExpandConstant(' https://dl.espressif.com/dl/idf-exe-v1.0.1.zip ' + TempDownloadFile);
ResultCode := SystemCheckExec(Command , ExpandConstant('{tmp}'));
if (ResultCode <> 0) then begin
SystemCheckHint := GetSystemCheckHint(Command, 'SystemCheckRemedyFailedHttpsDownload');
Result := False;
Exit;
end;
if (not FileExists(ExpandConstant('{tmp}\') + TempDownloadFile)) then begin
SystemLog(' [' + CustomMessage('SystemCheckResultFail') + '] - ' + CustomMessage('SystemCheckUnableToFindFile') + ' ' + ExpandConstant('{tmp}\') + TempDownloadFile);
Result := False;
Exit;
end;
ScriptFile := ExpandConstant('{tmp}\system_check_subprocess.py');
Command := pythonPath + ScriptFile;
ResultCode := SystemCheckExec(Command, ExpandConstant('{tmp}'));
if (ResultCode <> 0) then begin
RemedyCommand := pythonPath + '-m pip uninstall subprocess.run';
SystemCheckHint := GetSystemCheckHint(Command, 'SystemCheckRemedyFailedSubmoduleRun') + #13#10 + RemedyCommand;
AddFix(RemedyCommand);
Result := False;
Exit;
end;
SystemLog(' [' + CustomMessage('SystemCheckResultOk') + ']');
Result := True;
end;
procedure FindPythonVersionsFromKey(RootKey: Integer; SubKeyName: String);
var
CompanyNames: TArrayOfString;
CompanyName, CompanySubKey, TagName, TagSubKey: String;
ExecutablePath, DisplayName, Version: String;
TagNames: TArrayOfString;
CompanyId, TagId: Integer;
BaseDir: String;
begin
if not RegGetSubkeyNames(RootKey, SubKeyName, CompanyNames) then
begin
Log('Nothing found in ' + IntToStr(RootKey) + '\' + SubKeyName);
Exit;
end;
for CompanyId := 0 to GetArrayLength(CompanyNames) - 1 do
begin
CompanyName := CompanyNames[CompanyId];
if CompanyName = 'PyLauncher' then
continue;
CompanySubKey := SubKeyName + '\' + CompanyName;
Log('In ' + IntToStr(RootKey) + '\' + CompanySubKey);
if not RegGetSubkeyNames(RootKey, CompanySubKey, TagNames) then
continue;
for TagId := 0 to GetArrayLength(TagNames) - 1 do
begin
TagName := TagNames[TagId];
TagSubKey := CompanySubKey + '\' + TagName;
Log('In ' + IntToStr(RootKey) + '\' + TagSubKey);
if not GetPythonVersionInfoFromKey(RootKey, SubKeyName, CompanyName, TagName, Version, DisplayName, ExecutablePath, BaseDir) then
continue;
if (SystemCheckState = SYSTEM_CHECK_STATE_STOPPED) then begin
Exit;
end;
{ Verify Python installation and display hint in case of invalid version or env. }
if not IsPythonInstallationValid(DisplayName, ExecutablePath) then begin
if ((Length(SystemCheckHint) > 0) and (SystemCheckState <> SYSTEM_CHECK_STATE_STOPPED)) then begin
SystemLogTitle(CustomMessage('SystemCheckHint') + ': ' + SystemCheckHint);
end;
continue;
end;
PythonVersionAdd(Version, DisplayName, ExecutablePath);
end;
end;
end;
procedure FindInstalledPythonVersions();
begin
FindPythonVersionsFromKey(HKEY_CURRENT_USER, 'Software\Python');
FindPythonVersionsFromKey(HKEY_LOCAL_MACHINE, 'Software\Python');
FindPythonVersionsFromKey(HKEY_LOCAL_MACHINE, 'Software\Wow6432Node\Python');
end;
{ Get Boolean for UI to determine whether it make sense to register exceptions to Defender. }
function GetWindowsDefenderStatus(): Boolean;
var
bHasWD: Boolean;
szWDPath: String;
listPSModulePath: TStringList;
ResultCode: Integer;
x: Integer;
begin
Log('Checking PSMODULEPATH for Windows Defender module');
listPSModulePath := TStringList.Create;
listPSModulePath.Delimiter := ';';
listPSModulePath.StrictDelimiter := True;
listPSModulePath.DelimitedText := GetEnv('PsModulePath');
for x:=0 to (listPSModulePath.Count-1) do
begin
szWDPath := listPSModulePath[x] + '\Defender'
bHasWD := DirExists(szWDPath);
if bHasWD then
begin
break;
end
end;
if not bHasWD then begin
Result := False;
Exit;
end;
Log('Checking Windows Services Defender is enabled: (Get-MpComputerStatus).AntivirusEnabled');
ResultCode := SystemCheckExec('powershell -ExecutionPolicy Bypass "if((Get-MpComputerStatus).AntivirusEnabled) { Exit 0 } else { Exit 1 }"', ExpandConstant('{tmp}'));
if (ResultCode <> 0) then begin
Log('Result code: ' + IntToStr(ResultCode));
Result := False;
Exit;
end;
Result := True;
end;
{ Process user request to stop system checks. }
function SystemCheckStopRequest():Boolean;
begin
{ In case of stopped check by user, procees to next/previous step. }
if (SystemCheckState = SYSTEM_CHECK_STATE_STOPPED) then begin
Result := True;
Exit;
end;
if (SystemCheckState = SYSTEM_CHECK_STATE_RUNNING) then begin
if (MsgBox(CustomMessage('SystemCheckNotCompleteConsent'), mbConfirmation, MB_YESNO) = IDYES) then begin
SystemCheckState := SYSTEM_CHECK_STATE_STOPPED;
Result := True;
Exit;
end;
end;
if (SystemCheckState = SYSTEM_CHECK_STATE_COMPLETE) then begin
Result := True;
end else begin
Result := False;
end;
end;
{ Process request to proceed to next page. If the scan is running ask user for confirmation. }
function OnSystemCheckValidate(Sender: TWizardPage): Boolean;
begin
Result := SystemCheckStopRequest();
end;
{ Process request to go to previous screen (license). Prompt user for confirmation when system check is running. }
function OnSystemCheckBackButton(Sender: TWizardPage): Boolean;
begin
Result := SystemCheckStopRequest();
end;
{ Process request to stop System Check directly on the screen with System Check by Stop button. }
procedure StopSystemCheckButtonClick(Sender: TObject);
begin
SystemCheckStopRequest();
end;
{ Check whether site is reachable and that system trust the certificate. }
procedure VerifyRootCertificates();
var
ResultCode: Integer;
Command: String;
OutFile: String;
begin
SystemLogTitle(CustomMessage('SystemCheckRootCertificates') + ' ');
{ It's necessary to invoke PowerShell *BEFORE* Python. Invoke-Request will retrieve and add Root Certificate if necessary. }
{ Without the certificate Python is failing to connect to https. }
{ Windows command to list current certificates: certlm.msc }
OutFile := ExpandConstant('{tmp}\check');
Command := 'powershell -ExecutionPolicy Bypass ';
Command := Command + 'Invoke-WebRequest -Uri "https://dl.espressif.com/dl/?system_check=win' + GetWindowsVersionString + '" -OutFile "' + OutFile + '-1.txt";';
Command := Command + 'Invoke-WebRequest -Uri "https://github.com/espressif" -OutFile "' + OutFile + '-2.txt";';
{Command := Command + 'Invoke-WebRequest -Uri "https://www.s3.amazonaws.com/" -OutFile "' + OutFile + '-3.txt";';}
ResultCode := SystemCheckExec(Command, ExpandConstant('{tmp}'));
if (ResultCode <> 0) then begin
SystemLog(' [' + CustomMessage('SystemCheckResultWarn') + ']');
SystemLog(CustomMessage('SystemCheckRootCertificateWarning'));
end else begin
SystemLog(' [' + CustomMessage('SystemCheckResultOk') + ']');
end;
end;
{ Wrapper function for Run task. Run tasks requires calling function. }
function GetIsWindowsDefenderEnabled(): Boolean;
begin
Result := IsWindowsDefenderEnabled;
end;
{ Execute system check }
procedure ExecuteSystemCheck();
begin
{ Execute system check only once. Avoid execution in case of back button. }
if (SystemCheckState <> SYSTEM_CHECK_STATE_INIT) then begin
Exit;
end;
SystemCheckState := SYSTEM_CHECK_STATE_RUNNING;
SystemLogTitle(CustomMessage('SystemCheckStart'));
StopSystemCheckButton.Enabled := True;
if (not IsOfflineMode) then begin
VerifyRootCertificates();
end;
{ Search for the installed Python version only on explicit user request. }
if (not UseEmbeddedPython) then begin
FindInstalledPythonVersions();
end;
if (SystemCheckState <> SYSTEM_CHECK_STATE_STOPPED) then begin
SystemLogTitle(CustomMessage('SystemCheckForDefender') + ' ');
IsWindowsDefenderEnabled := GetWindowsDefenderStatus();
if (IsWindowsDefenderEnabled) then begin
SystemLog(' [' + CustomMessage('SystemCheckResultFound') + ']');
end else begin
SystemLog(' [' + CustomMessage('SystemCheckResultNotFound') + ']');
end;
end else begin
{ User cancelled the check, let's enable Defender script so that use can decide to disable it. }
IsWindowsDefenderEnabled := True;
end;
if (SystemCheckState = SYSTEM_CHECK_STATE_STOPPED) then begin
SystemLog('');
SystemLogTitle(CustomMessage('SystemCheckStopped'));
end else begin
SystemLogTitle(CustomMessage('SystemCheckComplete'));
SystemCheckState := SYSTEM_CHECK_STATE_COMPLETE;
end;
{ Enable Apply Script button if some fixes are available. }
if (Fixes.Count > 0) then begin
ApplyFixesButton.Enabled := True;
end;
StopSystemCheckButton.Enabled := False;
end;
{ Invoke scan of system environment. }
procedure OnSystemCheckActivate(Sender: TWizardPage);
begin
{ Display special controls. For some reason the first call of the page does not invoke SystemCheckOnCurPageChanged. }
FullLogButton.Visible := True;
ApplyFixesButton.Visible := True;
StopSystemCheckButton.Visible := True;
SystemCheckViewer.Visible := True;
if (SkipSystemCheck) then begin
SystemCheckState := SYSTEM_CHECK_STATE_STOPPED;
SystemLog('System Check disabled by command line option /SKIPSYSTEMCHECK.');
end;
ExecuteSystemCheck();
end;
{ Handle request to display full log from the installation. Open the log in notepad. }
procedure FullLogButtonClick(Sender: TObject);
var
ResultCode: Integer;
begin
Exec(ExpandConstant('{win}\notepad.exe'), ExpandConstant('{log}'), '', SW_SHOW, ewNoWait, ResultCode);
end;
{ Handle request to apply available fixes. }
procedure ApplyFixesButtonClick(Sender: TObject);
var
ResultCode: Integer;
FixIndex: Integer;
AreFixesApplied: Boolean;
begin
if (MsgBox(CustomMessage('SystemCheckApplyFixesConsent'), mbConfirmation, MB_YESNO) = IDNO) then begin
Exit;
end;
ApplyFixesButton.Enabled := false;
SystemCheckState := SYSTEM_CHECK_STATE_INIT;
SystemLog('');
SystemLogTitle('Starting application of fixes');
AreFixesApplied := True;
for FixIndex := 0 to Fixes.Count - 1 do
begin
ResultCode := SystemCheckExec(Fixes[FixIndex], ExpandConstant('{tmp}'));
if (ResultCode <> 0) then begin
AreFixesApplied := False;
break;
end;
end;
SystemLog('');
if (AreFixesApplied) then begin
SystemLogTitle(CustomMessage('SystemCheckFixesSuccessful'));
end else begin
SystemLogTitle(CustomMessage('SystemCheckFixesFailed'));
end;
SystemLog('');
Fixes.Clear();
{ Restart system check. }
ExecuteSystemCheck();
end;
{ Add Page for System Check so that user is informed about readiness of the system. }
<event('InitializeWizard')>
procedure CreateSystemCheckPage();
begin
{ Initialize data structure for Python }
InstalledPythonVersions := TStringList.Create();
InstalledPythonDisplayNames := TStringList.Create();
InstalledPythonExecutables := TStringList.Create();
PythonVersionAdd('{#PythonVersion}', 'Use Python {#PythonVersion} Embedded (Recommended)', 'tools\idf-python\{#PythonVersion}\python.exe');
{ Create Spinner animation. }
Spinner := TStringList.Create();
Spinner.Append('-');
Spinner.Append('\');
Spinner.Append('|');
Spinner.Append('/');
VirtualEnvCounter := 0;
Fixes := TStringList.Create();
SystemCheckState := SYSTEM_CHECK_STATE_INIT;
SystemCheckPage := CreateOutputMsgPage(wpLicense, CustomMessage('PreInstallationCheckTitle'), CustomMessage('PreInstallationCheckSubtitle'), '');
with SystemCheckPage do
begin
OnActivate := @OnSystemCheckActivate;
OnBackButtonClick := @OnSystemCheckBackButton;
OnNextButtonClick := @OnSystemCheckValidate;
end;
SystemCheckViewer := TNewMemo.Create(WizardForm);
with SystemCheckViewer do
begin
Parent := WizardForm;
Left := ScaleX(10);
Top := ScaleY(60);
ReadOnly := True;
Font.Name := 'Courier New';
Height := WizardForm.CancelButton.Top - ScaleY(40);
Width := WizardForm.ClientWidth + ScaleX(80);
WordWrap := True;
Visible := False;
end;
SystemLogText := TStringList.Create;
FullLogButton := TNewButton.Create(WizardForm);
with FullLogButton do
begin
Parent := WizardForm;
Left := WizardForm.ClientWidth;
Top := SystemCheckViewer.Top + SystemCheckViewer.Height + ScaleY(5);
Width := WizardForm.CancelButton.Width;
Height := WizardForm.CancelButton.Height;
Caption := CustomMessage('SystemCheckFullLogButtonCaption');
OnClick := @FullLogButtonClick;
Visible := False;
end;
ApplyFixesButton := TNewButton.Create(WizardForm);
with ApplyFixesButton do
begin
Parent := WizardForm;
Left := WizardForm.ClientWidth - FullLogButton.Width;
Top := FullLogButton.Top;
Width := WizardForm.CancelButton.Width;
Height := WizardForm.CancelButton.Height;
Caption := CustomMessage('SystemCheckApplyFixesButtonCaption');
OnClick := @ApplyFixesButtonClick;
Visible := False;
Enabled := False;
end;
StopSystemCheckButton := TNewButton.Create(WizardForm);
with StopSystemCheckButton do
begin
Parent := WizardForm;
Left := ApplyFixesButton.Left - ApplyFixesButton.Width;
Top := FullLogButton.Top;
Width := WizardForm.CancelButton.Width;
Height := WizardForm.CancelButton.Height;
Caption := CustomMessage('SystemCheckStopButtonCaption');
OnClick := @StopSystemCheckButtonClick;
Visible := False;
Enabled := False;
end;
{ Extract helper files for sanity check of Python environment. }
ExtractTemporaryFile('system_check_download.py')
ExtractTemporaryFile('system_check_subprocess.py')
ExtractTemporaryFile('system_check_virtualenv.py')
end;
{ Process Cancel Button Click event. Prompt user to confirm Cancellation of System check. }
{ Then continue with normal cancel window. }
procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
begin
if ((CurPageId = SystemCheckPage.ID) and (SystemCheckState = SYSTEM_CHECK_STATE_RUNNING)) then begin
SystemCheckStopRequest();
end;
end;
{ Display control specific for System Check page. }
<event('CurPageChanged')>
procedure SystemCheckOnCurPageChanged(CurPageID: Integer);
begin
FullLogButton.Visible := CurPageID = SystemCheckPage.ID;
ApplyFixesButton.Visible := CurPageID = SystemCheckPage.ID;
StopSystemCheckButton.Visible := CurPageID = SystemCheckPage.ID;
SystemCheckViewer.Visible := CurPageID = SystemCheckPage.ID;
end;

View File

@ -1,171 +0,0 @@
################################################################################
#
# Microsoft WindowsDefender exclusions cleaner
# Espressif Systems, 2019
#
################################################################################
#
# - cleans all Windows Defender process exclusions containing given path (both Process and Path)
# - run as Administrator, eg: PowerShell -ExecutionPolicy ByPass -File tools_WD_clean.ps1 -RmExclPath "C:\Program Files\Espressif\ESP-IDF Tools". If not running with admin privileges, the script tries to elevate itself (new process, output grabbed on exit)
# minimum requirements: Windows XP SP3, PowerShell 2.0, Windows Defender with relevant PS cmdlets
# - Returns 0 on success or -1 on failure
#
################################################################################
Param
(
[String]$RmExclPath,
[String]$logFile
)
function Check-Command($cmdname)
{
return [bool](Get-Command -Name $cmdname -ErrorAction SilentlyContinue)
}
function Log-Msg($msg, $logF = $null)
{
if( ![string]::IsNullOrEmpty($logF) ) { Write-Output $msg *>> $logF }
else { Write-Output $msg }
[Console]::Out.Flush()
}
$retVal = 1
Try
{
Import-Module Defender
#self-elevation support
$myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent()
$myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID)
$adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator
if( -not $myWindowsPrincipal.IsInRole($adminRole) ) {
$params = ""
foreach($key in $PSBoundParameters.keys) {
$params = -join( $params, "-", $key, " `"", $PSBoundParameters[$key], "`"" )
}
#running elevated and logFile not set
if( [string]::IsNullOrEmpty($logFile) ) {
$tempFileName = Get-Date -UFormat "%Y%m%d%H%M%s"
$lf = Join-Path -Path $env:TEMP -ChildPath "WDEspLog$tempFileName.log"
}
$newProcess = new-object System.Diagnostics.ProcessStartInfo "PowerShell"
$newProcess.Arguments = "-ExecutionPolicy ByPass -File " + $script:MyInvocation.MyCommand.Definition + " " + $params + " -logFile $lf"
$newProcess.Verb = "RunAs"
$newProcess.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Hidden
$proc = [System.Diagnostics.Process]::Start($newProcess)
$proc.WaitForExit()
if (Test-Path -Path $lf ) {
foreach($line in Get-Content $lf) {
Log-Msg -msg $line
}
Remove-Item $lf
}
exit $proc.ExitCode
}
Log-Msg -msg "Getting Windows Defender process exclusions..." -logF $logFile
$Preferences = Get-MpPreference
#ExclusionProcess
$cnt = $Preferences.ExclusionProcess.Count
$cntRemoved = 0
$cntRemovedTotal = 0
$cntMissed = 0
$cntMissedTotal = 0
$bRmPath = ![string]::IsNullOrEmpty($RmExclPath)
if( $bRmPath ) { Log-Msg -msg "Exclusion path: $RmExclPath" -logF $logFile }
Log-Msg -msg " Found total $cnt of ExclusionProcess items" -logF $logFile
foreach( $pref in $Preferences.ExclusionProcess ) {
if( $bRmPath ) { $bGoAhead = $pref.Contains($RmExclPath) }
else { $bGoAhead = $true }
if( $bGoAhead ) {
Log-Msg -msg " removing $pref" -logF $logFile
Try
{
Remove-MpPreference -ExclusionProcess $pref
$cntRemoved++
}
Catch
{
if( ![string]::IsNullOrEmpty($logFile) ) { Write-Error -Exception $_.Exception *>> $logFile }
Write-Error -Exception $_.Exception
$cntMissed++
}
}
}
if( $cntMissed -eq 0 ) { Log-Msg -msg " $cntRemoved relevant items removed from ExclusionProcess list" -logF $logFile }
else { Log-Msg -msg " WARNING: Only $cntRemoved out of $(cntRemoved+cntMissed) relevant items removed from ExclusionProcess list" -logF $logFile }
#ExclusionPath
$cnt = $Preferences.ExclusionPath.Count
$cntRemovedTotal = $cntRemoved
$cntRemoved = 0
$cntMissedTotal = $cntMissed
$cntMissed = 0
Log-Msg -msg " Found total $cnt of ExclusionPath items" -logF $logFile
foreach( $pref in $Preferences.ExclusionPath ) {
if( $bRmPath ) { $bGoAhead = $pref.Contains($RmExclPath) }
else { $bGoAhead = $true }
if( $bGoAhead ) {
Log-Msg -msg " removing $pref" -logF $logFile
Try
{
Remove-MpPreference -ExclusionPath $pref
$cntRemoved++
}
Catch
{
if( ![string]::IsNullOrEmpty($logFile) ) { Write-Error -Exception $_.Exception *>> $logFile }
Write-Error -Exception $_.Exception
$cntMissed++
}
}
}
if( $cntMissed -eq 0 ) { Log-Msg -msg " $cntRemoved relevant items removed from ExclusionPath list" -logF $logFile }
else { Log-Msg -msg " WARNING: Only $cntRemoved out of $(cntRemoved+cntMissed) relevant items removed from ExclusionPath list" -logF $logFile }
#TOTAL
$cntRemovedTotal += $cntRemoved
$cntMissedTotal += $cntMissed
Log-Msg -msg "============================" -logF $logFile
if( $cntMissedTotal -eq 0 ) { Log-Msg -msg "OK: Processed all $cntRemovedTotal items" -logF $logFile }
else { Log-Msg -msg "WARNING: Processed only $cntRemovedTotal out of $(cntRemovedTotal+cntMissedTotal) relevat items" -logF $logFile }
Log-Msg -msg "`nDone" -logF $logFile
$retVal = 0
}
Catch
{
if( ![string]::IsNullOrEmpty($logFile) ) { Write-Error -Exception $_.Exception *>> $logFile }
Write-Error -Exception $_.Exception
[Environment]::Exit($retVal)
}
Finally
{
[Environment]::Exit($retVal)
}

View File

@ -1,243 +0,0 @@
################################################################################
#
# Microsoft WindowsDefender exclusions handler
# Espressif Systems, 2019
#
################################################################################
#
# PS utility to add/remove PROCESS exceptions to/from MS WD real-time
# scanning. Files (referenced by 'path' or 'path\filemask') are expected
# to be Windows process executables, for obvious reasons.
#
# The script requires Administrator privileges to succeed -> self-elevation procedure is involved
#
# Usage:
#
# PowerShell -ExecutionPolicy ByPass -File tools_WD_excl.ps1 <ARGUMENTS>
#
# ARGUMENTS:
# -AddExclPath <path | path\*.filemask>
# add all matching files in the path (recursive) to the WD exception list
#
# -AddExclFile <filepath>
# adds file to the WD exception list exactly as specified by 'filepath'
#
# -RmExclPath <path | path\*.filemask>
# remove all matching files in the path (recursive) from WD exclusions
#
# -RmExclFile <filepath>
# adds file to the WD exception list exactly as specified by 'filepath'
#
# -logFile <filepath>
# stdout/stderr redirection file. Used internally for elevated process (generated in tempdir, deleted after the script finishing)
# use manually at your own risk
#
# Returns 0 on success or -1 on failure
#
#
# Example:
# PowerShell -ExecutionPolicy ByPass -File tools_WD_excl.ps1 -AddExclPath "C:\Program Files\Espressif\ESP-IDF Tools\*.exe"
#
# Notes:
# - default scenario is set to the following
# -AddExclPath "$Env:ProgramFiles\Espressif\ESP-IDF Tools\*.exe"
# (eg when called with no params)
# - only named parameters are supported, any other use-cases redirect to the default
# - multiple paths/files in 1 parameter are not supported by this version
# - minimum requirements: Windows XP SP3, PowerShell 2.0, Windows Defender with relevant PS cmdlets
#
################################################################################
Param
(
[String]$AddExclPath,
[String]$AddExclFile,
[String]$RmExclPath,
[String]$RmExclFile,
[String]$logFile
)
function Check-Command($cmdname)
{
return [bool](Get-Command -Name $cmdname -ErrorAction SilentlyContinue)
}
function Log-Msg($msg, $logF = $null)
{
if( ![string]::IsNullOrEmpty($logF) ) { Write-Output $msg *>> $logF }
else { Write-Output $msg }
[Console]::Out.Flush()
}
$retVal = 1
Try
{
$bDebug = $false
#parameter sanity check
if( $Args.Count -gt 0 ) {
if( $Args.Count -eq 1 -And $Args[0] -eq "Debug" ) {
$bDebug = $true
}
else {
$Exception = [ArgumentException]::new("Invalid parameters: $Args")
throw $Exception
}
}
Import-Module Defender
#self-elevation support
$myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent()
$myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID)
$adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator
if( -not $myWindowsPrincipal.IsInRole($adminRole) ) {
$params = ""
foreach($key in $PSBoundParameters.keys) {
$params = -join( $params, "-", $key, " `"", $PSBoundParameters[$key], "`"" )
}
$arguments = ""
foreach($a in $Args) {
$arguments = -join( $arguments, "-", $a )
}
#running elevated and logFile not set
$bOwnLogFile = [string]::IsNullOrEmpty($logFile)
if( $bOwnLogFile ) {
$tempFileName = Get-Date -UFormat "%Y%m%d%H%M%s"
$lf = Join-Path -Path $env:TEMP -ChildPath "WDEspLog$tempFileName.log"
}
else { $lf = $logFile }
$newProcess = new-object System.Diagnostics.ProcessStartInfo "PowerShell"
$newProcess.Arguments = "-ExecutionPolicy ByPass -File " + $script:MyInvocation.MyCommand.Definition + " " + $params + " -logFile $lf " + $arguments
$newProcess.Verb = "RunAs"
#show the process window for -Debug
if( !$bDebug ) { $newProcess.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Hidden }
$proc = [System.Diagnostics.Process]::Start($newProcess)
$proc.WaitForExit()
if (Test-Path -Path $lf ) {
foreach($line in Get-Content $lf) {
Log-Msg -msg $line
}
}
if( $bDebug ) { Log-Msg -msg "Process finished with code " + $proc.ExitCode -logF $lf }
if( $bOwnLogFile -And !$bDebug) { Remove-Item $lf }
[Environment]::Exit($proc.ExitCode)
}
$pathsToExclude = New-Object 'System.Collections.Generic.List[String]'
$filesToExclude = New-Object 'System.Collections.Generic.List[String]'
$pathsToInclude = New-Object 'System.Collections.Generic.List[String]'
$filesToRemove = New-Object 'System.Collections.Generic.List[String]'
if( $PSBoundParameters.Count -gt 0 ) {
$bAddPath = ![string]::IsNullOrEmpty($AddExclPath)
$bAddFile = ![string]::IsNullOrEmpty($AddExclFile)
$bRmPath = ![string]::IsNullOrEmpty($RmExclPath)
$bRmFile = ![string]::IsNullOrEmpty($RmExclFile)
if( !$bAddPath -And !$bAddFile -And !$bRmPath -And !$bRmFile ) {
throw (New-Object -TypeName System.ArgumentException -ArgumentList "Invalid parameter(s)")
}
#ADD exclusion paths
if( $bAddPath ) {
$pathsToExclude.Add( $AddExclPath )
}
#ADD exclusion files
if( $bAddFile ) {
$filesToExclude.Add( $AddExclFile )
}
#REMOVE exclusion paths
if( $bRmPath ) {
$pathsToInclude.Add( $RmExclPath )
}
#ADD exclusion file
if( $bAddFile ) {
$filesToRemove.Add( $RmExclFile )
}
}
else {
throw (New-Object -TypeName System.ArgumentException -ArgumentList "Mandatory parameter(s) missing")
}
#to exclude all files opened by a process including the process' binary, a record must be added to both Exclusions/Paths and Exclusions/Processes configurations, see
# https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-defender-antivirus/configure-process-opened-file-exclusions-windows-defender-antivirus :
# "When you add a process to the process exclusion list, Windows Defender Antivirus won't scan files opened by that process, no matter where the files are located. The process itself, however, will be scanned unless it has also been added to the file exclusion list.
#The exclusions only apply to always-on real-time protection and monitoring. They don't apply to scheduled or on-demand scans."
Log-Msg -msg "Updating Windows Defender real-time scan exclusions:" -logF $logFile
$itemCount = 0
#exclusions
foreach( $exclPath in $pathsToExclude ) {
$exclFiles = Get-ChildItem -Recurse -File -Path $exclPath | % { $_.FullName }
foreach ($exfile in $exclFiles) {
Log-Msg -msg " adding $exfile" -logF $logFile
Add-MpPreference -ExclusionProcess $exfile
Add-MpPreference -ExclusionPath $exfile
$itemCount++
}
}
### ! better run in separate, adding files to exclusion object array from above is very inefficient (forced reallocations)
foreach ($exfile1 in $filesToExclude) {
Log-Msg -msg " adding $exfile1" -logF $logFile
Add-MpPreference -ExclusionProcess $exfile1
Add-MpPreference -ExclusionPath $exfile1
$itemCount++
}
#inclusions
foreach( $inclPath in $pathsToInclude ) {
$inclFiles = Get-ChildItem -Recurse -File -Path $inclPath | % { $_.FullName }
foreach ($infile in $inclFiles) {
Log-Msg -msg " removing $infile" -logF $logFile
Remove-MpPreference -ExclusionProcess $infile
Remove-MpPreference -ExclusionPath $infile
$itemCount++
}
}
### ! see exclusions
foreach ($infile1 in $filesToExclude) {
Log-Msg -msg " removing $infile1" -logF $logFile
Remove-MpPreference -ExclusionProcess $infile1
Remove-MpPreference -ExclusionPath $infile1
$itemCount++
}
Log-Msg -msg "Done (processed $itemCount items)" -logF $logFile
$retVal = 0
[Environment]::Exit($retVal)
}
Catch
{
if( ![string]::IsNullOrEmpty($logFile) ) { Write-Error -Exception $_.Exception *>> $logFile }
Write-Error -Exception $_.Exception -ErrorAction Stop
[Environment]::Exit($retVal)
}
Finally
{
[Environment]::Exit($retVal)
}

View File

@ -1,390 +0,0 @@
{
"tools": [
{
"description": "Toolchain for Xtensa (ESP32) based on GCC",
"export_paths": [
[
"xtensa-esp32-elf",
"bin"
]
],
"export_vars": {},
"info_url": "https://github.com/espressif/crosstool-NG",
"install": "always",
"license": "GPL-3.0-with-GCC-exception",
"name": "xtensa-esp32-elf",
"version_cmd": [
"xtensa-esp32-elf-gcc",
"--version"
],
"version_regex": "\\(crosstool-NG\\s+(?:crosstool-ng-)?([0-9a-z\\.\\-]+)\\)\\s*([0-9\\.]+)",
"version_regex_replace": "\\1-\\2",
"versions": [
{
"name": "1.22.0-80-g6c4433a5-5.2.0",
"status": "recommended",
"win32": {
"sha256": "f217fccbeaaa8c92db239036e0d6202458de4488b954a3a38f35ac2ec48058a4",
"size": 125719261,
"url": "https://dl.espressif.com/dl/xtensa-esp32-elf-win32-1.22.0-80-g6c4433a-5.2.0.zip"
},
"win64": {
"sha256": "f217fccbeaaa8c92db239036e0d6202458de4488b954a3a38f35ac2ec48058a4",
"size": 125719261,
"url": "https://dl.espressif.com/dl/xtensa-esp32-elf-win32-1.22.0-80-g6c4433a-5.2.0.zip"
}
},
{
"linux-amd64": {
"sha256": "3fe96c151d46c1d4e5edc6ed690851b8e53634041114bad04729bc16b0445156",
"size": 44219107,
"url": "https://dl.espressif.com/dl/xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a-5.2.0.tar.gz"
},
"linux-i686": {
"sha256": "b4055695ffc2dfc0bcb6dafdc2572a6e01151c4179ef5fa972b3fcb2183eb155",
"size": 45566336,
"url": "https://dl.espressif.com/dl/xtensa-esp32-elf-linux32-1.22.0-80-g6c4433a-5.2.0.tar.gz"
},
"macos": {
"sha256": "a4307a97945d2f2f2745f415fbe80d727750e19f91f9a1e7e2f8a6065652f9da",
"size": 46517409,
"url": "https://dl.espressif.com/dl/xtensa-esp32-elf-osx-1.22.0-80-g6c4433a-5.2.0.tar.gz"
},
"name": "1.22.0-80-g6c4433a-5.2.0",
"status": "recommended"
}
]
},
{
"description": "Toolchain for ESP32 ULP coprocessor",
"export_paths": [
[
"esp32ulp-elf-binutils",
"bin"
]
],
"export_vars": {},
"info_url": "https://github.com/espressif/binutils-esp32ulp",
"install": "always",
"license": "GPL-2.0-or-later",
"name": "esp32ulp-elf",
"version_cmd": [
"esp32ulp-elf-as",
"--version"
],
"version_regex": "\\(GNU Binutils\\)\\s+([0-9a-z\\.\\-]+)",
"versions": [
{
"linux-amd64": {
"sha256": "c1bbcd65e1e30c7312a50344c8dbc70c2941580a79aa8f8abbce8e0e90c79566",
"size": 8246604,
"url": "https://dl.espressif.com/dl/binutils-esp32ulp-linux64-2.28.51-esp32ulp-20180809.tar.gz"
},
"macos": {
"sha256": "c92937d85cc9a90eb6c6099ce767ca021108c18c94e34bd7b1fa0cde168f94a0",
"size": 5726662,
"url": "https://dl.espressif.com/dl/binutils-esp32ulp-macos-2.28.51-esp32ulp-20180809.tar.gz"
},
"name": "2.28.51.20170517",
"status": "recommended",
"win32": {
"sha256": "92dc83e69e534c9f73d7b939088f2e84f757d2478483415d17fe9dd1c236f2fd",
"size": 12231559,
"url": "https://dl.espressif.com/dl/binutils-esp32ulp-win32-2.28.51-esp32ulp-20180809.zip"
},
"win64": {
"sha256": "92dc83e69e534c9f73d7b939088f2e84f757d2478483415d17fe9dd1c236f2fd",
"size": 12231559,
"url": "https://dl.espressif.com/dl/binutils-esp32ulp-win32-2.28.51-esp32ulp-20180809.zip"
}
}
]
},
{
"description": "CMake build system",
"export_paths": [
[
"bin"
]
],
"export_vars": {},
"info_url": "https://github.com/Kitware/CMake",
"install": "on_request",
"license": "BSD-3-Clause",
"name": "cmake",
"platform_overrides": [
{
"install": "always",
"platforms": [
"win32",
"win64"
]
},
{
"export_paths": [
[
"CMake.app",
"Contents",
"bin"
]
],
"platforms": [
"macos"
]
}
],
"strip_container_dirs": 1,
"version_cmd": [
"cmake",
"--version"
],
"version_regex": "cmake version ([0-9.]+)",
"versions": [
{
"linux-amd64": {
"sha256": "563a39e0a7c7368f81bfa1c3aff8b590a0617cdfe51177ddc808f66cc0866c76",
"size": 38405896,
"url": "https://github.com/Kitware/CMake/releases/download/v3.13.4/cmake-3.13.4-Linux-x86_64.tar.gz"
},
"macos": {
"sha256": "fef537614d73fda848f6168273b6c7ba45f850484533361e7bc50ac1d315f780",
"size": 32062124,
"url": "https://github.com/Kitware/CMake/releases/download/v3.13.4/cmake-3.13.4-Darwin-x86_64.tar.gz"
},
"name": "3.13.4",
"status": "recommended",
"win32": {
"sha256": "28daf772f55d817a13ef14e25af2a5569f8326dac66a6aa3cc5208cf1f8e943f",
"size": 26385104,
"url": "https://github.com/Kitware/CMake/releases/download/v3.13.4/cmake-3.13.4-win32-x86.zip"
},
"win64": {
"sha256": "bcd477d49e4a9400b41213d53450b474beaedb264631693c958ef9affa8e5623",
"size": 29696565,
"url": "https://github.com/Kitware/CMake/releases/download/v3.13.4/cmake-3.13.4-win64-x64.zip"
}
}
]
},
{
"description": "OpenOCD for ESP32",
"export_paths": [
[
"openocd-esp32",
"bin"
]
],
"export_vars": {
"OPENOCD_SCRIPTS": "${TOOL_PATH}/openocd-esp32/share/openocd/scripts"
},
"info_url": "https://github.com/espressif/openocd-esp32",
"install": "always",
"license": "GPL-2.0-only",
"name": "openocd-esp32",
"version_cmd": [
"openocd",
"--version"
],
"version_regex": "Open On-Chip Debugger\\s+([a-z0-9.-]+)\\s+",
"versions": [
{
"linux-amd64": {
"sha256": "e5b5579edffde090e426b4995b346e281843bf84394f8e68c8e41bd1e4c576bd",
"size": 1681596,
"url": "https://github.com/espressif/openocd-esp32/releases/download/v0.10.0-esp32-20190313/openocd-esp32-linux64-0.10.0-esp32-20190313.tar.gz"
},
"macos": {
"sha256": "09504eea5aa92646a117f16573c95b34e04b4010791a2f8fefcd2bd8c430f081",
"size": 1760536,
"url": "https://github.com/espressif/openocd-esp32/releases/download/v0.10.0-esp32-20190313/openocd-esp32-macos-0.10.0-esp32-20190313.tar.gz"
},
"name": "v0.10.0-esp32-20190313",
"status": "recommended",
"win32": {
"sha256": "b86a7f9f39dfc4d8e289fc819375bbb7a5e9fcb8895805ba2b5faf67b8b25ce2",
"size": 2098513,
"url": "https://github.com/espressif/openocd-esp32/releases/download/v0.10.0-esp32-20190313/openocd-esp32-win32-0.10.0-esp32-20190313.zip"
},
"win64": {
"sha256": "b86a7f9f39dfc4d8e289fc819375bbb7a5e9fcb8895805ba2b5faf67b8b25ce2",
"size": 2098513,
"url": "https://github.com/espressif/openocd-esp32/releases/download/v0.10.0-esp32-20190313/openocd-esp32-win32-0.10.0-esp32-20190313.zip"
}
}
]
},
{
"description": "menuconfig tool",
"export_paths": [
[
""
]
],
"export_vars": {},
"info_url": "https://github.com/espressif/kconfig-frontends",
"install": "never",
"license": "GPL-2.0-only",
"name": "mconf",
"platform_overrides": [
{
"install": "always",
"platforms": [
"win32",
"win64"
]
}
],
"strip_container_dirs": 1,
"version_cmd": [
"mconf-idf",
"-v"
],
"version_regex": "mconf-idf version mconf-([a-z0-9.-]+)-win32",
"versions": [
{
"name": "v4.6.0.0-idf-20190628",
"status": "recommended",
"win32": {
"sha256": "1b8f17f48740ab669c13bd89136e8cc92efe0cd29872f0d6c44148902a2dc40c",
"size": 826114,
"url": "https://github.com/espressif/kconfig-frontends/releases/download/v4.6.0.0-idf-20190628/mconf-v4.6.0.0-idf-20190628-win32.zip"
},
"win64": {
"sha256": "1b8f17f48740ab669c13bd89136e8cc92efe0cd29872f0d6c44148902a2dc40c",
"size": 826114,
"url": "https://github.com/espressif/kconfig-frontends/releases/download/v4.6.0.0-idf-20190628/mconf-v4.6.0.0-idf-20190628-win32.zip"
}
}
]
},
{
"description": "Ninja build system",
"export_paths": [
[
""
]
],
"export_vars": {},
"info_url": "https://github.com/ninja-build/ninja",
"install": "on_request",
"license": "Apache-2.0",
"name": "ninja",
"platform_overrides": [
{
"install": "always",
"platforms": [
"win32",
"win64"
]
}
],
"version_cmd": [
"ninja",
"--version"
],
"version_regex": "([0-9.]+)",
"versions": [
{
"linux-amd64": {
"sha256": "978fd9e26c2db8d33392c6daef50e9edac0a3db6680710a9f9ad47e01f3e49b7",
"size": 85276,
"url": "https://dl.espressif.com/dl/ninja-1.9.0-linux64.tar.gz"
},
"macos": {
"sha256": "9504cd1783ef3c242d06330a50d54dc8f838b605f5fc3e892c47254929f7350c",
"size": 91457,
"url": "https://dl.espressif.com/dl/ninja-1.9.0-osx.tar.gz"
},
"name": "1.9.0",
"status": "recommended",
"win64": {
"sha256": "2d70010633ddaacc3af4ffbd21e22fae90d158674a09e132e06424ba3ab036e9",
"size": 254497,
"url": "https://dl.espressif.com/dl/ninja-1.9.0-win64.zip"
}
}
]
},
{
"description": "IDF wrapper tool for Windows",
"export_paths": [
[
""
]
],
"export_vars": {},
"info_url": "https://github.com/espressif/esp-idf/tree/master/tools/windows/idf_exe",
"install": "never",
"license": "Apache-2.0",
"name": "idf-exe",
"platform_overrides": [
{
"install": "always",
"platforms": [
"win32",
"win64"
]
}
],
"version_cmd": [
"idf.py.exe",
"-v"
],
"version_regex": "([0-9.]+)",
"versions": [
{
"name": "1.0.1",
"status": "recommended",
"win32": {
"sha256": "53eb6aaaf034cc7ed1a97d5c577afa0f99815b7793905e9408e74012d357d04a",
"size": 11297,
"url": "https://dl.espressif.com/dl/idf-exe-v1.0.1.zip"
},
"win64": {
"sha256": "53eb6aaaf034cc7ed1a97d5c577afa0f99815b7793905e9408e74012d357d04a",
"size": 11297,
"url": "https://dl.espressif.com/dl/idf-exe-v1.0.1.zip"
}
}
]
},
{
"description": "Ccache (compiler cache)",
"export_paths": [
[
""
]
],
"export_vars": {},
"info_url": "https://github.com/ccache/ccache",
"install": "never",
"license": "GPL-3.0-or-later",
"name": "ccache",
"platform_overrides": [
{
"install": "always",
"platforms": [
"win64"
]
}
],
"version_cmd": [
"ccache.exe",
"--version"
],
"version_regex": "ccache version ([0-9.]+)",
"versions": [
{
"name": "3.7",
"status": "recommended",
"win64": {
"sha256": "37e833f3f354f1145503533e776c1bd44ec2e77ff8a2476a1d2039b0b10c78d6",
"size": 142401,
"url": "https://dl.espressif.com/dl/ccache-3.7-w64.zip"
}
}
]
}
],
"version": 1
}

View File

@ -1,157 +0,0 @@
{ Copyright 2019-2020 Espressif Systems (Shanghai) CO LTD
SPDX-License-Identifier: Apache-2.0 }
{ ------------------------------ Helper functions from libcmdlinerunner.dll ------------------------------ }
function ProcStart(cmdline, workdir: string): Longword;
external 'proc_start@files:cmdlinerunner.dll cdecl';
function ProcGetExitCode(inst: Longword): DWORD;
external 'proc_get_exit_code@files:cmdlinerunner.dll cdecl';
function ProcGetOutput(inst: Longword; dest: PAnsiChar; sz: DWORD): DWORD;
external 'proc_get_output@files:cmdlinerunner.dll cdecl';
procedure ProcEnd(inst: Longword);
external 'proc_end@files:cmdlinerunner.dll cdecl';
{ ------------------------------ WinAPI functions ------------------------------ }
#ifdef UNICODE
#define AW "W"
#else
#define AW "A"
#endif
function SetEnvironmentVariable(lpName: string; lpValue: string): BOOL;
external 'SetEnvironmentVariable{#AW}@kernel32.dll stdcall';
{ ------------------------------ Functions to query the registry ------------------------------ }
{ Utility to search in HKLM and HKCU for an installation path. Looks in both 64-bit & 32-bit registry. }
function GetInstallPath(key, valuename : String) : String;
var
value: String;
begin
Result := '';
if RegQueryStringValue(HKEY_LOCAL_MACHINE, key, valuename, value) then
begin
Result := value;
exit;
end;
if RegQueryStringValue(HKEY_CURRENT_USER, key, valuename, value) then
begin
Result := value;
exit;
end;
{ This is 32-bit setup running on 64-bit Windows, but ESP-IDF can use 64-bit tools also }
if IsWin64 and RegQueryStringValue(HKLM64, key, valuename, value) then
begin
Result := value;
exit;
end;
if IsWin64 and RegQueryStringValue(HKCU64, key, valuename, value) then
begin
Result := value;
exit;
end;
end;
{ ------------------------------ Function to exit from the installer ------------------------------ }
procedure AbortInstallation(Message: String);
begin
MsgBox(Message, mbError, MB_OK);
Abort();
end;
{ ------------------------------ File system related functions ------------------------------ }
function DirIsEmpty(DirName: String): Boolean;
var
FindRec: TFindRec;
begin
Result := True;
if FindFirst(DirName+'\*', FindRec) then begin
try
repeat
if (FindRec.Name <> '.') and (FindRec.Name <> '..') then begin
Result := False;
break;
end;
until not FindNext(FindRec);
finally
FindClose(FindRec);
end;
end;
end;
type
TFindFileCallback = procedure(Filename: String);
procedure FindFileRecursive(Directory: string; FileName: string; Callback: TFindFileCallback);
var
FindRec: TFindRec;
FilePath: string;
begin
if FindFirst(Directory + '\*', FindRec) then
begin
try
repeat
if (FindRec.Name = '.') or (FindRec.Name = '..') then
continue;
FilePath := Directory + '\' + FindRec.Name;
if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0 then
begin
FindFileRecursive(FilePath, FileName, Callback);
end else if CompareText(FindRec.Name, FileName) = 0 then
begin
Callback(FilePath);
end;
until not FindNext(FindRec);
finally
FindClose(FindRec);
end;
end;
end;
{ ------------------------------ Version related functions ------------------------------ }
function VersionExtractMajorMinor(Version: String; var Major: Integer; var Minor: Integer): Boolean;
var
Delim: Integer;
MajorStr, MinorStr: String;
OrigVersion, ExpectedPrefix: String;
begin
Result := False;
OrigVersion := Version;
Delim := Pos('.', Version);
if Delim = 0 then exit;
MajorStr := Version;
Delete(MajorStr, Delim, Length(MajorStr));
Delete(Version, 1, Delim);
Major := StrToInt(MajorStr);
Delim := Pos('.', Version);
if Delim = 0 then Delim := Length(MinorStr);
MinorStr := Version;
Delete(MinorStr, Delim, Length(MinorStr));
Delete(Version, 1, Delim);
Minor := StrToInt(MinorStr);
{ Sanity check }
ExpectedPrefix := IntToStr(Major) + '.' + IntToStr(Minor);
if Pos(ExpectedPrefix, OrigVersion) <> 1 then
begin
Log('VersionExtractMajorMinor: version=' + OrigVersion + ', expected=' + ExpectedPrefix);
exit;
end;
Result := True;
end;