From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp10.migadu.com ([2001:41d0:8:6d80::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms5.migadu.com with LMTPS id 6MJSL6+VgGPpJAEAbAwnHQ (envelope-from ) for ; Fri, 25 Nov 2022 11:15:11 +0100 Received: from aspmx1.migadu.com ([2001:41d0:8:6d80::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp10.migadu.com with LMTPS id wLt9Lq+VgGMiGwAAG6o9tA (envelope-from ) for ; Fri, 25 Nov 2022 11:15:11 +0100 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 39BF93EED7 for ; Fri, 25 Nov 2022 11:15:11 +0100 (CET) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oyVjc-00069e-Gq; Fri, 25 Nov 2022 05:15:04 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oyVja-00069W-SC for guix-patches@gnu.org; Fri, 25 Nov 2022 05:15:02 -0500 Received: from debbugs.gnu.org ([209.51.188.43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oyVja-0006zC-JZ for guix-patches@gnu.org; Fri, 25 Nov 2022 05:15:02 -0500 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1oyVja-0004Ow-Cl for guix-patches@gnu.org; Fri, 25 Nov 2022 05:15:02 -0500 X-Loop: help-debbugs@gnu.org Subject: [bug#49946] [PATCH v7 06/32] build-system: Add tree-sitter-build-system. Resent-From: Pierre Langlois Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Fri, 25 Nov 2022 10:15:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 49946 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 49946@debbugs.gnu.org Cc: Pierre Langlois Received: via spool by 49946-submit@debbugs.gnu.org id=B49946.166937125216841 (code B ref 49946); Fri, 25 Nov 2022 10:15:02 +0000 Received: (at 49946) by debbugs.gnu.org; 25 Nov 2022 10:14:12 +0000 Received: from localhost ([127.0.0.1]:33596 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oyVik-0004NY-VV for submit@debbugs.gnu.org; Fri, 25 Nov 2022 05:14:11 -0500 Received: from mout.gmx.net ([212.227.15.15]:58887) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oyVii-0004NJ-3w for 49946@debbugs.gnu.org; Fri, 25 Nov 2022 05:14:09 -0500 Received: from labiere ([82.69.64.142]) by mail.gmx.net (mrgmx004 [212.227.17.184]) with ESMTPSA (Nemesis) id 1MF3DW-1pDw380OBk-00FTYh; Fri, 25 Nov 2022 11:14:02 +0100 References: <87mtfi63ut.fsf@gmx.com> <20221125012142.22579-1-pierre.langlois@gmx.com> <20221125012142.22579-7-pierre.langlois@gmx.com> User-agent: mu4e 1.8.11; emacs 28.2 From: Pierre Langlois Date: Fri, 25 Nov 2022 01:57:21 +0000 In-reply-to: <20221125012142.22579-7-pierre.langlois@gmx.com> Message-ID: <87r0xrcpei.fsf@gmx.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Provags-ID: V03:K1:E4H3QSjbkqpNsCbOBY8GIFnPKi+n6f/T/e/+eMRMc9flTtqyjNM walxEI7NVuSeLV6N78p8mQLNnxrPGQCaIHcbn3rsCsF/EbiUUA1gNq+uEjmCTdWuRCPa6XV 44P/cb5Uhkg2vfOTsjudp36Dz/VANRAZc9QQS/xRoCpBvo1rMxUTHsKTUc+3cADBDQPxyRJ Gzf+O5DM8HBlptb/WCBCQ== UI-OutboundReport: notjunk:1;M01:P0:XvJ4sFxpvMc=;9Av/coRHkWP07fmI0F/yGNwBeO6 tFp1BXmujFit2rmPNY7Sc1S/r+vmcNPomuYZhe38emYZ0qv5Lag6NxjRieVbnhETnlenc+3yt PuPIIvpzKDSgblUiCvFWhtdRbmtEPy1qJctzssTScnn0COSKl6hIyEfbS08mXmbv/taVv0oEi 7ijZWIRb2SCSCXHvyQwIVvmMZfzoTIIU0RWe71bePd7h4PxlyvDsxxGNblgeolZdpEMSwOdro tDIm3ou2wuN6utzMfkyqioJd0/dcAHVwd8AiTmGz9I/lmUi+7ZMtjlIWtbX1r+JZlHVq3JZ0M NcgLFM0Sn9ia40fsk1p6/ll1QeYBsbDm9n12jnLcX81nUPJBK6U4P5FG9iflSSyUfwWIdF9f6 T7pndZjMJ8p9zEO17d9igEC4rrxaWGbNqiwWDbvp4suayEhkbl0xHDGErd7X1CQX5VbmiqKdh hEUFg6OTudN3TpJ0MUg545PAAwEViQ7wA979f+PR3TM4GwJYskUOfbMDlgRMm+QEKDE7374cM G5XdfzcB7zek/VJ4v4DubjhpzClNM/tTmD//PUbhn/mJ7SWRnR6vweVCS5NGKwhR+MDKMfQwV oD6zfmZTHMcrahsaM3MWmKibQDhI4NaDaIYYcJyvfQeNrgBaG1Ne6FPrwn++x6M8DNhCWL9hw pgS8+W1AR4qO57PyHQjjjXNdB9aF0F+QPAhuxTiy8aJnlzLnGbFfmrEqWAHBFmMZ0uKHTjPGd MGSAtRF3KshywQ7cYIUfjynW9QgUvPpmnKAe6rLSRg+Msjou+/+muhgQI+mRV4kaV63veoZT3 ChcIIFxyuAW2VsrS+D1ORkdcvRyeD7IbUsYrLEu4DWOhC8OJs7Lg6L6p6aJw5dRqNlQL6aQUG RJKlwn+VaGCC2myBpv+SzTV4sHtFeyatXqjN5Ga3Xx2vi3krZ9SYWjeGqaxj4qJ3SqT3eSl2U S3bUX7ueC2aKHwvWsX5D5m3zk2U= X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+larch=yhetil.org@gnu.org Sender: guix-patches-bounces+larch=yhetil.org@gnu.org X-Migadu-Flow: FLOW_IN X-Migadu-Country: US ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1669371311; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:resent-cc:resent-from:resent-sender: resent-message-id:in-reply-to:in-reply-to:references:references: list-id:list-help:list-unsubscribe:list-subscribe:list-post; bh=PGGBNzwdiBJfHmO62cOXXVVS5IJbRddCv17NN4JNJCo=; b=BM9RVgRmxvRQU2nFWyAJccNGpPud6B6E3hF4WiEpjELTkRQ3GF75PwXX92pOfF21H9iK/S byJmw8keFJkmlgbvBFYq2wUPfAK+46FU18iSbfbSSo7J4UEsCfu/L+zK3jhub323tYj1nw nfiLyE5EzLEpeWb8aLAb74S5PSIGvD+YHXeskrcnyLApAI5Cu990OWJAQE8J21NU+kuIrc laASZjfN6kZOT1/B5zWoG2/J3DIRdAV8tQngMeC26/1PmriTGbtIeLuQs+t5tO9KuDsmUm EWsMO2N4NHIWKImqRMxB0NyjVCIIk/z/uHOmxveXPXa/aspoKmkyBsna0UrmmA== ARC-Seal: i=1; s=key1; d=yhetil.org; t=1669371311; a=rsa-sha256; cv=none; b=lHwhd+0PMaTkbFkWNlYQl340iHLEu2salJzSNtJFUVL3BZb6QmfitO1tW2XSk6C+vMV1XB Vub6RpG33zA4U3QtfO9zbkoKtxE/YMx3OGX2paG0X8GNw+VvZupDpNoaUsIqMnsY6TbqEt g+dyZt66ugAYfWKMlFWAgO1pLp5BnkRIU6CNFAK9riEzpyBlaqyq22n41hjRDsPvs6P2sF nb959Wox+KLTYRoXKMtNns/COmtKENO3wwpf1imL/HJJDD4BQAZ5lb0YR2wBYcDtGJ5U7L Kf9NfTLckzsKEYW3nxcBeddyhcrs27J7x6VeUVT/GSM/TSGhHQrjGRXpFL5Dzw== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=none; dmarc=fail reason="SPF not aligned (relaxed), No valid DKIM" header.from=gmx.com (policy=none); spf=pass (aspmx1.migadu.com: domain of "guix-patches-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="guix-patches-bounces+larch=yhetil.org@gnu.org" X-Migadu-Spam-Score: -0.78 Authentication-Results: aspmx1.migadu.com; dkim=none; dmarc=fail reason="SPF not aligned (relaxed), No valid DKIM" header.from=gmx.com (policy=none); spf=pass (aspmx1.migadu.com: domain of "guix-patches-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="guix-patches-bounces+larch=yhetil.org@gnu.org" X-Migadu-Queue-Id: 39BF93EED7 X-Spam-Score: -0.78 X-Migadu-Scanner: scn0.migadu.com X-TUID: YI9UBqvjW8iQ --=-=-= Content-Type: multipart/signed; boundary="==-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" --==-=-= Content-Type: text/plain It appears this email is making it through, so here it is as an attachment: --==-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQFMBAEBCgA2FiEEctU9gYy29KFyWDdMqPyeRH9PfVQFAmOAlWYYHHBpZXJyZS5s YW5nbG9pc0BnbXguY29tAAoJEKj8nkR/T31UIo0H/iRioXzQ/9ulOwlNlgn2+FEi fgAUL+jF3uYEX96rWrBLIY2EDdGU1O+e/ymxxkonDkg5VV3Hp+qYNm+IfSPoxtdg frfk+60D0BIS82gTve6FWnjBCtlzVFLEHb6XuRk9+pgKOh2s/JsqLp+DFAYCWoFN onncjb7bBlNIsfH2cYfx5Bmj3GLXbNP1InCChE0WMSNCY7ZdBX1ph6Spsf6s0syL FjKiy8nLz852YsReR1RMxGr2fdxNQCbWMFr3w+3NoyfE5RXhsTfD4b+TlZv0Gjp8 5ToWkOV7Eys2YmjahRbCXx9H9IuCFi+qWMsBO+CdTNagyAlBv7I9VCwRSBRlfZg= =lxXa -----END PGP SIGNATURE----- --==-=-=-- --=-=-= Content-Type: text/x-patch; charset=utf-8 Content-Disposition: attachment; filename=0006-build-system-Add-tree-sitter-build-system.patch Content-Transfer-Encoding: quoted-printable >From 4a3c1fff8460a03bfb7c1aada9863205cd6f22fd Mon Sep 17 00:00:00 2001 From: Pierre Langlois Date: Tue, 29 Mar 2022 20:13:34 +0100 Subject: [PATCH v7 06/32] build-system: Add tree-sitter-build-system. * guix/build-system/tree-sitter.scm: New module. * guix/build/tree-sitter-build-system.scm: Likewise. * Makefile.am (MODULES): Add them. * doc/guix.texi: Document it. --- Makefile.am | 2 + doc/guix.texi | 21 ++- guix/build-system/tree-sitter.scm | 190 ++++++++++++++++++++++++ guix/build/tree-sitter-build-system.scm | 153 +++++++++++++++++++ 4 files changed, 365 insertions(+), 1 deletion(-) create mode 100644 guix/build-system/tree-sitter.scm create mode 100644 guix/build/tree-sitter-build-system.scm diff --git a/Makefile.am b/Makefile.am index c3af23b68e..a16c4fcd7e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -178,6 +178,7 @@ MODULES =3D \ guix/build-system/ruby.scm \ guix/build-system/scons.scm \ guix/build-system/texlive.scm \ + guix/build-system/tree-sitter.scm \ guix/build-system/trivial.scm \ guix/ftp-client.scm \ guix/http-client.scm \ @@ -234,6 +235,7 @@ MODULES =3D \ guix/build/ruby-build-system.scm \ guix/build/scons-build-system.scm \ guix/build/texlive-build-system.scm \ + guix/build/tree-sitter-build-system.scm \ guix/build/waf-build-system.scm \ guix/build/haskell-build-system.scm \ guix/build/julia-build-system.scm \ diff --git a/doc/guix.texi b/doc/guix.texi index e547d469f4..4e997f7176 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -79,7 +79,7 @@ Copyright @copyright{} 2020 Jack Hill@* Copyright @copyright{} 2020 Naga Malleswari@* Copyright @copyright{} 2020, 2021 Brice Waegeneire@* Copyright @copyright{} 2020 R Veera Kumar@* -Copyright @copyright{} 2020, 2021 Pierre Langlois@* +Copyright @copyright{} 2020, 2021, 2022 Pierre Langlois@* Copyright @copyright{} 2020 pinoaffe@* Copyright @copyright{} 2020 Andr=C3=A9 Batista@* Copyright @copyright{} 2020, 2021 Alexandru-Sergiu Marton@* @@ -9732,6 +9732,25 @@ be specified with the @code{#:node} parameter which = defaults to @code{node}. @end defvr =20 +@defvr {Scheme Variable} tree-sitter-build-system + +This variable is exported by @code{(guix build-system tree-sitter)}. It +implements procedures to compile grammars for the +@url{https://tree-sitter.github.io/tree-sitter/, Tree-sitter} parsing +library. It essentially runs @code{tree-sitter generate} to translate +@code{grammar.js} grammars to JSON and then to C. Which it then +compiles to native code. + +Tree-sitter packages may support multiple grammars, so this build system +supports a @code{#:grammar-directories} keyword to specify a list of +locations where a @code{grammar.js} file may be found. + +Grammars sometimes depend on each other, such as C++ depending on C and +TypeScript depending on JavaScript. You may use inputs to declare such +dependencies. + +@end defvr + Lastly, for packages that do not need anything as sophisticated, a ``trivial'' build system is provided. It is trivial in the sense that it provides basically no support: it does not pull any implicit inputs, diff --git a/guix/build-system/tree-sitter.scm b/guix/build-system/tree-sit= ter.scm new file mode 100644 index 0000000000..aeb96e3ef5 --- /dev/null +++ b/guix/build-system/tree-sitter.scm @@ -0,0 +1,190 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright =C2=A9 2022 Pierre Langlois +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see . + +(define-module (guix build-system tree-sitter) + #:use-module (guix store) + #:use-module (guix utils) + #:use-module (guix packages) + #:use-module (guix gexp) + #:use-module (guix monads) + #:use-module (guix search-paths) + #:use-module (guix build-system) + #:use-module (guix build-system gnu) + #:use-module (guix build-system node) + #:use-module (ice-9 match) + #:export (%tree-sitter-build-system-modules + tree-sitter-build + tree-sitter-build-system)) + +(define %tree-sitter-build-system-modules + ;; Build-side modules imported by default. + `((guix build tree-sitter-build-system) + ,@%node-build-system-modules)) + +(define* (lower name + #:key source inputs native-inputs outputs system target + #:allow-other-keys + #:rest arguments) + "Return a bag for NAME from the given arguments." + (define private-keywords + `(#:inputs #:native-inputs #:outputs ,@(if target + '() + '(#:target)))) + (define node + (module-ref (resolve-interface '(gnu packages node)) + 'node-lts)) + (define tree-sitter + (module-ref (resolve-interface '(gnu packages tree-sitter)) + 'tree-sitter)) + (define tree-sitter-cli + (module-ref (resolve-interface '(gnu packages tree-sitter)) + 'tree-sitter-cli)) + ;; Grammars depend on each other via JS modules, which we package into a + ;; dedicated js output. + (define grammar-inputs + (map (match-lambda + ((name package) + `(,name ,package "js"))) + inputs)) + (bag + (name name) + (system system) (target target) + (build-inputs `(,@(if source + `(("source" ,source)) + '()) + ("node" ,node) + ("tree-sitter-cli" ,tree-sitter-cli) + ,@native-inputs + ,@(if target '() grammar-inputs) + ;; Keep the standard inputs of 'gnu-build-system'. + ,@(if target + (standard-cross-packages target 'host) + '()) + ,@(standard-packages))) + (host-inputs `(("tree-sitter" ,tree-sitter) + ,@(if target grammar-inputs '()))) + ;; Keep the standard inputs of 'gnu-buid-system'. + (target-inputs (if target + (standard-cross-packages target 'target) + '())) + ;; XXX: this is a hack to get around issue #41569. + (outputs (match outputs + (("out") (cons "js" outputs)) + (_ outputs))) + (build (if target tree-sitter-cross-build tree-sitter-build)) + (arguments (strip-keyword-arguments private-keywords arguments)))) + +(define* (tree-sitter-build name inputs + #:key + source + (phases '%standard-phases) + (grammar-directories '(".")) + (tests? #t) + (outputs '("out" "js")) + (search-paths '()) + (system (%current-system)) + (guile #f) + (imported-modules %tree-sitter-build-system-mo= dules) + (modules '((guix build utils) + (guix build tree-sitter-build-syste= m)))) + (define builder + (with-imported-modules imported-modules + #~(begin + (use-modules #$@(sexp->gexp modules)) + (tree-sitter-build #:name #$name + #:source #+source + #:system #$system + #:phases #$phases + #:tests? #$tests? + #:grammar-directories '#$grammar-directories + #:outputs #$(outputs->gexp outputs) + #:search-paths '#$(sexp->gexp + (map search-path-specifica= tion->sexp + search-paths)) + #:inputs #$(input-tuples->gexp inputs))))) + + (mlet %store-monad ((guile (package->derivation (or guile (default-guile= )) + system #:graft? #f))) + (gexp->derivation name builder + #:system system + #:guile-for-build guile))) + +(define* (tree-sitter-cross-build name + #:key + target + build-inputs target-inputs host-inputs + guile source + (phases '%standard-phases) + (grammar-directories '(".")) + (tests? #t) + (outputs '("out" "js")) + (search-paths '()) + (native-search-paths '()) + (system (%current-system)) + (build (nix-system->gnu-triplet system)) + (imported-modules %tree-sitter-build-sys= tem-modules) + (modules '((guix build utils) + (guix build tree-sitter-build= -system)))) + (define builder + (with-imported-modules imported-modules + #~(begin + (use-modules #$@(sexp->gexp modules)) + + (define %build-host-inputs + #+(input-tuples->gexp build-inputs)) + + (define %build-target-inputs + (append #$(input-tuples->gexp host-inputs) + #+(input-tuples->gexp target-inputs))) + + (define %build-inputs + (append %build-host-inputs %build-target-inputs)) + + (tree-sitter-build #:name #$name + #:source #+source + #:system #$system + #:build #$build + #:target #$target + #:phases #$phases + #:tests? #$tests? + #:grammar-directories '#$grammar-directories + #:outputs #$(outputs->gexp outputs) + #:inputs %build-target-inputs + #:native-inputs %build-host-inputs + #:search-paths '#$(sexp->gexp + (map search-path-specifica= tion->sexp + search-paths)) + #:native-search-paths '#$(sexp->gexp + (map + search-path-specif= ication->sexp + native-search-path= s)))))) + + (mlet %store-monad ((guile (package->derivation (or guile (default-guile= )) + system #:graft? #f))) + (gexp->derivation name builder + #:system system + #:target target + #:guile-for-build guile))) + +(define tree-sitter-build-system + (build-system + (name 'tree-sitter) + (description "The Tree-sitter grammar build system") + (lower lower))) + +;;; tree-sitter.scm ends here diff --git a/guix/build/tree-sitter-build-system.scm b/guix/build/tree-sitt= er-build-system.scm new file mode 100644 index 0000000000..574b0f2a1c --- /dev/null +++ b/guix/build/tree-sitter-build-system.scm @@ -0,0 +1,153 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright =C2=A9 2022 Pierre Langlois +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see . + +(define-module (guix build tree-sitter-build-system) + #:use-module ((guix build node-build-system) #:prefix node:) + #:use-module (guix build json) + #:use-module (guix build utils) + #:use-module (ice-9 match) + #:use-module (ice-9 regex) + #:use-module (srfi srfi-1) + #:export (%standard-phases + tree-sitter-build)) + +;; Commentary: +;; +;; Build procedures for tree-sitter grammar packages. This is the +;; builder-side code, which builds on top fo the node build-system. +;; +;; Tree-sitter grammars are written in JavaScript and compiled to a native +;; shared object. The `tree-sitter generate' command invokes `node' in or= der +;; to evaluate the grammar.js into a grammar.json file, which is then +;; translated into C code. We then compile the C code ourselves. Packages +;; also sometimes add extra manually written C/C++ code. +;; +;; In order to support grammars depending on each other, such as C and C++, +;; JavaScript and TypeScript, this build-system installs the source of the +;; node module in a dedicated "js" output. +;; +;; Code: + +(define* (patch-dependencies #:key inputs #:allow-other-keys) + "Rewrite dependencies in 'package.json'. We remove all runtime dependen= cies +and replace development dependencies with tree-sitter grammar node modules= ." + + (define (rewrite package.json) + (map (match-lambda + (("dependencies" @ . _) + '("dependencies" @)) + (("devDependencies" @ . _) + `("devDependencies" @ + ,@(filter-map (match-lambda + ((key . directory) + (let ((node-module + (string-append directory + "/lib/node_modules/" + key))) + (and (directory-exists? node-module) + `(,key . ,node-module))))) + (alist-delete "node" inputs)))) + (other other)) + package.json)) + + (node:with-atomic-json-file-replacement "package.json" + (match-lambda + (('@ . package.json) + (cons '@ (rewrite package.json)))))) + +;; FIXME: The node build-system's configure phase does not support +;; cross-compiling so we re-define it. +(define* (configure #:key native-inputs inputs #:allow-other-keys) + (invoke (search-input-file (or native-inputs inputs) "/bin/npm") + "--offline" "--ignore-scripts" "install")) + +(define* (build #:key grammar-directories #:allow-other-keys) + (for-each (lambda (dir) + (with-directory-excursion dir + ;; Avoid generating binding code for other languages, we do + ;; not support this use-case yet and it relies on running + ;; `node-gyp' to build native addons. + (invoke "tree-sitter" "generate" "--no-bindings"))) + grammar-directories)) + +(define* (check #:key grammar-directories tests? #:allow-other-keys) + (when tests? + (for-each (lambda (dir) + (with-directory-excursion dir + (invoke "tree-sitter" "test"))) + grammar-directories))) + +(define* (install #:key target grammar-directories outputs #:allow-other-k= eys) + (let ((lib (string-append (assoc-ref outputs "out") + "/lib/tree-sitter"))) + (mkdir-p lib) + (define (compile-language dir) + (with-directory-excursion dir + (let ((lang (assoc-ref (call-with-input-file "src/grammar.json" + read-json) + "name")) + (source-file (lambda (path) + (if (file-exists? path) + path + #f)))) + (apply invoke + `(,(if target + (string-append target "-g++") + "g++") + "-shared" + "-fPIC" + "-fno-exceptions" + "-O2" + "-g" + "-o" ,(string-append lib "/" lang ".so") + ;; An additional `scanner.{c,cc}' file is sometimes + ;; provided. + ,@(cond + ((source-file "src/scanner.c") + =3D> (lambda (file) (list "-xc" "-std=3Dc99" file))) + ((source-file "src/scanner.cc") + =3D> (lambda (file) (list file))) + (else '())) + "-xc" "src/parser.c"))))) + (for-each compile-language grammar-directories))) + +(define* (install-js #:key native-inputs inputs outputs #:allow-other-keys) + (invoke (search-input-file (or native-inputs inputs) "/bin/npm") + "--prefix" (assoc-ref outputs "js") + "--global" + "--offline" + "--loglevel" "info" + "--production" + ;; Skip scripts to prevent building bindings via GYP. + "--ignore-scripts" + "install" "../package.tgz")) + +(define %standard-phases + (modify-phases node:%standard-phases + (replace 'patch-dependencies patch-dependencies) + (replace 'configure configure) + (replace 'build build) + (replace 'check check) + (replace 'install install) + (add-after 'install 'install-js install-js))) + +(define* (tree-sitter-build #:key inputs (phases %standard-phases) + #:allow-other-keys #:rest args) + (apply node:node-build #:inputs inputs #:phases phases args)) + +;;; tree-sitter-build-system.scm ends here --=20 2.38.1 --=-=-=--