packages.lua 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. -- imports
  2. import("core.package.package")
  3. import("core.platform.platform")
  4. -- is supported platform and architecture?
  5. function is_supported(instance, plat, arch, opt)
  6. -- ignore template package
  7. if instance.is_template and instance:is_template() then
  8. return false
  9. end
  10. -- get script
  11. local script = instance:get("install")
  12. local result = nil
  13. if type(script) == "function" then
  14. result = script
  15. elseif type(script) == "table" then
  16. -- get plat and arch
  17. local plat = plat or ""
  18. local arch = arch or ""
  19. -- match pattern
  20. --
  21. -- `@linux`
  22. -- `@linux|x86_64`
  23. -- `@macosx,linux`
  24. -- `android@macosx,linux`
  25. -- `android|armeabi-v7a@macosx,linux`
  26. -- `android|armeabi-v7a@macosx,linux|x86_64`
  27. -- `android|armeabi-v7a@linux|x86_64`
  28. --
  29. for _pattern, _script in pairs(script) do
  30. local hosts = {}
  31. local hosts_spec = false
  32. _pattern = _pattern:gsub("@(.+)", function (v)
  33. for _, host in ipairs(v:split(',')) do
  34. hosts[host] = true
  35. hosts_spec = true
  36. end
  37. return ""
  38. end)
  39. if _pattern:trim() == "" and opt and opt.onlyhost then
  40. _pattern = os.subhost()
  41. end
  42. if not _pattern:startswith("__") and (not hosts_spec or hosts[os.subhost() .. '|' .. os.subarch()] or hosts[os.subhost()])
  43. and (_pattern:trim() == "" or (plat .. '|' .. arch):find('^' .. _pattern .. '$') or plat:find('^' .. _pattern .. '$')) then
  44. result = _script
  45. break
  46. end
  47. end
  48. -- get generic script
  49. result = result or script["__generic__"]
  50. end
  51. return result
  52. end
  53. -- the main entry
  54. function main(opt)
  55. local packages = {}
  56. for _, packagedir in ipairs(os.dirs(path.join("packages", "*", "*"))) do
  57. local packagename = path.filename(packagedir)
  58. local packagefile = path.join(packagedir, "xmake.lua")
  59. local instance = package.load_from_repository(packagename, nil, packagedir, packagefile)
  60. local basename = instance:get("base")
  61. if instance and basename then
  62. local basedir = path.join("packages", basename:sub(1, 1):lower(), basename:lower())
  63. local basefile = path.join(basedir, "xmake.lua")
  64. instance._BASE = package.load_from_repository(basename, nil, basedir, basefile)
  65. end
  66. if instance then
  67. for _, plat in ipairs({"windows", "linux", "macosx", "iphoneos", "android", "mingw", "msys", "bsd", "wasm", "cross"}) do
  68. local archs = platform.archs(plat)
  69. if archs then
  70. local package_archs = {}
  71. for _, arch in ipairs(archs) do
  72. if is_supported(instance, plat, arch, opt) then
  73. table.insert(package_archs, arch)
  74. end
  75. end
  76. if #package_archs > 0 then
  77. packages[plat] = packages[plat] or {}
  78. table.insert(packages[plat], {name = instance:name(), instance = instance, archs = package_archs, generic = #package_archs == #archs})
  79. end
  80. end
  81. end
  82. end
  83. end
  84. for _, packages_plat in pairs(packages) do
  85. table.sort(packages_plat, function(a, b) return a.name < b.name end)
  86. end
  87. return packages
  88. end