;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2015 宋文武 <iyzsong@envs.net>
;;; Copyright © 2016, 2018, 2020, 2023 Efraim Flashner <efraim@flashner.co.il>
;;; Copyright © 2017, 2018, 2024 Ricardo Wurmus <rekado@elephly.net>
;;; Copyright © 2017 Corentin Bocquillon <corentin@nybble.fr>
;;; Copyright © 2017–2021 Tobias Geerinckx-Rice <me@tobias.gr>
;;; Copyright © 2018 Fis Trivial <ybbs.daans@hotmail.com>
;;; Copyright © 2018 Marius Bakke <marius@gnu.org>
;;; Copyright © 2018 Mark H Weaver <mhw@netris.org>
;;; Copyright © 2018 Tomáš Čech <sleep_walker@gnu.org>
;;; Copyright © 2018, 2020 Marius Bakke <mbakke@fastmail.com>
;;; Copyright © 2018 Alex Vong <alexvong1995@gmail.com>
;;; Copyright © 2019, 2020 Brett Gilio <brettg@gnu.org>
;;; Copyright © 2019 Jonathan Brielmaier <jonathan.brielmaier@web.de>
;;; Copyright © 2019 Mathieu Othacehe <m.othacehe@gmail.com>
;;; Copyright © 2020 Liliana Marie Prikler <liliana.prikler@gmail.com>
;;; Copyright © 2020 Yuval Kogman <nothingmuch@woobling.org>
;;; Copyright © 2020 Jakub Kądziołka <kuba@kadziolka.net>
;;; Copyright © 2021 qblade <qblade@protonmail.com>
;;; Copyright © 2021, 2023, 2024, 2025 Maxim Cournoyer <maxim@guixotic.coop>
;;; Copyright © 2022, 2023 Juliana Sims <juli@incana.org>
;;; Copyright © 2024 Evgeny Pisemsky <mail@pisemsky.site>
;;; Copyright © 2024 Janneke Nieuwenhuizen <janneke@gnu.org>
;;; Copyright © 2025,2026 Anderson Torres <anderson.torres.8519@gmail.com>
;;; Copyright © 2025 Aiden Isik <aidenisik+git@member.fsf.org>
;;; Copyright © 2025 Josep Bigorra <jjbigorra@gmail.com>
;;; Copyright © 2025 John Kehayias <john.kehayias@protonmail.com>
;;; Copyright © 2026 Nemin <bergengocia@protonmail.com>
;;;
;;; 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 <http://www.gnu.org/licenses/>.

