unofficial mirror of guix-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Timothy Sample <samplet@ngyro.com>
To: Fernando Oleo Blanco <irvise_ml@irvise.xyz>
Cc: Ricardo Wurmus <rekado@elephly.net>,
	 Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>,
	 guix-devel@gnu.org
Subject: Re: Adding GNAT/GCC-Ada to Guix
Date: Wed, 26 Jul 2023 19:35:39 -0600	[thread overview]
Message-ID: <87o7jyi1as.fsf@ngyro.com> (raw)
In-Reply-To: <2b47ef4f-49b4-e30e-7b12-c7bc7a2defb0@irvise.xyz> (Fernando Oleo Blanco's message of "Thu, 20 Jul 2023 18:13:59 +0000")

[-- Attachment #1: Type: text/plain, Size: 1396 bytes --]

Hi Fernando,

Fernando Oleo Blanco <irvise_ml@irvise.xyz> writes:

> I have talked with some people over at IRC and they recommended the use
> of the smaller GCC-Ada/GNAT binaries from Debian (even from older
> releases) and try to build an up-to-date Ada compiler toolchain with it.
>
> However, that would be a lot of work to get going and it may require a
> lot of trial and error for it to fully work. [...]

I did this five years ago!  Attached is a package that constructs a
working Ada compiler from Debian 8 (Jessie) binaries.  There are also
some packages that loosely follow the Guix commencement of GCC (as of
five years ago), but include GNAT.

Cf. https://logs.guix.gnu.org/guix/2018-09-04.log#165534

I just tested building ‘gnat-debian’ and ‘gnat-boot0’.  They still work!
The former is GCC 4 and the latter is (now) GCC 11.  I also built a
basic Ada program with ‘gnat-boot0’.  The rest of it may or may not
work.  The ‘gnat-5’ package is no longer appropriate, obviously.  :)

I hope that helps.  FWIW, I still think Debian is the best option here
for a bootstrapping binary.  Ada-Ed and old GNAT are the most likely
option for proper bootstrapping.  I found a yacc and lex grammar for Ada
95, too, but I can’t remember if it is freely licensed.  It could be
used to bridge the gap between Ada-Ed and old GNAT (maybe).


-- Tim


[-- Attachment #2: ada.scm --]
[-- Type: text/plain, Size: 11605 bytes --]

;;; Copyright © 2018 Timothy Sample <samplet@ngyro.com>
;;; SPDX-License-Identifier: GPL-3.0-or-later

(use-modules (gnu packages bootstrap)
             (gnu packages elf)
             (gnu packages guile)
             (gnu packages gcc)
             (gnu packages perl)
             (guix base16)
             (guix build-system gnu)
             (guix download)
             ((guix licenses) #:prefix license:)
             (guix packages)
             (guix utils)
             (ice-9 match))

\f
;;; Debian GNAT bootstrap binary

(define %debian-mirror "http://archive.debian.org/debian")

(define (debian-url source name version)
  (string-append %debian-mirror "/pool/main/" (substring source 0 1) "/"
                 source "/" name "_" version "_amd64.deb"))

(define %debian-gcc-packages
  '(("libasan1"
     "ea0c7defc2fbbb61f069a5d119a3e3e5c9740f7fafd5214bf3065aa8cb971097")
    ("libatomic1"
     "92d74070442f13a2e9403464862e1b0b1bb23992e5157e2ac83cc4ac9f17084a")
    ("libcilkrts5"
     "a0d57dd6273ef2366ba8b54669ac147226e24238e40c2c4a39a3e0e2a7eacb99")
    ("cpp-4.9"
     "f1b38be5b85df78265bba28dae8987b72904b7d36051703bc1f7e70c55136a91")
    ("gcc-4.9"
     "569a2ca8aed7eca54fbb9edae367064bbb0f7f773973e73c72e27fbfc703c3b0")
    ("libgomp1"
     "5e4425acbd597a4f091c69e787a9ea16f8bf4442c1dfd795d1ac8669912f2851")
    ("libitm1"
     "c005a4b836179ca9aa6ed28d9cb8785a3af6daa222cb55563fcc1edbca081eb4")
    ("libgcc-4.9-dev"
     "db89814eb484edf5d9c24a9def334ca1eac22afbfd3f8b23f12262e217ac80ff")
    ("libgcc1"
     "3101d5dc171fab3b4601bc3282bbc69f0fb9cfd1e1761389e1e6d2590e384623")
    ("libstdc++6"
     "a8f4ef6773b90bb39a8a8a0a5e3e20ca8501de6896204f665eb114d5b79f164f")
    ("liblsan0"
     "20caadf3fdd5905618f9933768bdbd79b9c16a26ece2774ad1b38d14329ecdf2")
    ("libquadmath0"
     "7e3779d41a42a88621f93c47a77874547b266b7c8166c80e254721e8347c3355")
    ("libtsan0"
     "5574f38d9b2f4987b90a70003ea7e60e0b5cab5c7a7c6ac9c2837eb1353e71bf")
    ("libubsan0"
     "49f00199613ff3d214c4137a2fe3b43bc3bbee79fa92ed9fb9cd0b0abaaf7c3e")))

(define %debian-gnat-packages
  '(("gnat-4.9"
     "0afb887980b819853f04e6c674f1a962836e3f691f14ad2b93af93c432db4bcb")
    ("libgnat-4.9"
     "9d6258a9dea4e78d4e6bd9996e00f673f1169df1aa00db713c716f22011b3638")
    ("libgnatprj4.9"
     "cadaf3f8d5f150589cbb286ecca07f1cd2f33b2f52675326398c9e1fb3b9aba5")
    ("libgnatvsn4.9"
     "227eaf2a40c24c9222e2f658d8b02e24e5f0d82f4c9003f994421c19c13f040d")))

