Merge branch 'feature/windows_installer_moved_to_github_backport_4.1' into 'release/v4.1'

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

See merge request espressif/esp-idf!15476
This commit is contained in:
Ivan Grokhotkov 2021-10-11 13:50:54 +00:00
commit ef647e941e
28 changed files with 0 additions and 3726 deletions

View File

@ -310,45 +310,3 @@ build_idf_exe:
- cd build
- cmake -DCMAKE_TOOLCHAIN_FILE=../toolchain-i686-w64-mingw32.cmake -DCMAKE_BUILD_TYPE=Release ..
- cmake --build .
build_cmdlinerunner:
stage: build
image: $CI_DOCKER_REGISTRY/esp32-toolchain-win-cross
tags:
- build
only:
refs:
- master
- /^release\/v/
- /^v\d+\.\d+(\.\d+)?($|-)/
- schedules
before_script: []
artifacts:
paths:
- tools/windows/tool_setup/cmdlinerunner/build/cmdlinerunner.dll
expire_in: 4 days
script:
- cd tools/windows/tool_setup/cmdlinerunner
- mkdir build
- cd build
- cmake -DCMAKE_TOOLCHAIN_FILE=../toolchain-i686-w64-mingw32.cmake -DCMAKE_BUILD_TYPE=Release ..
- cmake --build .
build_installer:
# using a different stage here to be able to use artifacts from build_cmdlinerunner job
stage: host_test
image: $CI_DOCKER_REGISTRY/wine-innosetup:1
tags:
- build
only:
refs:
- master
- /^release\/v/
- /^v\d+\.\d+(\.\d+)?($|-)/
- schedules
dependencies:
- build_cmdlinerunner
before_script: []
script:
- cd tools/windows/tool_setup/
- ./build_installer.sh

View File

@ -91,5 +91,3 @@ tools/test_idf_tools/test_idf_tools.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

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

View File

