packages.lua 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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. -- load package
  54. function _load_package(packagename, packagedir, packagefile)
  55. local funcinfo = debug.getinfo(package.load_from_repository)
  56. if funcinfo and funcinfo.nparams == 3 then -- >= 2.7.8
  57. return package.load_from_repository(packagename, packagedir, {packagefile = packagefile})
  58. else
  59. -- deprecated
  60. return package.load_from_repository(packagename, nil, packagedir, packagefile)
  61. end
  62. end
  63. -- the main entry
  64. function main(opt)
  65. local packages = {}
  66. for _, packagedir in ipairs(os.dirs(path.join("packages", "*", "*"))) do
  67. local packagename = path.filename(packagedir)
  68. local packagefile = path.join(packagedir, "xmake.lua")
  69. local instance = _load_package(packagename, packagedir, packagefile)
  70. local basename = instance:get("base")
  71. if instance and basename then
  72. local basedir = path.join("packages", basename:sub(1, 1):lower(), basename:lower())
  73. local basefile = path.join(basedir, "xmake.lua")
  74. instance._BASE = _load_package(basename, basedir, basefile)
  75. end
  76. if instance then
  77. for _, plat in ipairs({"windows", "linux", "macosx", "iphoneos", "android", "mingw", "msys", "bsd", "wasm", "cross"}) do
  78. local archs = platform.archs(plat)
  79. if archs then
  80. local package_archs = {}
  81. for _, arch in ipairs(archs) do
  82. if is_supported(instance, plat, arch, opt) then
  83. table.insert(package_archs, arch)
  84. end
  85. end
  86. if #package_archs > 0 then
  87. packages[plat] = packages[plat] or {}
  88. table.insert(packages[plat], {name = instance:name(), instance = instance, archs = package_archs, generic = #package_archs == #archs})
  89. end
  90. end
  91. end
  92. end
  93. end
  94. for _, packages_plat in pairs(packages) do
  95. table.sort(packages_plat, function(a, b) return a.name < b.name end)
  96. end
  97. return packages
  98. end