idf_tool_setup.iss 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. #include <idp.iss>
  2. [Setup]
  3. AppName=ESP-IDF Tools
  4. AppVersion=1.2
  5. OutputBaseFilename=esp-idf-tools-setup-unsigned
  6. DefaultDirName={pf}\Espressif\ESP-IDF Tools
  7. DefaultGroupName=ESP-IDF Tools
  8. Compression=lzma2
  9. SolidCompression=yes
  10. ChangesEnvironment=yes
  11. LicenseFile=license.txt
  12. ; Note: the rest of the installer setup is written to work cleanly on win32 also, *however*
  13. ; Ninja doesn't ship a 32-bit binary so there's no way yet to install on win32 :(
  14. ; See https://github.com/ninja-build/ninja/issues/1339
  15. ArchitecturesAllowed=x64
  16. ArchitecturesInstallIn64BitMode=x64
  17. [Types]
  18. Name: "full"; Description: "Default installation"
  19. Name: "custom"; Description: "Custom installation"; Flags: iscustom
  20. [Components]
  21. Name: xtensa_esp32; Description: ESP32 Xtensa GCC Cross-Toolchain; Types: full custom;
  22. Name: mconf_idf; Description: ESP-IDF console menuconfig tool; Types: full custom;
  23. Name: openocd_esp32; Description: openocd debug interface for ESP32; Types: full custom;
  24. Name: esp32ulp_elf_binutils; Description: ULP binutils toolchain for ESP32; Types: full custom;
  25. Name: ninja; Description: Install Ninja build v1.8.2; Types: full custom
  26. [Tasks]
  27. ; Should installer prepend to Path (does this by default)
  28. Name: addpath; Description: "Add tools to Path"; GroupDescription: "Add to Path:";
  29. Name: addpath\allusers; Description: "For all users"; GroupDescription: "Add to Path:"; Flags: exclusive
  30. Name: addpath\user; Description: "For the current user only"; GroupDescription: "Add to Path:"; Flags: exclusive unchecked
  31. ; External installation tasks
  32. ;
  33. ; Note: The Check conditions here auto-select 32-bit or 64-bit installers, as needed
  34. ; The tasks won't appear if CMake/Python27 already appear to be installed on this system
  35. Name: cmake32; Description: Download and Run CMake 3.11.1 Installer; GroupDescription: "Other Required Tools:"; Check: not IsWin64 and not CMakeInstalled
  36. Name: cmake64; Description: Download and Run CMake 3.11.1 Installer; GroupDescription: "Other Required Tools:"; Check: IsWin64 and not CMakeInstalled
  37. Name: python32; Description: Download and Run Python 2.7.14 Installer and install Python dependencies; GroupDescription: "Other Required Tools:"; Check: not IsWin64 and not Python27Installed
  38. Name: python64; Description: Download and Run Python 2.7.14 Installer and install Python dependencies; GroupDescription: "Other Required Tools:"; Check: IsWin64 and not Python27Installed
  39. Name: python_requirements; Description: Install any missing Python dependencies; GroupDescription: "Other Required Tools:"; Check: Python27Installed
  40. [Files]
  41. Components: xtensa_esp32; Source: "input\xtensa-esp32-elf\*"; DestDir: "{app}\tools\"; Flags: recursesubdirs;
  42. Components: mconf_idf; Source: "input\mconf-v4.6.0.0-idf-20180525-win32\*"; DestDir: "{app}\mconf-idf\";
  43. Components: esp32ulp_elf_binutils; Source: "input\esp32ulp-elf-binutils\*"; DestDir: "{app}\tools\"; Flags: recursesubdirs;
  44. ; Excludes for openocd are because some config files contain Cyrillic characters and inno can't encode them
  45. Components: openocd_esp32; Source: "input\openocd-esp32\*"; DestDir: "{app}\tools\"; Flags: recursesubdirs; Excludes: "target\1986*.cfg,target\*1879*.cfg"
  46. Components: ninja; Source: "input\ninja.exe"; DestDir: "{app}\tools\bin\";
  47. Tasks: python32 python64 python_requirements; Source: "..\..\..\requirements.txt"; DestDir: "{tmp}"; Flags: deleteafterinstall;
  48. [Run]
  49. Tasks: cmake32 cmake64; Filename: "msiexec.exe"; Parameters: "/i ""{tmp}\cmake.msi"" /qb! {code:GetCMakeInstallerArgs}"; StatusMsg: Running CMake installer...;
  50. Tasks: python32 python64; Filename: "msiexec.exe"; Parameters: "/i ""{tmp}\python.msi"" /qb! {code:GetPythonInstallerArgs} REBOOT=Supress"; StatusMsg: Running Python installer...;
  51. Tasks: python32 python64; Filename: "C:\Python27\Scripts\pip.exe"; Parameters: "install -r ""{tmp}\requirements.txt"""; StatusMsg: Installing Python modules...;
  52. Tasks: python_requirements; Filename: "{code:Python27InstallPathInclude}\Scripts\pip.exe"; Parameters: "install -r ""{tmp}\requirements.txt"""; StatusMsg: Installing Python modules...;
  53. [Registry]
  54. ; Prepend various entries to Path in the registry. Can either be HKLM (all users) or HKCU (single user only)
  55. ; "tools" bin dir (ninja, xtensa & ULP toolchains, openocd all in this dir)
  56. Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; \
  57. ValueType: expandsz; ValueName: "Path"; ValueData: "{app}\tools\bin;{olddata}"; Check: not IsInPath('{app}'); \
  58. Components: xtensa_esp32 esp32ulp_elf_binutils openocd_esp32 ninja; Tasks: addpath\allusers
  59. Root: HKCU; Subkey: "Environment"; \
  60. ValueType: expandsz; ValueName: "Path"; ValueData: "{app}\tools\bin;{olddata}"; Check: not IsInPath('{app}'); \
  61. Components: xtensa_esp32 esp32ulp_elf_binutils openocd_esp32 ninja; Tasks: addpath\user
  62. ; mconf-idf path
  63. Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; \
  64. ValueType: expandsz; ValueName: "Path"; ValueData: "{app}\mconf-idf;{olddata}"; Check: not IsInPath('{app}\mconf-idf'); \
  65. Components: mconf_idf; Tasks: addpath\allusers
  66. Root: HKCU; Subkey: "Environment"; \
  67. ValueType: expandsz; ValueName: "Path"; ValueData: "{app}\mconf-idf;{olddata}"; Check: not IsInPath('{app}\mconf-idf'); \
  68. Components: mconf_idf; Tasks: addpath\user
  69. ; set OPENOCD_SCRIPTS environment variable
  70. [Registry]
  71. Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; \
  72. ValueType:string; ValueName: "OPENOCD_SCRIPTS"; \
  73. ValueData: "{app}\tools\share\openocd\scripts"; Flags: preservestringtype createvalueifdoesntexist; \
  74. Components: openocd_esp32; Tasks: addpath\allusers
  75. Root: HKCU; Subkey: "Environment"; ValueType:string; ValueName: "OPENOCD_SCRIPTS"; \
  76. ValueData: "{app}\tools\share\openocd\scripts"; Flags: preservestringtype createvalueifdoesntexist; \
  77. Components: openocd_esp32; Tasks: addpath\user
  78. [Code]
  79. procedure InitializeWizard;
  80. begin
  81. idpDownloadAfter(wpReady);
  82. end;
  83. procedure CurPageChanged(CurPageID: Integer);
  84. begin
  85. { When the Ready page is being displayed, initialise downloads based on which Tasks are selected }
  86. if CurPageID=wpReady then
  87. begin
  88. if IsTaskSelected('python32') then
  89. begin
  90. idpAddFile('https://www.python.org/ftp/python/2.7.14/python-2.7.14.msi', ExpandConstant('{tmp}\python.msi'));
  91. end;
  92. if IsTaskSelected('python64') then
  93. begin
  94. idpAddFile('https://www.python.org/ftp/python/2.7.14/python-2.7.14.amd64.msi', ExpandConstant('{tmp}\python.msi'));
  95. end;
  96. if IsTaskSelected('cmake32') then
  97. begin
  98. idpAddFile('https://cmake.org/files/v3.11/cmake-3.11.1-win32-x86.msi', ExpandConstant('{tmp}\cmake.msi'));
  99. end;
  100. if IsTaskSelected('cmake64') then
  101. begin
  102. idpAddFile('https://cmake.org/files/v3.11/cmake-3.11.1-win64-x64.msi', ExpandConstant('{tmp}\cmake.msi'));
  103. end;
  104. end;
  105. end;
  106. { Utility to search in HKLM for an installation path. Looks in both 64-bit & 32-bit registry. }
  107. function GetInstallPath(key, valuename : String) : Variant;
  108. var
  109. value : string;
  110. begin
  111. Result := Null;
  112. if RegQueryStringValue(HKEY_LOCAL_MACHINE, key, valuename, value) then
  113. begin
  114. Result := value;
  115. end
  116. else
  117. begin
  118. { This is 32-bit setup running on 64-bit Windows, but ESP-IDF can use 64-bit tools also }
  119. if IsWin64 and RegQueryStringValue(HKLM64, key, valuename, value) then
  120. begin
  121. Result := value;
  122. end;
  123. end;
  124. end;
  125. { Return the path of the CMake install, if there is one }
  126. function CMakeInstallPath() : Variant;
  127. begin
  128. Result := GetInstallPath('SOFTWARE\Kitware\CMake', 'InstallDir');
  129. end;
  130. { Return 'True' if CMake is installed }
  131. function CMakeInstalled() : Boolean;
  132. begin
  133. Result := not VarIsNull(CMakeInstallPath());
  134. end;
  135. { Return the path where Python 2.7 is installed, if there is one }
  136. function Python27InstallPath() : Variant;
  137. begin
  138. Result := GetInstallPath('SOFTWARE\Python\PythonCore\2.7\InstallPath', '');
  139. end;
  140. { Return the path where Python 2.7 is installed, suitable for including in code: tag }
  141. function Python27InstallPathInclude(Ignored : String) : String;
  142. begin
  143. Result := Python27InstallPath();
  144. end;
  145. { Return True if Python 2.7 is installed }
  146. function Python27Installed() : Boolean;
  147. begin
  148. Result := not VarIsNull(Python27InstallPath());
  149. end;
  150. { Return arguments to pass to CMake installer, ie should it add CMake to the Path }
  151. function GetCMakeInstallerArgs(Param : String) : String;
  152. begin
  153. if IsTaskSelected('addpath\allusers') then
  154. begin
  155. Result := 'ADD_CMAKE_TO_PATH=System';
  156. end
  157. else if IsTaskSelected('addpath\user') then
  158. begin
  159. Result := 'ADD_CMAKE_TO_PATH=User';
  160. end
  161. else begin
  162. Result := 'ADD_CMAKE_TO_PATH=None';
  163. end;
  164. end;
  165. { Return arguments to pass to the Python installer,
  166. ie should it install for all users and should it prepend to the Path }
  167. function GetPythonInstallerArgs(Param : String) : String;
  168. begin
  169. { Note: The Python 2.7 installer appears to always add PATH to
  170. system environment variables, regardless of ALLUSERS setting.
  171. This appears to be fixed in the Python 3.x installers (which use WiX) }
  172. if IsTaskSelected('addpath') then
  173. begin
  174. Result := 'ADDLOCAL=ALL ';
  175. end
  176. else begin
  177. Result := ''
  178. end;
  179. if IsTaskSelected('addpath\allusers') then
  180. begin
  181. Result := Result + 'ALLUSERS=1';
  182. end
  183. else begin
  184. Result := Result + 'ALLUSERS=';
  185. end;
  186. end;
  187. { Return True if the param is already set in the Path
  188. (user or system, depending on which Task is chosen)
  189. Adapted from https://stackoverflow.com/a/3431379
  190. }
  191. function IsInPath(Param: string): boolean;
  192. var
  193. OrigPath: string;
  194. RootKey : Integer;
  195. SubKey : String;
  196. begin
  197. if IsTaskSelected('addpath\allusers') then
  198. begin
  199. RootKey := HKEY_LOCAL_MACHINE;
  200. SubKey := 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment';
  201. end
  202. else begin
  203. RootKey := HKEY_CURRENT_USER;
  204. SubKey := 'Environment';
  205. end;
  206. if not RegQueryStringValue(RootKey, SubKey, 'Path', OrigPath)
  207. then begin
  208. Result := False;
  209. end
  210. else begin
  211. { look for the path with leading and trailing semicolon }
  212. Result := Pos(';' + Param + ';', ';' + OrigPath + ';') > 0;
  213. end;
  214. end;