xmake.lua 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. local function qt_table(sdkdir, version)
  2. return {
  3. version = version,
  4. sdkdir = sdkdir,
  5. sdkver = version,
  6. bindir = path.join(sdkdir, "bin"),
  7. includedir = path.join(sdkdir, "include"),
  8. libdir = path.join(sdkdir, "lib"),
  9. libexecdir = path.join(sdkdir, "libexec"),
  10. mkspecsdir = path.join(sdkdir, "mkspecs"),
  11. qmldir = path.join(sdkdir, "qml"),
  12. pluginsdir = path.join(sdkdir, "plugins")
  13. }
  14. end
  15. package("qt5base")
  16. set_kind("phony")
  17. set_homepage("https://www.qt.io")
  18. 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.")
  19. set_license("LGPL-3")
  20. add_configs("shared", {description = "Download shared binaries.", default = true, type = "boolean", readonly = true})
  21. add_configs("vs_runtime", {description = "Set vs compiler runtime.", default = "MD", readonly = true})
  22. add_versions("5.15.2", "dummy")
  23. add_versions("5.12.5", "dummy")
  24. add_deps("aqt")
  25. on_fetch(function (package, opt)
  26. import("core.base.semver")
  27. import("core.cache.localcache")
  28. import("detect.sdks.find_qt")
  29. local qt = package:data("qt")
  30. if qt then
  31. return qt
  32. end
  33. if os.isfile(package:manifest_file()) then
  34. local installdir = package:installdir()
  35. local qt = qt_table(installdir, package:version():shortstr())
  36. package:data_set("qt", qt)
  37. return qt
  38. end
  39. if not opt.system then
  40. return
  41. end
  42. local qt = find_qt()
  43. if not qt then
  44. return
  45. end
  46. local qtversion = semver.new(qt.sdkver)
  47. if not qtversion:satisfies("5.x") then
  48. return
  49. end
  50. qt.version = qt.sdkver
  51. package:data_set("qt", qt)
  52. return qt
  53. end)
  54. on_install("windows", "linux", "macosx", "mingw", "android", "iphoneos", function (package)
  55. import("core.base.semver")
  56. import("core.project.config")
  57. import("core.tool.toolchain")
  58. local version = package:version()
  59. local versionstr = version:shortstr()
  60. local host
  61. if is_host("windows") or package:is_plat("mingw") then
  62. host = "windows"
  63. elseif is_host("linux") then
  64. host = "linux"
  65. elseif is_host("macosx") then
  66. host = "mac"
  67. else
  68. raise("unhandled host " .. os.host())
  69. end
  70. local target
  71. if package:is_plat("windows", "mingw", "linux", "macosx") then
  72. target = "desktop"
  73. elseif package:is_plat("android") then
  74. target = "android"
  75. elseif package:is_plat("iphoneos") then
  76. target = "ios"
  77. else
  78. raise("unhandled plat " .. package:plat())
  79. end
  80. local arch
  81. if package:is_plat("windows", "mingw") then
  82. local winarch
  83. if package:is_arch("x64", "x86_64") then
  84. winarch = "64"
  85. elseif package:is_arch("x86", "i386") then
  86. winarch = "32"
  87. else
  88. raise("unhandled arch " .. package:targetarch())
  89. end
  90. local compiler_version
  91. if package:is_plat("windows") then
  92. local vs = toolchain.load("msvc"):config("vs")
  93. if tonumber(vs) >= 2019 then
  94. compiler_version = "msvc2019"
  95. elseif vs == "2017" or vs == "2015" then
  96. compiler_version = "msvc" .. vs
  97. else
  98. raise("unhandled msvc version " .. vs)
  99. end
  100. if package:is_arch("x64", "x86_64") then
  101. compiler_version = compiler_version .. "_64"
  102. end
  103. else
  104. local cc = package:tool("cc")
  105. local version = os.iorunv(cc, {"-dumpversion"}):trim()
  106. local mingw_version = semver.new(version)
  107. if mingw_version:ge("8.1") then
  108. compiler_version = "mingw81"
  109. elseif mingw_version:ge("7.3") then
  110. compiler_version = "mingw73"
  111. elseif mingw_version:ge("5.3") then
  112. compiler_version = "mingw53"
  113. else
  114. raise("unhandled mingw version " .. version)
  115. end
  116. end
  117. arch = "win" .. winarch .. "_" .. compiler_version
  118. elseif package:is_plat("linux") then
  119. arch = "gcc_64"
  120. elseif package:is_plat("macosx") then
  121. arch = "clang_64"
  122. elseif package:is_plat("android") then
  123. if version:le("5.13") then
  124. if package:is_arch("x86_64", "x64") then
  125. arch = "android_x86_64"
  126. elseif package:is_arch("arm64", "arm64-v8a") then
  127. arch = "android_arm64_v8a"
  128. elseif package:is_arch("armv7", "armv7-a") then
  129. arch = "android_armv7"
  130. elseif package:is_arch("x86") then
  131. arch = "android_x86"
  132. end
  133. else
  134. arch = "android"
  135. end
  136. end
  137. local installdir = package:installdir()
  138. os.vrunv("aqt", {"install-qt", "-O", installdir, host, target, versionstr, arch})
  139. -- move files to root
  140. os.mv(path.join(installdir, versionstr, "*", "*"), installdir)
  141. os.rmdir(path.join(installdir, versionstr))
  142. -- special case for cross-compilation using MinGW since we need binaries we can run on the host
  143. if package:is_plat("mingw") and not is_host("windows") then
  144. local runhost
  145. if is_host("linux") then
  146. runhost = "linux"
  147. elseif is_host("macosx") then
  148. runhost = "mac"
  149. else
  150. raise("unhandled host " .. os.host())
  151. end
  152. -- download qtbase to bin_host folder
  153. os.vrunv("aqt", {"install-qt", "-O", path.join(installdir, "bin_host"), runhost, "desktop", versionstr, "--archives", "qtbase"})
  154. -- add symbolic links for useful tools
  155. local tools = {
  156. moc = true,
  157. qmake = true,
  158. rcc = true,
  159. uic = true
  160. }
  161. for _, file in pairs(os.files(path.join(installdir, "bin_host", versionstr, "*", "bin", "*"))) do
  162. local filename = path.filename(file)
  163. if (tools[filename]) then
  164. local targetpath = path.join(installdir, "bin", filename)
  165. os.ln(file, path.join(installdir, "bin", filename))
  166. -- some tools like CMake will try to run moc.exe, trick them
  167. os.rm(targetpath .. ".exe")
  168. os.ln(file, path.join(installdir, "bin", filename .. ".exe"))
  169. end
  170. end
  171. end
  172. package:data_set("qt", qt_table(installdir, versionstr))
  173. end)
  174. on_test(function (package)
  175. local qt = assert(package:data("qt"))
  176. os.vrun(path.join(qt.bindir, "moc") .. " -v")
  177. os.vrun(path.join(qt.bindir, "rcc") .. " -v")
  178. end)