tools: support for embedded python

This commit is contained in:
Juraj Michálek
2020-12-16 17:40:13 +01:00
parent c535d569aa
commit 1427b3a6d8
29 changed files with 556 additions and 161 deletions

View File

@ -62,4 +62,14 @@ On Linux and macOS, it is recommended to install ninja using the OS-specific pac
.. tool-dfu-util-notes .. tool-dfu-util-notes
---
.. tool-idf-python-notes
---
.. tool-idf-python-wheels-notes
--- ---

View File

@ -0,0 +1,49 @@
IDF Windows Installer
=====================
Command-line parameters
-----------------------
Windows Installer `esp-idf-tools-setup` provides the following command-line parameters:
* ``/GITRECURSIVE=[yes|no]`` - Clone recursively all git repository submodules. Default: yes``
* ``/GITREPO=[URL|PATH]`` - URL of repository to clone ESP-IDF. Default: https://github.com/espressif/esp-idf.git
* ``/GITRESET=[yes|no]`` - Enable/Disable git reset of repository during installation. Default: yes.
* ``/HELP`` - Display command line options provided by Inno Setup installer.
* ``/IDFDIR=[PATH]`` - Path to directory where it will be installed. Default: ``{userdesktop}\esp-idf}``
* ``/IDFVERSION=[v4.3|v4.1|master]`` - Use specific IDF version. E.g. v4.1, v4.2, master. Default: empty, pick the first version in the list.
* ``/IDFVERSIONSURL=[URL]`` - Use URL to download list of IDF versions. Default: https://dl.espressif.com/dl/esp-idf/idf_versions.txt
* ``/LOG=[PATH]`` - Store installation log file in specific directory. Default: empty.
* ``/OFFLINE=[yes|no]`` - Execute installation of Python packages by PIP in offline mode. The same result can be achieved by setting the environment variable PIP_NO_INDEX. Default: no.
* ``/USEEMBEDDEDPYTHON=[yes|no]`` - Use Embedded Python version for the installation. Set to ``no`` to allow Python selection screen in the installer. Default: yes.
* ``/PYTHONWHEELSURL=[URL]`` - Specify URLs to PyPi repositories for resolving binary Python Wheel dependencies. The same result can be achieved by setting the environment variable PIP_EXTRA_INDEX_URL. Default: https://dl.espressif.com/pypi
* ``/SKIPSYSTEMCHECK=[yes|no]`` - Skip System Check page. Default: no.
* ``/VERYSILENT /SUPPRESSMSGBOXES /SP- /NOCANCEL`` - Perform silent installation.
Unattended installation
-----------------------
The unattended installation of IDF can be achieved by following command-line parameters:
.. code-block:: batch
esp-idf-tools-setup-x.x.exe /VERYSILENT /SUPPRESSMSGBOXES /SP- /NOCANCEL
The installer detaches its process from the command-line. Waiting for installation to finish could be achieved by following PowerShell script:
.. code-block:: powershell
esp-idf-tools-setup-x.x.exe /VERYSILENT /SUPPRESSMSGBOXES /SP- /NOCANCEL
$InstallerProcess = Get-Process esp-idf-tools-setup
Wait-Process -Id $InstallerProcess.id
Custom Python and custom location of Python wheels
--------------------------------------------------
The IDF installer is using by default embedded Python with reference to Python Wheel mirror.
Following parameters allows to select custom Python and custom location of Python wheels:
.. code-block:: batch
esp-idf-tools-setup-x.x.exe /USEEMBEDDEDPYTHON=no /PYTHONWHEELSURL=https://pypi.org/simple/

View File

@ -7,3 +7,4 @@ Tools
IDF Tools <idf-tools> IDF Tools <idf-tools>
IDF Monitor <idf-monitor> IDF Monitor <idf-monitor>
IDF Docker image <idf-docker-image> IDF Docker image <idf-docker-image>
IDF Windows Installer <idf-windows-installer>

View File

@ -34,7 +34,7 @@ ESP-IDF Tools Installer
The easiest way to install ESP-IDF's prerequisites is to download the ESP-IDF Tools installer from this URL: The easiest way to install ESP-IDF's prerequisites is to download the ESP-IDF Tools installer from this URL:
https://dl.espressif.com/dl/esp-idf-tools-setup-2.3.exe https://dl.espressif.com/dl/esp-idf-tools-setup-2.4.exe
.. IMPORTANT: Next time this link is updated, please go to get-started/index.rst and rewrite the section under "Alternative File Downloads ... Windows". Then delete this comment. .. IMPORTANT: Next time this link is updated, please go to get-started/index.rst and rewrite the section under "Alternative File Downloads ... Windows". Then delete this comment.

View File

@ -64,4 +64,14 @@ On Linux and macOS, it is recommended to install ninja using the OS package mana
.. tool-dfu-util-notes .. tool-dfu-util-notes
---
.. tool-idf-python-notes
---
.. tool-idf-python-wheels-notes
--- ---

View File

@ -0,0 +1 @@
.. include:: ../../../en/api-guides/tools/idf-windows-installer.rst

View File

@ -7,3 +7,4 @@
IDF Tools <idf-tools> IDF Tools <idf-tools>
IDF 监视器 <idf-monitor> IDF 监视器 <idf-monitor>
IDF Docker image <idf-docker-image> IDF Docker image <idf-docker-image>
IDF Windows Installer <idf-windows-installer>

View File

@ -33,7 +33,7 @@ ESP-IDF 工具安装器
安装 ESP-IDF 必备工具最简易的方式是下载 ESP-IDF 工具安装器,地址如下: 安装 ESP-IDF 必备工具最简易的方式是下载 ESP-IDF 工具安装器,地址如下:
https://dl.espressif.com/dl/esp-idf-tools-setup-2.3.exe https://dl.espressif.com/dl/esp-idf-tools-setup-2.4.exe
.. 重要:下次更新此链接时,请重新写文件 get-started/index.rst 中“其它文件下载方式”这一章节,然后将此条注意事项删除。 .. 重要:下次更新此链接时,请重新写文件 get-started/index.rst 中“其它文件下载方式”这一章节,然后将此条注意事项删除。

