projects/guix·blob ruby-team · refs

1098 lines · 50.4 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.42.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 "1zrfdhm9yw9bsd55k5x89pyj3zyxyly3hs3mpj3bnvkzvki3bl39"))
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
463(define-public ldc
464 (let ((base ldc-bootstrap))
465 (package
466 (inherit base)
467 (arguments
468 (substitute-keyword-arguments
469 (strip-keyword-arguments
470 '(#:tests?) ; reinstate tests
471 (package-arguments base))
472 ((#:disallowed-references _ ''())
473 (list (lookup-package-native-input base "gdmd")
474 tzdata-for-tests))
475 ((#:configure-flags flags #~'())
476 #~(append
477 (fold delete #$flags '("-DD_COMPILER_FLAGS=-fPIC"
478 "-DBUILD_SHARED_LIBS=OFF"))
479 '("-DBUILD_SHARED_LIBS=ON")))
480 ((#:build-type _ ''())
481 "RelWithDebInfo")
482 ((#:phases phases #~%standard-phases)
483 #~(modify-phases #$phases
484 (add-after 'create-lib-output 'rewrite-references-to-bootstrap
485 ;; D compilers can keep references to the include files used to
486 ;; build a binary in exception messages. For ldc, rewrite the
487 ;; references to ldc-bootstrap to itself, to reduce its closure
488 ;; size.
489 (lambda* (#:key outputs #:allow-other-keys)
490 (let* ((in-ldc-bootstrap #$(this-package-native-input "ldc"))
491 (out (assoc-ref outputs "out"))
492 (out/bin (string-append out "/bin")))
493 ;; XXX: Use sed, as replace-store-references wouldn't
494 ;; replace the references, while substitute* throws an
495 ;; error.
496 (apply invoke "sed" "-i"
497 (format #f "s,~a,~a,g" in-ldc-bootstrap out)
498 (find-files out/bin)))))))))
499 (native-inputs
500 (modify-inputs (package-native-inputs base)
501 (delete "gdmd")
502 (append base)))
503 (properties
504 (alist-delete 'hidden? (package-properties base))))))
505
506
507;; Reference D compiler
508;; Note: Has limited supported-systems.
509
510;; DMD built with GDC as the bootstrap D compiler (via the gdmd wrapper).
511;; Shared libraries are not built, tests are disabled.
512(define-public dmd-bootstrap
513 (package
514 ;; This package is purposefully named just "dmd" and not "dmd-bootstrap",
515 ;; as the final dmd package rewrites references from this one to itself,
516 ;; and their names must have the same length to avoid corrupting the
517 ;; binary.
518 (name "dmd")
519 (version "2.112.0")
520 (source (origin
521 (method git-fetch)
522 (uri (git-reference
523 (url "https://github.com/dlang/dmd")
524 (commit (string-append "v" version))))
525 (file-name (git-file-name "dmd" version))
526 ;; Note: When updating, also update the hash of phobos in the
527 ;; native-inputs below.
528 (sha256
529 (base32
530 "0qvg2fb73kyng8k1wj482g07ar2qw5laa5fynwx7pdd610n0pjpc"))))
531 (build-system gnu-build-system)
532 (arguments
533 (list
534 #:disallowed-references (list (gexp-input (canonical-package gcc) "lib")
535 tzdata-for-tests)
536 ;; Disable tests, as gdmd cannot cope with some arguments used such as
537 ;; '-conf'.
538 #:tests? #f
539 #:out-of-source? #t
540 #:make-flags
541 #~(list (string-append "CC=" #$(cc-for-target))
542 (string-append "HOST_CXX=" #$(cxx-for-target))
543 "HOST_DMD=gdmd"
544 (string-append "INSTALL_DIR=" #$output)
545 (string-append "SYSCONFDIR=" #$output "/etc")
546 "ENABLE_RELEASE=1"
547 ;; Do not build the shared libphobos2.so library, to avoid
548 ;; retaining a reference to gcc:lib.
549 "SHARED=0"
550 "DIFFABLE=1" ;constant timestamp
551 "VERBOSE=1")
552 #:modules
553 `(,@%default-gnu-modules
554 (srfi srfi-1)
555 (srfi srfi-26))
556 #:phases
557 (let* ((wrap-in-directory-excursion
558 (lambda (sub-dir phase . extra-args)
559 #~(lambda args
560 (with-directory-excursion #$sub-dir
561 (apply (assoc-ref %standard-phases '#$phase)
562 (append args '#$extra-args))))))
563 (target-file (lambda (pkg-name path)
564 (file-append (this-package-input pkg-name) path)))
565 (target-bin-sh (target-file "bash-minimal" "/bin/sh"))
566 (target-lib-curl (target-file "curl" "/lib/libcurl.so")))
567 #~(modify-phases %standard-phases
568 (replace 'unpack
569 (lambda* (#:key source #:allow-other-keys)
570 (let ((dmd-source source)
571 (phobos-source #$(this-package-native-input
572 (git-file-name "phobos" version))))
573 (mkdir "source")
574 (chdir "source")
575 (copy-recursively dmd-source "dmd" #:keep-mtime? #t)
576 (copy-recursively phobos-source "phobos" #:keep-mtime? #t)
577 (for-each (lambda (f)
578 (false-if-exception (make-file-writable f)))
579 (find-files ".")))))
580 (add-after 'unpack 'patch-git-ls-tree
581 ;; The druntime Makefile tries to use git ls-tree to get all
582 ;; source files in dmd/druntime/. We replace the command with a
583 ;; listing of those files.
584 (lambda _
585 (with-directory-excursion "dmd/druntime"
586 (substitute* "Makefile"
587 (("^MANIFEST *:*=.*$")
588 (string-append "MANIFEST := "
589 (string-join (map (cut string-drop <> 2)
590 (find-files "./")))
591 "\n"))))))
592 (add-after 'unpack 'patch-paths-in-phobos
593 (lambda _
594 (with-directory-excursion "phobos"
595 (substitute* "std/net/curl.d"
596 (("\"libcurl\\.so\"")
597 (format #f "~s" #$target-lib-curl)))
598 (substitute* "std/process.d"
599 (("return \"/bin/sh\";")
600 (format #f "return ~s;" #$target-bin-sh))
601 (("#!/bin/sh")
602 (string-append "#!" #$target-bin-sh))))))
603 (add-after 'unpack 'patch-tests
604 (lambda _
605 ;; Since the implementation of SOURCE_DATE_EPOCH support in
606 ;; Ddoc, this test fails, as it expects Ddoc timestamps to
607 ;; match the output of the `date` command.
608 ;; XXX: Report upstream.
609 (substitute* (string-append
610 "dmd/compiler/test/compilable"
611 "/extra-files/ddocYear-postscript.sh")
612 (("^YEAR=.*$") "YEAR=1970\n"))
613
614 ;; This test creates a shell script and runs it.
615 (substitute* "dmd/compiler/test/dshell/test6952.d"
616 (("/usr/bin/env bash") #$target-bin-sh))
617
618 ;; In the sarif json output, the compiler version string ends
619 ;; with a raw newline for some reason, causing these tests to
620 ;; fail.
621 (for-each
622 delete-file
623 '("dmd/compiler/test/compilable/sarif_success_test.d"
624 "dmd/compiler/test/fail_compilation/sarif_test.d"
625 "dmd/compiler/test/fail_compilation/sarifmultiple_test.d"))
626
627 ;; tries to debug 64bit executable
628 ;; not in executable format: file format not recognized
629 #$@(if (target-32bit?)
630 #~((delete-file
631 (string-append "dmd/compiler/test/runnable"
632 "/gdb_slice_debuginfo_64.d")))
633 #~())
634
635 ;; Locations in stack traces are broken for some reason,
636 ;; causing these tests to fail.
637 ;; XXX: Report upstream.
638 (for-each
639 delete-file
640 '("dmd/compiler/test/runnable/test17559.d"
641 "dmd/compiler/test/runnable/test19086.d"))
642 (substitute* "dmd/druntime/test/exceptions/Makefile"
643 (((string-append "line_trace line_trace_21656 "
644 "long_backtrace_trunc rt_trap_exceptions "))
645 ""))
646 (substitute* "dmd/druntime/test/gc/Makefile"
647 ((" invariant ") " "))
648
649 ;; Skip a std.process unittest that fails due to "kill" not
650 ;; working properly in the build environment.
651 (substitute* "phobos/std/process.d"
652 (("^.*sleep.*10000" all)
653 (string-append " return;\n" all)))))
654 (delete 'bootstrap)
655 (delete 'configure)
656 (replace 'build
657 #$(wrap-in-directory-excursion "dmd" 'build))
658 (add-after 'build 'build-phobos
659 #$(wrap-in-directory-excursion "phobos" 'build))
660 (add-after 'build-phobos 'build-man
661 (lambda* (#:key make-flags #:allow-other-keys)
662 (with-directory-excursion "dmd/compiler/docs"
663 (let ((dmd (or (which "gdmd")
664 (which "dmd"))))
665 ((assoc-ref %standard-phases 'build)
666 #:make-flags (cons
667 (string-append "DMD=" dmd)
668 make-flags))))))
669 (replace 'check
670 #$(wrap-in-directory-excursion "dmd" 'check
671 #:test-target "test"))
672 (add-after 'check 'check-phobos
673 #$(wrap-in-directory-excursion "phobos" 'check
674 #:test-target "unittest"))
675 (replace 'install
676 (lambda* (#:key outputs #:allow-other-keys)
677 (let* ((platform (cond (#$(target-linux?) "linux")))
678 (bits (if #$(target-64bit?) 64 32))
679 (build-sub-dir (format #f "generated/~a/release/~a"
680 platform bits))
681 (out (assoc-ref outputs "out"))
682 (lib (assoc-ref outputs "lib"))
683 (out-bin (string-append out "/bin"))
684 (out-etc (string-append out "/etc"))
685 (out-include (string-append out "/include/d/dmd"))
686 (out-include-etc (string-append out-include "/etc"))
687 (out-include-std (string-append out-include "/std"))
688 (out-lib (string-append out "/lib"))
689 (lib-lib (string-append lib "/lib"))
690 (out-man (string-append out "/share/man")))
691 (with-directory-excursion "dmd"
692 (with-directory-excursion build-sub-dir
693 (install-file "dmd" out-bin)
694 (install-file "libdruntime.a" out-lib)
695 (for-each (cut install-file <> lib-lib)
696 (find-files "." "^libdruntime\\.so[.0-9]*$")))
697 (copy-recursively "druntime/import" out-include)
698 (copy-recursively "generated/docs/man" out-man))
699 (with-directory-excursion "phobos"
700 (with-directory-excursion build-sub-dir
701 (install-file "libphobos2.a" out-lib)
702 (for-each (cut install-file <> lib-lib)
703 (find-files "." "^libphobos2\\.so[.0-9]*$")))
704 (copy-recursively "etc" out-include-etc)
705 (copy-recursively "std" out-include-std))
706 (mkdir-p out-etc)
707 (with-output-to-file (string-append out-etc "/dmd.conf")
708 (lambda _
709 (format #t "[Environment]\n")
710 (format #t "DFLAGS=")
711 (format #t " -I~a" out-include)
712 (format #t " -L-L~a" out-lib)
713 (format #t " -L-L~a" lib-lib)
714 (format #t " -L--export-dynamic")
715 (format #t " -fPIC")
716 (format #t "\n"))))))
717 (replace 'install-license-files
718 ;; Phobos license is identical.
719 #$(wrap-in-directory-excursion "dmd" 'install-license-files))))))
720 (inputs
721 (list curl ; std.net.curl
722 bash-minimal)) ; std.process
723 (native-inputs
724 (list gdmd
725 which
726 gdb/pinned ; for tests
727 tzdata-for-tests ; for tests
728 (origin
729 (method git-fetch)
730 (uri (git-reference
731 (url "https://github.com/dlang/phobos")
732 (commit (string-append "v" version))))
733 (file-name (git-file-name "phobos" version))
734 (sha256
735 (base32
736 "0afi5glnf96242cbnr10ccjvfsgkh4k5y7qnmxv4ph5g0izvi1dc"))
737 (patches (search-patches "dmd-phobos-support-TZDIR.patch")))))
738 (outputs '("out" "lib" "debug"))
739 (home-page "https://github.com/dlang/dmd")
740 (synopsis "Reference D Programming Language compiler")
741 (description "@acronym{DMD, Digital Mars D compiler} is the reference
742compiler for the D programming language.")
743 (license license:boost1.0)
744 ;; As reported by upstream: https://wiki.dlang.org/Compilers#Comparison
745 ;; Note: aarch64-linux is currently unsupported as the build system doesn't
746 ;; work with gdmd yet. Attempting to force through anyways gives assembler
747 ;; errors.
748 (supported-systems '("i686-linux" "x86_64-linux"))
749
750 ;; This variant exists only for bootstrapping purposes.
751 (properties '((hidden? . #t)))))
752
753;; DMD built with dmd-bootstrap as the bootstrap D compiler.
754;; Shared libraries are built now, tests are no longer disabled.
755(define-public dmd
756 (package
757 (inherit dmd-bootstrap)
758 (arguments
759 (substitute-keyword-arguments
760 (strip-keyword-arguments
761 '(#:tests?) ;reinstate tests
762 (package-arguments dmd-bootstrap))
763 ((#:disallowed-references _ ''())
764 (list dmd-bootstrap tzdata-for-tests))
765 ((#:make-flags flags ''())
766 #~(fold delete #$flags '("HOST_DMD=gdmd"
767 "SHARED=0")))
768 ((#:phases phases #~%standard-phases)
769 #~(modify-phases #$phases
770 (add-after 'install 'rewrite-references-to-bootstrap
771 ;; D compilers can keep references to the include files used to
772 ;; build a binary in exception messages. For dmd, rewrite the
773 ;; references to dmd-bootstrap to itself, to reduce its closure
774 ;; size.
775 (lambda* (#:key outputs #:allow-other-keys)
776 (let* ((in-dmd-bootstrap #$(this-package-native-input "dmd"))
777 (out (assoc-ref outputs "out"))
778 (out-bin-dmd (string-append out "/bin/dmd")))
779 ;; XXX: Use sed, as replace-store-references wouldn't replace
780 ;; the references, while substitute* throws an error.
781 (invoke "sed" "-i"
782 (format #f "s,~a,~a,g" in-dmd-bootstrap out)
783 out-bin-dmd))))))))
784 (native-inputs
785 (modify-inputs native-inputs
786 (delete "gdmd")
787 (append dmd-bootstrap)))
788 (properties
789 (alist-delete 'hidden? (package-properties dmd-bootstrap)))))
790
791
792;; D related tools
793
794(define-public dub
795 (package
796 (name "dub")
797 (version "1.42.0-beta.1")
798 (source (origin
799 (method git-fetch)
800 (uri (git-reference
801 (url "https://github.com/dlang/dub")
802 (commit (string-append "v" version))))
803 (file-name (git-file-name name version))
804 (sha256
805 (base32
806 "1g2v7bf6sjqdwif64lic0l7jd6r0bididyc9balk8xnhiq5q65mz"))))
807 (build-system gnu-build-system) ; not really, uses a custom build script
808 (arguments
809 (list
810 #:modules
811 `(,@%default-gnu-modules
812 (srfi srfi-26))
813 #:phases
814 #~(modify-phases %standard-phases
815 (add-after 'unpack 'patch-tests
816 (lambda _
817 ;; These fail for various reasons. Some try to fetch a package
818 ;; from code.dlang.org. Some try to clone a git repo. Some try to
819 ;; run /bin/sh.
820 (for-each delete-file-recursively
821 '("test/dpath-variable"
822 "test/dub-as-a-library-cwd"
823 "test/git-dependency"
824 "test/issue502-root-import"
825 "test/issue1408-inherit-linker-files"
826 "test/issue1551-var-escaping"
827 "test/issue1775"
828 "test/issue2192-environment-variables"
829 "test/issue2452"
830 "test/issue2698-cimportpaths-broken-with-dmd-ldc"
831 "test/pr2642-cache-db"
832 "test/pr2644-describe-artifact-path"
833 "test/pr2647-build-deep"))))
834 (replace 'configure
835 (lambda _
836 (setenv "CC" #$(cc-for-target))))
837 (replace 'build
838 (lambda _
839 (invoke "ldmd2" "-run" "build.d")))
840 (add-after 'build 'prepare-post-build
841 (lambda _
842 (setenv "DC" "ldc2")
843 (setenv "DUB" "bin/dub")
844 ;; Don't store cache in $HOME, we have no home.
845 (setenv "DUB_HOME" "/tmp/dub-test-home")))
846 (add-after 'prepare-post-build 'generate-man
847 (lambda _
848 (setenv "DIFFABLE" "1") ; replaces currentTime with a static one
849 (invoke "bin/dub" "--single" "./scripts/man/gen_man.d")))
850 (replace 'check
851 (lambda* (#:key tests? #:allow-other-keys)
852 (when tests?
853 (invoke "sh" "./test/run-unittest.sh"))))
854 (replace 'install
855 (lambda* (#:key outputs #:allow-other-keys)
856 (let* ((out (assoc-ref outputs "out"))
857 (bin (string-append out "/bin"))
858 (man1 (string-append out "/share/man/man1"))
859 (bash-comp (string-append out "/etc/bash_completion.d"))
860 (fish-comp (string-append
861 out "/share/fish/vendor_completions.d"))
862 (zsh-comp (string-append out "/share/zsh/site-functions")))
863 (install-file "bin/dub" bin)
864 (with-directory-excursion "scripts/man"
865 (for-each (cut install-file <> man1)
866 (find-files "." "\\.1$")))
867 (install-file "scripts/bash-completion/dub.bash" bash-comp)
868 (install-file "scripts/fish-completion/dub.fish" fish-comp)
869 (install-file "scripts/zsh-completion/_dub" zsh-comp))))
870 (add-after 'install 'remove-d-include-references
871 #$(remove-d-include-references-phase
872 (this-package-native-input "ldc"))))))
873 (inputs
874 (list curl))
875 (native-inputs
876 (list ldc))
877 (home-page "https://dub.pm/")
878 (synopsis "Package and build manager for D projects")
879 (description
880 "DUB is a package and build manager for applications and
881libraries written in the D programming language. It can
882automatically retrieve a project's dependencies and integrate
883them in the build process.
884
885The design emphasis is on maximum simplicity for simple projects,
886while providing the opportunity to customize things when
887needed.")
888 (license license:boost1.0)))
889
890(define-public d-tools
891 (package
892 (name "d-tools")
893 (version "2.112.0")
894 (source (origin
895 (method git-fetch)
896 (uri (git-reference
897 (url "https://github.com/dlang/tools")
898 (commit (string-append "v" version))))
899 (file-name (git-file-name name version))
900 (sha256
901 (base32
902 "0z23ivy6nq3q45wgclp5y6cjm8awdamma491818qimgffzgiay2q"))))
903 (outputs '("out" "internal"))
904 (build-system gnu-build-system)
905 (arguments
906 (list
907 #:modules
908 `(,@%default-gnu-modules
909 (srfi srfi-26))
910 #:phases
911 #~(let ((sub-packages-out
912 '("ddemangle"
913 ;;"dman" ; skip as it depends “../dlang.org“
914 "dustmite"
915 "rdmd"))
916 (sub-packages-internal
917 '("catdoc"
918 "changed"
919 "checkwhitespace"
920 "contributors"
921 "detab"
922 "dget"
923 ;;"tests_extractor" ; skip as it depends on libdparse
924 "tolf")))
925 (modify-phases %standard-phases
926 (add-after 'unpack 'patch-tests
927 (lambda _
928 ;; Skip broken make ONESHELL shell test.
929 (substitute* "rdmd_test.d"
930 (("makeVersion = .*$") "makeVersion = \"skip\";"))))
931 (replace 'configure
932 (lambda _
933 (setenv "CC" #$(cc-for-target))
934 (setenv "DC" (which "ldc2"))
935 (setenv "DUB_HOME" "/tmp/.dub")))
936 (replace 'build
937 (lambda _
938 (for-each
939 (lambda (sub-package)
940 (invoke "dub" "build" "--build=release"
941 (string-append ":" sub-package)))
942 (append sub-packages-out sub-packages-internal))))
943 (replace 'check
944 (lambda* (#:key tests? #:allow-other-keys)
945 (when tests?
946 (invoke "./dtools_rdmd" "rdmd_test.d" "dtools_rdmd"
947 "-m" #$(if (target-64bit?) "64" "32")
948 "--rdmd-default-compiler" "ldmd2"))))
949 (replace 'install
950 (lambda* (#:key outputs #:allow-other-keys)
951 (let* ((out (assoc-ref outputs "out"))
952 (out-bin (string-append out "/bin"))
953 (out-man (string-append out "/man"))
954 (internal (assoc-ref outputs "internal"))
955 (internal-bin (string-append internal "/bin"))
956 (install-sub-package
957 (lambda (pkg dir)
958 (mkdir-p dir)
959 (copy-file (string-append "dtools_" pkg)
960 (string-append dir "/" pkg))))
961 (install-sub-packages
962 (lambda (pkgs dir)
963 (for-each (cut install-sub-package <> dir)
964 pkgs))))
965 (install-sub-packages sub-packages-out out-bin)
966 (install-sub-packages sub-packages-internal internal-bin)
967 (copy-recursively "man" out-man))))
968 (add-after 'install 'remove-d-include-references
969 #$(remove-d-include-references-phase
970 (this-package-native-input "ldc")))))))
971 (native-inputs
972 (list ldc
973 dub))
974 (home-page "https://github.com/dlang/tools")
975 (synopsis "Useful D-related tools")
976 (description
977 "@code{d-tools} provides some useful tools for working with the D
978programming language. In the output @code{out} are:
979@itemize
980@item @code{ddemangle} (demangles D symbols)
981@item @code{dustmite} (reduces D-like source code to mimimally reproduce some
982test case)
983@item @code{rdmd} (runs D source files as scripts)
984@end itemize
985In the @code{internal} output are:
986@itemize
987@item @code{catdoc} (concatenates Ddoc files)
988@item @code{changed} (change log generator)
989@item @code{checkwhitespace} (checks for correct whitespace usage in source
990files)
991@item @code{contributors} (query contributors between two D releases)
992@item @code{detab} (replace tabs with spaces, and remove trailing whitespace
993from lines)
994@item @code{dget} (D source code downloader)
995@item @code{tolf} (line endings converter)
996@end itemize")
997 (license license:boost1.0)))
998
999
1000;; D libraries
1001
1002(define-public gtkd
1003 (package
1004 (name "gtkd")
1005 (version "3.10.0")
1006 (source (origin
1007 (method url-fetch/zipbomb)
1008 (uri (string-append "https://gtkd.org/Downloads/sources/GtkD-"
1009 version ".zip"))
1010 (sha256
1011 (base32
1012 "0vc5ssb3ar02mg2pngmdi1xg4qjaya8332a9mk0sv97x6b4ddy3g"))))
1013 (build-system gnu-build-system)
1014 (arguments
1015 (list
1016 #:test-target "test"
1017 #:make-flags
1018 #~(list "DC=ldc2"
1019 (string-append "prefix=" (assoc-ref %outputs "out"))
1020 (string-append "libdir=" (assoc-ref %outputs "out") "/lib")
1021 "pkgconfigdir=lib/pkgconfig")
1022 #:phases
1023 #~(modify-phases %standard-phases
1024 (add-after 'unpack 'patch-tests
1025 (lambda _
1026 (for-each
1027 (lambda (file)
1028 (substitute* file (("debug\\(1\\)") "debug")))
1029 '("demos/gstreamer/mediaplayer/gst_mediaplayer.d"
1030 "demos/gstreamer/mediaplayer/gst_mediaplayer.d"
1031 "demos/gtkD/TestWindow/TestImage.d"
1032 "demos/gtkD/TestWindow/TestStock.d"
1033 "demos/gtkD/TestWindow/TestText.d"
1034 "demos/gtkD/TestWindow/TestThemes.d"
1035 "demos/gtkD/TestWindow/TestScales.d"
1036 "demos/gtkD/TestWindow/TestIdle.d"))))
1037 (delete 'configure)
1038 (add-before 'build 'patch-makefile
1039 (lambda* (#:key outputs #:allow-other-keys)
1040 (substitute* "GNUmakefile"
1041 ;; We do the tests ourselves.
1042 (("default-goal: libs test") "default-goal: libs")
1043 (("all: libs shared-libs test") "all: libs shared-libs")
1044 ;; Work around upstream bug.
1045 (("\\$\\(prefix\\)\\/\\$\\(libdir\\)") "$(libdir)"))))
1046 (add-before 'check 'pre-check
1047 (lambda _
1048 (system "Xvfb :1 &")
1049 (setenv "DISPLAY" ":1")
1050 (setenv "CC" #$(cc-for-target))))
1051 (add-after 'install 'remove-d-include-references
1052 #$(remove-d-include-references-phase
1053 (this-package-native-input "ldc"))))))
1054 (native-inputs
1055 (list unzip
1056 ldc
1057 pkg-config
1058 xorg-server-for-tests))
1059 (home-page "https://gtkd.org/")
1060 (synopsis "D binding and OO wrapper of GTK+")
1061 (description "This package provides bindings to GTK+ for D.")
1062 (license license:lgpl2.1)))
1063
1064(define-public d-demangler
1065 (package
1066 (name "d-demangler")
1067 (version "0.0.2")
1068 (source (origin
1069 (method git-fetch)
1070 (uri (git-reference
1071 (url "https://github.com/lievenhey/d_demangler")
1072 (commit (string-append "version-" version))))
1073 (file-name (git-file-name name version))
1074 (sha256
1075 (base32
1076 "13lbbxlaa1mffjs57xchl1g6kyr5lxi0z5x7snyvym0knslxwx2g"))))
1077 (build-system gnu-build-system)
1078 (arguments
1079 (list
1080 #:tests? #f ; no test suite
1081 #:make-flags #~(list (string-append "CC=" #$(cc-for-target))
1082 "d_demangle")
1083 #:phases #~(modify-phases %standard-phases
1084 (delete 'configure)
1085 (replace 'install
1086 (lambda _
1087 (install-file "libd_demangle.so"
1088 (string-append #$output "/lib"))))
1089 (add-after 'install 'remove-d-include-references
1090 #$(remove-d-include-references-phase
1091 (this-package-native-input "dmd"))))))
1092 (native-inputs (list dmd))
1093 (home-page "https://github.com/lievenhey/d_demangler")
1094 (synopsis "D symbol demangling library")
1095 (description "@code{libd_demangle.so} is a small shared library that can be
1096used to demangle D symbols. It exposes a C interface that wraps D's
1097@code{std.demangle}.")
1098 (license license:gpl3+)))