(define-module (gnu packages build-tools)
  #:use-module (ice-9 optargs)
  #:use-module ((guix licenses) #:prefix license:)
  #:use-module (gnu packages c)
  #:use-module (guix build-system cmake)
  #:use-module (guix build-system copy)
  #:use-module (guix build-system gnu)
  #:use-module (guix build-system guile)
  #:use-module (guix build-system hare)
  #:use-module (guix build-system meson)
  #:use-module (guix build-system pyproject)
  #:use-module (guix build-system python)
  #:use-module (guix build-system trivial)
  #:use-module (guix deprecation)
  #:use-module (guix download)
  #:use-module (guix gexp)
  #:use-module (guix git-download)
  #:use-module (guix modules)
  #:use-module (guix packages)
  #:use-module (guix search-paths)
  #:use-module (guix utils)
  #:use-module (gnu packages)
  #:use-module (gnu packages adns)
  #:use-module (gnu packages algebra)
  #:use-module (gnu packages autotools)
  #:use-module (gnu packages base)
  #:use-module (gnu packages bash)
  #:use-module (gnu packages check)
  #:use-module (gnu packages code)
  #:use-module (gnu packages compression)
  #:use-module (gnu packages cpp)
  #:use-module (gnu packages cppi)
  #:use-module (gnu packages elf)
  #:use-module (gnu packages gcc)
  #:use-module (gnu packages guile)
  #:use-module (gnu packages guile-xyz)
  #:use-module (gnu packages linux)
  #:use-module (gnu packages lisp)
  #:use-module (gnu packages logging)
  #:use-module (gnu packages lua)
  #:use-module (gnu packages man)
  #:use-module (gnu packages ninja)
  #:use-module (gnu packages package-management)
  #:use-module (gnu packages pcre)
  #:use-module (gnu packages perl)
  #:use-module (gnu packages pkg-config)
  #:use-module (gnu packages pretty-print)
  #:use-module (gnu packages protobuf)
  #:use-module (gnu packages python)
  #:use-module (gnu packages python-build)
  #:use-module (gnu packages python-check)
  #:use-module (gnu packages python-crypto)
  #:use-module (gnu packages python-web)
  #:use-module (gnu packages python-xyz)
  #:use-module (gnu packages regex)
  #:use-module (gnu packages rpc)
  #:use-module (gnu packages serialization)
  #:use-module (gnu packages sqlite)
  #:use-module (gnu packages tls)
  #:use-module (gnu packages unicode)
  #:use-module (gnu packages version-control)
  #:use-module (gnu packages xml))

(define-public acr
  (package
    (name "acr")
    (version "2.2.4")
    (source
     (origin
       (method git-fetch)
       (uri (git-reference
              (url "https://github.com/radareorg/acr")
              (commit version)))
       (file-name (git-file-name name version))
       (sha256
        (base32
         "1qd7p50b9gkh2ihf7gs6xpdkb5jk8frg90ajqlw1pbza8735f9q1"))
       (snippet
        #~(begin
            (delete-file "configure")))))
    (build-system gnu-build-system)
    (arguments
     (list
      #:tests? #f                     ; No tests
      #:phases
      #~(modify-phases %standard-phases
          (delete 'bootstrap)
          (add-after 'patch-source-shebangs 'bootstrap-after-patch-source-shebangs
            (assoc-ref %standard-phases 'bootstrap)))))
    (synopsis "Autoconf replacement written in pure Bash")
    (description
     "@acronym{ACR, Autoconf Replacement} tries to replace autoconf
functionality generating a full-compatible configure script, but relying on
Bourne shell script instead of m4.")
    (home-page "https://github.com/radareorg/acr")
    (license license:gpl2)))

(define-public bam
  (package
    (name "bam")
    (version "0.5.1")
    (source (origin
              ;; do not use auto-generated tarballs
              (method git-fetch)
              (uri (git-reference
                    (url "https://github.com/matricks/bam")
                    (commit (string-append "v" version))))
              (file-name (git-file-name name version))
              (sha256
               (base32
                "13br735ig7lygvzyfd15fc2rdygrqm503j6xj5xkrl1r7w2wipq6"))))
    (build-system gnu-build-system)
    (arguments
     `(#:make-flags `(,(string-append "CC=" ,(cc-for-target))
                      ,(string-append "INSTALL_PREFIX="
                                      (assoc-ref %outputs "out")))
       #:test-target "test"
       #:phases
       (modify-phases %standard-phases
         (delete 'configure))))
    (native-inputs
     `(("python" ,python-2)))
    (inputs
     (list lua))
    (home-page "https://matricks.github.io/bam/")
    (synopsis "Fast and flexible build system")
    (description "Bam is a fast and flexible build system.  Bam uses Lua to
describe the build process.  It takes its inspiration for the script files
from scons.  While scons focuses on being 100% correct when building, bam
makes a few sacrifices to acquire fast full and incremental build times.")
    (license license:bsd-3)))

(define-public bear
  (package
    (name "bear")
    (version "3.1.6")
    (source
     (origin
       (method git-fetch)
       (uri (git-reference
             (url "https://github.com/rizsotto/Bear")
             (commit version)))
       (file-name (git-file-name name version))
       (sha256
        (base32 "0pnrsnwvsqby0vgb33zsrjznb7l82ji7i4aigk32hg3rl674qqvx"))))
    (build-system cmake-build-system)
    (arguments
     `(#:phases (modify-phases %standard-phases
                  (add-after 'unpack 'disable-TEST_BEFORE_INSTALL
                    (lambda _
                      (substitute* "CMakeLists.txt"
                        ;; Delete the matching line—and comment out the next.
                        ((".*TEST_(BEFORE_INSTALL|COMMAND).*") "#"))))
                  (add-before 'check 'set-build-environment
                    (lambda _
                      (setenv "CC" "gcc")))
                  (replace 'check
                    ;; TODO: Test configuration is incomplete.
                    (lambda* (#:key tests? #:allow-other-keys)
                      (when tests?
                        (invoke "ctest")))))))
    (inputs
     `(("c-ares" ,c-ares)
       ("fmt" ,fmt-9)
       ("grpc" ,grpc)
       ("nlohmann-json" ,nlohmann-json)
       ("protobuf" ,protobuf)
       ("python" ,python-wrapper)
       ("re2" ,re2)
       ("spdlog" ,spdlog-1.13)))
    (native-inputs
     `(("abseil-cpp" ,abseil-cpp)
       ("googletest" ,googletest)
       ("openssl" ,openssl)
       ("pkg-config" ,pkg-config)
       ("python-lit" ,python-lit)
       ("zlib" ,zlib)))
    (home-page "https://github.com/rizsotto/Bear")
    (synopsis "Tool for generating a compilation database")
    (description "A JSON compilation database is used in the Clang project to
provide information on how a given compilation unit is processed.  With this,
it is easy to re-run the compilation with alternate programs.  Bear is used to
generate such a compilation database.")
    (license license:gpl3+)))

(define-public bmake
  (package
    (name "bmake")
    (version "20251111")
    (source
     (origin
       (method url-fetch)
       (uri (string-append
             "http://www.crufty.net/ftp/pub/sjg/bmake-" version ".tar.gz"))
       (sha256
        (base32 "0q30a04lg91g4932xgl0hg4c798inr5ky8fq6cwqzfkpar8zi8s5"))
       (patches (search-patches "bmake-run-check-separately.patch"))))
    (build-system gnu-build-system)
    (inputs
     (list bash-minimal))
    (native-inputs
     (list bc coreutils))
    (arguments
     (list
      #:test-target "test"
      #:phases
      #~(modify-phases %standard-phases
          ;; Ensure that a store path to /bin/sh is detected as a POSIX shell by
          ;; modifying the pattern matching in the use_defshell() function.
          ;; Without this, the tests won't correctly detect our provided default
          ;; shell as a POSIX shell and will thus fail.
          (add-after 'unpack 'fix-shell-detection
            (lambda _
              (substitute* "configure"
                (("sh\\|/bin/sh\\|\\*/bsh)")
                 "*/bin/sh)"))))
          (add-after 'configure 'fix-test ; fix from nixpkgs
            (lambda* (#:key inputs native-inputs #:allow-other-keys)
              (substitute* "unit-tests/unexport-env.mk"
                (("PATH=\t/bin:/usr/bin:/sbin:/usr/sbin")
                 "PATH := ${PATH}"))
              (substitute* '("unit-tests/varmod-sun-shell1.exp"
                             "unit-tests/suff.exp")
                (("/bin/sh")
                 (search-input-file (or native-inputs inputs) "/bin/sh")))
              (substitute* '("unit-tests/opt-keep-going-indirect.mk"
                             "unit-tests/opt-keep-going-indirect.exp")
                (("false")
                 (search-input-file (or native-inputs inputs) "/bin/false"))))))
      #:configure-flags
      #~(list
         (string-append
          "--with-defshell=" #$(this-package-input "bash-minimal") "/bin/sh")
         (string-append
          "--with-default-sys-path=" #$output "/share/mk"))
      #:make-flags
      #~(list
          "INSTALL=install"         ; use coreutils' install
          (string-append
            "BROKEN_TESTS="
            (string-join
              (list "cmd-interrupt"
                    "deptgt-interrupt"
                    "varmod-localtime"
                    ;; directive-export failures are related to TZ env.
                    ;; these tests are also disabled by nixpkgs.
                    "directive-export"
                    "directive-export-gmake"
              " "))))))
    (home-page "http://www.crufty.net/help/sjg/bmake.htm")
    (synopsis "BSD's make")
    (description
     "bmake is a program designed to simplify the maintenance of other
programs.  Its input is a list of specifications as to the files upon which
programs and other files depend.")
    (license license:bsd-3)))

(define-public gn
  (let ((commit "ee5b7e32b961a9da1933e9f46a018ba6cac8ef60")
        (revision "2277"))            ;as returned by `git describe`, used below
    (package
      (name "gn")
      (version (git-version "0.0" revision commit))
      (home-page "https://gn.googlesource.com/gn")
      (source (origin
                (method git-fetch)
                (uri (git-reference (url home-page) (commit commit)))
                (sha256
                 (base32
                  "19kkvwxl66vlzlfppbq03fmi59i5g8a1yc71fsfgwqqmx4wywd6w"))
                (file-name (git-file-name name version))))
      (build-system gnu-build-system)
      (arguments
       (list #:phases
             #~(modify-phases %standard-phases
                 (add-before 'configure 'set-build-environment
                   (lambda _
                     (setenv "CC" "gcc")
                     (setenv "CXX" "g++")
                     (setenv "CXXFLAGS" "-g -O2 -Wno-error=redundant-move")
                     (setenv "AR" "ar")))
                 (replace 'configure
                   (lambda _
                     (invoke "python" "build/gen.py"
                             "--no-last-commit-position")))
                 (add-after 'configure 'create-last-commit-position
                   (lambda _
                     ;; Mimic GenerateLastCommitPosition from gen.py.
                     (call-with-output-file "out/last_commit_position.h"
                       (lambda (port)
                         (format port
                                 "// Generated by Guix.

#ifndef OUT_LAST_COMMIT_POSITION_H_
#define OUT_LAST_COMMIT_POSITION_H_

#define LAST_COMMIT_POSITION_NUM ~a
#define LAST_COMMIT_POSITION \"~a (~a)\"

#endif  // OUT_LAST_COMMIT_POSITION_H_
"
                                 #$revision #$revision
                                 #$(string-take commit 12))))))
                 (replace 'build
                   (lambda _
                     (invoke "ninja" "-C" "out" "gn"
                             "-j" (number->string (parallel-job-count)))))
                 (replace 'check
                   (lambda* (#:key tests? #:allow-other-keys)
                     (if tests?
                         (begin
                           (invoke "ninja" "-C" "out" "gn_unittests"
                                   "-j" (number->string (parallel-job-count)))
                           (invoke "./out/gn_unittests"))
                         (format #t "test suite not run~%"))))
                 (replace 'install
                   (lambda _
                     (install-file "out/gn" (string-append #$output "/bin")))))))
      (native-inputs
       (list ninja python-wrapper))
      (synopsis "Generate Ninja build files")
      (description
       "GN is a tool that collects information about a project from @file{.gn}
files and generates build instructions for the Ninja build system.")
      ;; GN is distributed as BSD-3, but bundles some files from ICU using the
      ;; X11 license.
      (license (list license:bsd-3 license:x11)))))

(define-public meson
  (package
    (name "meson")
    (version "1.9.0")
    (source (origin
              (method url-fetch)
              (uri (string-append "https://github.com/mesonbuild/meson/"
                                  "releases/download/" version  "/meson-"
                                  version ".tar.gz"))
              (sha256
               (base32
                "13a9pj7d2mxgv5gbd78di4pb4w722vjis0vmk38m1vdm95v2f9yd"))))
    (build-system gnu-build-system)
    (arguments
     (list
      #:tests? #f                       ;disabled to avoid extra dependencies
      ;; Essentially a lighter copy of the former python-build-system.
      ;; Using it rather than pyproject-build-system allows to edit the latter
      ;; without a C++ world rebuild.
      #:phases
      #~(modify-phases %standard-phases
          (delete 'bootstrap)
          (delete 'configure)
          (replace 'build
            (lambda _
              (invoke "python" "./setup.py" "build")))
          (replace 'install
            (lambda _
              (invoke "python" "./setup.py" "install"
                      (string-append "--prefix=" #$output) "--no-compile")
              (invoke "python" "-m" "compileall"
                      "--invalidation-mode=unchecked-hash" #$output)))
          ;; Meson calls the various executables in out/bin through the
          ;; Python interpreter, so we cannot use the shell wrapper.
          (add-after 'install 'wrap
            (lambda _
              (let* ((mdist (car (find-files #$output "^mdist\\.py$")))
                     (site (dirname (dirname mdist))))
                (substitute* (string-append #$output "/bin/meson")
                  (("import sys" all)
                   (format #f "~a~%sys.path.insert(0, ~s)" all site)))))))))
    (native-inputs (list python-setuptools-bootstrap))
    (inputs (list python-wrapper ninja))
    (home-page "https://mesonbuild.com/")
    (synopsis "Build system designed to be fast and user-friendly")
    (description
     "The Meson build system is focused on user-friendliness and speed.
It can compile code written in C, C++, Fortran, Java, Rust, and other
languages.  Meson provides features comparable to those of the
Autoconf/Automake/make combo.  Build specifications, also known as @dfn{Meson
files}, are written in a custom domain-specific language (@dfn{DSL}) that
resembles Python.")
    (license license:asl2.0)))

(define-public muon
  (package
    (name "muon")
    (version "0.5.0")
    (source (origin
              (method git-fetch)
              (uri (git-reference
                     (url "https://github.com/muon-build/muon")
                     (commit version)))
              (file-name (git-file-name name version))
              (sha256
               (base32
                "1w0vkishj7r3swzg4m1fl3hacs8mycwhsrr5vw8sy67y81cihqbd"))))
    (build-system meson-build-system)
    (arguments
     (list #:meson (computed-file "null-package" #~(mkdir #$output))
           #:ninja samu-as-ninja-wrapper
           #:configure-flags #~(list "-Dsamurai=disabled")
           #:tests? #f                  ;to avoid extra dependencies
           #:phases
           #~(modify-phases %standard-phases
               (add-after 'unpack 'patch-/bin/sh
                 (lambda* (#:key inputs #:allow-other-keys)
                   (substitute* "tools/generate_test_check_script.py"
                     (("#!/bin/sh")
                      (string-append "#!" (search-input-file inputs
                                                             "bin/sh"))))))
               (add-after 'patch-source-shebangs 'build-muon-bootstrap
                 (lambda _
                   (setenv "CC" #$(cc-for-target))
                   (setenv "CFLAGS" "-DBOOTSTRAP_NO_SAMU")
                   (invoke "./bootstrap.sh" "build")))
               (add-after 'build-muon-bootstrap 'setup-muon-bootstrap-as-meson
                 (lambda _
                   (mkdir "bin")
                   (symlink "../build/muon-bootstrap" "bin/meson")
                   (setenv  "PATH" (string-append (getcwd) "/bin:"
                                                  (getenv "PATH"))))))))
    (native-inputs (list samurai))
    (inputs (list bash-minimal pkgconf))
    (native-search-paths (list $PKG_CONFIG_PATH))
    (home-page "https://muon.build/")
    (synopsis "Meson build system alternative implementation in C99")
    (description "Muon is an implementation of the meson build system in c99
with minimal dependencies.")
    (license license:gpl3)))            ;for the combined work

(define-public muon-as-meson-wrapper
  (package/inherit muon
    (name "muon-as-meson-wrapper")
    (build-system trivial-build-system)
    (arguments
     (list #:builder
           (with-imported-modules '((guix build utils))
             #~(begin
                 (use-modules (guix build utils))
                 (let ((bindir (string-append #$output "/bin"))
                       (samu (string-append #$(this-package-input "muon")
                                            "/bin/muon")))
                   (mkdir-p bindir)
                   (symlink samu (string-append bindir "/meson")))))))
    (inputs (list muon))
    (description "This package provides the @command{meson} command,
implemented as a symbolic link to the @command{muon} command of @code{muon}
package.")))

(define-public premake4
  (package
    (name "premake")
    (version "4.3")
    (source (origin
              (method url-fetch)
              (uri (string-append "mirror://sourceforge/premake/Premake/"
                                  version "/premake-" version "-src.zip"))
              (sha256
               (base32
                "1017rd0wsjfyq2jvpjjhpszaa7kmig6q1nimw76qx3cjz2868lrn"))))
    (build-system gnu-build-system)
    (native-inputs
     (list unzip)) ; for unpacking the source
    (arguments
     `(#:make-flags (list (string-append "CC=" ,(cc-for-target)))
       #:tests? #f ; No test suite
       #:phases
       (modify-phases %standard-phases
         (delete 'configure)
         (add-after 'unpack 'enter-source
           (lambda _ (chdir "build/gmake.unix") #t))
         (replace 'install
           (lambda* (#:key outputs #:allow-other-keys)
             (install-file "../../bin/release/premake4"
                           (string-append (assoc-ref outputs "out") "/bin"))
             #t)))))
    (synopsis "Portable software build tool")
    (description "@code{premake4} is a command line utility that reads a
scripted definition of a software project and outputs @file{Makefile}s or
other lower-level build files.")
    (home-page "https://premake.github.io")
    (license license:bsd-3)))

(define-public premake5
  (package
    (inherit premake4)
    (version "5.0.0-beta7")
    (source (origin
              (method url-fetch)
              (uri (string-append "https://github.com/premake/premake-core/"
                                  "releases/download/v" version
                                  "/premake-" version "-src.zip"))
              (sha256
               (base32
                "0q287af75d6w3c7dbfq7rmbh9isqzs9v30fjpm37lcafs2p7966k"))))
    (arguments
     (substitute-keyword-arguments (package-arguments premake4)
      ((#:phases phases)
       `(modify-phases ,phases
           (replace 'enter-source
             ;; For some reason we end up in the .github subdir of the source,
             ;; which is why we first go back a dir unlike in premake4.
             (lambda _ (chdir "..") #t))
           (add-after 'enter-source 'enter-build-dir
             (lambda _ (chdir "build/gmake.unix") #t))
           (add-after 'enter-source 'patch-builtin-uuidgen
             ;; Use built-in UUID generation
             (lambda _
               (substitute* "src/host/os_uuid.c"
                 (("#elif PLATFORM_LINUX")
                  "#elif 0"))
               (substitute* "build/gmake.unix/Premake5.make"
                 (("-luuid")
                  ""))
               (substitute* "premake5.lua"
                 (("filter \"system:linux or macosx\"")
                  "filter \"system:macosx\""))))
           (replace 'install
             (lambda* (#:key outputs #:allow-other-keys)
               (install-file "../../bin/release/premake5"
                             (string-append (assoc-ref outputs "out") "/bin"))
               #t))))))
    (description "@code{premake5} is a command line utility that reads a
scripted definition of a software project and outputs @file{Makefile}s or
other lower-level build files.")))

(define-public scons
  (package
    (name "scons")
    (version "4.9.1")
    (source (origin
              (method git-fetch)
              (uri (git-reference
                    (url "https://github.com/SCons/scons")
                    (commit version)))
              (file-name (git-file-name name version))
              (patches (search-patches "scons-test-environment.patch"))
              (sha256
               (base32
                "1h9653965bqf8zab4gbsilsmnhp6nxn5b5b9yvm6pf401qjx8n4x"))))
    (build-system pyproject-build-system)
    (arguments
     (list
      #:modules (append %pyproject-build-system-modules
                        '((ice-9 ftw) (srfi srfi-26)))
      #:phases
      #~(modify-phases (@ (guix build pyproject-build-system) %standard-phases)
          (add-after 'unpack 'adjust-hard-coded-paths
            (lambda _
              (substitute* "SCons/Script/Main.py"
                (("/usr/share/scons")
                 (string-append #$output "/share/scons")))))
          (replace 'check
            (lambda* (#:key tests? #:allow-other-keys)
              (when tests?
                ;; remove these tests as they require a read/write filesystem
                (delete-file "SCons/Variables/PathVariableTests.py")
                (invoke "python" "runtest.py" "--all" "--unit-only" ))))
          (add-after 'install 'move-manuals
            (lambda _
              ;; XXX: For some reason manuals get installed to the top-level
              ;; #$output directory.
              (with-directory-excursion #$output
                (let ((man1 (string-append #$output "/share/man/man1"))
                      (stray-manuals (scandir "."
                                              (cut string-suffix? ".1" <>))))
                  (mkdir-p man1)
                  (for-each (lambda (manual)
                              (link manual (string-append man1 "/" manual))
                              (delete-file manual))
                            stray-manuals))))))))
    (native-inputs
     ;; TODO: Add 'fop' when available in Guix to generate manuals.
     (list python-setuptools python-lxml python-wheel
           ;;For tests.
           python-psutil))
    (home-page "https://scons.org/")
    (synopsis "Software construction tool written in Python")
    (description
     "SCons is a software construction tool.  Think of SCons as an improved,
cross-platform substitute for the classic Make utility with integrated
functionality similar to autoconf/automake and compiler caches such as ccache.
In short, SCons is an easier, more reliable and faster way to build
software.")
    (license license:x11)))

(define-public scons-3
  (package
    (inherit scons)
    (version "3.1.2")
    (source
     (origin
       (method git-fetch)
       (uri (git-reference
             (url "https://github.com/SCons/scons")
             (commit version)))
       (file-name (git-file-name "scons" version))
       (sha256
        (base32 "0q6xq2y280fci3kay1z6638v7sv5p43vs7lsl1rrkgmxpwvkhx8b"))))
    (arguments
     (list
      #:tests? #f                         ; no 'python setup.py test' command
      #:phases
      #~(modify-phases %standard-phases
          (add-before 'build 'bootstrap
            (lambda _
              (invoke "python" "bootstrap.py" "build/scons" "DEVELOPER=guix")
              (chdir "build/scons"))))))
    (native-inputs (list python-setuptools python-wheel))))

(define-public tup
  (package
    (name "tup")
    (version "0.8")
    (source (origin
              (method url-fetch)
              (uri (string-append "https://gittup.org/tup/releases/tup-v"
                                  version ".tar.gz"))
              (sha256
               (base32
                "1yv60apd8dsigb74cjw1nzvqqqpjbsxz1i9dhq24jdkjwgsra3w4"))
              (modules '((guix build utils)))
              (snippet
               '(begin
                  ;; NOTE: Tup uses a slightly modified Lua, so it cannot be
                  ;; unbundled.  See: src/lua/tup-lua.patch
                  (delete-file-recursively "src/pcre")
                  (delete-file-recursively "src/sqlite3")
                  (delete-file-recursively "src/inih")
                  ;; ldpreload Used only on BSD.  Deleting to avoid putting
                  ;; license:bsd-2 in the licenses field
                  (delete-file-recursively "src/ldpreload")))))
    (build-system gnu-build-system)
    (arguments
     (list
      #:phases
      #~(modify-phases %standard-phases
          ;; There is a bootstrap script, but it doesn't do what you think - it
          ;; builds tup.
          (delete 'bootstrap)
          (replace 'configure
            (lambda* (#:key inputs #:allow-other-keys)
              (substitute* "build.sh"
                ;; LDFLAGS
                (("-lm") "-lm -lsqlite3 -linih `pcre2-config --libs8`")
                ;; CFLAGS
                (("-DHAVE_CONFIG_H") "-DHAVE_CONFIG_H `pcre2-config --cflags`")
                ;; Don't build bundled inih and pcre
                (("\\.\\./src/inih/ini\\.c \\.\\./src/pcre/\\*\\.c") "")
                ;; Don't build bundled sqlite3
                (("\\$CC \\$CFLAGS -c \\.\\./src/sqlite3/sqlite3\\.c.*") ""))
              (substitute* "src/tup/option.c"
                (("\"ini.h\"") "<ini.h>"))
              (substitute* '("src/tup/tupid.h"
                             "src/tup/db.c")
                (("sqlite3/sqlite3.h")
                 (search-input-file inputs "include/sqlite3.h")))
              (with-output-to-file "tup.config"
                (lambda _
                  (format #t (string-append "CONFIG_TUP_USE_SYSTEM_SQLITE=y~%"
                                            "CONFIG_TUP_USE_SYSTEM_PCRE=y~%"
                                            "CONFIG_TUP_USE_SYSTEM_INIH=y~%"))))))
          (delete 'check)    ; Most tests require fuse to be setup
          (replace 'build
            (lambda _
              ;; Based on bootstrap-nofuse.sh, but with a detour to patch-shebang.
              (invoke "./build.sh")
              (invoke "./build/tup" "init")
              (invoke "./build/tup" "generate" "--verbose" "build-nofuse.sh")
              (patch-shebang "build-nofuse.sh")
              (invoke "./build-nofuse.sh")))
          (replace 'install
            (lambda* (#:key outputs #:allow-other-keys)
              (let* ((outdir (assoc-ref outputs "out"))
                     (ftdetect (string-append outdir
                                              "/share/vim/vimfiles/ftdetect")))
                (install-file "tup" (string-append outdir "/bin"))
                (install-file "tup.1" (string-append outdir "/share/man/man1"))
                (install-file "contrib/syntax/tup.vim"
                              (string-append outdir "/share/vim/vimfiles/syntax"))
                (mkdir-p ftdetect)
                (with-output-to-file (string-append ftdetect "/tup.vim")
                  (lambda _
                    (display "au BufNewFile,BufRead Tupfile,*.tup setf tup")))))))))
    (inputs
     (list fuse libinih pcre2 sqlite))
    (native-inputs
     (list pkg-config))
    (home-page "https://gittup.org/tup/")
    (synopsis "Fast build system that's hard to get wrong")
    (description "Tup is a generic build system based on a directed acyclic
graphs of commands to be executed.  Tup instruments your build to detect the
exact dependencies of the commands, allowing you to take advantage of ideal
parallelism during incremental builds, and detecting any situations where
a build worked by accident.")
    (license (list
              license:gpl2
              license:x11))))     ; src/lua

(define-public osc
  (package
    (name "osc")
    (version "1.19.0")
    (source
     (origin
       (method git-fetch)
       (uri (git-reference
              (url "https://github.com/openSUSE/osc")
              (commit version)))
       (file-name (git-file-name name version))
       (sha256
        (base32 "09an4c5gjc99a6bfy4ax5yyng14v7b4fknkdzwl0hn89q5990xab"))))
    (build-system pyproject-build-system)
    (arguments
     (list
      #:tests? #f                       ; XXX: Fix tests.
      #:phases
      #~(modify-phases %standard-phases
          (add-before 'check 'check-setup
            (lambda* (#:key tests? #:allow-other-keys)
              (when tests?
                (setenv "HOME" (getcwd))))))))
    (native-inputs
     (list python-setuptools
           python-wheel
           diffstat))
    (inputs
     (list python-urllib3
           python-ruamel.yaml
           python-m2crypto
           python-pycurl
           rpm))                        ; for python-rpm
    (home-page "https://github.com/openSUSE/osc")
    (synopsis "Open Build Service command line tool")
    (description "@command{osc} is a command line interface to the Open Build
Service.  It allows you to checkout, commit, perform reviews etc.  The vast
majority of the OBS functionality is available via commands and the rest can
be reached via direct API calls.")
    (license license:gpl2+)))

(define-public compdb
  (package
    (name "compdb")
    (version "0.2.0")
    (source
     (origin
       (method git-fetch)
       (uri (git-reference
             (url "https://github.com/Sarcasm/compdb")
             (commit (string-append "v" version))))
       (file-name (git-file-name name version))
       (sha256
        (base32 "0f4x0gm5n1mr87dx3gzn5da16a1qhd2y3kz22dl5xsd9pd720l4w"))))
    (build-system pyproject-build-system)
    (arguments
     (list
      #:test-backend ''unittest))
    (native-inputs (list python-setuptools))
    (propagated-inputs (list python-configparser))
    (home-page "https://github.com/Sarcasm/compdb")
    (synopsis "Compilation database Swiss army knife")
    (description
     "@command{compdb} is a command line tool to manipulate compilation
databases.  It eases the usage of tooling in a codebase by spoon-feeding the
right compilation options.")
    (license license:expat)))

(define-public compiledb
  (package
    (name "compiledb")
    (version "0.10.1")
    (source
     (origin
       (method git-fetch)
       (uri (git-reference
             (url "https://github.com/nickdiego/compiledb")
             (commit (string-append "v" version))))
       (file-name (git-file-name name version))
       (sha256
        (base32 "0qricdgqzry7j3rmgwyd43av3c2kxpzkh6f9zcqbzrjkn78qbpd4"))))
    (build-system pyproject-build-system)
    (arguments
     (list
      #:phases
      #~(modify-phases %standard-phases
          (add-after 'unpack 'no-compat-shim-dependency
            ;; shutilwhich is only needed for python 3.3 and earlier
            (lambda* (#:key inputs #:allow-other-keys)
              (substitute* "setup.py"
                (("^ *'shutilwhich'\n")
                 ""))
              (substitute* "compiledb/compiler.py"
                (("shutilwhich")
                 "shutil"))
              (substitute* "tests/data/multiple_commands_oneline.txt"
                (("/bin/echo")
                 (search-input-file inputs "bin/echo"))))))))
    (propagated-inputs (list python-bashlex python-click))
    (native-inputs (list python-pytest python-setuptools python-wheel))
    (home-page "https://github.com/nickdiego/compiledb")
    (synopsis
     "Generate Clang JSON Compilation Database files for make-based build systems")
    (description
     "@code{compiledb} provides a @code{make} python wrapper script which,
besides executing the make build command, updates the JSON compilation
database file corresponding to that build, resulting in a command-line
interface similar to Bear.")
    (license license:gpl3)))

(define-public build
  (package
    (name "build")
    (version "0.3.10")
    (source
     (origin
       (method url-fetch)
       (uri (string-append "https://www.codesynthesis.com/download/"
                           "build/" (version-major+minor version)
                           "/build-" version ".tar.bz2"))
       (sha256
        (base32 "1lx5rpnmsbip43zpp0a57sl5rm7pjb0y6i2si6rfglfp4p9d3z76"))))
    (build-system gnu-build-system)
    (arguments
     `(#:make-flags (list (string-append "install_prefix=" %output))
       #:tests? #f
       #:phases (modify-phases %standard-phases
                  (delete 'build)
                  (delete 'configure))))
    (home-page "https://www.codesynthesis.com/projects/build/")
    (synopsis "Massively-parallel build system implemented on top of GNU make")
    (description "Build is a massively-parallel software build system
implemented on top of GNU Make, designed with the following tasks in mind:
@itemize
@item configuration
@item building
@item testing
@item installation
@end itemize
Build has features such as:
@itemize
@item Position-independent makefiles.
@item Non-recursive multi-makefile include-based structure.
@item Leaf makefiles are full-fledged GNU makefiles, not just variable definitions.
@item Complete dependency graph.
@item Inter-project dependency tracking.
@item Extensible language/compiler framework.
@end itemize")
    (license license:gpl2+)))

(define-public genie
  (let ((commit "22cc907a4351db46c55f73e6aa901f1b2f0c52ad")
        (revision "0"))
    (package
      (name "genie")
      (version (git-version "1170" revision commit))
      (source (origin
                (method git-fetch)
                (uri (git-reference
                      (url "https://github.com/bkaradzic/genie")
                      (commit commit)))
                (file-name (git-file-name name version))
                (sha256
                 (base32
                  "1wxhbdnr52qa2xr1i83577mwr25fxr5vby4r7m5brp9z5a08fwry"))))
      (build-system gnu-build-system)
      (arguments
       (list #:phases #~(modify-phases %standard-phases
                          (delete 'configure)
                          (replace 'install
                            (lambda _
                              (install-file "bin/linux/genie"
                                            (string-append #$output "/bin")))))
             #:tests? #f)) ;no tests
      (home-page "https://github.com/bkaradzic/genie")
      (synopsis "Project generator")
      (description
       "GENie generates projects from Lua scripts, making it easy to apply the
same settings to multiple projects.  It supports generating projects using GNU
Makefiles, JSON Compilation Database, and experimentally Ninja.")
      (license license:bsd-3))))

(define*-public (gnulib-checkout #:key
                                 version
                                 (revision "1")
                                 commit
                                 hash)
  "Return as a package the exact gnulib checkout."
  (package
    (name "gnulib")
    (version (git-version version revision commit))
    (source
     (origin
       (method git-fetch)
       (uri (git-reference
             (url "https://git.savannah.gnu.org/git/gnulib.git/")
             (commit commit)))
       (file-name (git-file-name name version))
       (sha256 hash)
       (snippet
        (with-imported-modules (source-module-closure '((guix build utils)))
          #~(begin
              (use-modules (guix build utils)
                           (ice-9 ftw)
                           (ice-9 rdelim))
              ;; .c, .h and .gperf files whose first line is /* DO NOT EDIT!
              ;; GENERATED AUTOMATICALLY! */ are generated automatically based
              ;; on the unicode database. Since we replace the unicode
              ;; database with our own, we need to regenerate them. So, they
              ;; are removed from the source. They are sprinkled all over the
              ;; place unfortunately, so we can’t exclude whole directories.
              (let ((generated-automatically?
                     (lambda (filename . unused)
                       (and (or (string-suffix? ".c" filename)
                                (string-suffix? ".h" filename)
                                (string-suffix? ".gperf" filename))
                            (call-with-input-file filename
                              (lambda (port)
                                (let ((first-line (read-line port)))
                                  (equal?
                                   first-line
                                   "/* DO NOT EDIT! GENERATED AUTOMATICALLY! */"))))))))
                (for-each delete-file (find-files (getcwd) generated-automatically?)))
              ;; Other files are copied from UCD.
              (for-each delete-file
                        '("tests/unigbrk/GraphemeBreakTest.txt"
                          "tests/uninorm/NormalizationTest.txt"
                          "tests/uniname/UnicodeData.txt"
                          "tests/uniname/NameAliases.txt"
                          ;; FIXME: tests/uniname/HangulSyllableNames.txt
                          ;; seems like a UCD file but it is not distributed
                          ;; with UCD.
                          "tests/uniwbrk/WordBreakTest.txt")))))
       (patches (search-patches "gnulib-bootstrap.patch"))))
    (build-system copy-build-system)
    (arguments
     (list
      #:install-plan
      #~'(("./gnulib-tool" "bin/")
          ("./gnulib-tool.py" "bin/")
          ("./gnulib-tool.sh" "bin/")
          ("." "src/gnulib" #:exclude-regexp ("\\.git.*")))
      #:modules '((ice-9 match)
                  (guix build utils)
                  (guix build copy-build-system)
                  ((guix build gnu-build-system) #:prefix gnu:))
      #:phases
      #~(modify-phases %standard-phases
          ;; Since this package is intended to be used in source form, it
          ;; should not retain references to tools (with the exception for the
          ;; commands we install, which should be wrapper for proper
          ;; execution).
          (delete 'patch-source-shebangs)
          (delete 'patch-generated-file-shebangs)
          (delete 'patch-usr-bin-file)
          (add-before 'install 'check
            (assoc-ref gnu:%standard-phases 'check))
          (add-before 'check 'fix-tests
            (lambda _
              (substitute* "Makefile"
                (("-f maint.mk syntax-check")
                 "_gl-Makefile=yes -f maint.mk syntax-check"))
              (invoke "git" "init")
              (invoke "git" "config" "user.name" "Guix")
              (invoke "git" "config" "user.email" "guix@localhost")
              (invoke "git" "add" ".")
              ;; Syntax checks are only run against committed files.
              (invoke "git" "commit" "-m" "Prepare for tests.")))
          (add-before 'check 'disable-failing-tests
            (lambda _
              (substitute* "cfg.mk"
                (("local-checks-to-skip =")
                 ;; sc_copyright_check fails because the fake commit date may
                 ;; be later than the copyright year.
                 "local-checks-to-skip = \\
  sc_Wundef_boolean \\
  sc_copyright_check \\
  sc_file_system \\
  sc_error_message_warn_fatal \\
  sc_indent \\
  sc_keep_gnulib_texi_files_mostly_ascii \\
  sc_prefer_angle_bracket_headers \\
  sc_prohibit_assert_without_use \\
  sc_prohibit_close_stream_without_use \\
  sc_prohibit_defined_have_decl_tests \\
  sc_prohibit_doubled_word \\
  sc_prohibit_empty_lines_at_EOF \\
  sc_prohibit_intprops_without_use \\
  sc_prohibit_openat_without_use \\
  sc_prohibit_test_minus_ao \\
  sc_readme_link_copying \\
  sc_readme_link_install \\
  sc_unportable_grep_q \\
  sc_unsigned_char \\
  sc_unsigned_int \\
  sc_unsigned_long \\
  sc_unsigned_short"))
              (substitute* "Makefile"
                (("sc_check_(sym_list|copyright|config_h_reminder)" rule)
                 (string-append "disabled_check_" rule))
                (("sc_cpp_indent_check")
                 "disabled_cpp_indent_check")
                (("sc_prefer_ac_check_funcs_once")
                 "disabled_prefer_ac_check_funcs_once")
                (("sc_prohibit_(AC_LIBOBJ_in_m4|leading_TABs\
|sc_omitted_at)" rule)
                 (string-append "disabled_prohibit_" rule)))))
          (add-before 'check 'regenerate-unicode
            (lambda* (#:key inputs #:allow-other-keys)
              (define (find-ucd-file name)
                (search-input-file inputs (string-append "share/ucd/" name)))
              (define (find-ucd-files . names)
                (map find-ucd-file names))
              (with-directory-excursion "lib"
                ;; See the compile-command buffer-local variable in
                ;; lib/gen-uni-tables.c
                (invoke "gcc" "-O" "-Wall" "gen-uni-tables.c"
                        "-Iunictype" "-o" "gen-uni-tables")
                (apply invoke
                       "./gen-uni-tables"
                       (append
                        (find-ucd-files "UnicodeData.txt"
                                        "PropList.txt"
                                        "DerivedCoreProperties.txt"
                                        "emoji/emoji-data.txt"
                                        "ArabicShaping.txt"
                                        "Scripts.txt"
                                        "Blocks.txt")
                        (list
                         #$(this-package-native-input "PropList.txt"))
                        (find-ucd-files "BidiMirroring.txt"
                                        "EastAsianWidth.txt"
                                        "LineBreak.txt"
                                        "auxiliary/WordBreakProperty.txt"
                                        "auxiliary/GraphemeBreakProperty.txt"
                                        "CompositionExclusions.txt"
                                        "SpecialCasing.txt"
                                        "CaseFolding.txt")
                         (list #$(package-version (this-package-native-input "ucd")))))
                (invoke "clisp" "-C" "uniname/gen-uninames.lisp"
                        (find-ucd-file "UnicodeData.txt") ;input file
                        (find-ucd-file "NameAliases.txt") ;alias file
                        "uniname/uninames.h")             ;output file
                (for-each
                 (match-lambda
                  ((ucd-file . directory)
                   (copy-file (find-ucd-file ucd-file)
                              (string-append "../tests/" directory "/"
                                             (basename ucd-file)))))
                 '(("NameAliases.txt" . "uniname")
                   ("UnicodeData.txt" . "uniname")
                   ("NormalizationTest.txt" . "uninorm")
                   ("auxiliary/GraphemeBreakTest.txt" . "unigbrk")
                   ("auxiliary/WordBreakTest.txt" . "uniwbrk")))
                (delete-file "gen-uni-tables")))))))
    (inputs
     (list bash-minimal)) ;shebang for gnulib-tool
    (native-inputs
     (list
      bash-minimal python perl clisp
      ;; Unicode data:
      ucd
      (origin
        (method url-fetch)
        (uri (string-append
              "https://www.unicode.org/Public/"
              "3.0-Update1/PropList-3.0.1.txt"))
        (file-name "PropList.txt")
        (sha256
         (base32
          "0k6wyijyzdl5g3nibcwfm898kfydx1pqaz28v7fdvnzdvd5fz7lh")))
      ;; Programs for the tests:
      cppi indent git-minimal/pinned autoconf))
    (home-page "https://www.gnu.org/software/gnulib/")
    (synopsis "Source files to share among distributions")
    (description
     "Gnulib is a central location for common infrastructure needed by GNU
packages.  It provides a wide variety of functionality, e.g., portability
across many systems, working with Unicode strings, cryptographic computation,
and much more.  The code is intended to be shared at the level of source
files, rather than being a standalone library that is distributed, built, and
installed.  The included @command{gnulib-tool} script helps with using Gnulib
code in other packages.  Gnulib also includes copies of licensing and
maintenance-related files, for convenience.")
    (native-search-paths
     (list (search-path-specification
            (variable "GNULIB_SRCDIR")
            (files (list "src/gnulib"))
            (separator #f))))
    (license (list license:lgpl2.0+ license:gpl3+))))

(define-public gnulib
  (gnulib-checkout
   #:version "2025-06-30"       ;date from last commit on stable-202507 branch
   #:commit "9297749090b01720888dceeb5f6dab3d52dcef40"
   #:hash (base32 "10qyhji7q71fhq2956aszj6bipbf11hn0xcrrpkwj9azwindw7ch")))

(define-public maak
  (package
    (name "maak")
    (version "0.2.12")
    (source
     (origin
       (method git-fetch)
       (uri (git-reference
             (url "https://codeberg.org/jjba23/maak.git")
             (commit (string-append "v" version))))
       (file-name (git-file-name name version))
       (sha256
        (base32 "0566damp7339n8rs2dvvq80h07amygnn3nakj2wwav2fmb1yzgx1"))))
    (build-system guile-build-system)
    (arguments
     (list
      #:source-directory "src"
      #:phases
      #~(modify-phases %standard-phases
          (add-before 'build 'install-program-files
            (lambda _
              (let ((bin (string-append #$output "/bin"))
                    (share (string-append #$output "/share")))
                (install-file "resources/help.txt"
                              (string-append share "/resources"))
                (install-file "scripts/maak" bin)
                (install-file "scripts/log.bash"
                              (string-append share "/scripts/"))
                (install-file "scripts/maak-completion.bash"
                                      (string-append share "/scripts/"))
                (chmod (string-append bin "/maak") #o755)))))))
    (native-inputs (list guile-3.0))
    (inputs (list guile-3.0 bash-minimal))
    (home-page "https://codeberg.org/jjba23/maak")
    (synopsis "Command runner à la Make using Guile Scheme")
    (description
     "Maak is a command runner and control plane for your
projects.  It allows you to use the power of Lisp (Guile Scheme) to define
your tasks, build steps, repetitive tasks or other automation.

With Maak you can easily call external shell commands and integrate with
your existing scripts and tools.  It is inspired by the GNU Make utility
but it does away with a lot of the complexity that comes with its history.")
    (license license:gpl3+)))

(define-public pdpmake
  (package
    (name "pdpmake")
    (version "2.0.4")
    (source
     (origin
       (method git-fetch)
       (uri (git-reference
              (url "git://git.frippery.org/pdpmake")
              (commit version)))
       (file-name (git-file-name name version))
       (sha256
        (base32
         "13qfvn0kw1fkpmjdpk0cscmvj5iycdq68kqfiml1slf1936pllb9"))))
    (build-system gnu-build-system)
    (arguments
     (list
      #:phases
      #~(modify-phases %standard-phases
          (delete 'configure)
          ;; pdpmake can be built easily without relying on a previous Make
          ;; implementation; let's do this for the sake of bootstrappability.
          (replace 'build
            (lambda _
              (let ((args (append (find-files "." "\\.c$")
                                  (list "-o" "make"))))
                (apply invoke #$(cc-for-target) args))))
          (replace 'check
            (lambda* (#:key tests? #:allow-other-keys)
              (when tests?
                (with-directory-excursion "testsuite"
                  (invoke "./runtest" "-v")))))
          (replace 'install
            (lambda _
              (let ((bindir (string-append #$output "/bin"))
                    (mandir (string-append #$output "/share/man/man1")))
                (mkdir-p bindir)
                (mkdir-p mandir)
                (install-file "make" bindir)
                (install-file "pdpmake.1" mandir)))))))
    (home-page "https://frippery.org/make/")
    (synopsis "Public domain POSIX make")
    (description
     "This package contains an implementation of POSIX make.  The default
configuration enables extensions.  Generally these extensions are compatible
with GNU make.")
    ;; pdpmake is distributed under the public domain, but the sources include
    ;; tests under the GPL license version 2.
    (license
     (list license:gpl2
           license:public-domain))))

(define-public potato-make
  ;; No releases.
  (let ((commit "e8c09ce1f6a33c013b27961b0a07f991db33e6fb")
        (revision "0"))
    (package
      (name "potato-make")
      (version (git-version "0" revision commit))
      (source
       (origin
         (method git-fetch)
         (uri (git-reference
               (url "https://github.com/spk121/potato-make")
               (commit commit)))
         (file-name (git-file-name name version))
         (sha256
          (base32 "0axgrkqdfip5f2bp7d2dprd74g58lyc0c7lgg2m93k5jqn1lpbmj"))
         ;; Delete files of the seemingly unfinished pmake program.
         (snippet '(begin
                     (delete-file "pmake")
                     (delete-file "documents/pmake.org")
                     (delete-file "make/main.scm")
                     (rmdir "documents")
                     (rmdir "make")))))
      (build-system guile-build-system)
      (arguments
       (list
        #:phases #~(modify-phases %standard-phases
                     (add-after 'build 'check
                       (lambda _
                         ;; Delete test referencing nonexistent file.
                         (delete-file "tests/parse.sh")
                         (for-each (lambda (f)
                                     (invoke "guile" "-L" "." "-s" f))
                                   (find-files "tests")))))))
      (native-inputs (list guile-3.0))
      (home-page "https://github.com/spk121/potato-make")
      (synopsis "Library to write makefiles in Guile Scheme")
      (description
       "Potato Make is a Scheme library that aims to simplify the task of
maintaining, updating, and regenerating programs.  It is inspired by
the POSIX make utility and allows writing a build script in Guile
Scheme.")
      (license license:expat))))

(define-public waf
  (package
    (name "waf")
    (version "2.0.19") ;TODO: newer version brakes API
    (source
     (origin
       (method url-fetch)
       (uri (string-append "https://waf.io/" "waf-" version ".tar.bz2"))
       (sha256
        (base32 "19dvqbsvxz7ch03dh1v0znklrwxlz6yzddc3k9smzrrgny4jch6q"))))
    (build-system pyproject-build-system)
    (arguments
     (list
      #:test-backend #~'custom
      ;; TODO: Project provides integration tests, see
      ;; <.pipelines/Jenkinsfile> how to run them.
      #:test-flags #~(list "waf" "--version")
      #:phases
      #~(modify-phases %standard-phases
          (replace 'build
            (lambda _
              ;; XXX: Find a way to add all extra tools.
              (let ((tools '("gccdeps" "clang_compilation_database")))
                (invoke "python" "waf-light" "configure" "build"
                        (string-append "--tools=" (string-join tools ","))))))
          (replace 'install
            (lambda _
              (install-file "waf" (string-append #$output "/bin"))))
          ;; waf breaks when it is wrapped.
          (delete 'wrap))))
    (home-page "https://waf.io/")
    (synopsis "Multi-level general purpose build system")
    (description
     "Waf is a build system framework for configuring, compiling and
installing applications.

Features:
@itemize
@item Automatic build order: the build order is computed from input and output
files, among others
@item Automatic dependencies: tasks to execute are detected by hashing files
and commands
@item Performance: tasks are executed in parallel automatically, the startup
time is meant to be fast (separation between configuration and build)
@item Flexibility: new commands and tasks can be added very easily through
subclassing, bottlenecks for specific builds can be eliminated through dynamic
method replacement
@item Extensibility: though many programming languages and compilers are
already supported by default, many others are available as extensions
@item IDE support: Eclipse, Visual Studio and Xcode project generators
(waflib/extras/)
@item Documentation: the application is based on a robust model documented in
The Waf Book and in the API docs
@item Python compatibility: cPython 2.7 to 3.x, Jython 2.7 and PyPy
@end itemize")
    (license license:bsd-3)))

;; waf is the final program no need to prefix it with "python-", the same way
;; as meson or ninja which are written in Python as well.
(define-deprecated-package python-waf
  waf)

(define-public haredo
  (package
    (name "haredo")
    (version "1.0.6")
    (source
     (origin
       (method git-fetch)
       (uri (git-reference
              (url "https://git.sr.ht/~autumnull/haredo/")
              (commit version)))
       (file-name (git-file-name name version))
       (sha256 (base32 "1ysm8rgxi0i4zb1q6xj3pf5bwxssjlcc4x158pyd78l8ahz30fn2"))))
    (build-system hare-build-system)
    (native-inputs
     ;; XXX: `harec` and `qbe` are pulled in because Haredo assumes these
     ;; programs are present and allows build scripts to rely on them freely.
     ;;
     ;; See: https://git.sr.ht/~autumnull/haredo/tree/1.0.6/item/doc/haredo.1.scd
     ;;
     ;; Importing `harec` the usual way results in a circular dependency for
     ;; packages that rely on `hare-build-system`.  To avoid that, we import
     ;; it using delayed evaluation.
     (list scdoc
           (module-ref (resolve-interface '(gnu packages hare)) 'harec)
           qbe))
    (supported-systems %hare-supported-systems)
    (arguments
     (list
      #:tests? #f
      #:phases
      #~(modify-phases %standard-phases
          (add-before 'build 'set-prefix
            (lambda _ (setenv "PREFIX" #$output)))
          (add-before 'build 'override-defaults
            (lambda* (#:key inputs #:allow-other-keys)
              ;; XXX: To prevent future packagers from needing to do delayed
              ;; input evaluation in all subsequent packages that rely on
              ;; `haredo` and `hare-build-system`, this package provides the
              ;; Guix-packaged `harec` and `qbe` as defaults (which can be
              ;; overridden if needed by setting the appropriate environment
              ;; variable).
              (let ((harec-binary (search-input-file inputs "/bin/harec"))
                    (qbe-binary (search-input-file inputs "/bin/qbe")))
                (substitute* "./src/haredo.ha"
                  (("(\"HAREC\", \"harec\")")
                   (format #f "(\"HAREC\", \"~a\")" harec-binary))
                  (("(\"QBE\", \"qbe\")")
                   (format #f "(\"QBE\", \"~a\")" qbe-binary))))))
          (replace 'build
            (lambda _ (invoke "./bootstrap.sh")))
          (replace 'install
            (lambda _ (invoke "./bootstrap.sh" "install"))))))
    (home-page "https://sr.ht/~autumnull/haredo/")
    (synopsis "Build automator, alternative to @command{make} and @command{redo}")
    (description "@command{haredo} is a build automator.
It is an alternative to e.g. @command{make(1)} and @command{redo(1)}.  Features:

@itemize
@item Script syntax is plain shell script,
@item Only one command with few extraneous rules,
@item .do files are short and modular like in redo,
@item Builds its dependency tree on the fly, uses no database,
@item Doesn't break the build state when interrupted.
@end itemize
")
    (license license:wtfpl2)))