@ -1,54 +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.
## 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
```
### 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`.
## 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,43 +0,0 @@
#!/bin/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 -e
set -u
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
if [[ -z "${IDF_PATH:-}" ]]; then
export IDF_PATH=$(cd ../../../; pwd)
echo "Assuming IDF_PATH: ${IDF_PATH}"
fi
echo "Downloading IDF Tools..."
mkdir -p 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 --tools-json tools_fallback.json --non-interactive download --platform Windows-x86_64 all
mkdir -p dist
cp idf_tools_tmp/dist/* dist/
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
echo "Downloading idf_versions.txt..."
wget --no-verbose -O idf_versions.txt https://dl.espressif.com/dl/esp-idf/idf_versions.txt
echo "Running ISCC..."
iscc idf_tool_setup.iss

View File

@ -1,247 +0,0 @@
var
ChoicePagePrepare: array of TNotifyEvent;
ChoicePageSelectionChange: array of TNotifyEvent;
ChoicePageValidate: array of TWizardPageButtonEvent;
ChoicePageMaxTag: Integer;
ChoicePages: array of TInputOptionWizardPage;
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,154 +0,0 @@
{ Copyright 2019 Espressif Systems (Shanghai) PTE 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,194 +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,98 +0,0 @@
{ Copyright 2019 Espressif Systems (Shanghai) PTE 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 Espressif Systems (Shanghai) PTE 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,117 +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=
)
:: 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,149 +0,0 @@
{ Copyright 2019 Espressif Systems (Shanghai) PTE 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
{ 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 DownloadIDFVersionsList();
var
Url: String;
VersionFile: String;
begin
Url := '{#IDFVersionsURL}';
VersionFile := ExpandConstant('{tmp}\idf_versions.txt');
if idpDownloadFile(Url, VersionFile) then
begin
Log('Downloaded ' + Url + ' to ' + VersionFile);
end else begin
Log('Download of ' + Url + ' failed, using a fallback versions list');
ExtractTemporaryFile('idf_versions.txt');
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;
DownloadIDFVersionsList();
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;
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;
IDFDownloadVersion := IDFDownloadAvailableVersions[Page.SelectedValueIndex];
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,
'Download ESP-IDF', 'Please choose ESP-IDF version to download',
'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 download ESP-IDF to',
True,
@OnIDFDownloadPagePrepare,
@OnIDFDownloadSelectionChange,
@OnIDFDownloadPageValidate);
end;

View File

@ -1,118 +0,0 @@
{ Copyright 2019 Espressif Systems (Shanghai) PTE 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('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,317 +0,0 @@
{ Copyright 2019 Espressif Systems (Shanghai) PTE 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);
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
ForceDirectories(ExpandConstant('{app}\releases'))
Log('Adding download: ' + Url + ', mirror: ' + MirrorUrl + ', destination: ' + IDFZIPFileName);
idpAddFile(Url, IDFZIPFileName);
idpAddMirror(Url, MirrorUrl);
end else begin
Log(IDFZIPFileName + ' already exists')
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);
FindFileRecusive(Path + '\.git', 'alternates', @RemoveAlternatesFile);
end;
{ Run git reset --hard in the repo and in the submodules, to fix the newlines. }
procedure GitRepoFixNewlines(Path: String);
var
CmdLine: String;
begin
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;
{
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 IDFDownload();
var
CmdLine: String;
IDFTempPath: String;
IDFPath: String;
NeedToClone: Boolean;
Res: 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;
ExtractTemporaryFile('7za.exe')
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 --recursive --progress -b ' + IDFDownloadVersion;
if IDFTempPath <> '' then
CmdLine := CmdLine + ' --reference ' + IDFTempPath;
CmdLine := CmdLine + ' https://github.com/espressif/esp-idf.git ' + 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('Moving ' + 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;
Res := RemoveDir(IDFPath);
if not Res then
begin
MsgBox('Failed to remove destination directory: ' + IDFPath, mbError, MB_OK);
RaiseException('Failed to copy ESP-IDF')
end;
end;
Res := RenameFile(IDFTempPath, IDFPath);
if not Res then
begin
MsgBox('Failed to copy ESP-IDF to the destination directory: ' + IDFPath, mbError, MB_OK);
RaiseException('Failed to copy ESP-IDF');
end;
GitRepoFixNewlines(IDFPath);
end;
end;
{ ------------------------------ IDF Tools setup, Python environment setup ------------------------------ }
procedure IDFToolsSetup();
var
CmdLine: String;
IDFPath: String;
IDFToolsPyPath: String;
IDFToolsPyCmd: String;
begin
IDFPath := GetIDFPath('');
IDFToolsPyPath := IDFPath + '\tools\idf_tools.py';
if FileExists(IDFToolsPyPath) then
begin
Log('idf_tools.py exists in IDF directory');
IDFToolsPyCmd := PythonExecutablePath + ' ' + IDFToolsPyPath;
end else begin
Log('idf_tools.py does not exist in IDF directory, using a fallback version');
IDFToolsPyCmd := ExpandConstant(PythonExecutablePath
+ ' "{app}\idf_tools_fallback.py"'
+ ' --idf-path ' + IDFPath
+ ' --tools "{app}\tools_fallback.json"');
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 ------------------------------ }
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" "') + PythonPath + '" "' + 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 Start menu shortcut: ' + Destination, mbError, MB_OK);
RaiseException('Failed to create the shortcut');
end;
end;
{ ------------------------------ WD exclusion registration ------------------------------ }
procedure RegisterIDFToolsExecutablesInWD();
var
CmdLine: String;
begin
CmdLine := ExpandConstant('powershell -ExecutionPolicy ByPass -File "{app}\dist\tools_WD_excl.ps1" -AddExclPath "{app}\*.exe"');
Log('Registering IDF Tools executables in Windows Defender: ' + CmdLine);
DoCmdlineInstall('Finishing ESP-IDF installation', 'Registering IDF Tools executables in Windows Defender', CmdLine);
end;
<event('CurPageChanged')>
procedure CheckWinDefenderAvailable(CurPageID: Integer);
var
bHasWD: Boolean;
szHasWD: String;
szWDPath: String;
listPSModulePath: TStringList;
x: Integer;
begin
if CurPageID = wpSelectTasks then
begin
listPSModulePath := TStringList.Create;
listPSModulePath.Delimiter := ';';
listPSModulePath.StrictDelimiter := True;
listPSModulePath.DelimitedText := GetEnv('PsModulePath');
Log('Checking PSMODULEPATH for Windows Defender module...');
for x:=0 to (listPSModulePath.Count-1) do
begin
szWDPath := listPSModulePath[x] + '\Defender'
bHasWD := DirExists(szWDPath);
if bHasWD then
begin
szHasWD := 'YES (' + szWDPath + ')';
Break;
end
else
szHasWD := 'NO';
end;
Log('CheckWinDefenderAvailable: ' + szHasWD);
{ WD registration checkbox is identified by 'Windows Defender' substring anywhere in its caption.
Please, keep this in mind when making changes }
for x:=0 to (WizardForm.TasksList.Items.Count-1) do
begin
if Pos('Windows Defender', WizardForm.TasksList.ItemCaption[x]) > 0 then
begin
WizardForm.TasksList.ItemEnabled[x] := bHasWD;
WizardForm.TasksList.Checked[x] := bHasWD;
break;
end;
end;
end;
end;

View File

@ -1,111 +0,0 @@
; Copyright 2019 Espressif Systems (Shanghai) PTE 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.2"
#define MyAppPublisher "Espressif Systems (Shanghai) Co. Ltd."
#define MyAppURL "https://github.com/espressif/esp-idf"
#define PythonVersion "3.7"
#define PythonInstallerName "python-3.7.3-amd64.exe"
#define PythonInstallerDownloadURL "https://www.python.org/ftp/python/3.7.3/python-3.7.3-amd64.exe"
#define GitVersion "2.21.0"
#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 IDFVersionsURL "https://dl.espressif.com/dl/esp-idf/idf_versions.txt"
#define IDFCmdExeShortcutDescription "Open ESP-IDF Command Prompt (cmd.exe)"
#define IDFCmdExeShortcutFile "ESP-IDF Command Prompt (cmd.exe).lnk"
[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=lzma
SolidCompression=yes
ArchitecturesAllowed=x64
ArchitecturesInstallIn64BitMode=x64
LicenseFile=license.txt
PrivilegesRequired=lowest
SetupLogging=yes
ChangesEnvironment=yes
WizardStyle=modern
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
[Dirs]
Name: "{app}\dist"
[Files]
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: "dist\*"; DestDir: "{app}\dist"
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: "{autodesktop}\{#IDFCmdExeShortcutFile}"
[Tasks]
Name: createlnk; Description: "Create Start Menu shortcut for the ESP-IDF Tools Command Prompt";
Name: createdsk; Description: "Create Desktop shortcut for the ESP-IDF Tools Command Prompt";
; 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
Name: wdexcl; Description: "Register the ESP-IDF Tools executables as Windows Defender exclusions (improves compilation speed, requires elevation)";
Name: idf_tools_use_mirror; Description: "Use Espressif download server instead of downloading tool packages from Github"; Flags: unchecked;
[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: "{group}\{#IDFCmdExeShortcutFile}"; Flags: postinstall shellexec; Description: "Run ESP-IDF Command Prompt (cmd.exe)"; Check: InstallationSuccessful
[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 "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 "idf_download_page.iss.inc"
#include "idf_setup.iss.inc"
#include "summary.iss.inc"
#include "main.iss.inc"

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,163 +0,0 @@
{ Copyright 2019 Espressif Systems (Shanghai) PTE 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
exit;
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
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;
begin
EnvPath := GetEnv('PATH');
if not PythonUseExisting then
PythonExecutablePathUpdateAfterInstall();
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}'))
{ Log and clear PYTHONPATH variable, as it might point to libraries of another Python version}
PythonLibPath := GetEnv('PYTHONPATH')
Log('PYTHONPATH=' + PythonLibPath)
SetEnvironmentVariable('PYTHONPATH', '')
end;
<event('CurStepChanged')>
procedure PostInstallSteps(CurStep: TSetupStep);
var
Err: Integer;
begin
if CurStep <> ssPostInstall then
exit;
try
AddPythonGitToPath();
if not IDFUseExisting then
IDFDownload();
if WizardIsTaskSelected('idf_tools_use_mirror') then
begin
SetEnvironmentVariable('IDF_GITHUB_ASSETS', 'dl.espressif.com/github_assets')
end;
IDFToolsSetup();
if WizardIsTaskSelected('createlnk') then
begin
CreateIDFCommandPromptShortcut('{autostartmenu}\Programs\ESP-IDF');
end;
if WizardIsTaskSelected('createdsk') then
begin
CreateIDFCommandPromptShortcut('{autodesktop}');
end;
if WizardIsTaskSelected('wdexcl') then
begin
RegisterIDFToolsExecutablesInWD();
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;

View File

@ -1,113 +0,0 @@
{ Copyright 2019 Espressif Systems (Shanghai) PTE 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): 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;
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;
procedure FindPythonVersionsFromKey(RootKey: Integer; SubKeyName: String);
var
CompanyNames: TArrayOfString;
CompanyName, CompanySubKey, TagName, TagSubKey: String;
ExecutablePath, DisplayName, Version: String;
TagNames: TArrayOfString;
CompanyId, TagId: Integer;
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) then
continue;
PythonVersionAdd(Version, DisplayName, ExecutablePath);
end;
end;
end;
procedure FindInstalledPythonVersions();
begin
InstalledPythonVersions := TStringList.Create();
InstalledPythonDisplayNames := TStringList.Create();
InstalledPythonExecutables := TStringList.Create();
FindPythonVersionsFromKey(HKEY_CURRENT_USER, 'Software\Python');
FindPythonVersionsFromKey(HKEY_LOCAL_MACHINE, 'Software\Python');
FindPythonVersionsFromKey(HKEY_LOCAL_MACHINE, 'Software\Wow6432Node\Python');
end;

View File

@ -1,149 +0,0 @@
{ Copyright 2019 Espressif Systems (Shanghai) PTE 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;
PythonUseExisting: Boolean;
function GetPythonPath(Unused: String): String;
begin
Result := PythonPath;
end;
function PythonInstallRequired(): Boolean;
begin
Result := not PythonUseExisting;
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;
FindInstalledPythonVersions();
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;
function OnPythonPageValidate(Sender: TWizardPage): Boolean;
var
Page: TInputOptionWizardPage;
begin
Page := TInputOptionWizardPage(Sender);
Log('OnPythonPageValidate index=' + IntToStr(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;
end;
procedure PythonExecutablePathUpdateAfterInstall();
var
Version, DisplayName, ExecutablePath: String;
begin
if not GetPythonVersionInfoFromKey(
HKEY_CURRENT_USER, 'Software\Python', 'PythonCore', '{#PythonVersion}',
Version, DisplayName, ExecutablePath) then
begin
Log('Failed to find ExecutablePath for the installed copy of Python');
exit;
end;
Log('Found ExecutablePath for ' + DisplayName + ': ' + ExecutablePath);
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;

View File

@ -1,49 +0,0 @@
#!/bin/bash
#
# Script to sign the IDF Tools installer for Windows, built with build_installer.sh.
#
set -e
set -u
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-unsigned.exe"
OUT_FILE="Output/esp-idf-tools-setup-${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 Espressif Systems (Shanghai) PTE 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 PythonUseExisting then
begin
Result := Result + 'Using Python ' + PythonVersion + ':' + NewLine
+ Space + PythonExecutablePath + NewLine + NewLine;
end else begin
Result := Result + 'Will download and install 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 download 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,172 +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 Espressif Systems (Shanghai) PTE 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 FindFileRecusive(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
FindFileRecusive(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;