package.lua 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. ---
  2. -- Create a source or binary release package.
  3. ---
  4. ---
  5. -- Helper function: run a command while hiding its output.
  6. ---
  7. local function execQuiet(cmd, ...)
  8. cmd = string.format(cmd, ...) .. " > _output_.log 2> _error_.log"
  9. local z = os.execute(cmd)
  10. os.remove("_output_.log")
  11. os.remove("_error_.log")
  12. return z
  13. end
  14. ---
  15. -- Check the command line arguments, and show some help if needed.
  16. ---
  17. local allowedCompilers = {}
  18. if os.ishost("windows") then
  19. allowedCompilers = {
  20. "vs2019",
  21. "vs2017",
  22. "vs2015",
  23. "vs2013",
  24. "vs2012",
  25. "vs2010",
  26. "vs2008",
  27. "vs2005",
  28. }
  29. elseif os.ishost("linux") or os.ishost("bsd") then
  30. allowedCompilers = {
  31. "gcc",
  32. "clang",
  33. }
  34. elseif os.ishost("macosx") then
  35. allowedCompilers = {
  36. "clang",
  37. }
  38. else
  39. error("Unsupported host os", 0)
  40. end
  41. local usage = 'usage is: package <branch> <type> [<compiler>]\n' ..
  42. ' <branch> is the name of the release branch to target\n' ..
  43. ' <type> is one of "source" or "binary"\n' ..
  44. ' <compiler> (default: ' .. allowedCompilers[1] .. ') is one of ' .. table.implode(allowedCompilers, "", "", " ")
  45. if #_ARGS ~= 2 and #_ARGS ~= 3 then
  46. error(usage, 0)
  47. end
  48. local branch = _ARGS[1]
  49. local kind = _ARGS[2]
  50. local compiler = _ARGS[3] or allowedCompilers[1]
  51. if kind ~= "source" and kind ~= "binary" then
  52. print("Invalid package kind: "..kind)
  53. error(usage, 0)
  54. end
  55. if not table.contains(allowedCompilers, compiler) then
  56. print("Invalid compiler: "..compiler)
  57. error(usage, 0)
  58. end
  59. local compilerIsVS = compiler:startswith("vs")
  60. --
  61. -- Make sure I've got what I've need to be happy.
  62. --
  63. local required = { "git" }
  64. if not compilerIsVS then
  65. table.insert(required, "make")
  66. table.insert(required, compiler)
  67. end
  68. for _, value in ipairs(required) do
  69. local z = execQuiet("%s --version", value)
  70. if not z then
  71. error("required tool '" .. value .. "' not found", 0)
  72. end
  73. end
  74. --
  75. -- Figure out what I'm making.
  76. --
  77. os.chdir("..")
  78. local text = os.outputof(string.format('git show %s:src/host/premake.h', branch))
  79. local _, _, version = text:find('VERSION%s*"([%w%p]+)"')
  80. local pkgName = "premake-" .. version
  81. local pkgExt = ".zip"
  82. if kind == "binary" then
  83. pkgName = pkgName .. "-" .. os.host()
  84. if not os.istarget("windows") then
  85. pkgExt = ".tar.gz"
  86. end
  87. else
  88. pkgName = pkgName .. "-src"
  89. end
  90. --
  91. -- Make sure I'm sure.
  92. --
  93. printf("")
  94. printf("I am about to create a %s package", kind:upper())
  95. printf(" ...named release/%s%s", pkgName, pkgExt)
  96. printf(" ...from the %s branch", branch)
  97. printf("")
  98. printf("Does this look right to you? If so, press [Enter] to begin.")
  99. io.read()
  100. --
  101. -- Pull down the release branch.
  102. --
  103. print("Preparing release folder")
  104. os.mkdir("release")
  105. os.chdir("release")
  106. os.rmdir(pkgName)
  107. print("Cloning source code")
  108. local z = execQuiet("git clone .. %s -b %s --recurse-submodules --depth 1 --shallow-submodules", pkgName, branch)
  109. if not z then
  110. error("clone failed", 0)
  111. end
  112. os.chdir(pkgName)
  113. --
  114. -- Bootstrap Premake in the newly cloned repository
  115. --
  116. print("Bootstrapping Premake...")
  117. if compilerIsVS then
  118. z = os.execute("Bootstrap.bat " .. compiler)
  119. else
  120. z = os.execute("make -j -f Bootstrap.mak " .. os.host())
  121. end
  122. if not z then
  123. error("Failed to Bootstrap Premake", 0)
  124. end
  125. local premakeBin = path.translate("./bin/release/premake5")
  126. --
  127. -- Make absolutely sure the embedded scripts have been updated
  128. --
  129. print("Updating embedded scripts...")
  130. local z = execQuiet("%s embed %s", premakeBin, iif(kind == "source", "", "--bytecode"))
  131. if not z then
  132. error("failed to update the embedded scripts", 0)
  133. end
  134. --
  135. -- Generate a source package.
  136. --
  137. if kind == "source" then
  138. local function genProjects(parameters)
  139. if not execQuiet("%s %s", premakeBin, parameters) then
  140. error("failed to generate project for "..parameters, 0)
  141. end
  142. end
  143. os.rmdir("build")
  144. print("Generating project files...")
  145. local ignoreActions = {
  146. "clean",
  147. "embed",
  148. "package",
  149. "self-test",
  150. "test",
  151. "gmake", -- deprecated
  152. }
  153. local perOSActions = {
  154. "gmake2",
  155. "codelite"
  156. }
  157. for action in premake.action.each() do
  158. if not table.contains(ignoreActions, action.trigger) then
  159. if table.contains(perOSActions, action.trigger) then
  160. local osList = {
  161. { "windows", },
  162. { "unix", "linux" },
  163. { "macosx", },
  164. { "bsd", },
  165. }
  166. for _, os in ipairs(osList) do
  167. local osTarget = os[2] or os[1]
  168. genProjects(string.format("--to=build/%s.%s --os=%s %s", action.trigger, os[1], osTarget, action.trigger))
  169. end
  170. else
  171. genProjects(string.format("--to=build/%s %s", action.trigger, action.trigger))
  172. end
  173. end
  174. end
  175. print("Creating source code package...")
  176. local excludeList = {
  177. ".gitignore",
  178. ".gitattributes",
  179. ".gitmodules",
  180. ".travis.yml",
  181. ".editorconfig",
  182. "appveyor.yml",
  183. "Bootstrap.*",
  184. "packages/*",
  185. }
  186. local includeList = {
  187. "build",
  188. "src/scripts.c",
  189. }
  190. if not execQuiet("git rm --cached -r -f --ignore-unmatch "..table.concat(excludeList, ' ')) or
  191. not execQuiet("git add -f "..table.concat(includeList, ' ')) or
  192. not execQuiet("git stash") or
  193. not execQuiet("git archive --format=zip -9 -o ../%s.zip --prefix=%s/ stash@{0}", pkgName, pkgName) or
  194. not execQuiet("git stash drop stash@{0}")
  195. then
  196. error("failed to archive release", 0)
  197. end
  198. os.chdir("..")
  199. end
  200. --
  201. -- Create a binary package for this platform. This step requires a working
  202. -- GNU/Make/GCC environment.
  203. --
  204. if kind == "binary" then
  205. print("Building binary...")
  206. os.chdir("bin/release")
  207. local addCommand = "git add -f premake5%s"
  208. local archiveCommand = "git archive --format=%s -o ../../../%s%s stash@{0} -- ./premake5%s"
  209. if os.ishost("windows") then
  210. addCommand = string.format(addCommand, ".exe")
  211. archiveCommand = string.format(archiveCommand, "zip -9", pkgName, pkgExt, ".exe")
  212. else
  213. addCommand = string.format(addCommand, "")
  214. archiveCommand = string.format(archiveCommand, "tar.gz", pkgName, pkgExt, "")
  215. end
  216. if not execQuiet(addCommand) or
  217. not execQuiet("git stash") or
  218. not execQuiet(archiveCommand) or
  219. not execQuiet("git stash drop stash@{0}")
  220. then
  221. error("failed to archive release", 0)
  222. end
  223. os.chdir("../../..")
  224. end
  225. --
  226. -- Clean up
  227. --
  228. -- Use RMDIR token instead of os.rmdir to force remove .git dir which has read only files
  229. execQuiet(os.translateCommands("{RMDIR} "..pkgName))