projects/guix·blob python-team · refs

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