From 556203a5b090042e9aed38cb6395e04f0ec2dc92 Mon Sep 17 00:00:00 2001 From: Michael South Date: Thu, 27 Jun 2024 04:46:39 -0700 Subject: [PATCH] As part of (archive) process, creates gentoo ebuilds and manifest. {base}/gentoo/clasp is an ephemeral directory, excluded from git - gentoo/clasp/clasp-N.N.N.N.ebuild -- Release build; src & depends in tarball - gentoo/clasp/clasp-9999.ebuild -- HEAD build; src & depends pulled w/ git - gentoo/clasp/metadata.xml -- Describes package to Gentoo Portage - gentoo/clasp/Manifest -- Describes distribution files to Portage {base}/gentoo is a permanent, version-controlled directory - gentoo/ebuild.template -- Source for clasp-{N.N.N.N,9999}.ebuild - gentoo/metadata.xml -- Source for gentoo/clasp/metadata.xml --- .gitignore | 3 +- gentoo/ebuild.template | 160 +++++++++++++++++++++++++++++++++++++++++ gentoo/metadata.xml | 31 ++++++++ src/koga/archive.lisp | 73 ++++++++++++++++++- 4 files changed, 263 insertions(+), 4 deletions(-) create mode 100644 gentoo/ebuild.template create mode 100644 gentoo/metadata.xml diff --git a/.gitignore b/.gitignore index 0ed0fb5723..1e1a842c22 100644 --- a/.gitignore +++ b/.gitignore @@ -50,10 +50,11 @@ debhelper-build-stamp clasp.substvars debian/clasp debian/files +gentoo/clasp src/lisp/regression-tests/*.txt src/lisp/regression-tests/*.bc src/lisp/regression-tests/*.newfasl src/analysis/*.lst src/analysis/*.cc bench/ -repos-*.sexp \ No newline at end of file +repos-*.sexp diff --git a/gentoo/ebuild.template b/gentoo/ebuild.template new file mode 100644 index 0000000000..0f75d53e96 --- /dev/null +++ b/gentoo/ebuild.template @@ -0,0 +1,160 @@ +# -*- mode: sh-script; mode: ebuild; -*- +# Copyright 1999-2024 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 or later. + +EAPI=8 + +CHECKREQS_MEMORY="2G" +LLVM_COMPAT=( {15..18} ) + +inherit check-reqs edo flag-o-matic llvm-r1 multiprocessing ninja-utils toolchain-funcs + +# Dependencies are in two groups: (1) a minimal set which are spec'd in +# this ebuild and must be pre-installed, and (2) an additional set which +# are obtained by the build scripts. +# +# Version N.N.N is a normal release. All necessary sources are wrapped +# up in a tarball, including the additional dependencies but not the +# minimal ebuild set. +# +# Version 9999 is the standard Gentoo "live ebuild" (git HEAD). The +# minimal set of dependencies must already be installed, the Clasp +# sources will be pulled down via git in this ebuild, and then the build +# scripts will pull down the additional set of dependencies, also via +# git. + +if [ ${PV} = "9999" ]; then + EGIT_REPO_URI="https://github.com/clasp-developers/clasp" + EGIT_BRANCH="main" + # The app build script will git the dependencies not in BDEPEND. + EGIT_MIN_CLONE_TYPE="shallow" + inherit git-r3 + SLOT="0" +else + SRC_URI="https://github.com/clasp-developers/clasp/releases/download/${PV}/${P}.tar.gz" + KEYWORDS="~amd64" + SLOT="0/${PV}" +fi + +DESCRIPTION="Common Lisp implementation based on LLVM." +HOMEPAGE="https://github.com/clasp-developers/clasp" +# Primary Clasp and core ECL (src/lisp/kernel/lsp) are LGPL-2+, +# Parts of Clasp are MIT. +# MPS is Sleepycat, +# src/lisp/kernel/clos is LGPL-2+, +# src/lisp/kernel/lsp/loop2.lisp is MIT, +# src/lisp/kernel/lsp/{pprint,format}.lisp are Public Domain by CMU, +# src/lisp/kernel/clos is LGPL-2+ +LICENSE="LGPL-2+ Sleepycat MIT public-domain" + +IUSE="+bcfaso" + +# Clasp needs llvm's libunwind, but runs OK without the Portage +# sys-devel/llvm-libunwind being installed. (Or even an "unwind" +# lib anywhere in installed llvm tree.) Don't question it, +# it's magic. + +RDEPEND="sys-devel/binutils:= + $(llvm_gen_dep ' + sys-devel/clang:${LLVM_SLOT}= + sys-devel/llvm:${LLVM_SLOT}= + sys-devel/lld:${LLVM_SLOT}= + ') + dev-libs/boost:= + >=dev-libs/libfmt-7.1.0 + >=dev-libs/gmp-6.0.0[cxx] + virtual/pkgconfig + virtual/libelf:=" +DEPEND="${RDEPEND}" +BDEPEND="app-alternatives/ninja + dev-lisp/sbcl" +[ "${PV}" = "2.6.0" ] && BDEPEND+=" dev-util/ctags" +IDEPEND="app-alternatives/ninja + dev-lisp/sbcl" + +RESTRICT="strip" + +DOCS=( + CONTRIBUTING.md + README.md + RELEASE_NOTES.md + SECURITY.md +) +MANDOCS=( docs/clasp.1 ) + +pkg_pretend() { + if [ "${PV}" = "9999" ]; then + ewarn "This live ebuild is incompatible with make.conf FEATURE 'network-sandbox'." + ewarn "The koga/ninja build script downloads additional C++ and Common Lisp" + ewarn "dependencies by internally calling git, without going through ebuild" + ewarn "helpers. network-sandbox intentionally prevents all such access." + ewarn "See https://wiki.gentoo.org/wiki/Sandbox_(Portage)" + ewarn " https://bugs.gentoo.org/691472" + fi +} + +src_unpack() { + [ -n "${EGIT_REPO_URI}" ] && git-r3_src_unpack + default +} + +src_configure() { + # Get job count from MAKEOPTS '-j' flag. Use for Lisp builds and Ninja. + export CLASP_BUILD_JOBS=$(get_makeopts_jobs) + + strip-unsupported-flags + # Clasp needs un-stripped binaries. + filter-flags -Wl,-s + filter-ldflags -s + # Clasp build scripts set -fno-omit-fpointer where its needed. + + # Set up paths to LLVM components. + llvm-r1_pkg_setup + + local myconf=( + --ldflags="${LDFLAGS}" + --jobs=${CLASP_BUILD_JOBS} + --reproducible + --build-path="${S}/build" + --prefix="${EPREFIX}/usr" + --bin-path="${EPREFIX}/usr/bin" + --lib-path="${EPREFIX}/usr/$(get_libdir)/${PF}" + --share-path="${EPREFIX}/usr/share/${PF}" + --pkg-config=$(tc-getPKG_CONFIG) + --ld="lld" + --lisp=sbcl # Upstream really, really prefers SBCL + ) + + # Yes, we get a pkgcheck VariableScope warning on {ED}, + # Unfortunately, the Clasp koga script creates all of the ninja + # scripts at src_configure time, and the generated scripts have no + # provision for looking at DESTDIR at install time. This config + # setting only affects the install-time script, and seems to be the + # least-fragile way to handle it. + myconf+=( --package-path="${ED}" ) + + # All needed sources are bundled in release tarballs + [ "${PV}" != "9999" ] && myconf+=( --skip-sync ) + + use bcfaso && myconf+=( --build-mode=bytecode-faso ) + + edo ./koga "${myconf[@]}" +} + +src_compile() { + edob eninja -C "${S}/build" +} + +src_test() { + # False positives from backtrace tests + #eninja -C "${S}/build" test + edo "${S}/build/boehmprecise/clasp" --norc --disable-debugger --non-interactive \ + --eval '(ext:quit (if (eql (* 6 7) 42) 0 1))' +} + +src_install() { + eninja -C "${S}/build" install + dodoc ${DOCS[@]} + dodoc -r licenses + [ -e "${MANDOCS}" ] && doman ${MANDOCS[@]} +} diff --git a/gentoo/metadata.xml b/gentoo/metadata.xml new file mode 100644 index 0000000000..ccff09da01 --- /dev/null +++ b/gentoo/metadata.xml @@ -0,0 +1,31 @@ + + + + + msouth@hamptonandsouth.com + Michael South + + Clasp is a new Common Lisp implementation that + seamlessly interoperates with C++ libraries and programs using LLVM + for compilation to native code. + + Building Clasp requires that you already have a running CL compiler. + This is hard-coded to SBCL due to strong preference from upstream. + + + Build-mode :bytecode-faso rather than the default + :faso (LLVM binary format). :bytecode-faso leaves the kernel and modules + as FASO but user code is bytecode (faster compilation but slower execution). + + + + clasp-developers/clasp + + clasp-devel@common-lisp.net + Clasp developers + + https://github.com/clasp-developers/clasp/blob/main/RELEASE_NOTES.md + https://clasp-developers.github.io/manual.html + https://github.com/clasp-developers/clasp/issues/new + + diff --git a/src/koga/archive.lisp b/src/koga/archive.lisp index 803bd1ee63..02138555aa 100644 --- a/src/koga/archive.lisp +++ b/src/koga/archive.lisp @@ -9,8 +9,8 @@ &key archive extensions tag &allow-other-keys) (declare (ignore initargs)) - (let* ((prefix (format nil "clasp-~a/" - (getf (read-file-form #P"version.sexp" tag) :version))) + (let* ((version (getf (read-file-form #P"version.sexp" tag) :version)) + (prefix (format nil "clasp-~a/" version)) (tar-name (concatenate 'string (if (stringp archive) archive "archive") ".tar")) (gz-name (concatenate 'string tar-name ".gz"))) (uiop:delete-file-if-exists tar-name) @@ -40,4 +40,71 @@ tar-name temp-path)))) :want-stream-p nil) (message nil "Compressing archive...") - (run-program (format nil "gzip ~a" tar-name)))) + (run-program (format nil "gzip ~a" tar-name)) + (generate-ebuild version gz-name))) + +(defun generate-ebuild (&optional (version "9999") archive) + (labels ((mk-os-path (&rest args) + ;; args: (full-os-path) | (dir fname) | (dir base ext) + (format nil "~<~^~a~^/~a~^.~a~:>" args)) + (os-path-fname (path) + (nth-value 2 (uiop:split-unix-namestring-directory-components path))) + (os->cl-path (os-path) + (uiop:ensure-absolute-pathname os-path (uiop:getcwd))) + (fbytes (os-path) + (or (with-open-file (s (os->cl-path os-path) :element-type 'unsigned-byte + :if-does-not-exist nil) + (when s (file-length s))) + 0)) + (calc-hash (os-path hash-type) + (subseq (uiop:run-program (format nil "cksum -a ~a --untagged \"~a\"" os-path hash-type) + :output :string) + 0 128)) + (copy-f (src-os-path dest-os-path) + (let ((s-path (os->cl-path src-os-path)) + (d-path (os->cl-path dest-os-path))) + (uiop:ensure-all-directories-exist (list d-path)) + (uiop:delete-file-if-exists d-path) + (uiop:copy-file s-path d-path)))) + (let* ((src-dir "gentoo") + (dest-dir "gentoo/clasp") + (manifest-name "Manifest") + (pkg-ver (concatenate 'string "clasp-" version)) + ;; Files to copy: each entry (manifest-label source dest) + (flist `(,@(unless (equal version "9999") + `(("EBUILD" ,(mk-os-path src-dir "ebuild.template") + ,(mk-os-path dest-dir pkg-ver "ebuild")))) + ("EBUILD" ,(mk-os-path src-dir "ebuild.template") + ,(mk-os-path dest-dir "clasp-9999.ebuild")) + ("MISC" ,(mk-os-path src-dir "metadata.xml") + ,(mk-os-path dest-dir "metadata.xml")) + ,@(when archive `(("DIST" nil ,(mk-os-path archive)))))) + ;; -- + (manifest-path (os->cl-path (mk-os-path dest-dir manifest-name))) + (manifest-temp-path (uiop:tmpize-pathname manifest-path))) + (message nil "Creating Gentoo/Portage distro files for ~a..." pkg-ver) + (uiop:ensure-all-directories-exist (list manifest-temp-path)) + (with-open-file (mfst-dest manifest-temp-path :direction :output :if-exists :supersede) + ;; Copy existing Manifest into temp file, dropping entries we're about + ;; to create. + (with-open-file (mfst-src manifest-path :direction :input :if-does-not-exist nil) + (when mfst-src + (loop + for line = (read-line mfst-src nil nil) + while line + ;; Omit manifest entries we're about to create + unless (some (lambda (x) (search (os-path-fname (third x)) line)) flist) + do (write-line line mfst-dest)))) + ;; Copy files, add them to manifest + (loop for (mfst-type s-os-path d-os-path) in flist + when s-os-path + do (copy-f s-os-path d-os-path) + do (with-standard-io-syntax + (format mfst-dest "~a ~a ~d BLAKE2B ~a SHA512 ~a~%" + mfst-type + (os-path-fname d-os-path) + (fbytes d-os-path) + (calc-hash "blake2b" d-os-path) + (calc-hash "sha512" d-os-path))))) + (uiop:rename-file-overwriting-target manifest-temp-path manifest-path) + manifest-path)))