projects/guix·blob kernel-updates · refs

1101 lines · 50.6 KiB

1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2015, 2016 Roel Janssen <[email protected]>
3;;; Copyright © 2015, 2018 Pjotr Prins <[email protected]>
4;;; Copyright © 2017 Frederick Muriithi <[email protected]>
5;;; Copyright © 2017 Ricardo Wurmus <[email protected]>
6;;; Copyright © 2017, 2019, 2022 Tobias Geerinckx-Rice <[email protected]>
7;;; Copyright © 2020 Guy Fleury Iteriteka <[email protected]>
8;;; Copyright © 2021-2024 Efraim Flashner <[email protected]>
9;;; Copyright © 2021, 2024 Maxim Cournoyer <[email protected]>
10;;; Copyright © 2022 ( <[email protected]>
11;;; Copyright © 2022 Esther Flashner <[email protected]>
12;;; Copyright © 2025-2026 Jonas Meeuws <[email protected]>
13;;; Copyright © 2026 Daniel Littlewood <[email protected]>
14;;;
15;;; This file is part of GNU Guix.
16;;;
17;;; GNU Guix is free software; you can redistribute it and/or modify it
18;;; under the terms of the GNU General Public License as published by
19;;; the Free Software Foundation; either version 3 of the License, or (at
20;;; your option) any later version.
21;;;
22;;; GNU Guix is distributed in the hope that it will be useful, but
23;;; WITHOUT ANY WARRANTY; without even the implied warranty of
24;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25;;; GNU General Public License for more details.
26;;;
27;;; You should have received a copy of the GNU General Public License
28;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
29
30(define-module (gnu packages dlang)
31 #:use-module ((guix licenses) #:prefix license:)
32 #:use-module (guix packages)
33 #:use-module (guix download)
34 #:use-module (guix git-download)
35 #:use-module (guix gexp)
36 #:use-module (guix utils)
37 #:use-module ((guix build utils) #:hide (delete which))
38 #:use-module (guix build-system)
39 #:use-module (guix build-system gnu)
40 #:use-module (guix build-system cmake)
41 #:use-module (guix build-system copy)
42 #:use-module (gnu packages)
43 #:use-module (gnu packages base)
44 #:use-module (gnu packages bash)
45 #:use-module (gnu packages build-tools)
46 #:use-module (gnu packages check)
47 #:use-module (gnu packages compression)
48 #:use-module (gnu packages curl)
49 #:use-module (gnu packages gcc)
50 #:use-module (gnu packages gdb)
51 #:use-module (gnu packages libedit)
52 #:use-module (gnu packages llvm)
53 #:use-module (gnu packages perl)
54 #:use-module (gnu packages pkg-config)
55 #:use-module (gnu packages python)
56 #:use-module (gnu packages python-build)
57 #:use-module (gnu packages python-xyz)
58 #:use-module (gnu packages textutils)
59 #:use-module (gnu packages xorg)
60 #:use-module (srfi srfi-1))
61
62
63;; Compilers and tooling for the D programming language.
64;; Note: The GNU D compiler is defined in (gnu packages gcc) instead.
65
66;; Removes references to druntime and standard library source paths that may be
67;; printed in backtraces.
68(define-public (remove-d-include-references-phase compiler)
69 #~(lambda* (#:key outputs #:allow-other-keys)
70 (for-each
71 (lambda (file)
72 ;; Set the last character of the hash to *.
73 (let* ((compiler #$compiler)
74 (char-offset (+ (string-length (%store-directory))
75 (string-length "/")
76 %store-hash-string-length
77 -1))
78 (patched (string-append
79 (string-take compiler char-offset)
80 "*"
81 (string-drop compiler (+ char-offset 1))))
82 (sources-regex (string-append
83 "[[:alnum:]/_.\\-]*"
84 "/include/"
85 "[[:alnum:]/_.\\-]*"
86 "\\.d"))
87 (command (list "sed" "-i"
88 (format #f "s,~a\\(~a\\),~a\\1,g"
89 compiler sources-regex patched)
90 file)))
91 ;; XXX: Use sed, as substitute* fails on binary files.
92 (apply invoke command)))
93 (apply append (map find-files
94 (map cdr outputs))))))
95
96
97;; LLVM-based D compiler
98
99(define-public ldc-bootstrap
100 (package
101 ;; This package is purposefully named just "ldc" and not "ldc-bootstrap",
102 ;; as the final ldc package rewrites references from this one to itself,
103 ;; and their names must have the same length to avoid corrupting the
104 ;; binary.
105 (name "ldc")
106 (version "1.43.0")
107 (source (origin
108 (method git-fetch)
109 (uri (git-reference
110 (url "https://github.com/ldc-developers/ldc")
111 (commit (string-append "v" version))
112 ;; Note: ldc-developers/phobos checked out in
113 ;; runtime/phobos.
114 ;; TODO: capture in own variable.
115 (recursive? #t)))
116 (file-name (git-file-name name version))
117 (sha256
118 (base32
119 "0ym3wrvy9vndc23l25aj8a09a6vr7r0n8ljlr4yrsklkfn1h1ik4"))
120 (patches (search-patches "ldc-i686-int128-alignment.patch"
121 "ldc-phobos-support-TZDIR.patch"))))
122 (build-system cmake-build-system)
123 (arguments
124 (list
125 #:disallowed-references (list tzdata-for-tests)
126 #:modules '((guix build cmake-build-system)
127 (guix build utils)
128 (srfi srfi-1))
129 #:generator "Ninja"
130 #:configure-flags
131 #~(list "-DD_COMPILER_FLAGS=-fPIC"
132 "-DBUILD_SHARED_LIBS=OFF" ; see .github/actions/2-build-bootstrap
133 "-DLDC_DYNAMIC_COMPILE=OFF" ; likewise
134 (format #f "-DCOMPILER_RT_LIBDIR_CONFIG=~a/lib/linux"
135 #$(this-package-input "clang-runtime"))
136 (format #f "-DCMAKE_INSTALL_RPATH=~a/lib"
137 (assoc-ref %outputs "lib"))
138 #$@(if (target-riscv64?)
139 #~(("-DCMAKE_EXE_LINKER_FLAGS=-latomic"))
140 #~())
141 (format #f "-DINCLUDE_INSTALL_DIR=~a/include/d/ldc"
142 (assoc-ref %outputs "out")))
143 #:build-type "Debug"
144 #:make-flags #~(list "all") ; used as build targets
145 #:tests? #f ; skip in the bootstrap
146 #:phases
147 (let* ((target-file
148 (lambda (pkg path)
149 (file-append (this-package-input pkg) path)))
150 (native-file
151 (lambda (pkg path)
152 (file-append (this-package-native-input pkg) path)))
153 (target-bin-sh (target-file "bash-minimal" "/bin/sh"))
154 (target-bin-clang (target-file "clang" "/bin/clang"))
155 (target-clang-runtime (target-file "clang-runtime" ""))
156 (target-lib-curl (target-file "curl" "/lib/libcurl.so"))
157 (native-bin-clang (native-file "clang" "/bin/clang"))
158 (native-bin-clang++ (native-file "clang" "/bin/clang++")))
159 #~(modify-phases %standard-phases
160 ;; LDC needs a C compiler as a linker wrapper.
161 ;; Change the default fallback "cc" to clang.
162 ;; Discovery implemented in ldc v1.19.0.
163 (add-after 'patch-usr-bin-file 'patch-default-cc
164 (lambda _
165 (substitute* "driver/tool.h"
166 (("\"cc\"")
167 (format #f "~s" #$target-bin-clang)))))
168 (add-after 'unpack 'patch-compiler-rt-library-discovery
169 ;; See also the -DCOMPILER_RT_LIBDIR_CONFIG configure flag.
170 (lambda _
171 (let* ((system #$(or (%current-target-system)
172 (%current-system)))
173 (arch (car (string-split system #\-)))
174 (clang-arch (cond
175 ((string-suffix? "86" arch) "i386")
176 (#t arch))))
177 ;; Coax LLVM into agreeing with Clang about system target
178 ;; naming.
179 (substitute* "driver/linker-gcc.cpp"
180 (("triple.getArchName\\(\\)")
181 (format #f "~s" clang-arch))))))
182 ;; Using ImportC will always emit warnings when using gcc 14+
183 ;; as its preprocessor, causing tests that read stderr to
184 ;; fail.
185 ;; Introduced in ldc v1.29.0.
186 ;; Fixed (like this) in ldc v1.40.0.
187 (add-after 'unpack 'patch-importc-system-header
188 (lambda _
189 (substitute* "runtime/druntime/src/importc.h"
190 (("^#define __IMPORTC__ 1.*$" all)
191 (string-append
192 all
193 "\n"
194 "#ifdef __GNUC__\n"
195 "#pragma GCC system_header\n"
196 "#endif\n")))))
197 ;; Using ImportC with clang as preprocessor will cause
198 ;; ImportC to fail on glibc float headers.
199 ;; Introduced in ldc v1.33.0.
200 (add-after 'unpack 'patch-importc-float128
201 (lambda _
202 (substitute* "runtime/druntime/src/importc.h"
203 (("^#ifndef __clang__.*$")
204 (string-append
205 "#ifdef __clang__\n"
206 "#define __float128 long double\n"
207 "#else\n")))))
208 (add-after 'unpack 'patch-paths-in-phobos
209 (lambda _
210 (with-directory-excursion "runtime/phobos"
211 (substitute* "std/net/curl.d"
212 (("\"libcurl\\.so\"")
213 (format #f "~s" #$target-lib-curl)))
214 (substitute* "std/process.d"
215 (("return \"/bin/sh\";")
216 (format #f "return ~s;" #$target-bin-sh))
217 (("#!/bin/sh")
218 (string-append "#!" #$target-bin-sh))))))
219 (add-after 'unpack 'patch-getInstalledTZNames-infinite-symlink
220 (lambda _
221 ;; Disable following directory symlinks when iterating tzdata.
222 (substitute* "runtime/phobos/std/datetime/timezone.d"
223 (("SpanMode\\.depth\\)") "SpanMode.depth, false)"))))
224 (add-after 'unpack 'patch-tests
225 (lambda _
226 ;; Fails often. Relies on guessing the test binary size,
227 ;; sleeps, and file timestamps.
228 ;; Introduced in ldc v1.1.0.
229 (delete-file "tests/linking/ir2obj_cache_pruning2.d")
230 ;; Very unreliable.
231 ;; Introduced in ldc v1.4.0.
232 (delete-file "tests/sanitizers/fuzz_asan.d")
233 ;; These 2 tests try to build a Makefile on their own.
234 ;; Introduced in ldc v1.8.0.
235 (delete-file-recursively "tests/plugins")
236 ;; This test doesn't expect the linker to demangle D symbols.
237 ;; Introduced in ldc v1.8.1.
238 (substitute* "tests/dmd/fail_compilation/needspkgmod.d"
239 (("_D7imports9pkgmod3133mod3barFZv")
240 "imports.pkgmod313.mod.bar()"))
241 ;; These CTFE tests fail on riscv64-linux.
242 ;; Test for signbit introduced in ldc v1.19.0.
243 ;; Test for getNaNPayload introduced in ldc v1.25.0.
244 ;; std.math was split into modules in ldc v1.27.0.
245 #$@(if (target-riscv64?)
246 #~((substitute* "runtime/phobos/std/math/operations.d"
247 (("static assert\\(getNaNPayload\\(a\\)" line)
248 (string-append "//" line)))
249 (substitute* "runtime/phobos/std/math/traits.d"
250 (("static assert\\(signbit\\(-.*\\.nan" line)
251 (string-append "//" line))))
252 #~())
253 ;; This test creates a shell script and runs it.
254 ;; Introduced in ldc v1.22.0.
255 (substitute* "tests/dmd/dshell/test6952.d"
256 (("/usr/bin/env bash") #$target-bin-sh))
257 ;; Fails to detect the race condition for some reason.
258 ;; Introduced in ldc v1.23.0.
259 (for-each delete-file
260 '("tests/sanitizers/tsan_tiny_race.d"
261 "tests/sanitizers/tsan_tiny_race_TLS.d"))
262 ;; Likewise. Introduced in ldc v1.27.0.
263 (for-each delete-file
264 '("tests/sanitizers/msan_noerror.d"
265 "tests/sanitizers/msan_uninitialized.d"))
266 ;; Likewise. Introduced in ldc v1.30.0.
267 (for-each delete-file
268 '("tests/sanitizers/lsan_memleak.d"))
269 ;; Patch a shell path in the druntime profile test Makefile.
270 ;; Introduced in ldc v1.34.0.
271 (substitute* "runtime/druntime/test/profile/Makefile"
272 (("SHELL=/bin/bash")
273 (string-append "SHELL=" #$target-bin-sh)))
274 ;; Since the implementation of SOURCE_DATE_EPOCH support in
275 ;; Ddoc, this test fails, as it expects Ddoc timestamps to
276 ;; match the output of the `date` command.
277 ;; Introduced in ldc v1.36.0.
278 (substitute*
279 "tests/dmd/compilable/extra-files/ddocYear-postscript.sh"
280 (("^YEAR=.*$") "YEAR=1970\n"))
281 ;; This tests how the CC env var is handled by the compiler,
282 ;; by setting it to cc, which we don't have.
283 ;; Introduced in ldc v1.37.0.
284 (substitute* "tests/driver/cli_CC_envvar.d"
285 (("\\bcc\\b") #$native-bin-clang))
286 ;; One of these tests hangs when a modern llvm opt is applied.
287 ;; Fix by only running debug builds.
288 ;; Introduced in ldc v1.41.0.
289 (substitute* "runtime/druntime/test/exceptions/Makefile"
290 (("TESTS\\+=memoryerror.*$" all)
291 (string-append "ifeq ($(BUILD),debug)\n" all "endif\n")))
292 ;; The following tests fail on some systems, not all of
293 ;; which are tested upstream.
294 (for-each
295 (lambda (path) (false-if-file-not-found (delete-file path)))
296 (list
297 #$@(if (or (target-x86-32?)
298 (target-arm32?))
299 #~("tests/codegen/mangling.d"
300 "tests/debuginfo/print_gdb.d"
301 "tests/dmd/runnable_cxx/cppa.d"
302 "tests/dmd/runnable/gdb_slice_debuginfo_64.d"
303 "tests/instrument/xray_check_pipeline.d"
304 "tests/instrument/xray_link.d"
305 "tests/instrument/xray_simple_execution.d"
306 "tests/PGO/profile_rt_calls.d"
307 "tests/sanitizers/fuzz_basic.d"
308 "tests/sanitizers/fuzz_mixin.d"
309 "tests/sanitizers/link_fuzzer.d"
310 "tests/sanitizers/msan_noerror.d"
311 "tests/sanitizers/msan_uninitialized.d")
312 #~())
313 #$@(if (target-riscv64?)
314 #~("tests/dmd/codegen/simd_alignment.d"
315 "tests/dmd/compilable/test23705.d"
316 "tests/dmd/fail_compilation/diag7420.d"
317 "tests/dmd/runnable/argufilem.d"
318 "tests/dmd/runnable_cxx/cppa.d")
319 #~())))))
320 ;; The tests require to be built with Clang; build everything
321 ;; with it, for simplicity.
322 (add-before 'configure 'set-cc
323 (lambda _
324 (setenv "CC" #$native-bin-clang)
325 (setenv "CXX" #$native-bin-clang++)))
326 ;; The test targets are tested separately to provide
327 ;; finer-grained diagnostics (see the `.github/actions/4*`
328 ;; files in the source).
329 (replace 'check
330 (lambda* (#:key tests? parallel-tests? #:allow-other-keys)
331 (define* (run-tests name includes excludes
332 #:key
333 (job-count (if parallel-tests?
334 (parallel-job-count)
335 1)))
336 (define (regex-flags prefix patterns)
337 (if (> (length patterns) 0)
338 (list prefix
339 (format #f "(~a)" (string-join patterns "|")))
340 '()))
341 (format #t "running the ~a...\n" name)
342 (apply invoke
343 `("ctest"
344 "--output-on-failure"
345 "-j" ,(number->string job-count)
346 ,@(regex-flags "-R" includes)
347 ,@(regex-flags "-E" excludes))))
348 (when tests?
349 (run-tests "ldc2 unit tests"
350 (list "ldc2-unittest")
351 (list))
352 (run-tests "lit test suite"
353 (list "lit-tests")
354 (list))
355 ;; This test has a race condition so run it with 1 core.
356 (run-tests "dmd test suite"
357 (list "dmd-testsuite")
358 (list)
359 #:job-count 1)
360 (run-tests "druntime unit tests"
361 (list "druntime-test-runner"
362 "^core\\."
363 "^etc\\.linux" "etc\\.valgrind"
364 "^ldc\\."
365 "^object"
366 "^rt\\.")
367 (list #$@(if (target-riscv64?)
368 ;; These hang forever
369 #~("core.thread.fiber-.*shared"
370 "core.thread.osthread-.*shared")
371 #~())))
372 (run-tests "druntime integration tests"
373 (list "druntime-test")
374 (list "druntime-test-runner"
375 #$@(if (target-aarch64?)
376 #~("druntime-test-exceptions-debug")
377 #~())))
378 ;; Building these tests is very resource intensive, so
379 ;; limit the job count.
380 (run-tests
381 "phobos unit tests"
382 (list "phobos"
383 "etc\\.c\\."
384 "^std")
385 (list #$@(if (target-aarch64?)
386 #~("std.internal.math.gammafunction-.*shared"
387 "std.math.exponential-shared")
388 #~())
389 #$@(if (target-riscv64?)
390 #~("std.internal.math.errorfunction-.*shared"
391 "std.internal.math.gammafunction-.*shared"
392 "std.math.exponential-.*shared"
393 "std.math.operations-debug-shared"
394 "std.math.traits-debug-shared"
395 "std.math.trigonometry-.*shared"
396 "std.mathspecial-.*shared"
397 "std.socket-debug-shared"
398 "std.socket-shared")
399 #~()))
400 #:job-count 1))))
401 (add-after 'install 'create-lib-output
402 (lambda* (#:key outputs #:allow-other-keys)
403 (let* ((out (assoc-ref outputs "out"))
404 (out/etc (string-append out "/etc"))
405 (out/lib (string-append out "/lib"))
406 (lib (assoc-ref outputs "lib"))
407 (lib/lib (string-append lib "/lib"))
408 (libs (find-files out/lib "\\.so")))
409 (mkdir-p lib/lib)
410 (for-each (lambda (original)
411 (install-file original lib/lib)
412 (delete-file original))
413 libs)
414 ;; Append to default lib-dirs and override rpath.
415 (with-output-to-file
416 (string-append out/etc "/ldc2.conf/80-guix.conf")
417 (lambda ()
418 (format #t "\"default\":~%")
419 (format #t "{~%")
420 (format #t " lib-dirs ~~= [\"~a\"];~%" lib/lib)
421 (format #t " rpath = \"~a\";~%" lib/lib)
422 (format #t "};~%"))))))))))
423 (inputs
424 (list clang-runtime-21
425 libconfig
426 llvm-21
427 zlib
428 clang ; used as a linker wrapper
429 curl ; std.net.curl
430 bash-minimal)) ; std.process
431 (native-inputs
432 (list gdmd
433 clang ; propagates llvm and clang-runtime
434 lld-as-ld-wrapper
435 ;; For testing
436 tzdata-for-tests ; std.datetime.timezone
437 gdb
438 python-wrapper
439 python-setuptools
440 python-lit))
441 (outputs '("out" "lib" "debug"))
442 (home-page "http://wiki.dlang.org/LDC")
443 (synopsis "LLVM-based compiler for the D programming language")
444 (description "The LDC project provides a portable D programming language
445compiler with modern optimization and code generation capabilities. The
446compiler uses the official DMD frontend to support the latest version of D2,
447and relies on the LLVM Core libraries for code generation.
448
449This compiler is based on the DMD frontend version 2.112.1.")
450 ;; Most of the code is released under BSD-3, except for code originally
451 ;; written for GDC, which is released under GPLv2+, and the DMD frontend
452 ;; and the druntime and phobos libraries which are released under the
453 ;; "Boost Software License version 1.0".
454 (license (list license:bsd-3
455 license:gpl2+
456 license:boost1.0))
457 (properties
458 `((hidden? . #t)
459 ;; Some of the tests take a very long time on ARMv7. See
460 ;; https://lists.gnu.org/archive/html/guix-devel/2018-02/msg00312.html.
461 ,@(if (target-arm32?) `((max-silent-time . ,(* 3600 3))) '())
462 ;; This prevents "dmd-rewrite-..." tags from being selected.
463 (release-tag-prefix . "^v")))))
464
465(define-public ldc
466 (let ((base ldc-bootstrap))
467 (package
468 (inherit base)
469 (arguments
470 (substitute-keyword-arguments
471 (strip-keyword-arguments
472 '(#:tests?) ; reinstate tests
473 (package-arguments base))
474 ((#:disallowed-references _ ''())
475 (list (lookup-package-native-input base "gdmd")
476 tzdata-for-tests))
477 ((#:configure-flags flags #~'())
478 #~(append
479 (fold delete #$flags '("-DD_COMPILER_FLAGS=-fPIC"
480 "-DBUILD_SHARED_LIBS=OFF"))
481 '("-DBUILD_SHARED_LIBS=ON")))
482 ((#:build-type _ ''())
483 "RelWithDebInfo")
484 ((#:phases phases #~%standard-phases)
485 #~(modify-phases #$phases
486 (add-after 'create-lib-output 'rewrite-references-to-bootstrap
487 ;; D compilers can keep references to the include files used to
488 ;; build a binary in exception messages. For ldc, rewrite the
489 ;; references to ldc-bootstrap to itself, to reduce its closure
490 ;; size.
491 (lambda* (#:key outputs #:allow-other-keys)
492 (let* ((in-ldc-bootstrap #$(this-package-native-input "ldc"))
493 (out (assoc-ref outputs "out"))
494 (out/bin (string-append out "/bin")))
495 ;; XXX: Use sed, as replace-store-references wouldn't
496 ;; replace the references, while substitute* throws an
497 ;; error.
498 (apply invoke "sed" "-i"
499 (format #f "s,~a,~a,g" in-ldc-bootstrap out)
500 (find-files out/bin)))))))))
501 (native-inputs
502 (modify-inputs (package-native-inputs base)
503 (delete "gdmd")
504 (append base)))
505 (properties
506 (alist-delete 'hidden? (package-properties base))))))
507
508
509;; Reference D compiler
510;; Note: Has limited supported-systems.
511
512;; DMD built with GDC as the bootstrap D compiler (via the gdmd wrapper).
513;; Shared libraries are not built, tests are disabled.
514(define-public dmd-bootstrap
515 (package
516 ;; This package is purposefully named just "dmd" and not "dmd-bootstrap",
517 ;; as the final dmd package rewrites references from this one to itself,
518 ;; and their names must have the same length to avoid corrupting the
519 ;; binary.
520 (name "dmd")
521 (version "2.113.0")
522 (source (origin
523 (method git-fetch)
524 (uri (git-reference
525 (url "https://github.com/dlang/dmd")
526 (commit (string-append "v" version))))
527 (file-name (git-file-name "dmd" version))
528 ;; Note: When updating, also update the hash of phobos in the
529 ;; native-inputs below.
530 (sha256
531 (base32
532 "1b1zf7vck35ab67npjiakpyh60g5dlyl4f7v8chjnc2bwzyyc58a"))))
533 (build-system gnu-build-system)
534 (arguments
535 (list
536 #:disallowed-references (list (gexp-input (canonical-package gcc) "lib")
537 tzdata-for-tests)
538 ;; Disable tests, as gdmd cannot cope with some arguments used such as
539 ;; '-conf'.
540 #:tests? #f
541 #:out-of-source? #t
542 #:make-flags
543 #~(list (string-append "CC=" #$(cc-for-target))
544 (string-append "HOST_CXX=" #$(cxx-for-target))
545 "HOST_DMD=gdmd"
546 (string-append "INSTALL_DIR=" #$output)
547 (string-append "SYSCONFDIR=" #$output "/etc")
548 "ENABLE_RELEASE=1"
549 ;; Do not build the shared libphobos2.so library, to avoid
550 ;; retaining a reference to gcc:lib.
551 "SHARED=0"
552 "DIFFABLE=1" ;constant timestamp
553 "VERBOSE=1")
554 #:modules
555 `(,@%default-gnu-modules
556 (srfi srfi-1)
557 (srfi srfi-26))
558 #:phases
559 (let* ((wrap-in-directory-excursion
560 (lambda (sub-dir phase . extra-args)
561 #~(lambda args
562 (with-directory-excursion #$sub-dir
563 (apply (assoc-ref %standard-phases '#$phase)
564 (append args '#$extra-args))))))
565 (target-file (lambda (pkg-name path)
566 (file-append (this-package-input pkg-name) path)))
567 (target-bin-sh (target-file "bash-minimal" "/bin/sh"))
568 (target-lib-curl (target-file "curl" "/lib/libcurl.so")))
569 #~(modify-phases %standard-phases
570 (replace 'unpack
571 (lambda* (#:key source #:allow-other-keys)
572 (let ((dmd-source source)
573 (phobos-source #$(this-package-native-input
574 (git-file-name "phobos" version))))
575 (mkdir "source")
576 (chdir "source")
577 (copy-recursively dmd-source "dmd" #:keep-mtime? #t)
578 (copy-recursively phobos-source "phobos" #:keep-mtime? #t)
579 (for-each (lambda (f)
580 (false-if-exception (make-file-writable f)))
581 (find-files ".")))))
582 (add-after 'unpack 'patch-git-ls-tree
583 ;; The druntime Makefile tries to use git ls-tree to get all
584 ;; source files in dmd/druntime/. We replace the command with a
585 ;; listing of those files.
586 (lambda _
587 (with-directory-excursion "dmd/druntime"
588 (substitute* "Makefile"
589 (("^MANIFEST *:*=.*$")
590 (string-append "MANIFEST := "
591 (string-join (map (cut string-drop <> 2)
592 (find-files "./")))
593 "\n"))))))
594 (add-after 'unpack 'patch-paths-in-phobos
595 (lambda _
596 (with-directory-excursion "phobos"
597 (substitute* "std/net/curl.d"
598 (("\"libcurl\\.so\"")
599 (format #f "~s" #$target-lib-curl)))
600 (substitute* "std/process.d"
601 (("return \"/bin/sh\";")
602 (format #f "return ~s;" #$target-bin-sh))
603 (("#!/bin/sh")
604 (string-append "#!" #$target-bin-sh))))))
605 (add-after 'unpack 'patch-tests
606 (lambda _
607 ;; Since the implementation of SOURCE_DATE_EPOCH support in
608 ;; Ddoc, this test fails, as it expects Ddoc timestamps to
609 ;; match the output of the `date` command.
610 ;; XXX: Report upstream.
611 (substitute* (string-append
612 "dmd/compiler/test/compilable"
613 "/extra-files/ddocYear-postscript.sh")
614 (("^YEAR=.*$") "YEAR=1970\n"))
615
616 ;; This test creates a shell script and runs it.
617 (substitute* "dmd/compiler/test/dshell/test6952.d"
618 (("/usr/bin/env bash") #$target-bin-sh))
619
620 ;; In the sarif json output, the compiler version string ends
621 ;; with a raw newline for some reason, causing these tests to
622 ;; fail.
623 (for-each
624 delete-file
625 '("dmd/compiler/test/compilable/sarif_success_test.d"
626 "dmd/compiler/test/fail_compilation/sarif_test.d"
627 "dmd/compiler/test/fail_compilation/sarifmultiple_test.d"))
628
629 ;; tries to debug 64bit executable
630 ;; not in executable format: file format not recognized
631 #$@(if (target-32bit?)
632 #~((delete-file
633 (string-append "dmd/compiler/test/runnable"
634 "/gdb_slice_debuginfo_64.d")))
635 #~())
636
637 ;; Locations in stack traces are broken for some reason,
638 ;; causing these tests to fail.
639 ;; XXX: Report upstream.
640 (for-each
641 delete-file
642 '("dmd/compiler/test/runnable/test17559.d"
643 "dmd/compiler/test/runnable/test19086.d"))
644 (substitute* "dmd/druntime/test/exceptions/Makefile"
645 (((string-append "line_trace line_trace_21656 "
646 "long_backtrace_trunc rt_trap_exceptions "))
647 ""))
648 (substitute* "dmd/druntime/test/gc/Makefile"
649 ((" invariant ") " "))
650
651 ;; Skip a std.process unittest that fails due to "kill" not
652 ;; working properly in the build environment.
653 (substitute* "phobos/std/process.d"
654 (("^.*sleep.*10000" all)
655 (string-append " return;\n" all)))))
656 (delete 'bootstrap)
657 (delete 'configure)
658 (replace 'build
659 #$(wrap-in-directory-excursion "dmd" 'build))
660 (add-after 'build 'build-phobos
661 #$(wrap-in-directory-excursion "phobos" 'build))
662 (add-after 'build-phobos 'build-man
663 (lambda* (#:key make-flags #:allow-other-keys)
664 (with-directory-excursion "dmd/compiler/docs"
665 (let ((dmd (or (which "gdmd")
666 (which "dmd"))))
667 ((assoc-ref %standard-phases 'build)
668 #:make-flags (cons
669 (string-append "DMD=" dmd)
670 make-flags))))))
671 (replace 'check
672 #$(wrap-in-directory-excursion "dmd" 'check
673 #:test-target "test"))
674 (add-after 'check 'check-phobos
675 #$(wrap-in-directory-excursion "phobos" 'check
676 #:test-target "unittest"))
677 (replace 'install
678 (lambda* (#:key outputs #:allow-other-keys)
679 (let* ((platform (cond (#$(target-linux?) "linux")))
680 (bits (if #$(target-64bit?) 64 32))
681 (build-sub-dir (format #f "generated/~a/release/~a"
682 platform bits))
683 (out (assoc-ref outputs "out"))
684 (lib (assoc-ref outputs "lib"))
685 (out-bin (string-append out "/bin"))
686 (out-etc (string-append out "/etc"))
687 (out-include (string-append out "/include/d/dmd"))
688 (out-include-etc (string-append out-include "/etc"))
689 (out-include-std (string-append out-include "/std"))
690 (out-lib (string-append out "/lib"))
691 (lib-lib (string-append lib "/lib"))
692 (out-man (string-append out "/share/man")))
693 (with-directory-excursion "dmd"
694 (with-directory-excursion build-sub-dir
695 (install-file "dmd" out-bin)
696 (install-file "libdruntime.a" out-lib)
697 (for-each (cut install-file <> lib-lib)
698 (find-files "." "^libdruntime\\.so[.0-9]*$")))
699 (copy-recursively "druntime/import" out-include)
700 (copy-recursively "generated/docs/man" out-man))
701 (with-directory-excursion "phobos"
702 (with-directory-excursion build-sub-dir
703 (install-file "libphobos2.a" out-lib)
704 (for-each (cut install-file <> lib-lib)
705 (find-files "." "^libphobos2\\.so[.0-9]*$")))
706 (copy-recursively "etc" out-include-etc)
707 (copy-recursively "std" out-include-std))
708 (mkdir-p out-etc)
709 (with-output-to-file (string-append out-etc "/dmd.conf")
710 (lambda _
711 (format #t "[Environment]\n")
712 (format #t "DFLAGS=")
713 (format #t " -I~a" out-include)
714 (format #t " -L-L~a" out-lib)
715 (format #t " -L-L~a" lib-lib)
716 (format #t " -L--export-dynamic")
717 (format #t " -fPIC")
718 (format #t "\n"))))))
719 (replace 'install-license-files
720 ;; Phobos license is identical.
721 #$(wrap-in-directory-excursion "dmd" 'install-license-files))))))
722 (inputs
723 (list curl ; std.net.curl
724 bash-minimal)) ; std.process
725 (native-inputs
726 (list gdmd
727 which
728 gdb/pinned ; for tests
729 tzdata-for-tests ; for tests
730 (origin
731 (method git-fetch)
732 (uri (git-reference
733 (url "https://github.com/dlang/phobos")
734 (commit (string-append "v" version))))
735 (file-name (git-file-name "phobos" version))
736 (sha256
737 (base32
738 "1w2ncn6q2fiq05wsygdfyyb0sbnsiddlnajkmajqcdcxjlih90cp"))
739 (patches (search-patches "dmd-phobos-support-TZDIR.patch")))))
740 (outputs '("out" "lib" "debug"))
741 (home-page "https://github.com/dlang/dmd")
742 (synopsis "Reference D Programming Language compiler")
743 (description "@acronym{DMD, Digital Mars D compiler} is the reference
744compiler for the D programming language.")
745 (license license:boost1.0)
746 ;; As reported by upstream: https://wiki.dlang.org/Compilers#Comparison
747 ;; Note: aarch64-linux is currently unsupported as the build system doesn't
748 ;; work with gdmd yet. Attempting to force through anyways gives assembler
749 ;; errors.
750 (supported-systems '("i686-linux" "x86_64-linux"))
751
752 ;; This variant exists only for bootstrapping purposes.
753 (properties '((hidden? . #t)))))
754
755;; DMD built with dmd-bootstrap as the bootstrap D compiler.
756;; Shared libraries are built now, tests are no longer disabled.
757(define-public dmd
758 (package
759 (inherit dmd-bootstrap)
760 (arguments
761 (substitute-keyword-arguments
762 (strip-keyword-arguments
763 '(#:tests?) ;reinstate tests
764 (package-arguments dmd-bootstrap))
765 ((#:disallowed-references _ ''())
766 (list dmd-bootstrap tzdata-for-tests))
767 ((#:make-flags flags ''())
768 #~(fold delete #$flags '("HOST_DMD=gdmd"
769 "SHARED=0")))
770 ((#:phases phases #~%standard-phases)
771 #~(modify-phases #$phases
772 (add-after 'install 'rewrite-references-to-bootstrap
773 ;; D compilers can keep references to the include files used to
774 ;; build a binary in exception messages. For dmd, rewrite the
775 ;; references to dmd-bootstrap to itself, to reduce its closure
776 ;; size.
777 (lambda* (#:key outputs #:allow-other-keys)
778 (let* ((in-dmd-bootstrap #$(this-package-native-input "dmd"))
779 (out (assoc-ref outputs "out"))
780 (out-bin-dmd (string-append out "/bin/dmd")))
781 ;; XXX: Use sed, as replace-store-references wouldn't replace
782 ;; the references, while substitute* throws an error.
783 (invoke "sed" "-i"
784 (format #f "s,~a,~a,g" in-dmd-bootstrap out)
785 out-bin-dmd))))))))
786 (native-inputs
787 (modify-inputs native-inputs
788 (delete "gdmd")
789 (append dmd-bootstrap)))
790 (properties
791 (alist-delete 'hidden? (package-properties dmd-bootstrap)))))
792
793
794;; D related tools
795
796(define-public dub
797 (package
798 (name "dub")
799 (version "1.42.0")
800 (source (origin
801 (method git-fetch)
802 (uri (git-reference
803 (url "https://github.com/dlang/dub")
804 (commit (string-append "v" version))))
805 (file-name (git-file-name name version))
806 (sha256
807 (base32
808 "1qql90zdnizv9jasivya4k8xg75ya9jkbzg5ixm8fmnnqnrfjyqq"))))
809 (build-system gnu-build-system) ; not really, uses a custom build script
810 (arguments
811 (list
812 #:modules
813 `(,@%default-gnu-modules
814 (srfi srfi-26))
815 #:phases
816 #~(modify-phases %standard-phases
817 (add-after 'unpack 'patch-tests
818 (lambda _
819 ;; These fail for various reasons. Some try to fetch a package
820 ;; from code.dlang.org. Some try to clone a git repo. Some try to
821 ;; run /bin/sh.
822 (for-each delete-file-recursively
823 '("test/dpath-variable"
824 "test/dub-as-a-library-cwd"
825 "test/git-dependency"
826 "test/issue502-root-import"
827 "test/issue1408-inherit-linker-files"
828 "test/issue1551-var-escaping"
829 "test/issue1775"
830 "test/issue2192-environment-variables"
831 "test/issue2452"
832 "test/issue2698-cimportpaths-broken-with-dmd-ldc"
833 "test/pr2642-cache-db"
834 "test/pr2644-describe-artifact-path"
835 "test/pr2647-build-deep"))))
836 (replace 'configure
837 (lambda _
838 (setenv "CC" #$(cc-for-target))))
839 (replace 'build
840 (lambda _
841 (invoke "ldmd2" "-run" "build.d")))
842 (add-after 'build 'prepare-post-build
843 (lambda _
844 (setenv "DC" "ldc2")
845 (setenv "DUB" "bin/dub")
846 ;; Don't store cache in $HOME, we have no home.
847 (setenv "DUB_HOME" "/tmp/dub-test-home")))
848 (add-after 'prepare-post-build 'generate-man
849 (lambda _
850 (setenv "DIFFABLE" "1") ; replaces currentTime with a static one
851 (invoke "bin/dub" "--single" "./scripts/man/gen_man.d")))
852 (replace 'check
853 (lambda* (#:key tests? #:allow-other-keys)
854 (when tests?
855 (invoke "sh" "./test/run-unittest.sh"))))
856 (replace 'install
857 (lambda* (#:key outputs #:allow-other-keys)
858 (let* ((out (assoc-ref outputs "out"))
859 (bin (string-append out "/bin"))
860 (man1 (string-append out "/share/man/man1"))
861 (bash-comp (string-append out "/etc/bash_completion.d"))
862 (fish-comp (string-append
863 out "/share/fish/vendor_completions.d"))
864 (zsh-comp (string-append out "/share/zsh/site-functions")))
865 (install-file "bin/dub" bin)
866 (with-directory-excursion "scripts/man"
867 (for-each (cut install-file <> man1)
868 (find-files "." "\\.1$")))
869 (install-file "scripts/bash-completion/dub.bash" bash-comp)
870 (install-file "scripts/fish-completion/dub.fish" fish-comp)
871 (install-file "scripts/zsh-completion/_dub" zsh-comp))))
872 (add-after 'install 'remove-d-include-references
873 #$(remove-d-include-references-phase
874 (this-package-native-input "ldc"))))))
875 (inputs
876 (list curl))
877 (native-inputs
878 (list ldc))
879 (home-page "https://dub.pm/")
880 (synopsis "Package and build manager for D projects")
881 (description
882 "DUB is a package and build manager for applications and
883libraries written in the D programming language. It can
884automatically retrieve a project's dependencies and integrate
885them in the build process.
886
887The design emphasis is on maximum simplicity for simple projects,
888while providing the opportunity to customize things when
889needed.")
890 (license license:boost1.0)))
891
892(define-public d-tools
893 (package
894 (name "d-tools")
895 (version "2.113.0")
896 (source (origin
897 (method git-fetch)
898 (uri (git-reference
899 (url "https://github.com/dlang/tools")
900 (commit (string-append "v" version))))
901 (file-name (git-file-name name version))
902 (sha256
903 (base32
904 "1zlhr5r4inrg7l7y0yasxmn025778g7zldnmqgfxs7wcsqcfr1cn"))))
905 (outputs '("out" "internal"))
906 (build-system gnu-build-system)
907 (arguments
908 (list
909 #:modules
910 `(,@%default-gnu-modules
911 (srfi srfi-26))
912 #:phases
913 #~(let ((sub-packages-out
914 '("ddemangle"
915 ;;"dman" ; skip as it depends “../dlang.org“
916 "dustmite"
917 "rdmd"))
918 (sub-packages-internal
919 '("catdoc"
920 "changed"
921 "checkwhitespace"
922 "contributors"
923 "detab"
924 "dget"
925 ;;"tests_extractor" ; skip as it depends on libdparse
926 "tolf")))
927 (modify-phases %standard-phases
928 (add-after 'unpack 'patch-tests
929 (lambda _
930 ;; Skip broken make ONESHELL shell test.
931 (substitute* "rdmd_test.d"
932 (("makeVersion = .*$") "makeVersion = \"skip\";"))))
933 (replace 'configure
934 (lambda _
935 (setenv "CC" #$(cc-for-target))
936 (setenv "DC" (which "ldc2"))
937 (setenv "DUB_HOME" "/tmp/.dub")))
938 (replace 'build
939 (lambda _
940 (for-each
941 (lambda (sub-package)
942 (invoke "dub" "build" "--build=release"
943 (string-append ":" sub-package)))
944 (append sub-packages-out sub-packages-internal))))
945 (replace 'check
946 (lambda* (#:key tests? #:allow-other-keys)
947 (when tests?
948 (invoke "./dtools_rdmd" "rdmd_test.d" "dtools_rdmd"
949 "-m" #$(if (target-64bit?) "64" "32")
950 "--rdmd-default-compiler" "ldmd2"))))
951 (replace 'install
952 (lambda* (#:key outputs #:allow-other-keys)
953 (let* ((out (assoc-ref outputs "out"))
954 (out-bin (string-append out "/bin"))
955 (out-man (string-append out "/man"))
956 (internal (assoc-ref outputs "internal"))
957 (internal-bin (string-append internal "/bin"))
958 (install-sub-package
959 (lambda (pkg dir)
960 (mkdir-p dir)
961 (copy-file (string-append "dtools_" pkg)
962 (string-append dir "/" pkg))))
963 (install-sub-packages
964 (lambda (pkgs dir)
965 (for-each (cut install-sub-package <> dir)
966 pkgs))))
967 (install-sub-packages sub-packages-out out-bin)
968 (install-sub-packages sub-packages-internal internal-bin)
969 (copy-recursively "man" out-man))))
970 (add-after 'install 'remove-d-include-references
971 #$(remove-d-include-references-phase
972 (this-package-native-input "ldc")))))))
973 (native-inputs
974 (list ldc
975 dub))
976 (home-page "https://github.com/dlang/tools")
977 (synopsis "Useful D-related tools")
978 (description
979 "@code{d-tools} provides some useful tools for working with the D
980programming language. In the output @code{out} are:
981@itemize
982@item @code{ddemangle} (demangles D symbols)
983@item @code{dustmite} (reduces D-like source code to mimimally reproduce some
984test case)
985@item @code{rdmd} (runs D source files as scripts)
986@end itemize
987In the @code{internal} output are:
988@itemize
989@item @code{catdoc} (concatenates Ddoc files)
990@item @code{changed} (change log generator)
991@item @code{checkwhitespace} (checks for correct whitespace usage in source
992files)
993@item @code{contributors} (query contributors between two D releases)
994@item @code{detab} (replace tabs with spaces, and remove trailing whitespace
995from lines)
996@item @code{dget} (D source code downloader)
997@item @code{tolf} (line endings converter)
998@end itemize")
999 (license license:boost1.0)))
1000
1001
1002;; D libraries
1003
1004(define-public gtkd
1005 (package
1006 (name "gtkd")
1007 (version "3.10.0")
1008 (source (origin
1009 (method url-fetch/zipbomb)
1010 (uri (string-append "https://gtkd.org/Downloads/sources/GtkD-"
1011 version ".zip"))
1012 (sha256
1013 (base32
1014 "0vc5ssb3ar02mg2pngmdi1xg4qjaya8332a9mk0sv97x6b4ddy3g"))))
1015 (build-system gnu-build-system)
1016 (arguments
1017 (list
1018 #:test-target "test"
1019 #:make-flags
1020 #~(list "DC=ldc2"
1021 (string-append "prefix=" (assoc-ref %outputs "out"))
1022 (string-append "libdir=" (assoc-ref %outputs "out") "/lib")
1023 "pkgconfigdir=lib/pkgconfig")
1024 #:phases
1025 #~(modify-phases %standard-phases
1026 (add-after 'unpack 'patch-tests
1027 (lambda _
1028 (for-each
1029 (lambda (file)
1030 (substitute* file (("debug\\(1\\)") "debug")))
1031 '("demos/gstreamer/mediaplayer/gst_mediaplayer.d"
1032 "demos/gstreamer/mediaplayer/gst_mediaplayer.d"
1033 "demos/gtkD/TestWindow/TestImage.d"
1034 "demos/gtkD/TestWindow/TestStock.d"
1035 "demos/gtkD/TestWindow/TestText.d"
1036 "demos/gtkD/TestWindow/TestThemes.d"
1037 "demos/gtkD/TestWindow/TestScales.d"
1038 "demos/gtkD/TestWindow/TestIdle.d"))))
1039 (delete 'configure)
1040 (add-before 'build 'patch-makefile
1041 (lambda* (#:key outputs #:allow-other-keys)
1042 (substitute* "GNUmakefile"
1043 ;; We do the tests ourselves.
1044 (("default-goal: libs test") "default-goal: libs")
1045 (("all: libs shared-libs test") "all: libs shared-libs")
1046 ;; Work around upstream bug.
1047 (("\\$\\(prefix\\)\\/\\$\\(libdir\\)") "$(libdir)"))))
1048 (add-before 'check 'pre-check
1049 (lambda _
1050 (system "Xvfb :1 &")
1051 (setenv "DISPLAY" ":1")
1052 (setenv "CC" #$(cc-for-target))))
1053 (add-after 'install 'remove-d-include-references
1054 #$(remove-d-include-references-phase
1055 (this-package-native-input "ldc"))))))
1056 (native-inputs
1057 (list unzip
1058 ldc
1059 pkg-config
1060 xorg-server-for-tests))
1061 (home-page "https://gtkd.org/")
1062 (synopsis "D binding and OO wrapper of GTK+")
1063 (description "This package provides bindings to GTK+ for D.")
1064 (license license:lgpl2.1)
1065 (properties `((release-monitoring-url . ,home-page)))))
1066
1067(define-public d-demangler
1068 (package
1069 (name "d-demangler")
1070 (version "0.0.2")
1071 (source (origin
1072 (method git-fetch)
1073 (uri (git-reference
1074 (url "https://github.com/lievenhey/d_demangler")
1075 (commit (string-append "version-" version))))
1076 (file-name (git-file-name name version))
1077 (sha256
1078 (base32
1079 "13lbbxlaa1mffjs57xchl1g6kyr5lxi0z5x7snyvym0knslxwx2g"))))
1080 (build-system gnu-build-system)
1081 (arguments
1082 (list
1083 #:tests? #f ; no test suite
1084 #:make-flags #~(list (string-append "CC=" #$(cc-for-target))
1085 "d_demangle")
1086 #:phases #~(modify-phases %standard-phases
1087 (delete 'configure)
1088 (replace 'install
1089 (lambda _
1090 (install-file "libd_demangle.so"
1091 (string-append #$output "/lib"))))
1092 (add-after 'install 'remove-d-include-references
1093 #$(remove-d-include-references-phase
1094 (this-package-native-input "dmd"))))))
1095 (native-inputs (list dmd))
1096 (home-page "https://github.com/lievenhey/d_demangler")
1097 (synopsis "D symbol demangling library")
1098 (description "@code{libd_demangle.so} is a small shared library that can be
1099used to demangle D symbols. It exposes a C interface that wraps D's
1100@code{std.demangle}.")
1101 (license license:gpl3+)))