tree-sitter.scm 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2022 Pierre Langlois <pierre.langlois@gmx.com>
  3. ;;;
  4. ;;; This file is part of GNU Guix.
  5. ;;;
  6. ;;; GNU Guix is free software; you can redistribute it and/or modify it
  7. ;;; under the terms of the GNU General Public License as published by
  8. ;;; the Free Software Foundation; either version 3 of the License, or (at
  9. ;;; your option) any later version.
  10. ;;;
  11. ;;; GNU Guix is distributed in the hope that it will be useful, but
  12. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. ;;; GNU General Public License for more details.
  15. ;;;
  16. ;;; You should have received a copy of the GNU General Public License
  17. ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
  18. (define-module (guix build-system tree-sitter)
  19. #:use-module (guix store)
  20. #:use-module (guix utils)
  21. #:use-module (guix packages)
  22. #:use-module (guix gexp)
  23. #:use-module (guix monads)
  24. #:use-module (guix search-paths)
  25. #:use-module (guix build-system)
  26. #:use-module (guix build-system gnu)
  27. #:use-module (guix build-system node)
  28. #:use-module (ice-9 match)
  29. #:export (%tree-sitter-build-system-modules
  30. tree-sitter-build
  31. tree-sitter-build-system))
  32. (define %tree-sitter-build-system-modules
  33. ;; Build-side modules imported by default.
  34. `((guix build tree-sitter-build-system)
  35. ,@%node-build-system-modules))
  36. (define* (lower name
  37. #:key source inputs native-inputs outputs system target
  38. #:allow-other-keys
  39. #:rest arguments)
  40. "Return a bag for NAME from the given arguments."
  41. (define private-keywords
  42. `(#:inputs #:native-inputs #:outputs ,@(if target
  43. '()
  44. '(#:target))))
  45. (define node
  46. (module-ref (resolve-interface '(gnu packages node))
  47. 'node-lts))
  48. (define tree-sitter
  49. (module-ref (resolve-interface '(gnu packages tree-sitter))
  50. 'tree-sitter))
  51. (define tree-sitter-cli
  52. (module-ref (resolve-interface '(gnu packages tree-sitter))
  53. 'tree-sitter-cli))
  54. ;; Grammars depend on each other via JS modules, which we package into a
  55. ;; dedicated js output.
  56. (define grammar-inputs
  57. (map (match-lambda
  58. ((name package)
  59. `(,name ,package "js")))
  60. inputs))
  61. (bag
  62. (name name)
  63. (system system) (target target)
  64. (build-inputs `(,@(if source
  65. `(("source" ,source))
  66. '())
  67. ("node" ,node)
  68. ("tree-sitter-cli" ,tree-sitter-cli)
  69. ,@native-inputs
  70. ,@(if target '() grammar-inputs)
  71. ;; Keep the standard inputs of 'gnu-build-system'.
  72. ,@(if target
  73. (standard-cross-packages target 'host)
  74. '())
  75. ,@(standard-packages)))
  76. (host-inputs `(("tree-sitter" ,tree-sitter)
  77. ,@(if target grammar-inputs '())))
  78. ;; Keep the standard inputs of 'gnu-buid-system'.
  79. (target-inputs (if target
  80. (standard-cross-packages target 'target)
  81. '()))
  82. ;; XXX: this is a hack to get around issue #41569.
  83. (outputs (match outputs
  84. (("out") (cons "js" outputs))
  85. (_ outputs)))
  86. (build (if target tree-sitter-cross-build tree-sitter-build))
  87. (arguments (strip-keyword-arguments private-keywords arguments))))
  88. (define* (tree-sitter-build name inputs
  89. #:key
  90. source
  91. (phases '%standard-phases)
  92. (grammar-directories '("."))
  93. (tests? #t)
  94. (outputs '("out" "js"))
  95. (search-paths '())
  96. (system (%current-system))
  97. (guile #f)
  98. (imported-modules %tree-sitter-build-system-modules)
  99. (modules '((guix build utils)
  100. (guix build tree-sitter-build-system))))
  101. (define builder
  102. (with-imported-modules imported-modules
  103. #~(begin
  104. (use-modules #$@(sexp->gexp modules))
  105. (tree-sitter-build #:name #$name
  106. #:source #+source
  107. #:system #$system
  108. #:phases #$phases
  109. #:tests? #$tests?
  110. #:grammar-directories '#$grammar-directories
  111. #:outputs #$(outputs->gexp outputs)
  112. #:search-paths
  113. '#$(sexp->gexp
  114. (map search-path-specification->sexp
  115. search-paths))
  116. #:inputs #$(input-tuples->gexp inputs)))))
  117. (mlet %store-monad ((guile (package->derivation (or guile (default-guile))
  118. system #:graft? #f)))
  119. (gexp->derivation name builder
  120. #:system system
  121. #:guile-for-build guile)))
  122. (define* (tree-sitter-cross-build name
  123. #:key
  124. target
  125. build-inputs target-inputs host-inputs
  126. guile source
  127. (phases '%standard-phases)
  128. (grammar-directories '("."))
  129. (tests? #t)
  130. (outputs '("out" "js"))
  131. (search-paths '())
  132. (native-search-paths '())
  133. (system (%current-system))
  134. (build (nix-system->gnu-triplet system))
  135. (imported-modules
  136. %tree-sitter-build-system-modules)
  137. (modules
  138. '((guix build utils)
  139. (guix build tree-sitter-build-system))))
  140. (define builder
  141. (with-imported-modules imported-modules
  142. #~(begin
  143. (use-modules #$@(sexp->gexp modules))
  144. (define %build-host-inputs
  145. #+(input-tuples->gexp build-inputs))
  146. (define %build-target-inputs
  147. (append #$(input-tuples->gexp host-inputs)
  148. #+(input-tuples->gexp target-inputs)))
  149. (define %build-inputs
  150. (append %build-host-inputs %build-target-inputs))
  151. (tree-sitter-build #:name #$name
  152. #:source #+source
  153. #:system #$system
  154. #:build #$build
  155. #:target #$target
  156. #:phases #$phases
  157. #:tests? #$tests?
  158. #:grammar-directories '#$grammar-directories
  159. #:outputs #$(outputs->gexp outputs)
  160. #:inputs %build-target-inputs
  161. #:native-inputs %build-host-inputs
  162. #:search-paths '
  163. #$(sexp->gexp
  164. (map search-path-specification->sexp
  165. search-paths))
  166. #:native-search-paths
  167. '#$(sexp->gexp
  168. (map
  169. search-path-specification->sexp
  170. native-search-paths))))))
  171. (mlet %store-monad ((guile (package->derivation (or guile (default-guile))
  172. system #:graft? #f)))
  173. (gexp->derivation name builder
  174. #:system system
  175. #:target target
  176. #:guile-for-build guile)))
  177. (define tree-sitter-build-system
  178. (build-system
  179. (name 'tree-sitter)
  180. (description "The Tree-sitter grammar build system")
  181. (lower lower)))
  182. ;;; tree-sitter.scm ends here