View File

@ -1310,6 +1310,19 @@ def action_install(args):
tool_obj.install(tool_version) tool_obj.install(tool_version)
def get_wheels_dir():
tools_info = load_tools_info()
wheels_package_name = 'idf-python-wheels'
if wheels_package_name not in tools_info:
return None
wheels_package = tools_info[wheels_package_name]
recommended_version = wheels_package.get_recommended_version()
wheels_dir = wheels_package.get_path_for_version(recommended_version)
if not os.path.exists(wheels_dir):
return None
return wheels_dir
def action_install_python_env(args): def action_install_python_env(args):
idf_python_env_path, _, virtualenv_python = get_python_env_path() idf_python_env_path, _, virtualenv_python = get_python_env_path()
@ -1339,6 +1352,15 @@ def action_install_python_env(args):
run_args += ['-r', requirements_txt] run_args += ['-r', requirements_txt]
if args.extra_wheels_dir: if args.extra_wheels_dir:
run_args += ['--find-links', args.extra_wheels_dir] run_args += ['--find-links', args.extra_wheels_dir]
if args.no_index:
run_args += ['--no-index']
if args.extra_wheels_url:
run_args += ['--extra-index-url', args.extra_wheels_url]
wheels_dir = get_wheels_dir()
if wheels_dir is not None:
run_args += ['--find-links', wheels_dir]
info('Installing Python packages from {}'.format(requirements_txt)) info('Installing Python packages from {}'.format(requirements_txt))
subprocess.check_call(run_args, stdout=sys.stdout, stderr=sys.stderr) subprocess.check_call(run_args, stdout=sys.stdout, stderr=sys.stderr)
@ -1542,6 +1564,8 @@ def main(argv):
action='store_true') action='store_true')
install_python_env.add_argument('--extra-wheels-dir', help='Additional directories with wheels ' + install_python_env.add_argument('--extra-wheels-dir', help='Additional directories with wheels ' +
'to use during installation') 'to use during installation')
install_python_env.add_argument('--extra-wheels-url', help='Additional URL with wheels', default='https://dl.espressif.com/pypi')
install_python_env.add_argument('--no-index', help='Work offline without retrieving wheels index')
if IDF_MAINTAINER: if IDF_MAINTAINER:
add_version = subparsers.add_parser('add-version', help='Add or update download info for a version') add_version = subparsers.add_parser('add-version', help='Add or update download info for a version')

View File

@ -627,6 +627,73 @@
} }
} }
] ]
},
{
"description": "Embeddable Python distribution",
"export_paths": [],
"export_vars": {},
"info_url": "https://github.com/espressif/esp-idf/tree/master/tools/windows/",
"install": "never",
"license": "PSF License",
"name": "idf-python",
"platform_overrides": [
{
"install": "on_request",
"platforms": [
"win64"
]
}
],
"version_cmd": [
"python",
"--version"
],
"version_regex": "Python ([0-9.]+)",
"versions": [
{
"name": "3.9.1",
"status": "recommended",
"win64": {
"sha256": "d5a0e625dd5b2bc6872de90292d71009c17e2396e3d1575d886a94d0dfb00c87",
"size": 20362758,
"url": "https://dl.espressif.com/dl/idf-python/idf-python-3.9.1-embed-win64.zip"
}
}
]
},
{
"description": "Python Wheels distribution bundled for the specific version of IDF and Python",
"export_paths": [],
"export_vars": {},
"info_url": "https://github.com/espressif/esp-idf/tree/master/tools/windows/",
"install": "never",
"license": "Open-source licenses",
"name": "idf-python-wheels",
"platform_overrides": [
{
"install": "always",
"platforms": [
"win64"
]
}
],
"version_cmd": [
"cmd",
"/c",
"echo idf4.3_py3.9_2021-01-07"
],
"version_regex": "(idf4.3_py3.9_2021-01-07)",
"versions": [
{
"name": "idf4.3_py3.9_2021-01-07",
"status": "recommended",
"win64": {
"sha256": "2a33dbaa106aec9c5098b1af46f04c69923be947291c19855ff355b9707314b6",
"size": 8316997,
"url": "https://dl.espressif.com/dl/idf-python-wheels/idf-python-wheels-idf4.3_py3.9_2021-01-07-win64.zip"
}
}
]
} }
], ],
"version": 1 "version": 1

View File

