xmake.lua 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. package("qtbase")
  2. set_kind("template")
  3. set_homepage("https://www.qt.io")
  4. set_description("Qt is the faster, smarter way to create innovative devices, modern UIs & applications for multiple screens. Cross-platform software development at its best.")
  5. set_license("LGPL-3")
  6. add_configs("shared", {description = "Download shared binaries.", default = true, type = "boolean", readonly = true})
  7. add_configs("vs_runtime", {description = "Set vs compiler runtime.", default = "MD", readonly = true})
  8. add_deps("aqt")
  9. on_load(function (package)
  10. package:addenv("PATH", "bin")
  11. end)
  12. on_fetch(function (package, opt)
  13. import("core.base.semver")
  14. import("detect.sdks.find_qt")
  15. local qt = package:data("qt")
  16. if qt then
  17. return qt
  18. end
  19. local sdkdir
  20. if not opt.system then
  21. sdkdir = package:installdir()
  22. end
  23. local qt = find_qt(sdkdir, {force = opt.force})
  24. if not qt then
  25. return
  26. end
  27. local qtversion = semver.new(qt.sdkver)
  28. if not qtversion:ge(package:version()) then
  29. return
  30. end
  31. qt.version = qt.sdkver
  32. package:data_set("qt", qt)
  33. return qt
  34. end)
  35. on_install(function (package)
  36. import("core.base.semver")
  37. import("core.project.config")
  38. import("core.tool.toolchain")
  39. local version = package:version()
  40. local versionstr = version:shortstr()
  41. local host
  42. if is_host("windows") or package:is_plat("mingw") then
  43. host = "windows"
  44. elseif is_host("linux") then
  45. host = "linux"
  46. elseif is_host("macosx") then
  47. host = "mac"
  48. else
  49. raise("unhandled host " .. os.host())
  50. end
  51. local target
  52. if package:is_plat("windows", "mingw", "linux", "macosx") then
  53. target = "desktop"
  54. elseif package:is_plat("android") then
  55. target = "android"
  56. elseif package:is_plat("iphoneos") then
  57. target = "ios"
  58. else
  59. raise("unhandled plat " .. package:plat())
  60. end
  61. local arch
  62. if package:is_plat("windows", "mingw") then
  63. local winarch
  64. if package:is_arch("x64", "x86_64", "arm64") then
  65. winarch = "64"
  66. elseif version:lt("6.0") and package:is_arch("x86", "i386") then -- 32bits support was removed in Qt6
  67. winarch = "32"
  68. else
  69. raise("unhandled arch " .. package:targetarch())
  70. end
  71. local compiler_version
  72. if package:is_plat("windows") then
  73. local vs = toolchain.load("msvc"):config("vs")
  74. if tonumber(vs) >= 2019 or version:ge("6.0") then
  75. compiler_version = "msvc2019"
  76. elseif vs == "2017" or vs == "2015" then
  77. compiler_version = "msvc" .. vs
  78. else
  79. raise("unhandled msvc version " .. vs)
  80. end
  81. if package:is_arch("x64", "x86_64") then
  82. compiler_version = compiler_version .. "_64"
  83. elseif package:is_arch("arm64") then -- arm64 support was added in Qt6.2
  84. compiler_version = compiler_version .. "_arm64"
  85. end
  86. else
  87. local cc = package:tool("cc")
  88. local ccversion = os.iorunv(cc, {"-dumpversion"}):trim()
  89. local mingw_version = semver.new(ccversion)
  90. if version:ge("6.2.2") then
  91. compiler_version = "mingw"
  92. elseif mingw_version:ge("8.1") then
  93. compiler_version = "mingw81"
  94. elseif mingw_version:ge("7.3") then
  95. compiler_version = "mingw73"
  96. elseif mingw_version:ge("5.3") then
  97. compiler_version = "mingw53"
  98. else
  99. raise("unhandled mingw version " .. version)
  100. end
  101. end
  102. arch = "win" .. winarch .. "_" .. compiler_version
  103. elseif package:is_plat("linux") then
  104. arch = "gcc_64"
  105. elseif package:is_plat("macosx") then
  106. arch = "clang_64"
  107. elseif package:is_plat("android") then
  108. if version:le("5.13") or version:ge("6.0") then
  109. if package:is_arch("x86_64", "x64") then
  110. arch = "android_x86_64"
  111. elseif package:is_arch("arm64", "arm64-v8a") then
  112. arch = "android_arm64_v8a"
  113. elseif package:is_arch("armv7", "armv7-a", "armeabi", "armeabi-v7a") then
  114. arch = "android_armv7"
  115. elseif package:is_arch("x86") then
  116. arch = "android_x86"
  117. else
  118. raise("unhandled arch " .. package:targetarch())
  119. end
  120. else
  121. arch = "android"
  122. end
  123. end
  124. local installdir = package:installdir()
  125. os.vrunv("aqt", {"install-qt", "-O", installdir, host, target, versionstr, arch})
  126. -- move files to root
  127. os.mv(path.join(installdir, versionstr, "*", "*"), installdir)
  128. os.rmdir(path.join(installdir, versionstr))
  129. -- special case for cross-compilation since we need binaries we can run on the host
  130. if package:is_cross() then
  131. local runhost
  132. if is_host("windows") or package:is_plat("mingw") then
  133. runhost = "windows"
  134. elseif is_host("linux") then
  135. runhost = "linux"
  136. elseif is_host("macosx") then
  137. runhost = "mac"
  138. else
  139. raise("unhandled host " .. os.host())
  140. end
  141. -- download qtbase to bin_host folder
  142. os.vrunv("aqt", {"install-qt", "-O", path.join(installdir, "bin_host"), runhost, "desktop", versionstr, "--archives", "qtbase"})
  143. -- add symbolic links for useful tools
  144. local tool_folders = {}
  145. if version:ge("6.0") then
  146. tool_folders.bin = {
  147. qmake = true,
  148. qmake6 = true
  149. }
  150. tool_folders.libexec = {
  151. moc = true,
  152. rcc = true,
  153. uic = true
  154. }
  155. else
  156. tool_folders.bin = {
  157. qmake = true,
  158. moc = true,
  159. rcc = true,
  160. uic = true
  161. }
  162. end
  163. for folder, tools in pairs(tool_folders) do
  164. for _, file in pairs(os.files(path.join(installdir, "bin_host", versionstr, "*", folder, "*"))) do
  165. local filename = path.filename(file)
  166. if tools[filename] then
  167. local targetpath = path.join(installdir, folder, filename)
  168. os.rm(targetpath)
  169. if is_host("windows") then
  170. os.cp(file, targetpath)
  171. else
  172. os.ln(file, targetpath)
  173. end
  174. -- some tools like CMake will try to run moc.exe even on Linux, trick them (ln bin/moc.exe => bin_host/bin/moc)
  175. if package:is_plat("mingw") then
  176. os.rm(targetpath .. ".exe")
  177. if is_host("windows") then
  178. os.cp(file, targetpath .. ".exe")
  179. else
  180. os.ln(file, targetpath .. ".exe")
  181. end
  182. end
  183. end
  184. end
  185. end
  186. end
  187. end)
  188. on_test(function (package)
  189. local qt = assert(package:data("qt"))
  190. local function getbin(name)
  191. if is_host("windows") then
  192. name = name .. ".exe"
  193. end
  194. local exec = path.join(qt.bindir, name)
  195. if not os.isexec(exec) and qt.libexecdir then
  196. exec = path.join(qt.libexecdir, name)
  197. end
  198. if not os.isexec(exec) and qt.libexecdir_host then
  199. exec = path.join(qt.libexecdir_host, name)
  200. end
  201. assert(os.isexec(exec), name .. " not found!")
  202. return exec
  203. end
  204. os.vrun(getbin("qmake") .. " -v")
  205. os.vrun(getbin("moc") .. " -v")
  206. -- rcc -v and uic -v seems to hang CI forever
  207. --os.vrun(getbin("rcc") .. " -v") -- rcc -v hangs CI
  208. --os.vrun(getbin("uic") .. " -v") -- uic -v seems to hang on CI
  209. end)