idf_tool_setup.iss 8.5 KB

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