From patchwork Wed Jan 12 09:47:52 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: iyzsong--- via Guix-patches via X-Patchwork-Id: 36238 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id 65C2427BBEA; Wed, 12 Jan 2022 09:48:16 +0000 (GMT) X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.7 required=5.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL, SPF_HELO_PASS,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.6 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id B239727BBE9 for ; Wed, 12 Jan 2022 09:48:14 +0000 (GMT) Received: from localhost ([::1]:53562 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1n7aEn-0001M7-Oo for patchwork@mira.cbaines.net; Wed, 12 Jan 2022 04:48:13 -0500 Received: from eggs.gnu.org ([209.51.188.92]:34912) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n7aEc-0001Lj-9a for guix-patches@gnu.org; Wed, 12 Jan 2022 04:48:03 -0500 Received: from debbugs.gnu.org ([209.51.188.43]:35144) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1n7aEb-0005Va-W2 for guix-patches@gnu.org; Wed, 12 Jan 2022 04:48:02 -0500 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1n7aEb-0005cL-Oh for guix-patches@gnu.org; Wed, 12 Jan 2022 04:48:01 -0500 X-Loop: help-debbugs@gnu.org Subject: [bug#48463] gnu: Add j. Resent-From: elaexuotee@wilsonb.com Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Wed, 12 Jan 2022 09:48:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 48463 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: Liliana Marie Prikler Cc: 48463@debbugs.gnu.org Received: via spool by 48463-submit@debbugs.gnu.org id=B48463.164198086921512 (code B ref 48463); Wed, 12 Jan 2022 09:48:01 +0000 Received: (at 48463) by debbugs.gnu.org; 12 Jan 2022 09:47:49 +0000 Received: from localhost ([127.0.0.1]:56280 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1n7aEG-0005Zz-Q8 for submit@debbugs.gnu.org; Wed, 12 Jan 2022 04:47:49 -0500 Received: from m42-5.mailgun.net ([69.72.42.5]:46643) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1n7aEB-0005ZN-8R for 48463@debbugs.gnu.org; Wed, 12 Jan 2022 04:47:39 -0500 DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.wilsonb.com; q=dns/txt; s=krs; t=1641980855; h=Content-Type: MIME-Version: Message-Id: In-Reply-To: References: From: Subject: Cc: To: Date: Sender; bh=BbO0FvEw0Vnh/fvPzF01OOTdChhzCbaW+O6xQxKYL9k=; b=e5X1kcxIjFLtV/+s3PJ8C7Fsi3av88iHpWwdWWrZJFSQMk8i+C7jvOFHAIvLucI3m3mKfTOn uVDqQLDiOi6QjyNucv0AI32Z5y30NGfwix9DF1GwI3uPL0yxGwm1mNDdorkR9H04W4nwFNzh GJfjyHIL53Z8PAhOBxBl8+dHEQpDVt3sN4yyBTLlIoqjplVTNuChxXN83I2Pa7hVHThLCY8G RB70niwL1rMun+GI2lYfyqMT558QNqMw//XqFiLkGlvP7RJLOHHwJNzpv6ugBakUbMO7ZjHu mRCfrDDhteR+pVPZNQhsHRz11r2mUV2m/M6OCzbOjPPdjIfjeoI/2g== X-Mailgun-Sending-Ip: 69.72.42.5 X-Mailgun-Sid: WyJjZGI4NCIsICI0ODQ2M0BkZWJidWdzLmdudS5vcmciLCAiMDg1NDdhIl0= Received: from wilsonb.com (wilsonb.com [104.199.203.42]) by smtp-out-n05.prod.us-east-1.postgun.com with SMTP id 61dea3b12b595aa321bbe087 (version=TLS1.3, cipher=TLS_AES_128_GCM_SHA256); Wed, 12 Jan 2022 09:47:29 GMT Received: from localhost (aj097104.dynamic.ppp.asahi-net.or.jp [220.150.97.104]) by wilsonb.com (Postfix) with ESMTPSA id 6C412A04C7; Wed, 12 Jan 2022 09:47:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=wilsonb.com; s=201703; t=1641980845; bh=BbO0FvEw0Vnh/fvPzF01OOTdChhzCbaW+O6xQxKYL9k=; h=Date:To:Cc:Subject:From:References:In-Reply-To:From; b=gr+en7htJbvbUoKQAWmtIcJ62z4QK5EIpeXxbAsTEympKXcn600w1PxB5vv5cscxu bCqz1rraVvC1LfgCKUY/bYDTWbrRsYL9V4ZVaGC4kMRtbq4po/GbnhfTCGFKHLsVz8 xTk6kuyl1/WbSYqvs5CVYIuQ1tNK1Za0WJilVTpekj20bVeqvVFwDs0E5Yv7JOCQEF FoBP06Qjj13gKl1RfWIQV45tP5DgoekO98nT7VzGdTBGBUHBDX/+vU15bbJrxYyYDr KUXv/bAYnGBUaHYRWDFTKxXW/3nbCdHRgoE/3SPj2PNVSBmOZGXYMghW+ZmX5tVKnt oxtsJNZbTTvxYsNb5CT9eGgKZ0K+s9zquVYFMnt+yPu6AYQxduBPvmSMFU4apksZN0 8dv3RHd1QJ2Zpm5QSr/hReo4LjYqBJrdhMphLKsp1NFjvU/GL2ahGe6otOe6GNOXef 5bvQLg0fUlaCk8szIK8hNdRcNppxwbBnptCv9lOBxmyy6EXmnM1W3eXDUKv1ulsmf3 1r1jGrWFl/HV1Zjz8joqcnOal5gaHeUnd4+HLKDsWRR6vfdqtizrT42AXv6EFzO/Yb ZdsQKWh7Ik55ezp65j148PYPBhtF3O8gqnNtQ9lg1elX/ETcrQVT53VySS9GnnmbHY ZS2afEmr+AkZdFEwbbFvAcKU= Date: Wed, 12 Jan 2022 18:47:52 +0900 References: <3LOAUDT0FLL4U.2SOD925YP915T@wilsonb.com> <8b853d0585505ce29c9afc638b644fa34805e6c0.camel@student.tugraz.at> <293L8YPQS4CLB.3VK1B1A36XNAY@wilsonb.com> <5d30160bd2a4592459cd407f99cbd3edadb1db1b.camel@student.tugraz.at> <27DCD25Y68ZWJ.2HRC4G65PWIA7@wilsonb.com> <94f4625dcb0479d873cf60449631527e841fd457.camel@gmail.com> In-Reply-To: <94f4625dcb0479d873cf60449631527e841fd457.camel@gmail.com> Message-Id: <2JQJMV0O718S1.31FZE8GKCTLPF@wilsonb.com> User-Agent: mblaze/1.1 MIME-Version: 1.0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: "Guix-patches" Reply-to: elaexuotee@wilsonb.com X-ACL-Warn: , elaexuotee--- via Guix-patches X-Patchwork-Original-From: elaexuotee--- via Guix-patches via From: iyzsong--- via Guix-patches via X-getmail-retrieved-from-mailbox: Patches Here's a long-needed update. > > For now, instead of messing with the union, would it make sense to > > just create a (non-public?) jsoftware-addons package that contains > > all addons and point jlib at those? > > Are those addons data packages or can they be compiled without needing > jlib? If they're pure data, then you can pack them up and refer them > as you wanted to, if not, you first have to create jlib-minimal without > them, then package up everything and finally do jlib. They're pure data, which is nice. The J package manager also lets users install arbitrary addons from GitHub, so packaging up the official addons would lock the `addons/' directory under the non-writable store, meaning that we probably also want an importer. I am working on that, but instead of keeping this package in lingo much longer, maybe we can release sonner and consider the addon package code a separate issue? > Oh, and one thing that was previously ignored is that using XDG > standards for things we can't simply put in the store (like > configuration if it needs that) is preferable to having a ~/.j > directory. Excellent point. Fixed. > > > That's less than the number of Rust versions we need just for > > > bootstrap, but still a few too many in my opinion. Are all of > > > those still used in production or would it be wiser to to put some > > > of them into Guix-Past [1]? > > People are also still running ancient versions of Debian. Python 2 has > officially reached end of life, yet it is used as well. At some point > we do have to declare software that people are still using as old :) Sounds sane. I will probably eventually work on getting the j80x series in Guix and the really ancient ones in Guix Past. However, that will be a future task for myself. > > > Having keyword lists is also nice and declarative, but more > > > importantly, it lets you call the function as a normal function > > > without having to worry about constructing some record in a > > > particular way. The configuration you're using doesn't have a > > > specific setting? Just override it with your own. It's as simple > > > as calling (append old-config extra-config). > > ... > Yup. Now using keyword lists. > > > I find this way of mistreating the version field very > > > weird. You're not adding anything new by doing this and you're not > > > making anything more secure (I'd argue, that it's less secure, > > > because you could update the version and forget about the property > > > or vice versa). The code overall is a lot more straightforward now. How does the versioning stuff look now? > > My thinking was that 4 means we want a separate *-beta package, > > meaning that the version field should probably just look like > > "-". > > Additionally, relating back to the above discussion about multiple > > versions > Sounds good, though . would be equally acceptable. > Your call. > > > 5) It would be nice to be able to install the latest j901 without > > having to > > know that this corresponds to patch level f, i.e. currently > > j@901-f. > I think `guix build j@901' ought to resolve this automatically. It turns out that the j@901 specification only gets recognized with versions strings of the form ., so going with that. > > > First of all, do you even need all this info? `j' is an > > > objectively bad name > > > for a package. `j-beta' is not better in any way, it only avoids > > > the user installing a potentially unstable "J" package. > > > > Yeah, "j" is pretty short but it does mirror "r". I'm agnostic about > > package name, though. Suggestions welcome. > Fair enough, though this remains a problem for single letter programs > in which others would likely want to claim the letter as well. R has > the benefit of being old and well-known enough, it would probably be > rlang otherwise (not to be confused with erlang). J has been around from the 1990's :D That said, I went ahead and named it `jsoftware-j', since despite age, J is still pretty obscure, and there's not much of a good reason to monopolize a single letter name. > > I see what you mean in a general sense but not quite how to apply it > > in this case. I am all ears if you have a simpler, cleaner solution > > that addresses the constraints listed above! > I think the cleaner solution here is to not store those properties in > the package, but still having them as parameters to the make-j function > call. Happily, the new package re-organization was able to get rid of these properties. > > > Next, should ijconsole not simply be a package like jlib (both > > > properly prefixed with jsoftware- of course)? > > > > This is effectively what make-j does, no? ijconsole needs to know the > > path to jlib, so make-j points it at the correct one and wraps > > everything up into a package. > I don't really understand why those needs to be done in two steps > however. ijconsole could already contain the fully functioning j > program. Or partially functioning if we account for addons. As you can see, there's no need for a separate ijconsole package any more. Instead, `ijconsole' is just defined as a program-file that becomes an input to jsoftware-j. It is also worth pointing out the convenience procedure `jsoftware-ijconsole-symlink'. Basically, it p Anyway, let me know what you think! From 98be43134f62132a98a97f7601e97c3ae9ec63c6 Mon Sep 17 00:00:00 2001 From: "B. Wilson" Date: Wed, 12 Jan 2022 18:44:36 +0900 Subject: [PATCH] gnu: Add j. To: guix-patches@gnu.org * gnu/packages/jsoftware.scm: New file. * gnu/packages/patches/jsoftware-j901-f-fixes.patch: New file. * gnu/local.mk: Register it. --- gnu/local.mk | 1 + gnu/packages/jsoftware.scm | 455 ++++++++++++++++++ .../patches/jsoftware-j901-f-fixes.patch | 80 +++ 3 files changed, 536 insertions(+) create mode 100644 gnu/packages/jsoftware.scm create mode 100644 gnu/packages/patches/jsoftware-j901-f-fixes.patch diff --git a/gnu/local.mk b/gnu/local.mk index 1706663bde..0cbb8899ee 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -1290,6 +1290,7 @@ dist_patch_DATA = \ %D%/packages/patches/irrlicht-use-system-libs.patch \ %D%/packages/patches/isc-dhcp-gcc-compat.patch \ %D%/packages/patches/isl-0.11.1-aarch64-support.patch \ + %D%/packages/patches/jsoftware-j901-f-fixes.patch \ %D%/packages/patches/json-c-0.13-CVE-2020-12762.patch \ %D%/packages/patches/json-c-0.12-CVE-2020-12762.patch \ %D%/packages/patches/jsoncpp-pkg-config-version.patch \ diff --git a/gnu/packages/jsoftware.scm b/gnu/packages/jsoftware.scm new file mode 100644 index 0000000000..472a6c30d4 --- /dev/null +++ b/gnu/packages/jsoftware.scm @@ -0,0 +1,455 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2022 B. Wilson +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see . + +(define-module (gnu packages jsoftware) + #:use-module ((guix build utils)) + #:use-module ((guix build-system gnu)) + #:use-module ((guix build-system trivial)) + #:use-module ((guix git-download)) + #:use-module ((guix licenses) #:prefix license:) + #:use-module ((guix packages)) + #:use-module ((guix utils)) + #:use-module ((gnu packages)) + #:use-module ((gnu packages libedit)) + #:use-module ((gnu packages llvm)) + #:use-module ((gnu packages maths)) + #:use-module ((guix gexp)) + #:use-module ((ice-9 ftw)) + #:use-module ((ice-9 match)) + #:use-module ((ice-9 regex)) + #:use-module ((ice-9 rdelim)) + #:use-module ((srfi srfi-26))) + + +;;; TODO: Make importer and packages for J addons: +;;; http://www.jsoftware.com/jal/ + +;;; TODO: Package up j80x series + + +(define (jname prefix jtype) + "Return a package name for the given prefix and jtype, e.g. `jlib', + `jlib-beta', `j', and `j-beta'." + (let ((postfix (if (eq? jtype 'release) "" + (string-append "-" (symbol->string jtype))))) + (string-append prefix postfix))) + +(define (jversion->string version revision) + "Return a string representation of a J version and (optional) revision pair." + (let ((postfix (if (not revision) "" + (string-append "." revision)))) + (string-append version postfix))) + +(define (jinfo->git-tag jversion jtype jrevision) + "Given version parameters, construct a git tag for upstream releases." + (let ((postfix (if (not jrevision) "" + (string-append "-" jrevision)))) + (string-append "j" jversion "-" (symbol->string jtype) postfix))) + +(define (ijconsole) + "Generate a G-exp script that detects AVX/AVX2 support at runtime and + executes jconsole with the appropriate libj.so and profile.ijs." + (program-file "ijconsole" + #~(begin + (use-modules ((ice-9 rdelim) #:select (read-line)) + ((ice-9 regex) #:select (regexp-match? string-match))) + + ;; Assume that this script will be installed under bin/. + (define %basedir (dirname (dirname (current-filename)))) + + (define (cpu-feature-line? string) + (string-prefix? "flags" string)) + + (define (contains-word? word string) + (regexp-match? + (string-match (string-join `("\\<" ,word "\\>") "") + string))) + + (define (has-cpu-feature? feature) + (with-input-from-file "/proc/cpuinfo" + (lambda () + (catch 'found + (lambda () + (let loop ((line (read-line))) + (cond ((eof-object? line) #f) + ((and (cpu-feature-line? line) + (contains-word? feature line)) + (throw 'found)) + (else (loop (read-line)))))) + (const #t))))) + + (let* ((jconsole (string-append %basedir "/libexec/j/jconsole")) + (libj (format #f "~a/lib/j/libj-~a.so" %basedir + (cond ((has-cpu-feature? "avx2") "avx2") + ((has-cpu-feature? "avx") "avx") + (else "")))) + (jprofile (string-append %basedir "/etc/j/profile.ijs"))) + (apply execl jconsole "ijconsole" "-lib" libj "-jprofile" jprofile + (cdr (command-line))))))) + +(define* (make-j #:key + (builder "guix.gnu.org") + vername + revision + hash + (type 'release) + commit + (patches '()) + (extra-inputs '()) + (extra-envars '())) + (package + (name (jname "jsoftware-j" type)) + (version (jversion->string vername revision)) + (source + (origin + (method git-fetch) + (uri (git-reference + (url "https://github.com/jsoftware/jsource") + (commit (or commit (jinfo->git-tag vername type revision))))) + (sha256 (base32 hash)) + (file-name (git-file-name name version)) + (patches patches))) + (build-system gnu-build-system) + (native-inputs `(("clang-toolchain" ,clang-toolchain))) + (inputs (cons* `("libedit" ,libedit) + `("libomp" ,libomp) + `("ijconsole" ,(ijconsole)) + extra-inputs)) + (arguments + `(#:tests? #f + #:modules (((ice-9 ftw) #:select (scandir)) + ((ice-9 popen) #:select (open-pipe* close-pipe)) + ((ice-9 regex) #:select (match:substring string-match)) + ((ice-9 threads) #:select (parallel par-for-each)) + ((srfi srfi-26) #:select (cut)) + ((srfi srfi-1) #:select (fold)) + ,@%gnu-build-system-modules) + #:phases + ;; Upstream's build system consists of ad-hoc scripts that build build up + ;; (very complicated) environment variables to pass to make. The basic + ;; build process looks like this: + ;; + ;; 1) Copy jsrc/jversion-x.h to jsrc/jversion.h and edit values; + ;; 2) Set jplatform and j64x environment variables; + ;; 3) Run make2/build_jconsole.sh and make2/build_libj.sh; + ;; + ;; However, upstream expects users to run J directly from the source + ;; directory; they do not supply a make `install' target. Thus it takes + ;; some massaging to install files in FHS-style directories. + (modify-phases %standard-phases + ;; In particular, we have to set up + ;; + ;; 1) jsrc/jversion.h as in a typical build; + ;; 2) jlibrary/bin/profilex.ijs to point to writable directories; + ;; 3) make2/build_*.sh to respect standard build conventions; + ;; 4) jsrc/jconsole.c to fix libedit dlopen; and + ;; 5) Hard coded references to addons directory. + (replace 'configure + (lambda* (#:key target inputs outputs #:allow-other-keys) + (let* ((clang-toolchain (assoc-ref inputs "clang-toolchain")) + (clang (string-append clang-toolchain "/bin/clang")) + (libedit (assoc-ref inputs "libedit")) + (out (assoc-ref outputs "out"))) + ;; Set up build constants + (copy-file "jsrc/jversion-x.h" "jsrc/jversion.h") + (substitute* "jsrc/jversion.h" + (("^#define jversion.*$") + (format #f "#define jversion ~s\n" ,version)) + (("^#define jtype.*$") + (format #f "#define jtype ~s\n" (symbol->string ',type))) + (("^#define jbuilder.*$") + (format #f "#define jbuilder ~s\n" ,builder))) + ;; Create profilex.ijs overrides to point to the correct store + ;; items. Note that we set ~install and ~addons directories to + ;; reside under ~user to allow installing and loading addons. + ;; TODO: Guix-ify J addons as well. + (call-with-output-file "jlibrary/bin/profilex.ijs" + (lambda (port) + (display + (string-join + (list + "share=. '/share/j',~ ({.~ _2 { I.@:=&'/') BINPATH" + "system=. share,'/system'" + "tools=. share,'/tools'" + ;; Upstream defaults to spamming $HOME with unhidden + ;; userdata directories. Set this to be + ;; $HOME/.j// instead + "'jtype jversion'=. (3&{,{.) <;._2 ,&'/' 9!:14''" + "jversion=. ({.~ i.&'-') jversion" + "jsuffix=. >@{&('';'-beta') jtype -: 'beta'" + "user=. home,'/.config/j/',jversion,jsuffix" + "addons=. user,'/addons'" + "break=. user,'/break'" + "config=. user,'/config'" + "install=. user,'/install'" + "snap=. user,'/snap'" + "temp=. user,'/temp'" + "\n") + "\n") + port))) + ;; Munge the build scripts into reason: + ;; 1. Short-circuit the fragile compiler detection; + ;; 2. Make sure to include our CFLAGS and LFLAGS; and + ;; 3. Propagate script errors to top level. + (for-each + (lambda (file) + (with-directory-excursion "make2" + (substitute* file + ;; The `compiler' variable doesn't point to the actual + ;; compiler. It is just a switch to tell the build + ;; scripts whether to use gcc- or clang-specific flags. + (("^compiler=.*$") "compiler=clang\n") + (("^LDFLAGS=\"" def) (string-append def "$LDFLAGS ")) + (("^(common=\")(\\$USETHREAD.*)$" _ def rest) + (string-append def "$CFLAGS " rest)) + (("^#!.*" shebang) + (string-append shebang "set -o errexit\n"))))) + '("build_jconsole.sh" "build_libj.sh")) + ;; The jconsole manually loads libedit with dlopen. The path + ;; must be absolute to correctly point to our input. + (substitute* "jsrc/jconsole.c" + (("libedit\\.so\\.[0-9]" so-file) + (format #f "~a/lib/~a" libedit so-file))) + ;; The ~addons/dev directory supplies tentative J-script + ;; definitions of new J engine functionality. Since we point + ;; ~addons under the ~user directory, we move it under ~system + ;; instead, which sits as-is in the output. + (with-directory-excursion "jsrc" + (for-each + (lambda (file) + (substitute* file (("~addons/dev") "~system/dev"))) + (scandir "." + (lambda (f) (eq? (stat:type (stat f)) 'regular))))) + ;; Implementation of 9!:14 records build time which breaks build + ;; reproducibility. Note that upstream code depends on the exact + ;; format of these strings, so we need to mimic the standard. + (substitute* "jsrc/j.c" + (("__DATE__") "\"Jan 01 1970\"") + (("__TIME__") "\"00:00:00\"")) + ;; Upstream recommends using clang, with GCC support being + ;; second-class, often resulting in build failures. + (setenv "CC" clang)))) + + ;; The build output depends primarily on the values of the `jplatform' + ;; and `j64x' environment variables. If the target is ARM, then + ;; `jplatform' is "raspberry", otherwise it is `linux'. In addition to + ;; 32- and 64- bit versions, `j64x' controlls whether AVX or AVX2 + ;; variants of libj are built. + ;; + ;; However, build targets are not fine-grained enough to distinguish + ;; between CPU features. Thus we build and install all variants of + ;; libj, expecting jconsole to be called with a wrapper script that + ;; detects AVX features and loads the appropriate libj at runtime. + (replace 'build + (lambda _ + (setenv "USE_OPENMP" "1") + (setenv "USE_THREAD" "1") + (for-each (lambda (var-val) (apply setenv var-val)) + (quote ,extra-envars)) + ;; The build scripts assume that PWD is make2. + (with-directory-excursion "make2" + (let* ((platform ,(if (target-arm?) "raspberry" "linux")) + (jplat (string-append "jplatform=" platform)) + (target-bit ,(if (target-64bit?) "64" "32")) + (jbit (string-append "j64x=" "j" target-bit)) + (jbit-avx (string-append jbit "avx")) + (jbit-avx2 (string-append jbit "avx2"))) + (parallel + ;; Since jconsole doesn't depend on AVX features, we just + ;; build it once. + (invoke "env" jplat jbit "./build_jconsole.sh") + (invoke "env" jplat jbit "./build_libj.sh") + (if ,(target-64bit?) + (parallel + (invoke "env" jplat jbit-avx "./build_libj.sh") + (invoke "env" jplat jbit-avx2 + "./build_libj.sh")))))))) + ;; The test suite is expected to be run as follows for each variant of + ;; libj that we build: + ;; + ;; $ echo 'RUN ddall' | jconsole test/tsu.ijs + ;; + ;; This requires a working jconsole with accessible jlibrary files. We + ;; simply place these all under test/bin. + (replace 'check + (lambda* (#:key tests? #:allow-other-keys) + (when tests? + (let ((jplatform ,(if (target-arm?) "raspberry" "linux"))) + (mkdir-p "test/bin") + (for-each + (lambda (dir) + (let ((source (string-append "jlibrary/" dir)) + (dest (string-append "test/bin/" dir))) + (begin + (mkdir-p dest) + (copy-recursively source dest)))) + '("system" "tools" "addons")) + ;; The jlibrary/dev directory only sometimes exists, but needs + ;; to be copied into the ~system directory when it does. + (for-each + (lambda (dev-dir) + (if (access? dev-dir R_OK) + (copy-recursively dev-dir "test/bin/system/dev"))) + '("jlibrary/dev" "jlibrary/addons/dev")) + (par-for-each + (lambda (dir) + (let* ((jbin (string-append "bin/" jplatform)) + (jbit ,(if (target-64bit?) "j64" "j32")) + (jconsole (string-append jbin "/" jbit + "/jconsole")) + (source (string-append jbin "/" dir)) + (dest (string-append "test/bin/" dir))) + (begin + (mkdir-p dest) + (copy-recursively source dest) + (install-file "jlibrary/bin/profile.ijs" dest) + (install-file jconsole dest) + (let* ((jc (string-append dest "/jconsole")) + (tests "test/tsu.ijs") + (port (open-pipe* OPEN_WRITE jc tests))) + (display "RUN ddall\n" port) + (when (not (zero? (status:exit-val + (close-pipe port)))) + (error "Some J build tests failed.")))))) + (scandir (string-append "bin/" jplatform) + (negate (cut member <> '("." ".."))))) + #t)))) + ;; Now that everything is built, installation is fairly + ;; straightforward, following FHS conventions. The only quirk is that + ;; we install jconsole under /libexec to make room for the wrapper + ;; replacement under /bin. + (replace 'install + (lambda* (#:key outputs inputs #:allow-other-keys) + (let* ((jplat ,(if (target-arm?) "raspberry" "linux")) + (jbit ,(if (target-64bit?) "j64" "j32")) + (ijconsole (assoc-ref inputs "ijconsole")) + (interp (string-join `("bin" ,jplat ,jbit "jconsole") "/")) + (out (assoc-ref outputs "out")) + (bin (string-append out "/bin")) + (etc (string-append out "/etc/j")) + (lib (string-append out "/lib/j")) + (libexec (string-append out "/libexec/j")) + (share (string-append out "/share/j")) + (system (string-append share "/system")) + (dev (string-append system "/dev"))) + (mkdir-p bin) + (copy-file ijconsole (string-append bin "/ijconsole-" ,vername)) + (mkdir-p lib) + (for-each + (lambda (jarch) + (let* ((jbin (string-join `("bin" ,jplat ,jarch) "/")) + (javx-match (string-match "avx.*" jarch)) + (javx (if (not javx-match) "" + (match:substring javx-match))) + (sep (if javx-match "-" "")) + (source (string-append jbin "/libj.so")) + (dest (format #f "~a/libj~a~a.so" lib sep javx))) + (copy-file source dest))) + (scandir (string-append "bin/" jplat) + (negate (cut member <> '("." ".."))))) + (install-file interp libexec) + (copy-recursively "jlibrary/system" system) + (for-each + (lambda (source-dev) + (if (access? source-dev R_OK) + (copy-recursively source-dev dev))) + '("jlibrary/dev" "jlibrary/addons/dev")) + (install-file "jlibrary/bin/profile.ijs" etc) + (install-file "jlibrary/bin/profilex.ijs" etc))))))) + (home-page "https://www.jsoftware.com/") + (synopsis "Ascii-only, array programming language in the APL family") + (description + "J is a high-level, general-purpose programming language that is +particularly suited to the mathematical, statistical, and logical analysis of +data. It is a powerful tool for developing algorithms and exploring problems +that are not already well understood.") + (license license:gpl3+))) + + +(define-public jsoftware-j-901 + (make-j + #:vername "901" + #:revision "f" + #:hash "1776021m0j1aanzwg60by83n53pw7i6afd5wplfzczwk8bywax4p" + #:patches (search-patches "jsoftware-j901-f-fixes.patch"))) + + +(define jlib-build-configuration-with-sleef + `(#:extra-inputs (("sleef" ,sleef)) + #:extra-envars (("USE_SLEEF_SRC" "0") + ("LDFLAGS" "-lsleef")))) + +(define-public jsoftware-j-902 + (apply make-j + (append jlib-build-configuration-with-sleef + '(#:vername "902" + #:revision "b" + #:hash "0j67vgikqflwjqacsdicasvyv1k54s2c8vjgwmf0ix7l41p4xqz0")))) + + +(define-public jsoftware-j-903 + (apply make-j + (append jlib-build-configuration-with-sleef + '(#:vername "903" + #:revision "a" + #:commit "903-release-a" + #:hash "1fcfl7q7c2vj4fmnqqc8c6hwgsjm20ff93v8xxfniasss1b2fmc4")))) + +;; Keep until j904-beta is released. +(define-public jsoftware-j-903-beta + (apply make-j + (append jlib-build-configuration-with-sleef + `(#:vername "903" + #:revision "w" + #:type ,'beta + #:hash "0kd63mrkaq0bs42gw0wrlb14fymhigznx1lrb698dgv6fzlfglim")))) + + +(define-public (jsoftware-ijconsole-symlink jpkg) + "Provide bin/ijconsole symlink that points to pkg's bin/ijconsole-" + (package + (name "jsoftware-ijconsole") + (version (package-version jpkg)) + (source #f) + (build-system trivial-build-system) + (propagated-inputs `(("jpkg" ,jpkg))) + (arguments + `(#:modules ((guix build utils) + (srfi srfi-26)) + #:builder + (begin + (use-modules ((guix build utils) #:select (mkdir-p)) + ((ice-9 regex) #:select (string-match)) + ((ice-9 ftw) #:select (scandir)) + ((srfi srfi-26) #:select (cut))) + (let* ((out (assoc-ref %outputs "out")) + (jpkg (assoc-ref %build-inputs "jpkg")) + (interp (car (scandir (string-append jpkg "/bin") + (cut string-match "ijconsole-.*" <>)))) + (source (string-append jpkg "/bin/" interp)) + (dest (string-append out "/bin/ijconsole"))) + (mkdir-p (dirname dest)) + (symlink source dest))))) + (home-page (package-home-page jpkg)) + (synopsis "Provide `ijconsole' symlink to default interpreter version") + (description + "The interpreter provided by the J package has a filename like +ijconsole-, which provides support for having multiple, concurrent +versions installed. This package provides a version-agnostic `ijconsole' +symlink to interpreter version indicated and build time.") + (license license:gpl3+))) diff --git a/gnu/packages/patches/jsoftware-j901-f-fixes.patch b/gnu/packages/patches/jsoftware-j901-f-fixes.patch new file mode 100644 index 0000000000..0ac7e94de4 --- /dev/null +++ b/gnu/packages/patches/jsoftware-j901-f-fixes.patch @@ -0,0 +1,80 @@ +This patch fixes two separate issues with ustream sources: + +* Normalize import paths in jsrc/cip.c + +Upstream claims to have some build requirements that force them to use strange +import paths. However, these paths do not exist inside our build chroot. + +* Fix unititialized variable warning + +Clang 9 issues some warnings which cause the build to fail since upstream +compiles with -Werror. + + +diff --git a/jsrc/cip.c b/jsrc/cip.c +index 61da4088..fb3c03b6 100644 +--- a/jsrc/cip.c ++++ b/jsrc/cip.c +@@ -3,9 +3,9 @@ + /* */ + /* Conjunctions: Inner Product */ + +-#include "../../jsource/jsrc/j.h" +-#include "../../jsource/jsrc/vasm.h" +-#include "../../jsource/jsrc/gemm.h" ++#include "j.h" ++#include "vasm.h" ++#include "gemm.h" + + #define MAXAROWS 384 // max rows of a that we can process to stay in L2 cache a strip is m*CACHEHEIGHT, z strip is m*CACHEWIDTH this is wired to 128*3 - check if you chage + +@@ -1057,15 +1057,15 @@ static A jtipbx(J jt,A a,A w,C c,C d){A g=0,x0,x1,z;B*av,*av0,b,*v0,*v1,*zv;C c0 + switch(c){ + case CPLUSDOT: + #define F |= +-#include "../../jsource/jsrc/cip_t.h" ++#include "cip_t.h" + break; + case CSTARDOT: + #define F &= +-#include "../../jsource/jsrc/cip_t.h" ++#include "cip_t.h" + break; + case CNE: + #define F ^= +-#include "../../jsource/jsrc/cip_t.h" ++#include "cip_t.h" + break; + } + R z; +diff --git a/jsrc/gemm.c b/jsrc/gemm.c +index 51fe306e..b105dfc1 100644 +--- a/jsrc/gemm.c ++++ b/jsrc/gemm.c +@@ -318,7 +318,7 @@ dgemm_nn (I m, + _B); + + // loop 3 +- I i; ++ I i=0; + #pragma omp parallel for default(none),private(i),shared(j,l,A,C,mb,nc,kc,alpha,_beta,_mc,_B,rs_a,cs_a,rs_c,cs_c) + for (i=0; i