(define %debian-gnat-closure
  `(("cloog" "libcloog-isl4" "0.18.2-1+b2"
     "8bb4ba985d65ededbfc24d76d3610af57a70787b635841407558d25a7f06ff49")
    ("gmp" "libgmp10" "6.0.0+dfsg-6"
     "155a31b0f716aa3dcd7ee68e9bd57e0b76a6b31f4e41fb2d953e986315437082")
    ("isl" "libisl10" "0.12.2-2"
     "5a091cf30221e183d319f4906a746043be7220061f3b742b2ad958ee79ac01f7")
    ("mpclib3" "libmpc3" "1.0.2-1"
     "0a252dcf89843ee8b402fd226c8fb552d69c82c7013a28e335ba36878468d959")
    ("mpfr4" "libmpfr4" "3.1.2-2"
     "1b6ef16024e7850c4f2d47dbe06cba1143ac36d5584db515f63d5fbd873e3eb2")
    ("zlib" "zlib1g" "1.2.8.dfsg-2+b1"
     "b75102f61ace79c14ea6f06fdd9509825ee2af694c6aa503253df4e6659d6772")
    ("gcc-defaults" "gcc" "4.9.2-2"
     "b7a60f9bc12d8ac0bbce99160390f28ee4a2d1d94753d123a7016d0443e46518")
    ("gcc-defaults" "cpp" "4.9.2-2"
     "e0d777817359da6dd7d003c164f12a55a8b889eb360ba2c945d5316ee7dbefd8")
    ,@(map (match-lambda
             ((name hash)
              `("gcc-4.9" ,name "4.9.2-10+deb8u1" ,hash)))
           %debian-gcc-packages)
    ,@(map (match-lambda
             ((name hash)
              `("gnat-4.9" ,name "4.9.2-1" ,hash)))
           %debian-gnat-packages)))

(define gnat-debian
  (package
    (name "gnat-debian")
    (version "4.9.2-1")
    (source #f)
    (build-system gnu-build-system)
    (arguments
     `(#:tests? #f
       #:strip-binaries? #f
       #:modules ((ice-9 match)
                  ,@%gnu-build-system-modules)
       #:phases
       (modify-phases %standard-phases
         ;; Instead of a single source archive, we have a bunch of
         ;; Debian package archives to unpack.
         (replace 'unpack
           (lambda* (#:key inputs #:allow-other-keys)
             (for-each (match-lambda
                         ((name . value)
                          (when (string-suffix? ".deb" name)
                            (invoke "ar" "x" value)
                            (invoke "tar" "xvf" "data.tar.xz"))))
                       inputs)
             ;; Most of the libraries are in "/usr/lib" but a few are in
             ;; "/lib".  They are easier to work with if consolidated.
             (copy-recursively "lib" "usr/lib")
             #t))
         ;; There is a symlink to "libgcc_s.so" that uses an absolute
         ;; path.  We need to make it relative.
         (add-after 'unpack 'fix-libgcc_s-link
           (lambda _
             (with-directory-excursion "usr//lib/gcc/x86_64-linux-gnu/4.9"
               (delete-file "libgcc_s.so")
               (symlink "../../../x86_64-linux-gnu/libgcc_s.so.1"
                        "libgcc_s.so"))
             #t))
         ;; This follows the Rust bootstrap binary packages.  We need to
         ;; patch the binaries so that they can find their shared
         ;; libraries and the dynamic linker.
         (add-after 'configure 'patch-elves
           (lambda* (#:key inputs outputs #:allow-other-keys)
             (let* ((out (assoc-ref outputs "out"))
                    (ld-so (string-append (assoc-ref inputs "libc")
                                          ,(glibc-dynamic-linker)))
                    (rpath (string-append out "/lib/x86_64-linux-gnu:"
                                          (dirname ld-so)))
                    (elves (find-files "."
                                       (lambda (file stat)
                                         (and (not (string-suffix? ".o" file))
                                              (elf-file? file))))))
               (for-each (lambda (elf)
                           (format #t "Setting RUNPATH for ~a~%" elf)
                           (invoke "patchelf" "--set-rpath" rpath elf)
                           (when (with-output-to-port (%make-void-port "w")
                                   (lambda ()
                                     (zero? (system* "patchelf"
                                                     "--print-interpreter"
                                                     elf))))
                             (format #t "Setting interpreter for ~a~%" elf)
                             (invoke "patchelf" "--set-interpreter" ld-so elf)))
                         elves)
               #t)))
         (delete 'configure)
         (delete 'build)
         (replace 'install
           (lambda* (#:key outputs #:allow-other-keys)
             (let ((out (assoc-ref outputs "out")))
               (copy-recursively "usr" out)
               #t)))
         ;; Tthe easiest way to ensure that GNAT uses Guix's dynamic
         ;; linker is to wrap the "collect2" program and modify its
         ;; arguments.  Normally, one would use LDFLAGS to set it, but
         ;; this doesn't propagate through the GNAT tools (e.g.,
         ;; "gnatmake").
         (add-after 'install 'wrap-collect
           (lambda* (#:key inputs outputs #:allow-other-keys)
             (let* ((out (string-append (assoc-ref outputs "out")))
                    (collect2 (string-append out "/lib/gcc/"
                                             "x86_64-linux-gnu/4.9/"
                                             "collect2"))
                    (ld-so (string-append (assoc-ref inputs "libc")
                                          ,(glibc-dynamic-linker)))
                    (guile (string-append (assoc-ref inputs "guile")
                                          "/bin/guile")))
               ;; Hide the real "collect2" program.
               (copy-file collect2 (string-append collect2 "-real"))
               ;; Write a small script to change the "-dynamic-linker"
               ;; argument before running the real "collect2".
               (with-output-to-file collect2
                 (lambda _
                   (display
                    (string-append "#!" guile " --no-auto-compile\n!#\n"))
                   (write
                    `(begin
                       (use-modules (ice-9 match))
                       (define (update-dynamic-linker args)
                         (let loop ((args args) (acc '()))
                           (match args
                             (() (reverse acc))
                             (("-dynamic-linker" _ . rest)
                              (loop rest (cons* ,ld-so "-dynamic-linker" acc)))
                             ((arg . rest)
                              (loop rest (cons arg acc))))))
                       (apply execl ,(string-append collect2 "-real")
                              (update-dynamic-linker (command-line)))))))
               #t))))))
    (inputs
     `(("guile" ,guile-2.2)))
    (native-inputs
     `(("patchelf" ,patchelf)
       ,@(map (match-lambda
                ((source name version hash)
                 `(,(string-append name ".deb")
                   ,(origin
                      (method url-fetch)
                      (uri (debian-url source name version))
                      (sha256 (base16-string->bytevector hash))))))
              %debian-gnat-closure)))
    (synopsis "GNU Ada compiler")
    (description "GNAT is a full-featured Ada 2012 compiler.")
    (home-page "https://gcc.gnu.org/")
    (license license:gpl3+)))

\f
;;; GNAT commencement

(define-public gnat-boot0
  (package
    (inherit gcc)
    (name "gnat-boot0")
    (arguments
     (substitute-keyword-arguments (package-arguments gcc)
       ((#:configure-flags flags)
        `(cons "--enable-languages=c,c++,ada"
               (filter (lambda (flag)
                         (not (string-prefix? "--enable-languages" flag)))
                       ,flags)))))
    (native-inputs
     `(("gcc" ,gnat-debian)
       ,@(package-native-inputs gcc)))))

(define gnat-final
  (package
    (inherit gnat-boot0)
    (name "gnat-final")
    (native-inputs
     `(("gcc" ,gnat-boot0)
       ,@(package-native-inputs gcc)))))

\f
;;; GNAT packages

;; XXX: These packages conflict with GCC.  Ideally, they would extend
;; GCC, but that may require modifying the GCC package, which is
;; something I would like to avoid (unless it could be merged
;; upstream).  It may be possible to wrap `gcc' and use its `-B' flag
;; to find the Ada compiler.  Another option could be to make a union
;; package.

(define (make-gnat gcc)
  (package
    (inherit gcc)
    (name "gnat")
    (arguments
     (substitute-keyword-arguments (package-arguments gcc)
       ((#:configure-flags flags)
        `(cons "--enable-languages=c,c++,ada"
               (filter (lambda (flag)
                         (not (string-prefix? "--enable-languages" flag)))
                       ,flags)))))
    (native-inputs
     (cons `("gcc" ,gnat-final)
           (package-native-inputs gcc)))))

(define-public gnat-5
  (make-gnat gcc-5))

(define-public gnat gnat-5)

(define-public gnat-toolchain
  (package
    (inherit ((@@ (gnu packages commencement) make-gcc-toolchain) gnat))
    (name "gnat-toolchain")))

      reply	other threads:[~2023-07-27  1:46 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-16  8:47 Adding GNAT/GCC-Ada to Guix Fernando Oleo Blanco
2023-07-16 14:36 ` Denis 'GNUtoo' Carikli
2023-07-17  7:44   ` Ricardo Wurmus
2023-07-20 18:13     ` Fernando Oleo Blanco
2023-07-27  1:35       ` Timothy Sample [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://guix.gnu.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87o7jyi1as.fsf@ngyro.com \
    --to=samplet@ngyro.com \
    --cc=GNUtoo@cyberdimension.org \
    --cc=guix-devel@gnu.org \
    --cc=irvise_ml@irvise.xyz \
    --cc=rekado@elephly.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).