idf_setup.iss.inc 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. { Copyright 2019 Espressif Systems (Shanghai) PTE LTD
  2. SPDX-License-Identifier: Apache-2.0 }
  3. { ------------------------------ Downloading ESP-IDF ------------------------------ }
  4. var
  5. IDFZIPFileVersion, IDFZIPFileName: String;
  6. function GetIDFPath(Unused: String): String;
  7. begin
  8. if IDFUseExisting then
  9. Result := IDFExistingPath
  10. else
  11. Result := IDFDownloadPath;
  12. end;
  13. function GetIDFZIPFileVersion(Version: String): String;
  14. var
  15. ReleaseVerPart: String;
  16. i: Integer;
  17. Found: Boolean;
  18. begin
  19. if WildCardMatch(Version, 'v*') or WildCardMatch(Version, 'v*-rc*') then
  20. Result := Version
  21. else if Version = 'master' then
  22. Result := ''
  23. else if WildCardMatch(Version, 'release/v*') then
  24. begin
  25. ReleaseVerPart := Version;
  26. Log('ReleaseVerPart=' + ReleaseVerPart)
  27. Delete(ReleaseVerPart, 1, Length('release/'));
  28. Log('ReleaseVerPart=' + ReleaseVerPart)
  29. Found := False;
  30. for i := 0 to GetArrayLength(IDFDownloadAvailableVersions) - 1 do
  31. begin
  32. if Pos(ReleaseVerPart, IDFDownloadAvailableVersions[i]) = 1 then
  33. begin
  34. Result := IDFDownloadAvailableVersions[i];
  35. Found := True;
  36. break;
  37. end;
  38. end;
  39. if not Found then
  40. Result := '';
  41. end;
  42. Log('GetIDFZIPFileVersion(' + Version + ')=' + Result);
  43. end;
  44. procedure IDFAddDownload();
  45. var
  46. Url, MirrorUrl: String;
  47. begin
  48. IDFZIPFileVersion := GetIDFZIPFileVersion(IDFDownloadVersion);
  49. if IDFZIPFileVersion <> '' then
  50. begin
  51. Url := 'https://github.com/espressif/esp-idf/releases/download/' + IDFZIPFileVersion + '/esp-idf-' + IDFZIPFileVersion + '.zip';
  52. MirrorUrl := 'https://dl.espressif.com/dl/esp-idf/releases/esp-idf-' + IDFZIPFileVersion + '.zip';
  53. IDFZIPFileName := ExpandConstant('{app}\releases\esp-idf-' + IDFZIPFileVersion + '.zip')
  54. if not FileExists(IDFZIPFileName) then
  55. begin
  56. ForceDirectories(ExpandConstant('{app}\releases'))
  57. Log('Adding download: ' + Url + ', mirror: ' + MirrorUrl + ', destination: ' + IDFZIPFileName);
  58. idpAddFile(Url, IDFZIPFileName);
  59. idpAddMirror(Url, MirrorUrl);
  60. end else begin
  61. Log(IDFZIPFileName + ' already exists')
  62. end;
  63. end;
  64. end;
  65. procedure RemoveAlternatesFile(Path: String);
  66. begin
  67. Log('Removing ' + Path);
  68. DeleteFile(Path);
  69. end;
  70. {
  71. Replacement of the '--dissociate' flag of 'git clone', to support older versions of Git.
  72. '--reference' is supported for submodules since git 2.12, but '--dissociate' only from 2.18.
  73. }
  74. procedure GitRepoDissociate(Path: String);
  75. var
  76. CmdLine: String;
  77. begin
  78. CmdLine := GitExecutablePath + ' -C ' + Path + ' repack -d -a'
  79. DoCmdlineInstall('Finishing ESP-IDF installation', 'Re-packing the repository', CmdLine);
  80. CmdLine := GitExecutablePath + ' -C ' + Path + ' submodule foreach git repack -d -a'
  81. DoCmdlineInstall('Finishing ESP-IDF installation', 'Re-packing the submodules', CmdLine);
  82. FindFileRecusive(Path + '\.git', 'alternates', @RemoveAlternatesFile);
  83. end;
  84. { Run git reset --hard in the repo and in the submodules, to fix the newlines. }
  85. procedure GitRepoFixNewlines(Path: String);
  86. var
  87. CmdLine: String;
  88. begin
  89. CmdLine := GitExecutablePath + ' -C ' + Path + ' reset --hard';
  90. Log('Resetting the repository: ' + CmdLine);
  91. DoCmdlineInstall('Finishing ESP-IDF installation', 'Updating newlines', CmdLine);
  92. Log('Resetting the submodules: ' + CmdLine);
  93. CmdLine := GitExecutablePath + ' -C ' + Path + ' submodule foreach git reset --hard';
  94. DoCmdlineInstall('Finishing ESP-IDF installation', 'Updating newlines in submodules', CmdLine);
  95. end;
  96. {
  97. There are 3 possible ways how an ESP-IDF copy can be obtained:
  98. - Download the .zip archive with submodules included, extract to destination directory,
  99. then do 'git reset --hard' and 'git submodule foreach git reset --hard' to correct for
  100. possibly different newlines. This is done for release versions.
  101. - Do a git clone of the Github repository into the destination directory.
  102. This is done for the master branch.
  103. - Download the .zip archive of a "close enough" release version, extract into a temporary
  104. directory. Then do a git clone of the Github repository, using the temporary directory
  105. as a '--reference'. This is done for other versions (such as release branches).
  106. }
  107. procedure IDFDownload();
  108. var
  109. CmdLine: String;
  110. IDFTempPath: String;
  111. IDFPath: String;
  112. NeedToClone: Boolean;
  113. Res: Boolean;
  114. begin
  115. IDFPath := IDFDownloadPath;
  116. { If there is a release archive to download, IDFZIPFileName and IDFZIPFileVersion will be set.
  117. See GetIDFZIPFileVersion function.
  118. }
  119. if IDFZIPFileName <> '' then
  120. begin
  121. if IDFZIPFileVersion <> IDFDownloadVersion then
  122. begin
  123. { The version of .zip file downloaded is not the same as the version the user has requested.
  124. Will use 'git clone --reference' to obtain the correct version, using the contents
  125. of the .zip file as reference.
  126. }
  127. NeedToClone := True;
  128. end;
  129. ExtractTemporaryFile('7za.exe')
  130. CmdLine := ExpandConstant('{tmp}\7za.exe x -o' + ExpandConstant('{tmp}') + ' -r -aoa "' + IDFZIPFileName + '"');
  131. IDFTempPath := ExpandConstant('{tmp}\esp-idf-') + IDFZIPFileVersion;
  132. Log('Extracting ESP-IDF reference repository: ' + CmdLine);
  133. Log('Reference repository path: ' + IDFTempPath);
  134. DoCmdlineInstall('Extracting ESP-IDF', 'Setting up reference repository', CmdLine);
  135. end else begin
  136. { IDFZIPFileName is not set, meaning that we will rely on 'git clone'. }
  137. NeedToClone := True;
  138. Log('Not .zip release archive. Will do full clone.');
  139. end;
  140. if NeedToClone then
  141. begin
  142. CmdLine := GitExecutablePath + ' clone --recursive --progress -b ' + IDFDownloadVersion;
  143. if IDFTempPath <> '' then
  144. CmdLine := CmdLine + ' --reference ' + IDFTempPath;
  145. CmdLine := CmdLine + ' https://github.com/espressif/esp-idf.git ' + IDFPath;
  146. Log('Cloning IDF: ' + CmdLine);
  147. DoCmdlineInstall('Downloading ESP-IDF', 'Using git to clone ESP-IDF repository', CmdLine);
  148. if IDFTempPath <> '' then
  149. GitRepoDissociate(IDFPath);
  150. end else begin
  151. Log('Moving ' + IDFTempPath + ' to ' + IDFPath);
  152. if DirExists(IDFPath) then
  153. begin
  154. if not DirIsEmpty(IDFPath) then
  155. begin
  156. MsgBox('Destination directory exists and is not empty: ' + IDFPath, mbError, MB_OK);
  157. RaiseException('Failed to copy ESP-IDF')
  158. end;
  159. Res := RemoveDir(IDFPath);
  160. if not Res then
  161. begin
  162. MsgBox('Failed to remove destination directory: ' + IDFPath, mbError, MB_OK);
  163. RaiseException('Failed to copy ESP-IDF')
  164. end;
  165. end;
  166. Res := RenameFile(IDFTempPath, IDFPath);
  167. if not Res then
  168. begin
  169. MsgBox('Failed to copy ESP-IDF to the destination directory: ' + IDFPath, mbError, MB_OK);
  170. RaiseException('Failed to copy ESP-IDF');
  171. end;
  172. GitRepoFixNewlines(IDFPath);
  173. end;
  174. end;
  175. { ------------------------------ IDF Tools setup, Python environment setup ------------------------------ }
  176. procedure IDFToolsSetup();
  177. var
  178. CmdLine: String;
  179. IDFPath: String;
  180. IDFToolsPyPath: String;
  181. IDFToolsPyCmd: String;
  182. begin
  183. IDFPath := GetIDFPath('');
  184. IDFToolsPyPath := IDFPath + '\tools\idf_tools.py';
  185. if FileExists(IDFToolsPyPath) then
  186. begin
  187. Log('idf_tools.py exists in IDF directory');
  188. IDFToolsPyCmd := PythonExecutablePath + ' ' + IDFToolsPyPath;
  189. end else begin
  190. Log('idf_tools.py does not exist in IDF directory, using a fallback version');
  191. IDFToolsPyCmd := ExpandConstant(PythonExecutablePath
  192. + ' "{app}\idf_tools_fallback.py"'
  193. + ' --idf-path ' + IDFPath
  194. + ' --tools "{app}\tools_fallback.json"');
  195. end;
  196. Log('idf_tools.py command: ' + IDFToolsPyCmd);
  197. CmdLine := IDFToolsPyCmd + ' install';
  198. Log('Installing tools:' + CmdLine);
  199. DoCmdlineInstall('Installing ESP-IDF tools', '', CmdLine);
  200. CmdLine := IDFToolsPyCmd + ' install-python-env';
  201. Log('Installing Python environment:' + CmdLine);
  202. DoCmdlineInstall('Installing Python environment', '', CmdLine);
  203. end;
  204. { ------------------------------ Start menu shortcut ------------------------------ }
  205. procedure CreateIDFCommandPromptShortcut();
  206. var
  207. Destination: String;
  208. Description: String;
  209. Command: String;
  210. begin
  211. ForceDirectories(ExpandConstant('{group}'));
  212. Destination := ExpandConstant('{group}\{#IDFCmdExeShortcutFile}');
  213. Description := '{#IDFCmdExeShortcutDescription}';
  214. { If cmd.exe command argument starts with a quote, the first and last quote chars in the command
  215. will be removed by cmd.exe; each argument needs to be surrounded by quotes as well. }
  216. Command := ExpandConstant('/k ""{app}\idf_cmd_init.bat" "') + PythonPath + '" "' + GitPath + '""';
  217. Log('CreateShellLink Destination=' + Destination + ' Description=' + Description + ' Command=' + Command)
  218. try
  219. CreateShellLink(
  220. Destination,
  221. Description,
  222. 'cmd.exe',
  223. Command,
  224. GetIDFPath(''),
  225. '', 0, SW_SHOWNORMAL);
  226. except
  227. MsgBox('Failed to create the Start menu shortcut: ' + Destination, mbError, MB_OK);
  228. RaiseException('Failed to create the shortcut');
  229. end;
  230. end;