@ -12,9 +12,9 @@ Some functionality of the installer depends on additional programs:
* [7-zip](https://www.7-zip.org) — used to extract downloaded IDF archives. * [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. * [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.
## Instalation of dependencies via Chocolatey ## Installation of dependencies via Chocolatey
Run with Administrator privileges: Run with Administrator privileges:
@ -22,7 +22,7 @@ Run with Administrator privileges:
choco install inno-download-plugin choco install inno-download-plugin
``` ```
## Building the installer ## Building the installer
### In Docker ### In Docker
@ -60,3 +60,47 @@ docker run --rm -v $IDF_PATH:/idf -w /idf/tools/windows/tool_setup -it $CI_DOCKE
- `export CERTCHAIN=certchain.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. * 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.
## Development and 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 perform full silent installation and executes build of get-started example.
Commands for testing multiple versions:
```
$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
```
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.

View File

@ -0,0 +1,15 @@
param (
[string]$Installer="C:\Output\esp-idf-tools-setup-unsigned.exe",
[string]$IdfPath = "C:\Users\ContainerAdministrator\Desktop\esp-idf",
[string]$IdfVersion = "v4.1"
)
$Installer
$IdfPath
$IdfVersion
mkdir C:\Temp
C:\Output\esp-idf-tools-setup-unsigned.exe /VERYSILENT /LOG=C:\Temp\install.txt /SUPPRESSMSGBOXES /SP- /NOCANCEL /NORESTART /IDFVERSION=${IdfVersion}
$InstallerProcess = Get-Process esp-idf-tools-setup-unsigned
Wait-Process -Id $InstallerProcess.id
Get-Content C:\Temp\install.txt

View File

@ -0,0 +1,8 @@
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

@ -0,0 +1,28 @@
param (
[string]$PythonPath = "C:\Python38\",
[string]$IdfPath = "C:\Users\ContainerAdministrator\Desktop\esp-idf"
)
$env:PATH+=";${PythonPath}"
Set-Location "${IdfPath}"
#.\export.ps1
$env:PYTHONPATH="C:\Users\ContainerAdministrator\Desktop\esp-idf\tools\"
# Append build script and launch via link
#Add-Content -Path ${IdfPath}\export.bat -Value ${BuildCommands}
# 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
#powershell.exe
#C:\Windows\system32\cmd.exe /c '"C:\Users\ContainerAdministrator\.espressif\idf_cmd_init.bat" "C:\Users\ContainerAdministrator\.espressif\python_env\idf4.1_py3.7_env\Scripts" "C:\Program Files\Git\cmd\" && cd examples\get-started\blink\ && idf.py build'
#cmd /c "ping -n 4 127.0.0.1 && .\export.bat && cd examples\get-started\blink\ && idf.py build"
#cmd /c "ping -n 4 127.0.0.1 && .\export.bat && cd examples\get-started\blink\ && idf.py build"
#cmd /c "timeout 4 && C:\Users\ContainerAdministrator\.espressif\idf_cmd_init.bat 'C:\' && cd examples\get-started\blink\ && idf.py build"
#& "C:\Users\ContainerAdministrator\Desktop\esp-idf\Run ESP-IDF Command Prompt (cmd.exe).lnk"

View File

@ -10,6 +10,19 @@
set -e set -e
set -u set -u
INSTALLER_TYPE="$1"
if [[ -z "$INSTALLER_TYPE" ]]; then
INSTALLER_TYPE="full"
fi
echo "Selected installer type: $INSTALLER_TYPE"
echo "Available installer types: full, netinst"
PACKAGES="all"
if [[ "$INSTALLER_TYPE" == "netinst" ]]; then
PACKAGES="idf-python"
fi
iscc_path=$(which iscc) iscc_path=$(which iscc)
if [[ -z "$iscc_path" ]]; then if [[ -z "$iscc_path" ]]; then
echo "Inno setup compiler (iscc) not found. Are you running wine-innosetup Docker image?" echo "Inno setup compiler (iscc) not found. Are you running wine-innosetup Docker image?"
@ -24,7 +37,7 @@ fi
echo "Downloading IDF Tools..." echo "Downloading IDF Tools..."
mkdir -p idf_tools_tmp mkdir -p idf_tools_tmp
export IDF_TOOLS_PATH=$PWD/idf_tools_tmp export IDF_TOOLS_PATH=$PWD/idf_tools_tmp
$IDF_PATH/tools/idf_tools.py --non-interactive download --platform Windows-x86_64 all $IDF_PATH/tools/idf_tools.py --non-interactive download --platform Windows-x86_64 $PACKAGES
$IDF_PATH/tools/idf_tools.py --tools-json tools_fallback.json --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
mkdir -p dist mkdir -p dist
cp idf_tools_tmp/dist/* dist/ cp idf_tools_tmp/dist/* dist/
@ -40,4 +53,5 @@ echo "Downloading idf_versions.txt..."
wget --no-verbose -O idf_versions.txt https://dl.espressif.com/dl/esp-idf/idf_versions.txt wget --no-verbose -O idf_versions.txt https://dl.espressif.com/dl/esp-idf/idf_versions.txt
echo "Running ISCC..." echo "Running ISCC..."
iscc idf_tool_setup.iss # https://jrsoftware.org/ishelp/index.php?topic=compilercmdline
iscc /F "esp-idf-tools-setup-$INSTALLER_TYPE-unsigned" idf_tool_setup.iss

View File

@ -1,4 +1,4 @@
{ Copyright 2019-2020 Espressif Systems (Shanghai) CO LTD { Copyright 2019-2021 Espressif Systems (Shanghai) CO LTD
SPDX-License-Identifier: Apache-2.0 } SPDX-License-Identifier: Apache-2.0 }
var var

View File

@ -1,4 +1,4 @@
{ Copyright 2019-2020 Espressif Systems (Shanghai) CO LTD { Copyright 2019-2021 Espressif Systems (Shanghai) CO LTD
SPDX-License-Identifier: Apache-2.0 } SPDX-License-Identifier: Apache-2.0 }
{ ------------------------------ Progress & log page for command line tools ------------------------------ } { ------------------------------ Progress & log page for command line tools ------------------------------ }

View File

@ -0,0 +1,24 @@
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-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-unsigned.exe' -IdfVersion ${IDF_VERSION}; C:/Scripts/Test-Idf.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,4 +1,4 @@
{ Copyright 2019-2020 Espressif Systems (Shanghai) CO LTD { Copyright 2019-2021 Espressif Systems (Shanghai) CO LTD
SPDX-License-Identifier: Apache-2.0 } SPDX-License-Identifier: Apache-2.0 }
{ ------------------------------ Find installed copies of Git ------------------------------ } { ------------------------------ Find installed copies of Git ------------------------------ }

View File

@ -1,4 +1,4 @@
{ Copyright 2019-2020 Espressif Systems (Shanghai) CO LTD { Copyright 2019-2021 Espressif Systems (Shanghai) CO LTD
SPDX-License-Identifier: Apache-2.0 } SPDX-License-Identifier: Apache-2.0 }
{ ------------------------------ Page to select Git ------------------------------ } { ------------------------------ Page to select Git ------------------------------ }

View File

@ -1,4 +1,4 @@
{ Copyright 2019-2020 Espressif Systems (Shanghai) CO LTD { Copyright 2019-2021 Espressif Systems (Shanghai) CO LTD
SPDX-License-Identifier: Apache-2.0 } SPDX-License-Identifier: Apache-2.0 }
{ ------------------------------ Page to select the version of ESP-IDF to download ------------------------------ } { ------------------------------ Page to select the version of ESP-IDF to download ------------------------------ }
@ -46,7 +46,7 @@ var
Url: String; Url: String;
VersionFile: String; VersionFile: String;
begin begin
Url := '{#IDFVersionsURL}'; Url := ExpandConstant('{param:IDFVERSIONSURL|https://dl.espressif.com/dl/esp-idf/idf_versions.txt}')
VersionFile := ExpandConstant('{tmp}\idf_versions.txt'); VersionFile := ExpandConstant('{tmp}\idf_versions.txt');
if idpDownloadFile(Url, VersionFile) then if idpDownloadFile(Url, VersionFile) then
begin begin
@ -62,6 +62,7 @@ var
Page: TInputOptionWizardPage; Page: TInputOptionWizardPage;
VersionFile: String; VersionFile: String;
i: Integer; i: Integer;
SuggestedIDFDirectory: String;
begin begin
Page := TInputOptionWizardPage(Sender); Page := TInputOptionWizardPage(Sender);
Log('OnIDFDownloadPagePrepare'); Log('OnIDFDownloadPagePrepare');
@ -86,7 +87,26 @@ begin
end; end;
Page.SelectedValueIndex := 0; Page.SelectedValueIndex := 0;
ChoicePageSetInputText(Page, GetSuggestedIDFDirectory()); SuggestedIDFDirectory := ExpandConstant('{param:IDFDIR|' + GetSuggestedIDFDirectory() + '}');
ChoicePageSetInputText(Page, SuggestedIDFDirectory);
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; end;
procedure OnIDFDownloadSelectionChange(Sender: TObject); procedure OnIDFDownloadSelectionChange(Sender: TObject);
@ -122,7 +142,24 @@ begin
end; end;
IDFDownloadPath := IDFPath; IDFDownloadPath := IDFPath;
IDFDownloadVersion := IDFDownloadAvailableVersions[Page.SelectedValueIndex];
{ Use parameter /IDFVE=x to override selection in the box. }
IDFDownloadVersion := ExpandConstant('{param: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.1') 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; Result := True;
end; end;

View File

@ -1,4 +1,4 @@
{ Copyright 2019-2020 Espressif Systems (Shanghai) CO LTD { Copyright 2019-2021 Espressif Systems (Shanghai) CO LTD
SPDX-License-Identifier: Apache-2.0 } SPDX-License-Identifier: Apache-2.0 }
{ ------------------------------ Page to select whether to download ESP-IDF, or use an existing copy ------------------------------ } { ------------------------------ Page to select whether to download ESP-IDF, or use an existing copy ------------------------------ }

View File

@ -1,4 +1,4 @@
{ Copyright 2019-2020 Espressif Systems (Shanghai) CO LTD { Copyright 2019-2021 Espressif Systems (Shanghai) CO LTD
SPDX-License-Identifier: Apache-2.0 } SPDX-License-Identifier: Apache-2.0 }
{ ------------------------------ Downloading ESP-IDF ------------------------------ } { ------------------------------ Downloading ESP-IDF ------------------------------ }
@ -140,7 +140,9 @@ var
IDFTempPath: String; IDFTempPath: String;
IDFPath: String; IDFPath: String;
NeedToClone: Boolean; NeedToClone: Boolean;
GitRepoParam: String;
GitResetParam: String;
GitRecursiveParam: String;
begin begin
IDFPath := IDFDownloadPath; IDFPath := IDFDownloadPath;
{ If there is a release archive to download, IDFZIPFileName and IDFZIPFileVersion will be set. { If there is a release archive to download, IDFZIPFileName and IDFZIPFileVersion will be set.
@ -158,7 +160,6 @@ begin
NeedToClone := True; NeedToClone := True;
end; end;
ExtractTemporaryFile('7za.exe')
CmdLine := ExpandConstant('{tmp}\7za.exe x -o' + ExpandConstant('{tmp}') + ' -r -aoa "' + IDFZIPFileName + '"'); CmdLine := ExpandConstant('{tmp}\7za.exe x -o' + ExpandConstant('{tmp}') + ' -r -aoa "' + IDFZIPFileName + '"');
IDFTempPath := ExpandConstant('{tmp}\esp-idf-') + IDFZIPFileVersion; IDFTempPath := ExpandConstant('{tmp}\esp-idf-') + IDFZIPFileVersion;
Log('Extracting ESP-IDF reference repository: ' + CmdLine); Log('Extracting ESP-IDF reference repository: ' + CmdLine);
@ -172,12 +173,19 @@ begin
if NeedToClone then if NeedToClone then
begin begin
CmdLine := GitExecutablePath + ' clone --recursive --progress -b ' + IDFDownloadVersion; CmdLine := GitExecutablePath + ' clone --progress -b ' + IDFDownloadVersion;
GitRecursiveParam := ExpandConstant('{param:GITRECURSIVE|yes}');
if (GitRecursiveParam = 'yes') then begin
CmdLine := CmdLine + ' --recursive ';
end;
if IDFTempPath <> '' then if IDFTempPath <> '' then
CmdLine := CmdLine + ' --reference ' + IDFTempPath; CmdLine := CmdLine + ' --reference ' + IDFTempPath;
CmdLine := CmdLine + ' https://github.com/espressif/esp-idf.git ' + IDFPath; GitRepoParam := ExpandConstant('{param:GITREPO|https://github.com/espressif/esp-idf.git}');
CmdLine := CmdLine + ' ' + GitRepoParam +' ' + IDFPath;
Log('Cloning IDF: ' + CmdLine); Log('Cloning IDF: ' + CmdLine);
DoCmdlineInstall('Downloading ESP-IDF', 'Using git to clone ESP-IDF repository', CmdLine); DoCmdlineInstall('Downloading ESP-IDF', 'Using git to clone ESP-IDF repository', CmdLine);
@ -202,7 +210,14 @@ begin
CmdLine := ExpandConstant('cmd.exe /c ""xcopy" /s /e /i /h /q "' + IDFTempPath + '" "' + IDFPath + '""'); 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); DoCmdlineInstall('Extracting ESP-IDF', 'Copying ESP-IDF into the destination directory', CmdLine);
GitRepoFixFileMode(IDFPath); GitRepoFixFileMode(IDFPath);
GitRepoFixNewlines(IDFPath);
GitResetParam := ExpandConstant('{param:GITRESET|yes}');
if (GitResetParam = 'yes') then begin
GitRepoFixNewlines(IDFPath);
end else begin
Log('Git reset disabled by command line option /GITRESET=yes.');
end;
DelTree(IDFTempPath, True, True, True); DelTree(IDFTempPath, True, True, True);
end; end;
end; end;
@ -222,51 +237,6 @@ begin
end; end;
end; end;
procedure IDFToolsSetup();
var
CmdLine: String;
IDFPath: String;
IDFToolsPyPath: String;
IDFToolsPyCmd: String;
BundledIDFToolsPyPath: String;
JSONArg: 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')
Log('idf_tools.py command: ' + IDFToolsPyCmd);
CmdLine := IDFToolsPyCmd + ' install';
Log('Installing tools:' + CmdLine);
DoCmdlineInstall('Installing ESP-IDF tools', '', CmdLine);
CmdLine := IDFToolsPyCmd + ' install-python-env';
Log('Installing Python environment:' + CmdLine);
DoCmdlineInstall('Installing Python environment', '', CmdLine);
end;
{ Find Major and Minor version in esp_idf_version.h file. } { Find Major and Minor version in esp_idf_version.h file. }
function GetIDFVersionFromHeaderFile():String; function GetIDFVersionFromHeaderFile():String;
var var
@ -300,17 +270,119 @@ begin
end; 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;
procedure IDFToolsSetup();
var
CmdLine: String;
IDFPath: String;
IDFToolsPyPath: String;
IDFToolsPyCmd: String;
BundledIDFToolsPyPath: String;
JSONArg: String;
OfflineParameter: String;
PythonWheelsUrlParameter: 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');
OfflineParameter := ExpandConstant('{param:OFFLINE|no}');
if (OfflineParameter = 'yes') then begin
SetEnvironmentVariable('PIP_NO_INDEX', 'true');
Log('Offline installation selected. Setting environment variable PIP_NO_INDEX=1');
end else begin
PythonWheelsUrlParameter := ExpandConstant('{param:PYTHONWHEELSURL|https://dl.espressif.com/pypi}');
SetEnvironmentVariable('PIP_EXTRA_INDEX_URL', PythonWheelsUrlParameter);
Log('Adding extra Python wheels location. Setting environment variable PIP_EXTRA_INDEX_URL=' + PythonWheelsUrlParameter);
end;
Log('idf_tools.py command: ' + IDFToolsPyCmd);
CmdLine := IDFToolsPyCmd + ' install';
Log('Installing tools:' + CmdLine);
DoCmdlineInstall('Installing ESP-IDF tools', '', CmdLine);
CmdLine := IDFToolsPyCmd + ' install-python-env';
Log('Installing Python environment:' + CmdLine);
DoCmdlineInstall('Installing Python environment', '', CmdLine);
end;
{ ------------------------------ Start menu shortcut ------------------------------ } { ------------------------------ Start menu shortcut ------------------------------ }
procedure CreateIDFCommandPromptShortcut(LnkString: String); procedure CreateIDFCommandPromptShortcut(LnkString: String);
var var
Destination: String; Destination: String;
Description: String; Description: String;
VersionIndex: Integer;
MajorString: String;
MinorString: String;
DotIndex: Integer;
IDFVersionString: String;
PythonVirtualEnvPath: String; PythonVirtualEnvPath: String;
Command: String; Command: String;
begin begin
@ -318,39 +390,14 @@ begin
Destination := ExpandConstant(LnkString + '\{#IDFCmdExeShortcutFile}'); Destination := ExpandConstant(LnkString + '\{#IDFCmdExeShortcutFile}');
Description := '{#IDFCmdExeShortcutDescription}'; Description := '{#IDFCmdExeShortcutDescription}';
IDFVersionString := IDFDownloadVersion;
{ Transform version vx.y or release/vx.y to x.y }
VersionIndex := pos('v', IDFVersionString);
if (VersionIndex > 0) then begin
Delete(IDFVersionString, 1, VersionIndex);
end;
{ Transform version x.y.z to x.y }
DotIndex := pos('.', IDFVersionString);
if (DotIndex > 0) then begin
MajorString := Copy(IDFVersionString, 1, DotIndex - 1);
Delete(IDFVersionString, 1, DotIndex);
{ Trim trailing version numbers. }
DotIndex := pos('.', IDFVersionString);
if (DotIndex > 0) then begin
MinorString := Copy(IDFVersionString, 1, DotIndex - 1);
IDFVersionString := MajorString + '.' + MinorString;
end else begin
IDFVersionString := MajorString + '.' + IDFVersionString;
end;
end;
{ Transform master to x.y }
if (IDFVersionString = 'master') then begin
IDFVersionString := GetIDFVersionFromHeaderFile();
end;
{ The links should contain reference to Python vitual env } { The links should contain reference to Python vitual env }
PythonVirtualEnvPath := ExpandConstant('{app}\python_env\idf') + IDFVersionString + '_py' + PythonVersion + '_env\Scripts'; PythonVirtualEnvPath := ExpandConstant('{app}\python_env\') + GetIDFPythonEnvironmentVersion() + '_env\Scripts';
Log('Path to Python in virtual env: ' + PythonVirtualEnvPath);
{ Fallback in case of not existing environment. } { Fallback in case of not existing environment. }
if (not FileExists(PythonVirtualEnvPath + '\python.exe')) then begin if (not FileExists(PythonVirtualEnvPath + '\python.exe')) then begin
PythonVirtualEnvPath := PythonPath; PythonVirtualEnvPath := PythonPath;
Log('python.exe not found, reverting to:' + PythonPath);
end; end;
{ If cmd.exe command argument starts with a quote, the first and last quote chars in the command { If cmd.exe command argument starts with a quote, the first and last quote chars in the command

View File

@ -1,24 +1,22 @@
; Copyright 2019-2020 Espressif Systems (Shanghai) CO LTD ; Copyright 2019-2021 Espressif Systems (Shanghai) CO LTD
; SPDX-License-Identifier: Apache-2.0 ; SPDX-License-Identifier: Apache-2.0
#pragma include __INCLUDE__ + ";" + ReadReg(HKLM, "Software\Mitrich Software\Inno Download Plugin", "InstallDir") #pragma include __INCLUDE__ + ";" + ReadReg(HKLM, "Software\Mitrich Software\Inno Download Plugin", "InstallDir")
#include <idp.iss> #include <idp.iss>
#define MyAppName "ESP-IDF Tools" #define MyAppName "ESP-IDF Tools"
#define MyAppVersion "2.3" #define MyAppVersion "2.4"
#define MyAppPublisher "Espressif Systems (Shanghai) Co. Ltd." #define MyAppPublisher "Espressif Systems (Shanghai) Co. Ltd."
#define MyAppURL "https://github.com/espressif/esp-idf" #define MyAppURL "https://github.com/espressif/esp-idf"
#define PythonVersion "3.7" #define PythonVersion "3.9.1"
#define PythonInstallerName "python-3.7.3-amd64.exe" #define PythonInstallerName "idf-python-3.9.1-embed-win64.zip"
#define PythonInstallerDownloadURL "https://www.python.org/ftp/python/3.7.3/python-3.7.3-amd64.exe" #define PythonInstallerDownloadURL "https://dl.espressif.com/dl/idf-python/idf-python-3.9.1-embed-win64.zip"
#define GitVersion "2.21.0" #define GitVersion "2.21.0"
#define GitInstallerName "Git-2.21.0-64-bit.exe" #define GitInstallerName "Git-2.21.0-64-bit.exe"
#define GitInstallerDownloadURL "https://github.com/git-for-windows/git/releases/download/v2.21.0.windows.1/Git-2.21.0-64-bit.exe" #define GitInstallerDownloadURL "https://github.com/git-for-windows/git/releases/download/v2.21.0.windows.1/Git-2.21.0-64-bit.exe"
#define IDFVersionsURL "https://dl.espressif.com/dl/esp-idf/idf_versions.txt"
#define IDFCmdExeShortcutDescription "Open ESP-IDF Command Prompt (cmd.exe)" #define IDFCmdExeShortcutDescription "Open ESP-IDF Command Prompt (cmd.exe)"
#define IDFCmdExeShortcutFile "ESP-IDF Command Prompt (cmd.exe).lnk" #define IDFCmdExeShortcutFile "ESP-IDF Command Prompt (cmd.exe).lnk"
@ -90,7 +88,6 @@ Name: wdexcl; Description: "Register the ESP-IDF Tools executables as Windows De
Name: idf_tools_use_mirror; Description: "Use Espressif download server instead of downloading tool packages from Github"; Flags: unchecked; Name: idf_tools_use_mirror; Description: "Use Espressif download server instead of downloading tool packages from Github"; Flags: unchecked;
[Run] [Run]
Filename: "{app}\dist\{#PythonInstallerName}"; Parameters: "/passive PrependPath=1 InstallLauncherAllUsers=0 Include_dev=0 Include_tcltk=0 Include_launcher=0 Include_test=0 Include_doc=0"; Description: "Installing Python"; Check: PythonInstallRequired
Filename: "{app}\dist\{#GitInstallerName}"; Parameters: "/silent /tasks="""" /norestart"; Description: "Installing Git"; Check: GitInstallRequired Filename: "{app}\dist\{#GitInstallerName}"; Parameters: "/silent /tasks="""" /norestart"; Description: "Installing Git"; Check: GitInstallRequired
Filename: "{group}\{#IDFCmdExeShortcutFile}"; Flags: postinstall shellexec; Description: "Run ESP-IDF Command Prompt (cmd.exe)"; Check: InstallationSuccessful Filename: "{group}\{#IDFCmdExeShortcutFile}"; Flags: postinstall shellexec; Description: "Run ESP-IDF Command Prompt (cmd.exe)"; Check: InstallationSuccessful

View File

@ -1,4 +1,4 @@
{ Copyright 2019-2020 Espressif Systems (Shanghai) CO LTD { Copyright 2019-2021 Espressif Systems (Shanghai) CO LTD
SPDX-License-Identifier: Apache-2.0 } SPDX-License-Identifier: Apache-2.0 }
{ ------------------------------ Custom steps before the main installation flow ------------------------------ } { ------------------------------ Custom steps before the main installation flow ------------------------------ }
@ -45,17 +45,6 @@ begin
ForceDirectories(ExpandConstant('{app}\dist')); ForceDirectories(ExpandConstant('{app}\dist'));
if not PythonUseExisting then
begin
DestPath := ExpandConstant('{app}\dist\{#PythonInstallerName}');
if FileExists(DestPath) then
begin
Log('Python installer already downloaded: ' + DestPath);
end else begin
idpAddFile('{#PythonInstallerDownloadURL}', DestPath);
end;
end;
if not GitUseExisting then if not GitUseExisting then
begin begin
DestPath := ExpandConstant('{app}\dist\{#GitInstallerName}'); DestPath := ExpandConstant('{app}\dist\{#GitInstallerName}');
@ -82,9 +71,6 @@ var
begin begin
EnvPath := GetEnv('PATH'); EnvPath := GetEnv('PATH');
if not PythonUseExisting then
PythonExecutablePathUpdateAfterInstall();
if not GitUseExisting then if not GitUseExisting then
GitExecutablePathUpdateAfterInstall(); GitExecutablePathUpdateAfterInstall();
@ -103,6 +89,26 @@ begin
SetEnvironmentVariable('PYTHONPATH', '') SetEnvironmentVariable('PYTHONPATH', '')
end; 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
Exit;
end;
CmdLine := ExpandConstant('{tmp}\7za.exe x -o{app}\tools\python\' + PythonVersion + '\ -r -aoa "{app}\dist\idf-python-' + PythonVersion + '-embed-win64.zip"');
DoCmdlineInstall('Extracting Python Interpreter', 'Using Embedded Python', CmdLine);
end;
<event('CurStepChanged')> <event('CurStepChanged')>
procedure PostInstallSteps(CurStep: TSetupStep); procedure PostInstallSteps(CurStep: TSetupStep);
var var
@ -111,6 +117,9 @@ begin
if CurStep <> ssPostInstall then if CurStep <> ssPostInstall then
exit; exit;
ExtractTemporaryFile('7za.exe')
InstallEmbeddedPython();
try try
AddPythonGitToPath(); AddPythonGitToPath();

View File

@ -1,4 +1,4 @@
{ Copyright 2019-2020 Espressif Systems (Shanghai) CO LTD { Copyright 2019-2021 Espressif Systems (Shanghai) CO LTD
SPDX-License-Identifier: Apache-2.0 } SPDX-License-Identifier: Apache-2.0 }
{ ------------------------------ Find installed Python interpreters in Windows Registry (see PEP 514) ------------------------------ } { ------------------------------ Find installed Python interpreters in Windows Registry (see PEP 514) ------------------------------ }

View File

@ -1,4 +1,4 @@
{ Copyright 2019-2020 Espressif Systems (Shanghai) CO LTD { Copyright 2019-2021 Espressif Systems (Shanghai) CO LTD
SPDX-License-Identifier: Apache-2.0 } SPDX-License-Identifier: Apache-2.0 }
{ ------------------------------ Page to select Python interpreter ------------------------------ } { ------------------------------ Page to select Python interpreter ------------------------------ }
@ -8,7 +8,6 @@
var var
PythonPage: TInputOptionWizardPage; PythonPage: TInputOptionWizardPage;
PythonVersion, PythonPath, PythonExecutablePath: String; PythonVersion, PythonPath, PythonExecutablePath: String;
PythonUseExisting: Boolean;
function GetPythonPath(Unused: String): String; function GetPythonPath(Unused: String): String;
@ -16,11 +15,6 @@ begin
Result := PythonPath; Result := PythonPath;
end; end;
function PythonInstallRequired(): Boolean;
begin
Result := not PythonUseExisting;
end;
function PythonVersionSupported(Version: String): Boolean; function PythonVersionSupported(Version: String): Boolean;
var var
Major, Minor: Integer; Major, Minor: Integer;
@ -93,40 +87,26 @@ begin
Log('OnPythonSelectionChange index=' + IntToStr(Page.SelectedValueIndex)); Log('OnPythonSelectionChange index=' + IntToStr(Page.SelectedValueIndex));
end; 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; function OnPythonPageValidate(Sender: TWizardPage): Boolean;
var var
Page: TInputOptionWizardPage; Page: TInputOptionWizardPage;
begin begin
Page := TInputOptionWizardPage(Sender); Page := TInputOptionWizardPage(Sender);
Log('OnPythonPageValidate index=' + IntToStr(Page.SelectedValueIndex)); ApplyPythonConfigurationByIndex(Page.SelectedValueIndex);
if Page.SelectedValueIndex < InstalledPythonExecutables.Count then
begin
PythonUseExisting := True;
PythonExecutablePath := InstalledPythonExecutables[Page.SelectedValueIndex];
PythonPath := ExtractFilePath(PythonExecutablePath);
PythonVersion := InstalledPythonVersions[Page.SelectedValueIndex];
end else begin
PythonUseExisting := False;
PythonExecutablePath := '';
PythonPath := '';
PythonVersion := '{#PythonVersion}';
end;
Log('OnPythonPageValidate: PythonPath='+PythonPath+' PythonExecutablePath='+PythonExecutablePath);
Result := True; Result := True;
end; end;
procedure PythonExecutablePathUpdateAfterInstall(); procedure UpdatePythonVariables(ExecutablePath: String);
var
Version, DisplayName, ExecutablePath, BaseDir: String;
begin begin
if not GetPythonVersionInfoFromKey(
HKEY_CURRENT_USER, 'Software\Python', 'PythonCore', '{#PythonVersion}',
Version, DisplayName, ExecutablePath, BaseDir) then
begin
Log('Failed to find ExecutablePath for the installed copy of Python');
exit;
end;
Log('Found ExecutablePath for ' + DisplayName + ': ' + ExecutablePath);
PythonExecutablePath := ExecutablePath; PythonExecutablePath := ExecutablePath;
PythonPath := ExtractFilePath(PythonExecutablePath); PythonPath := ExtractFilePath(PythonExecutablePath);
Log('PythonExecutablePathUpdateAfterInstall: PythonPath='+PythonPath+' PythonExecutablePath='+PythonExecutablePath); Log('PythonExecutablePathUpdateAfterInstall: PythonPath='+PythonPath+' PythonExecutablePath='+PythonExecutablePath);
@ -145,3 +125,18 @@ begin
@OnPythonSelectionChange, @OnPythonSelectionChange,
@OnPythonPageValidate); @OnPythonPageValidate);
end; end;
<event('ShouldSkipPage')>
function ShouldSkipPythonPage(PageID: Integer): Boolean;
var
UseEmbeddedPythonParam: String;
begin
if (PageID = PythonPage.ID) then begin
{ Skip in case of embedded Python. }
UseEmbeddedPythonParam := ExpandConstant('{param:USEEMBEDDEDPYTHON|yes}');
if (UseEmbeddedPythonParam = 'yes') then begin
ApplyPythonConfigurationByIndex(0);
Result := True;
end;
end;
end;

View File

@ -1,4 +1,4 @@
{ Copyright 2019-2020 Espressif Systems (Shanghai) CO LTD { Copyright 2019-2021 Espressif Systems (Shanghai) CO LTD
SPDX-License-Identifier: Apache-2.0 } SPDX-License-Identifier: Apache-2.0 }
{ ------------------------------ Installation summary page ------------------------------ } { ------------------------------ Installation summary page ------------------------------ }
@ -8,12 +8,12 @@ function UpdateReadyMemo(Space, NewLine, MemoUserInfoInfo, MemoDirInfo,
begin begin
Result := '' Result := ''
if PythonUseExisting then if (FileExists(PythonExecutablePath)) then
begin begin
Result := Result + 'Using Python ' + PythonVersion + ':' + NewLine Result := Result + 'Using Python ' + PythonVersion + ':' + NewLine
+ Space + PythonExecutablePath + NewLine + NewLine; + Space + PythonExecutablePath + NewLine + NewLine;
end else begin end else begin
Result := Result + 'Will download and install Python ' + PythonVersion + NewLine + NewLine; Result := Result + 'Using embedded Python ' + PythonVersion + NewLine + NewLine;
end; end;
if GitUseExisting then if GitUseExisting then

View File

@ -1,4 +1,4 @@
{ Copyright 2019-2020 Espressif Systems (Shanghai) CO LTD { Copyright 2019-2021 Espressif Systems (Shanghai) CO LTD
SPDX-License-Identifier: Apache-2.0 } SPDX-License-Identifier: Apache-2.0 }
{ SystemCheck states } { SystemCheck states }
@ -474,6 +474,8 @@ end;
{ Execute system check } { Execute system check }
procedure ExecuteSystemCheck(); procedure ExecuteSystemCheck();
var
UseEmbeddedPythonParam: String;
begin begin
{ Execute system check only once. Avoid execution in case of back button. } { Execute system check only once. Avoid execution in case of back button. }
if (SystemCheckState <> SYSTEM_CHECK_STATE_INIT) then begin if (SystemCheckState <> SYSTEM_CHECK_STATE_INIT) then begin
@ -486,7 +488,11 @@ begin
VerifyRootCertificates(); VerifyRootCertificates();
FindInstalledPythonVersions(); { Search for the installed Python version only on explicit user request. }
UseEmbeddedPythonParam := ExpandConstant('{param:USEEMBEDDEDPYTHON|yes}');
if (UseEmbeddedPythonParam <> 'yes') then begin
FindInstalledPythonVersions();
end;
if (SystemCheckState <> SYSTEM_CHECK_STATE_STOPPED) then begin if (SystemCheckState <> SYSTEM_CHECK_STATE_STOPPED) then begin
SystemLogTitle(CustomMessage('SystemCheckForDefender') + ' '); SystemLogTitle(CustomMessage('SystemCheckForDefender') + ' ');
@ -519,6 +525,7 @@ end;
{ Invoke scan of system environment. } { Invoke scan of system environment. }
procedure OnSystemCheckActivate(Sender: TWizardPage); procedure OnSystemCheckActivate(Sender: TWizardPage);
var SystemCheckParam:String;
begin begin
{ Display special controls. For some reason the first call of the page does not invoke SystemCheckOnCurPageChanged. } { Display special controls. For some reason the first call of the page does not invoke SystemCheckOnCurPageChanged. }
FullLogButton.Visible := True; FullLogButton.Visible := True;
@ -526,6 +533,12 @@ begin
StopSystemCheckButton.Visible := True; StopSystemCheckButton.Visible := True;
SystemCheckViewer.Visible := True; SystemCheckViewer.Visible := True;
SystemCheckParam := ExpandConstant('{param:SKIPSYSTEMCHECK|no}');
if (SystemCheckParam = 'yes') then begin
SystemCheckState := SYSTEM_CHECK_STATE_STOPPED;
SystemLog('System Check disabled by command line option /SKIPSYSTEMCHECK.');
end;
ExecuteSystemCheck(); ExecuteSystemCheck();
end; end;
@ -585,6 +598,7 @@ begin
InstalledPythonVersions := TStringList.Create(); InstalledPythonVersions := TStringList.Create();
InstalledPythonDisplayNames := TStringList.Create(); InstalledPythonDisplayNames := TStringList.Create();
InstalledPythonExecutables := TStringList.Create(); InstalledPythonExecutables := TStringList.Create();
PythonVersionAdd('{#PythonVersion}', 'Use Python {#PythonVersion} Embedded (Recommended)', 'tools\python\{#PythonVersion}\python.exe');
{ Create Spinner animation. } { Create Spinner animation. }
Spinner := TStringList.Create(); Spinner := TStringList.Create();