wayland_protocols.lua 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. -- Generate source files from wayland protocol files.
  2. -- Example:
  3. --[[
  4. if is_plat("linux") then
  5. add_rules("@wayland-protocols/wayland.protocols")
  6. on_load(function(target)
  7. local pkg = target:pkg("wayland-protocols")
  8. local wayland_protocols_dir = path.join(target:pkg("wayland-protocols"):installdir() or "/usr", "share", "wayland-protocols")
  9. local protocols = {path.join("stable", "xdg-shell", "xdg-shell.xml"),
  10. path.join("unstable", "xdg-decoration", "xdg-decoration-unstable-v1.xml")}
  11. for _, protocol in ipairs(protocols) do
  12. target:add("files", path.join(wayland_protocols_dir, protocol))
  13. end
  14. end)
  15. end
  16. ]]
  17. -- Options:
  18. --[[
  19. add_rules("@wayland-protocols/wayland.protocols", {
  20. outputdir = "...", -- Path for generated files, default is `path.join(target:autogendir(), "rules", "wayland.protocols")`
  21. client = "...", -- Path format for client protocol header files, default is `"%s.h"`, set to `false` to disable its generation
  22. server = "...", -- Path format for server protocol header files, default is `nil`
  23. code = "...", -- Path format for code files, default is `"%s.c"`
  24. public = false, -- Visibility for headers and symbols in generated code, can be `false` or `true`, default is `false`
  25. })
  26. ]]
  27. rule("wayland.protocols")
  28. set_extensions(".xml")
  29. on_config(function(target)
  30. import("core.base.option")
  31. local rule_name = "@wayland-protocols/wayland.protocols"
  32. if target:rule("c++.build") then
  33. local rule = target:rule("c++.build"):clone()
  34. rule:add("deps", rule_name, {order = true})
  35. target:rule_add(rule)
  36. end
  37. local public = target:extraconf("rules", rule_name, "public")
  38. local outputdir = target:extraconf("rules", rule_name, "outputdir") or path.join(target:autogendir(), "rules", "wayland.protocols")
  39. if not os.isdir(outputdir) then
  40. os.mkdir(outputdir)
  41. end
  42. target:add("includedirs", outputdir, {public = public})
  43. local dryrun = option.get("dry-run")
  44. local sourcebatches = target:sourcebatches()[rule_name]
  45. if not dryrun and sourcebatches and sourcebatches.sourcefiles then
  46. local client = target:extraconf("rules", rule_name, "client")
  47. if client == nil then
  48. client = "%s.h"
  49. end
  50. local server = target:extraconf("rules", rule_name, "server")
  51. for _, protocol in ipairs(sourcebatches.sourcefiles) do
  52. local basename = path.basename(protocol)
  53. -- For C++ module dependency discovery
  54. if client then
  55. local clientfile = path.join(outputdir, client:format(basename))
  56. os.touch(clientfile)
  57. end
  58. if server then
  59. local serverfile = path.join(outputdir, server:format(basename))
  60. os.touch(serverfile)
  61. end
  62. -- Add code file to target
  63. local code = target:extraconf("rules", rule_name, "code") or "%s.c"
  64. local codefile = path.join(outputdir, code:format(basename))
  65. target:add("files", codefile, {always_added = true})
  66. end
  67. end
  68. end)
  69. before_buildcmd_file(function(target, batchcmds, sourcefile, opt)
  70. import("lib.detect.find_tool")
  71. local rule_name = "@wayland-protocols/wayland.protocols"
  72. local outputdir = target:extraconf("rules", rule_name, "outputdir") or path.join(target:autogendir(), "rules", "wayland.protocols")
  73. local wayland_scanner = find_tool("wayland-scanner")
  74. assert(wayland_scanner, "wayland-scanner not found! please install wayland package")
  75. local basename = path.basename(sourcefile)
  76. -- Generate client protocol header
  77. local client = target:extraconf("rules", rule_name, "client")
  78. if client == nil then
  79. client = "%s.h"
  80. end
  81. if client then
  82. local clientfile = path.join(outputdir, client:format(basename))
  83. local client_args = {"client-header", sourcefile, clientfile}
  84. batchcmds:show_progress(opt.progress, "${color.build.object}generating.wayland.protocol.client %s", basename)
  85. batchcmds:vexecv(wayland_scanner.program, client_args)
  86. end
  87. -- Generate server protocol header
  88. local server = target:extraconf("rules", rule_name, "server")
  89. if server then
  90. local serverfile = path.join(outputdir, server:format(basename))
  91. local server_args = {"server-header", sourcefile, serverfile}
  92. batchcmds:show_progress(opt.progress, "${color.build.object}generating.wayland.protocol.server %s", basename)
  93. batchcmds:vexecv(wayland_scanner.program, server_args)
  94. end
  95. -- Generate code
  96. local public = target:extraconf("rules", rule_name, "public")
  97. local visibility = public and "public" or "private"
  98. local code = target:extraconf("rules", rule_name, "code") or "%s.c"
  99. local codefile = path.join(outputdir, code:format(basename))
  100. local code_args = {visibility .. "-code", sourcefile, codefile}
  101. batchcmds:show_progress(opt.progress, "${color.build.object}generating.wayland.protocol.%s %s", visibility, basename)
  102. batchcmds:vexecv(wayland_scanner.program, code_args)
  103. batchcmds:add_depfiles(sourcefile)
  104. batchcmds:set_depmtime(os.mtime(codefile))
  105. batchcmds:set_depcache(target:dependfile(codefile))
  106. end)